Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 2e15497c

History | View | Annotate | Download (365.1 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 and microMIPS 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 "cpu.h"
24
#include "disas.h"
25
#include "tcg-op.h"
26

    
27
#include "helper.h"
28
#define GEN_HELPER 1
29
#include "helper.h"
30

    
31
//#define MIPS_DEBUG_DISAS
32
//#define MIPS_DEBUG_SIGN_EXTENSIONS
33

    
34
/* MIPS major opcodes */
35
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
36

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

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

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

    
191
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
192

    
193
    /* Special */
194
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
195
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
196
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
197
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
198
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
199

    
200
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
201
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
202
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
203
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
204
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
205
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
206
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
207
};
208

    
209
/* Multiplication variants of the vr54xx. */
210
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
211

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

    
229
/* REGIMM (rt field) opcodes */
230
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
231

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

    
252
/* Special2 opcodes */
253
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
254

    
255
enum {
256
    /* Multiply & xxx operations */
257
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
258
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
259
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
260
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
261
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
262
    /* Loongson 2F */
263
    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
264
    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
265
    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
266
    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
267
    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
268
    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
269
    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
270
    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
271
    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
272
    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
273
    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
274
    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
275
    /* Misc */
276
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
277
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
278
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
279
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
280
    /* Special */
281
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
282
};
283

    
284
/* Special3 opcodes */
285
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
286

    
287
enum {
288
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
289
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
290
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
291
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
292
    OPC_INS      = 0x04 | OPC_SPECIAL3,
293
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
294
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
295
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
296
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
297
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
298
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
299
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
300
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
301

    
302
    /* Loongson 2E */
303
    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
304
    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
305
    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
306
    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
307
    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
308
    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
309
    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
310
    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
311
    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
312
    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
313
    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
314
    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
315
};
316

    
317
/* BSHFL opcodes */
318
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
319

    
320
enum {
321
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
322
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
323
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
324
};
325

    
326
/* DBSHFL opcodes */
327
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
328

    
329
enum {
330
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
331
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
332
};
333

    
334
/* Coprocessor 0 (rs field) */
335
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
336

    
337
enum {
338
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
339
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
340
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
341
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
342
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
343
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
344
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
345
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
346
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
347
    OPC_C0       = (0x10 << 21) | OPC_CP0,
348
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
349
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
350
};
351

    
352
/* MFMC0 opcodes */
353
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
354

    
355
enum {
356
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
357
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
358
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
359
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
360
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
361
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
362
};
363

    
364
/* Coprocessor 0 (with rs == C0) */
365
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
366

    
367
enum {
368
    OPC_TLBR     = 0x01 | OPC_C0,
369
    OPC_TLBWI    = 0x02 | OPC_C0,
370
    OPC_TLBWR    = 0x06 | OPC_C0,
371
    OPC_TLBP     = 0x08 | OPC_C0,
372
    OPC_RFE      = 0x10 | OPC_C0,
373
    OPC_ERET     = 0x18 | OPC_C0,
374
    OPC_DERET    = 0x1F | OPC_C0,
375
    OPC_WAIT     = 0x20 | OPC_C0,
376
};
377

    
378
/* Coprocessor 1 (rs field) */
379
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
380

    
381
/* Values for the fmt field in FP instructions */
382
enum {
383
    /* 0 - 15 are reserved */
384
    FMT_S = 16,          /* single fp */
385
    FMT_D = 17,          /* double fp */
386
    FMT_E = 18,          /* extended fp */
387
    FMT_Q = 19,          /* quad fp */
388
    FMT_W = 20,          /* 32-bit fixed */
389
    FMT_L = 21,          /* 64-bit fixed */
390
    FMT_PS = 22,         /* paired single fp */
391
    /* 23 - 31 are reserved */
392
};
393

    
394
enum {
395
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
396
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
397
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
398
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
399
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
400
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
401
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
402
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
403
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
404
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
405
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
406
    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
407
    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
408
    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
409
    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
410
    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
411
    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
412
    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
413
};
414

    
415
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
416
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
417

    
418
enum {
419
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
420
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
421
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
422
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
423
};
424

    
425
enum {
426
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
427
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
428
};
429

    
430
enum {
431
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
432
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
433
};
434

    
435
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
436

    
437
enum {
438
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
439
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
440
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
441
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
442
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
443
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
444
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
445
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
446
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
447
};
448

    
449
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
450

    
451
enum {
452
    OPC_LWXC1   = 0x00 | OPC_CP3,
453
    OPC_LDXC1   = 0x01 | OPC_CP3,
454
    OPC_LUXC1   = 0x05 | OPC_CP3,
455
    OPC_SWXC1   = 0x08 | OPC_CP3,
456
    OPC_SDXC1   = 0x09 | OPC_CP3,
457
    OPC_SUXC1   = 0x0D | OPC_CP3,
458
    OPC_PREFX   = 0x0F | OPC_CP3,
459
    OPC_ALNV_PS = 0x1E | OPC_CP3,
460
    OPC_MADD_S  = 0x20 | OPC_CP3,
461
    OPC_MADD_D  = 0x21 | OPC_CP3,
462
    OPC_MADD_PS = 0x26 | OPC_CP3,
463
    OPC_MSUB_S  = 0x28 | OPC_CP3,
464
    OPC_MSUB_D  = 0x29 | OPC_CP3,
465
    OPC_MSUB_PS = 0x2E | OPC_CP3,
466
    OPC_NMADD_S = 0x30 | OPC_CP3,
467
    OPC_NMADD_D = 0x31 | OPC_CP3,
468
    OPC_NMADD_PS= 0x36 | OPC_CP3,
469
    OPC_NMSUB_S = 0x38 | OPC_CP3,
470
    OPC_NMSUB_D = 0x39 | OPC_CP3,
471
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
472
};
473

    
474
/* global register indices */
475
static TCGv_ptr cpu_env;
476
static TCGv cpu_gpr[32], cpu_PC;
477
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
478
static TCGv cpu_dspctrl, btarget, bcond;
479
static TCGv_i32 hflags;
480
static TCGv_i32 fpu_fcr0, fpu_fcr31;
481

    
482
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
483

    
484
#include "gen-icount.h"
485

    
486
#define gen_helper_0i(name, arg) do {                             \
487
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
488
    gen_helper_##name(helper_tmp);                                \
489
    tcg_temp_free_i32(helper_tmp);                                \
490
    } while(0)
491

    
492
#define gen_helper_1i(name, arg1, arg2) do {                      \
493
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
494
    gen_helper_##name(arg1, helper_tmp);                          \
495
    tcg_temp_free_i32(helper_tmp);                                \
496
    } while(0)
497

    
498
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
499
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
500
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
501
    tcg_temp_free_i32(helper_tmp);                                \
502
    } while(0)
503

    
504
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
505
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
506
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
507
    tcg_temp_free_i32(helper_tmp);                                \
508
    } while(0)
509

    
510
typedef struct DisasContext {
511
    struct TranslationBlock *tb;
512
    target_ulong pc, saved_pc;
513
    uint32_t opcode;
514
    int singlestep_enabled;
515
    /* Routine used to access memory */
516
    int mem_idx;
517
    uint32_t hflags, saved_hflags;
518
    int bstate;
519
    target_ulong btarget;
520
} DisasContext;
521

    
522
enum {
523
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
524
                      * exception condition */
525
    BS_STOP     = 1, /* We want to stop translation for any reason */
526
    BS_BRANCH   = 2, /* We reached a branch condition     */
527
    BS_EXCP     = 3, /* We reached an exception condition */
528
};
529

    
530
static const char *regnames[] =
531
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
532
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
533
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
534
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
535

    
536
static const char *regnames_HI[] =
537
    { "HI0", "HI1", "HI2", "HI3", };
538

    
539
static const char *regnames_LO[] =
540
    { "LO0", "LO1", "LO2", "LO3", };
541

    
542
static const char *regnames_ACX[] =
543
    { "ACX0", "ACX1", "ACX2", "ACX3", };
544

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

    
551
#ifdef MIPS_DEBUG_DISAS
552
#define MIPS_DEBUG(fmt, ...)                         \
553
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
554
                       TARGET_FMT_lx ": %08x " fmt "\n", \
555
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
556
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
557
#else
558
#define MIPS_DEBUG(fmt, ...) do { } while(0)
559
#define LOG_DISAS(...) do { } while (0)
560
#endif
561

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

    
568
/* General purpose registers moves. */
569
static inline void gen_load_gpr (TCGv t, int reg)
570
{
571
    if (reg == 0)
572
        tcg_gen_movi_tl(t, 0);
573
    else
574
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
575
}
576

    
577
static inline void gen_store_gpr (TCGv t, int reg)
578
{
579
    if (reg != 0)
580
        tcg_gen_mov_tl(cpu_gpr[reg], t);
581
}
582

    
583
/* Moves to/from ACX register.  */
584
static inline void gen_load_ACX (TCGv t, int reg)
585
{
586
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
587
}
588

    
589
static inline void gen_store_ACX (TCGv t, int reg)
590
{
591
    tcg_gen_mov_tl(cpu_ACX[reg], t);
592
}
593

    
594
/* Moves to/from shadow registers. */
595
static inline void gen_load_srsgpr (int from, int to)
596
{
597
    TCGv t0 = tcg_temp_new();
598

    
599
    if (from == 0)
600
        tcg_gen_movi_tl(t0, 0);
601
    else {
602
        TCGv_i32 t2 = tcg_temp_new_i32();
603
        TCGv_ptr addr = tcg_temp_new_ptr();
604

    
605
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
606
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
607
        tcg_gen_andi_i32(t2, t2, 0xf);
608
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
609
        tcg_gen_ext_i32_ptr(addr, t2);
610
        tcg_gen_add_ptr(addr, cpu_env, addr);
611

    
612
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
613
        tcg_temp_free_ptr(addr);
614
        tcg_temp_free_i32(t2);
615
    }
616
    gen_store_gpr(t0, to);
617
    tcg_temp_free(t0);
618
}
619

    
620
static inline void gen_store_srsgpr (int from, int to)
621
{
622
    if (to != 0) {
623
        TCGv t0 = tcg_temp_new();
624
        TCGv_i32 t2 = tcg_temp_new_i32();
625
        TCGv_ptr addr = tcg_temp_new_ptr();
626

    
627
        gen_load_gpr(t0, from);
628
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
629
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
630
        tcg_gen_andi_i32(t2, t2, 0xf);
631
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
632
        tcg_gen_ext_i32_ptr(addr, t2);
633
        tcg_gen_add_ptr(addr, cpu_env, addr);
634

    
635
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
636
        tcg_temp_free_ptr(addr);
637
        tcg_temp_free_i32(t2);
638
        tcg_temp_free(t0);
639
    }
640
}
641

    
642
/* Floating point register moves. */
643
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
644
{
645
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
646
}
647

    
648
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
649
{
650
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
651
}
652

    
653
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
654
{
655
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
656
}
657

    
658
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
659
{
660
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
661
}
662

    
663
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
664
{
665
    if (ctx->hflags & MIPS_HFLAG_F64) {
666
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
667
    } else {
668
        TCGv_i32 t0 = tcg_temp_new_i32();
669
        TCGv_i32 t1 = tcg_temp_new_i32();
670
        gen_load_fpr32(t0, reg & ~1);
671
        gen_load_fpr32(t1, reg | 1);
672
        tcg_gen_concat_i32_i64(t, t0, t1);
673
        tcg_temp_free_i32(t0);
674
        tcg_temp_free_i32(t1);
675
    }
676
}
677

    
678
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
679
{
680
    if (ctx->hflags & MIPS_HFLAG_F64) {
681
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
682
    } else {
683
        TCGv_i64 t0 = tcg_temp_new_i64();
684
        TCGv_i32 t1 = tcg_temp_new_i32();
685
        tcg_gen_trunc_i64_i32(t1, t);
686
        gen_store_fpr32(t1, reg & ~1);
687
        tcg_gen_shri_i64(t0, t, 32);
688
        tcg_gen_trunc_i64_i32(t1, t0);
689
        gen_store_fpr32(t1, reg | 1);
690
        tcg_temp_free_i32(t1);
691
        tcg_temp_free_i64(t0);
692
    }
693
}
694

    
695
static inline int get_fp_bit (int cc)
696
{
697
    if (cc)
698
        return 24 + cc;
699
    else
700
        return 23;
701
}
702

    
703
/* Tests */
704
static inline void gen_save_pc(target_ulong pc)
705
{
706
    tcg_gen_movi_tl(cpu_PC, pc);
707
}
708

    
709
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
710
{
711
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
712
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
713
        gen_save_pc(ctx->pc);
714
        ctx->saved_pc = ctx->pc;
715
    }
716
    if (ctx->hflags != ctx->saved_hflags) {
717
        tcg_gen_movi_i32(hflags, ctx->hflags);
718
        ctx->saved_hflags = ctx->hflags;
719
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
720
        case MIPS_HFLAG_BR:
721
            break;
722
        case MIPS_HFLAG_BC:
723
        case MIPS_HFLAG_BL:
724
        case MIPS_HFLAG_B:
725
            tcg_gen_movi_tl(btarget, ctx->btarget);
726
            break;
727
        }
728
    }
729
}
730

    
731
static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
732
{
733
    ctx->saved_hflags = ctx->hflags;
734
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
735
    case MIPS_HFLAG_BR:
736
        break;
737
    case MIPS_HFLAG_BC:
738
    case MIPS_HFLAG_BL:
739
    case MIPS_HFLAG_B:
740
        ctx->btarget = env->btarget;
741
        break;
742
    }
743
}
744

    
745
static inline void
746
generate_exception_err (DisasContext *ctx, int excp, int err)
747
{
748
    TCGv_i32 texcp = tcg_const_i32(excp);
749
    TCGv_i32 terr = tcg_const_i32(err);
750
    save_cpu_state(ctx, 1);
751
    gen_helper_raise_exception_err(texcp, terr);
752
    tcg_temp_free_i32(terr);
753
    tcg_temp_free_i32(texcp);
754
}
755

    
756
static inline void
757
generate_exception (DisasContext *ctx, int excp)
758
{
759
    save_cpu_state(ctx, 1);
760
    gen_helper_0i(raise_exception, excp);
761
}
762

    
763
/* Addresses computation */
764
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
765
{
766
    tcg_gen_add_tl(ret, arg0, arg1);
767

    
768
#if defined(TARGET_MIPS64)
769
    /* For compatibility with 32-bit code, data reference in user mode
770
       with Status_UX = 0 should be casted to 32-bit and sign extended.
771
       See the MIPS64 PRA manual, section 4.10. */
772
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
773
        !(ctx->hflags & MIPS_HFLAG_UX)) {
774
        tcg_gen_ext32s_i64(ret, ret);
775
    }
776
#endif
777
}
778

    
779
static inline void check_cp0_enabled(DisasContext *ctx)
780
{
781
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
782
        generate_exception_err(ctx, EXCP_CpU, 0);
783
}
784

    
785
static inline void check_cp1_enabled(DisasContext *ctx)
786
{
787
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
788
        generate_exception_err(ctx, EXCP_CpU, 1);
789
}
790

    
791
/* Verify that the processor is running with COP1X instructions enabled.
792
   This is associated with the nabla symbol in the MIPS32 and MIPS64
793
   opcode tables.  */
794

    
795
static inline void check_cop1x(DisasContext *ctx)
796
{
797
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
798
        generate_exception(ctx, EXCP_RI);
799
}
800

    
801
/* Verify that the processor is running with 64-bit floating-point
802
   operations enabled.  */
803

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

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

    
827
/* This code generates a "reserved instruction" exception if the
828
   CPU does not support the instruction set corresponding to flags. */
829
static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
830
{
831
    if (unlikely(!(env->insn_flags & flags)))
832
        generate_exception(ctx, EXCP_RI);
833
}
834

    
835
/* This code generates a "reserved instruction" exception if 64-bit
836
   instructions are not enabled. */
837
static inline void check_mips_64(DisasContext *ctx)
838
{
839
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
840
        generate_exception(ctx, EXCP_RI);
841
}
842

    
843
/* Define small wrappers for gen_load_fpr* so that we have a uniform
844
   calling interface for 32 and 64-bit FPRs.  No sense in changing
845
   all callers for gen_load_fpr32 when we need the CTX parameter for
846
   this one use.  */
847
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
848
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
849
#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
850
static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
851
                                               int ft, int fs, int cc)        \
852
{                                                                             \
853
    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
854
    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
855
    switch (ifmt) {                                                           \
856
    case FMT_PS:                                                              \
857
        check_cp1_64bitmode(ctx);                                             \
858
        break;                                                                \
859
    case FMT_D:                                                               \
860
        if (abs) {                                                            \
861
            check_cop1x(ctx);                                                 \
862
        }                                                                     \
863
        check_cp1_registers(ctx, fs | ft);                                    \
864
        break;                                                                \
865
    case FMT_S:                                                               \
866
        if (abs) {                                                            \
867
            check_cop1x(ctx);                                                 \
868
        }                                                                     \
869
        break;                                                                \
870
    }                                                                         \
871
    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
872
    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
873
    switch (n) {                                                              \
874
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
875
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
876
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
877
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
878
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
879
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
880
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
881
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
882
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
883
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
884
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
885
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
886
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
887
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
888
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
889
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
890
    default: abort();                                                         \
891
    }                                                                         \
892
    tcg_temp_free_i##bits (fp0);                                              \
893
    tcg_temp_free_i##bits (fp1);                                              \
894
}
895

    
896
FOP_CONDS(, 0, d, FMT_D, 64)
897
FOP_CONDS(abs, 1, d, FMT_D, 64)
898
FOP_CONDS(, 0, s, FMT_S, 32)
899
FOP_CONDS(abs, 1, s, FMT_S, 32)
900
FOP_CONDS(, 0, ps, FMT_PS, 64)
901
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
902
#undef FOP_CONDS
903
#undef gen_ldcmp_fpr32
904
#undef gen_ldcmp_fpr64
905

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

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

    
936
#ifdef CONFIG_USER_ONLY
937
#define OP_LD_ATOMIC(insn,fname)                                           \
938
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
939
{                                                                          \
940
    TCGv t0 = tcg_temp_new();                                              \
941
    tcg_gen_mov_tl(t0, arg1);                                              \
942
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
943
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
944
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
945
    tcg_temp_free(t0);                                                     \
946
}
947
#else
948
#define OP_LD_ATOMIC(insn,fname)                                           \
949
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
950
{                                                                          \
951
    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
952
}
953
#endif
954
OP_LD_ATOMIC(ll,ld32s);
955
#if defined(TARGET_MIPS64)
956
OP_LD_ATOMIC(lld,ld64);
957
#endif
958
#undef OP_LD_ATOMIC
959

    
960
#ifdef CONFIG_USER_ONLY
961
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
962
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
963
{                                                                            \
964
    TCGv t0 = tcg_temp_new();                                                \
965
    int l1 = gen_new_label();                                                \
966
    int l2 = gen_new_label();                                                \
967
                                                                             \
968
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
969
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
970
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
971
    generate_exception(ctx, EXCP_AdES);                                      \
972
    gen_set_label(l1);                                                       \
973
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
974
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
975
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
976
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
977
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
978
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
979
    gen_set_label(l2);                                                       \
980
    tcg_gen_movi_tl(t0, 0);                                                  \
981
    gen_store_gpr(t0, rt);                                                   \
982
    tcg_temp_free(t0);                                                       \
983
}
984
#else
985
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
986
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
987
{                                                                            \
988
    TCGv t0 = tcg_temp_new();                                                \
989
    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
990
    gen_store_gpr(t0, rt);                                                   \
991
    tcg_temp_free(t0);                                                       \
992
}
993
#endif
994
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
995
#if defined(TARGET_MIPS64)
996
OP_ST_ATOMIC(scd,st64,ld64,0x7);
997
#endif
998
#undef OP_ST_ATOMIC
999

    
1000
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1001
                                  int base, int16_t offset)
1002
{
1003
    if (base == 0) {
1004
        tcg_gen_movi_tl(addr, offset);
1005
    } else if (offset == 0) {
1006
        gen_load_gpr(addr, base);
1007
    } else {
1008
        tcg_gen_movi_tl(addr, offset);
1009
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1010
    }
1011
}
1012

    
1013
static target_ulong pc_relative_pc (DisasContext *ctx)
1014
{
1015
    target_ulong pc = ctx->pc;
1016

    
1017
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1018
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1019

    
1020
        pc -= branch_bytes;
1021
    }
1022

    
1023
    pc &= ~(target_ulong)3;
1024
    return pc;
1025
}
1026

    
1027
/* Load */
1028
static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1029
                    int rt, int base, int16_t offset)
1030
{
1031
    const char *opn = "ld";
1032
    TCGv t0, t1;
1033

    
1034
    if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1035
        /* Loongson CPU uses a load to zero register for prefetch.
1036
           We emulate it as a NOP. On other CPU we must perform the
1037
           actual memory access. */
1038
        MIPS_DEBUG("NOP");
1039
        return;
1040
    }
1041

    
1042
    t0 = tcg_temp_new();
1043
    t1 = tcg_temp_new();
1044
    gen_base_offset_addr(ctx, t0, base, offset);
1045

    
1046
    switch (opc) {
1047
#if defined(TARGET_MIPS64)
1048
    case OPC_LWU:
1049
        save_cpu_state(ctx, 0);
1050
        op_ld_lwu(t0, t0, ctx);
1051
        gen_store_gpr(t0, rt);
1052
        opn = "lwu";
1053
        break;
1054
    case OPC_LD:
1055
        save_cpu_state(ctx, 0);
1056
        op_ld_ld(t0, t0, ctx);
1057
        gen_store_gpr(t0, rt);
1058
        opn = "ld";
1059
        break;
1060
    case OPC_LLD:
1061
        save_cpu_state(ctx, 1);
1062
        op_ld_lld(t0, t0, ctx);
1063
        gen_store_gpr(t0, rt);
1064
        opn = "lld";
1065
        break;
1066
    case OPC_LDL:
1067
        save_cpu_state(ctx, 1);
1068
        gen_load_gpr(t1, rt);
1069
        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1070
        gen_store_gpr(t1, rt);
1071
        opn = "ldl";
1072
        break;
1073
    case OPC_LDR:
1074
        save_cpu_state(ctx, 1);
1075
        gen_load_gpr(t1, rt);
1076
        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1077
        gen_store_gpr(t1, rt);
1078
        opn = "ldr";
1079
        break;
1080
    case OPC_LDPC:
1081
        save_cpu_state(ctx, 0);
1082
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1083
        gen_op_addr_add(ctx, t0, t0, t1);
1084
        op_ld_ld(t0, t0, ctx);
1085
        gen_store_gpr(t0, rt);
1086
        opn = "ldpc";
1087
        break;
1088
#endif
1089
    case OPC_LWPC:
1090
        save_cpu_state(ctx, 0);
1091
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1092
        gen_op_addr_add(ctx, t0, t0, t1);
1093
        op_ld_lw(t0, t0, ctx);
1094
        gen_store_gpr(t0, rt);
1095
        opn = "lwpc";
1096
        break;
1097
    case OPC_LW:
1098
        save_cpu_state(ctx, 0);
1099
        op_ld_lw(t0, t0, ctx);
1100
        gen_store_gpr(t0, rt);
1101
        opn = "lw";
1102
        break;
1103
    case OPC_LH:
1104
        save_cpu_state(ctx, 0);
1105
        op_ld_lh(t0, t0, ctx);
1106
        gen_store_gpr(t0, rt);
1107
        opn = "lh";
1108
        break;
1109
    case OPC_LHU:
1110
        save_cpu_state(ctx, 0);
1111
        op_ld_lhu(t0, t0, ctx);
1112
        gen_store_gpr(t0, rt);
1113
        opn = "lhu";
1114
        break;
1115
    case OPC_LB:
1116
        save_cpu_state(ctx, 0);
1117
        op_ld_lb(t0, t0, ctx);
1118
        gen_store_gpr(t0, rt);
1119
        opn = "lb";
1120
        break;
1121
    case OPC_LBU:
1122
        save_cpu_state(ctx, 0);
1123
        op_ld_lbu(t0, t0, ctx);
1124
        gen_store_gpr(t0, rt);
1125
        opn = "lbu";
1126
        break;
1127
    case OPC_LWL:
1128
        save_cpu_state(ctx, 1);
1129
        gen_load_gpr(t1, rt);
1130
        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1131
        gen_store_gpr(t1, rt);
1132
        opn = "lwl";
1133
        break;
1134
    case OPC_LWR:
1135
        save_cpu_state(ctx, 1);
1136
        gen_load_gpr(t1, rt);
1137
        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1138
        gen_store_gpr(t1, rt);
1139
        opn = "lwr";
1140
        break;
1141
    case OPC_LL:
1142
        save_cpu_state(ctx, 1);
1143
        op_ld_ll(t0, t0, ctx);
1144
        gen_store_gpr(t0, rt);
1145
        opn = "ll";
1146
        break;
1147
    }
1148
    (void)opn; /* avoid a compiler warning */
1149
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1150
    tcg_temp_free(t0);
1151
    tcg_temp_free(t1);
1152
}
1153

    
1154
/* Store */
1155
static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1156
                    int base, int16_t offset)
1157
{
1158
    const char *opn = "st";
1159
    TCGv t0 = tcg_temp_new();
1160
    TCGv t1 = tcg_temp_new();
1161

    
1162
    gen_base_offset_addr(ctx, t0, base, offset);
1163
    gen_load_gpr(t1, rt);
1164
    switch (opc) {
1165
#if defined(TARGET_MIPS64)
1166
    case OPC_SD:
1167
        save_cpu_state(ctx, 0);
1168
        op_st_sd(t1, t0, ctx);
1169
        opn = "sd";
1170
        break;
1171
    case OPC_SDL:
1172
        save_cpu_state(ctx, 1);
1173
        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1174
        opn = "sdl";
1175
        break;
1176
    case OPC_SDR:
1177
        save_cpu_state(ctx, 1);
1178
        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1179
        opn = "sdr";
1180
        break;
1181
#endif
1182
    case OPC_SW:
1183
        save_cpu_state(ctx, 0);
1184
        op_st_sw(t1, t0, ctx);
1185
        opn = "sw";
1186
        break;
1187
    case OPC_SH:
1188
        save_cpu_state(ctx, 0);
1189
        op_st_sh(t1, t0, ctx);
1190
        opn = "sh";
1191
        break;
1192
    case OPC_SB:
1193
        save_cpu_state(ctx, 0);
1194
        op_st_sb(t1, t0, ctx);
1195
        opn = "sb";
1196
        break;
1197
    case OPC_SWL:
1198
        save_cpu_state(ctx, 1);
1199
        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1200
        opn = "swl";
1201
        break;
1202
    case OPC_SWR:
1203
        save_cpu_state(ctx, 1);
1204
        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1205
        opn = "swr";
1206
        break;
1207
    }
1208
    (void)opn; /* avoid a compiler warning */
1209
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1210
    tcg_temp_free(t0);
1211
    tcg_temp_free(t1);
1212
}
1213

    
1214

    
1215
/* Store conditional */
1216
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1217
                         int base, int16_t offset)
1218
{
1219
    const char *opn = "st_cond";
1220
    TCGv t0, t1;
1221

    
1222
    t0 = tcg_temp_local_new();
1223

    
1224
    gen_base_offset_addr(ctx, t0, base, offset);
1225
    /* Don't do NOP if destination is zero: we must perform the actual
1226
       memory access. */
1227

    
1228
    t1 = tcg_temp_local_new();
1229
    gen_load_gpr(t1, rt);
1230
    switch (opc) {
1231
#if defined(TARGET_MIPS64)
1232
    case OPC_SCD:
1233
        save_cpu_state(ctx, 1);
1234
        op_st_scd(t1, t0, rt, ctx);
1235
        opn = "scd";
1236
        break;
1237
#endif
1238
    case OPC_SC:
1239
        save_cpu_state(ctx, 1);
1240
        op_st_sc(t1, t0, rt, ctx);
1241
        opn = "sc";
1242
        break;
1243
    }
1244
    (void)opn; /* avoid a compiler warning */
1245
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1246
    tcg_temp_free(t1);
1247
    tcg_temp_free(t0);
1248
}
1249

    
1250
/* Load and store */
1251
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1252
                          int base, int16_t offset)
1253
{
1254
    const char *opn = "flt_ldst";
1255
    TCGv t0 = tcg_temp_new();
1256

    
1257
    gen_base_offset_addr(ctx, t0, base, offset);
1258
    /* Don't do NOP if destination is zero: we must perform the actual
1259
       memory access. */
1260
    switch (opc) {
1261
    case OPC_LWC1:
1262
        {
1263
            TCGv_i32 fp0 = tcg_temp_new_i32();
1264

    
1265
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1266
            tcg_gen_trunc_tl_i32(fp0, t0);
1267
            gen_store_fpr32(fp0, ft);
1268
            tcg_temp_free_i32(fp0);
1269
        }
1270
        opn = "lwc1";
1271
        break;
1272
    case OPC_SWC1:
1273
        {
1274
            TCGv_i32 fp0 = tcg_temp_new_i32();
1275
            TCGv t1 = tcg_temp_new();
1276

    
1277
            gen_load_fpr32(fp0, ft);
1278
            tcg_gen_extu_i32_tl(t1, fp0);
1279
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1280
            tcg_temp_free(t1);
1281
            tcg_temp_free_i32(fp0);
1282
        }
1283
        opn = "swc1";
1284
        break;
1285
    case OPC_LDC1:
1286
        {
1287
            TCGv_i64 fp0 = tcg_temp_new_i64();
1288

    
1289
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1290
            gen_store_fpr64(ctx, fp0, ft);
1291
            tcg_temp_free_i64(fp0);
1292
        }
1293
        opn = "ldc1";
1294
        break;
1295
    case OPC_SDC1:
1296
        {
1297
            TCGv_i64 fp0 = tcg_temp_new_i64();
1298

    
1299
            gen_load_fpr64(ctx, fp0, ft);
1300
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1301
            tcg_temp_free_i64(fp0);
1302
        }
1303
        opn = "sdc1";
1304
        break;
1305
    default:
1306
        MIPS_INVAL(opn);
1307
        generate_exception(ctx, EXCP_RI);
1308
        goto out;
1309
    }
1310
    (void)opn; /* avoid a compiler warning */
1311
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1312
 out:
1313
    tcg_temp_free(t0);
1314
}
1315

    
1316
static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1317
                          uint32_t op, int rt, int rs, int16_t imm)
1318
{
1319
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1320
        check_cp1_enabled(ctx);
1321
        gen_flt_ldst(ctx, op, rt, rs, imm);
1322
    } else {
1323
        generate_exception_err(ctx, EXCP_CpU, 1);
1324
    }
1325
}
1326

    
1327
/* Arithmetic with immediate operand */
1328
static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1329
                           int rt, int rs, int16_t imm)
1330
{
1331
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1332
    const char *opn = "imm arith";
1333

    
1334
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1335
        /* If no destination, treat it as a NOP.
1336
           For addi, we must generate the overflow exception when needed. */
1337
        MIPS_DEBUG("NOP");
1338
        return;
1339
    }
1340
    switch (opc) {
1341
    case OPC_ADDI:
1342
        {
1343
            TCGv t0 = tcg_temp_local_new();
1344
            TCGv t1 = tcg_temp_new();
1345
            TCGv t2 = tcg_temp_new();
1346
            int l1 = gen_new_label();
1347

    
1348
            gen_load_gpr(t1, rs);
1349
            tcg_gen_addi_tl(t0, t1, uimm);
1350
            tcg_gen_ext32s_tl(t0, t0);
1351

    
1352
            tcg_gen_xori_tl(t1, t1, ~uimm);
1353
            tcg_gen_xori_tl(t2, t0, uimm);
1354
            tcg_gen_and_tl(t1, t1, t2);
1355
            tcg_temp_free(t2);
1356
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1357
            tcg_temp_free(t1);
1358
            /* operands of same sign, result different sign */
1359
            generate_exception(ctx, EXCP_OVERFLOW);
1360
            gen_set_label(l1);
1361
            tcg_gen_ext32s_tl(t0, t0);
1362
            gen_store_gpr(t0, rt);
1363
            tcg_temp_free(t0);
1364
        }
1365
        opn = "addi";
1366
        break;
1367
    case OPC_ADDIU:
1368
        if (rs != 0) {
1369
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1370
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1371
        } else {
1372
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1373
        }
1374
        opn = "addiu";
1375
        break;
1376
#if defined(TARGET_MIPS64)
1377
    case OPC_DADDI:
1378
        {
1379
            TCGv t0 = tcg_temp_local_new();
1380
            TCGv t1 = tcg_temp_new();
1381
            TCGv t2 = tcg_temp_new();
1382
            int l1 = gen_new_label();
1383

    
1384
            gen_load_gpr(t1, rs);
1385
            tcg_gen_addi_tl(t0, t1, uimm);
1386

    
1387
            tcg_gen_xori_tl(t1, t1, ~uimm);
1388
            tcg_gen_xori_tl(t2, t0, uimm);
1389
            tcg_gen_and_tl(t1, t1, t2);
1390
            tcg_temp_free(t2);
1391
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1392
            tcg_temp_free(t1);
1393
            /* operands of same sign, result different sign */
1394
            generate_exception(ctx, EXCP_OVERFLOW);
1395
            gen_set_label(l1);
1396
            gen_store_gpr(t0, rt);
1397
            tcg_temp_free(t0);
1398
        }
1399
        opn = "daddi";
1400
        break;
1401
    case OPC_DADDIU:
1402
        if (rs != 0) {
1403
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1404
        } else {
1405
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1406
        }
1407
        opn = "daddiu";
1408
        break;
1409
#endif
1410
    }
1411
    (void)opn; /* avoid a compiler warning */
1412
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1413
}
1414

    
1415
/* Logic with immediate operand */
1416
static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
1417
{
1418
    target_ulong uimm;
1419
    const char *opn = "imm logic";
1420

    
1421
    if (rt == 0) {
1422
        /* If no destination, treat it as a NOP. */
1423
        MIPS_DEBUG("NOP");
1424
        return;
1425
    }
1426
    uimm = (uint16_t)imm;
1427
    switch (opc) {
1428
    case OPC_ANDI:
1429
        if (likely(rs != 0))
1430
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1431
        else
1432
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1433
        opn = "andi";
1434
        break;
1435
    case OPC_ORI:
1436
        if (rs != 0)
1437
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1438
        else
1439
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1440
        opn = "ori";
1441
        break;
1442
    case OPC_XORI:
1443
        if (likely(rs != 0))
1444
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1445
        else
1446
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1447
        opn = "xori";
1448
        break;
1449
    case OPC_LUI:
1450
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1451
        opn = "lui";
1452
        break;
1453
    }
1454
    (void)opn; /* avoid a compiler warning */
1455
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1456
}
1457

    
1458
/* Set on less than with immediate operand */
1459
static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
1460
{
1461
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1462
    const char *opn = "imm arith";
1463
    TCGv t0;
1464

    
1465
    if (rt == 0) {
1466
        /* If no destination, treat it as a NOP. */
1467
        MIPS_DEBUG("NOP");
1468
        return;
1469
    }
1470
    t0 = tcg_temp_new();
1471
    gen_load_gpr(t0, rs);
1472
    switch (opc) {
1473
    case OPC_SLTI:
1474
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1475
        opn = "slti";
1476
        break;
1477
    case OPC_SLTIU:
1478
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1479
        opn = "sltiu";
1480
        break;
1481
    }
1482
    (void)opn; /* avoid a compiler warning */
1483
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1484
    tcg_temp_free(t0);
1485
}
1486

    
1487
/* Shifts with immediate operand */
1488
static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1489
                          int rt, int rs, int16_t imm)
1490
{
1491
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1492
    const char *opn = "imm shift";
1493
    TCGv t0;
1494

    
1495
    if (rt == 0) {
1496
        /* If no destination, treat it as a NOP. */
1497
        MIPS_DEBUG("NOP");
1498
        return;
1499
    }
1500

    
1501
    t0 = tcg_temp_new();
1502
    gen_load_gpr(t0, rs);
1503
    switch (opc) {
1504
    case OPC_SLL:
1505
        tcg_gen_shli_tl(t0, t0, uimm);
1506
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1507
        opn = "sll";
1508
        break;
1509
    case OPC_SRA:
1510
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1511
        opn = "sra";
1512
        break;
1513
    case OPC_SRL:
1514
        if (uimm != 0) {
1515
            tcg_gen_ext32u_tl(t0, t0);
1516
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1517
        } else {
1518
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1519
        }
1520
        opn = "srl";
1521
        break;
1522
    case OPC_ROTR:
1523
        if (uimm != 0) {
1524
            TCGv_i32 t1 = tcg_temp_new_i32();
1525

    
1526
            tcg_gen_trunc_tl_i32(t1, t0);
1527
            tcg_gen_rotri_i32(t1, t1, uimm);
1528
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1529
            tcg_temp_free_i32(t1);
1530
        } else {
1531
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1532
        }
1533
        opn = "rotr";
1534
        break;
1535
#if defined(TARGET_MIPS64)
1536
    case OPC_DSLL:
1537
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1538
        opn = "dsll";
1539
        break;
1540
    case OPC_DSRA:
1541
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1542
        opn = "dsra";
1543
        break;
1544
    case OPC_DSRL:
1545
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1546
        opn = "dsrl";
1547
        break;
1548
    case OPC_DROTR:
1549
        if (uimm != 0) {
1550
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1551
        } else {
1552
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
1553
        }
1554
        opn = "drotr";
1555
        break;
1556
    case OPC_DSLL32:
1557
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1558
        opn = "dsll32";
1559
        break;
1560
    case OPC_DSRA32:
1561
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1562
        opn = "dsra32";
1563
        break;
1564
    case OPC_DSRL32:
1565
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1566
        opn = "dsrl32";
1567
        break;
1568
    case OPC_DROTR32:
1569
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1570
        opn = "drotr32";
1571
        break;
1572
#endif
1573
    }
1574
    (void)opn; /* avoid a compiler warning */
1575
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1576
    tcg_temp_free(t0);
1577
}
1578

    
1579
/* Arithmetic */
1580
static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1581
                       int rd, int rs, int rt)
1582
{
1583
    const char *opn = "arith";
1584

    
1585
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1586
       && opc != OPC_DADD && opc != OPC_DSUB) {
1587
        /* If no destination, treat it as a NOP.
1588
           For add & sub, we must generate the overflow exception when needed. */
1589
        MIPS_DEBUG("NOP");
1590
        return;
1591
    }
1592

    
1593
    switch (opc) {
1594
    case OPC_ADD:
1595
        {
1596
            TCGv t0 = tcg_temp_local_new();
1597
            TCGv t1 = tcg_temp_new();
1598
            TCGv t2 = tcg_temp_new();
1599
            int l1 = gen_new_label();
1600

    
1601
            gen_load_gpr(t1, rs);
1602
            gen_load_gpr(t2, rt);
1603
            tcg_gen_add_tl(t0, t1, t2);
1604
            tcg_gen_ext32s_tl(t0, t0);
1605
            tcg_gen_xor_tl(t1, t1, t2);
1606
            tcg_gen_xor_tl(t2, t0, t2);
1607
            tcg_gen_andc_tl(t1, t2, t1);
1608
            tcg_temp_free(t2);
1609
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1610
            tcg_temp_free(t1);
1611
            /* operands of same sign, result different sign */
1612
            generate_exception(ctx, EXCP_OVERFLOW);
1613
            gen_set_label(l1);
1614
            gen_store_gpr(t0, rd);
1615
            tcg_temp_free(t0);
1616
        }
1617
        opn = "add";
1618
        break;
1619
    case OPC_ADDU:
1620
        if (rs != 0 && rt != 0) {
1621
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1622
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1623
        } else if (rs == 0 && rt != 0) {
1624
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1625
        } else if (rs != 0 && rt == 0) {
1626
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1627
        } else {
1628
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1629
        }
1630
        opn = "addu";
1631
        break;
1632
    case OPC_SUB:
1633
        {
1634
            TCGv t0 = tcg_temp_local_new();
1635
            TCGv t1 = tcg_temp_new();
1636
            TCGv t2 = tcg_temp_new();
1637
            int l1 = gen_new_label();
1638

    
1639
            gen_load_gpr(t1, rs);
1640
            gen_load_gpr(t2, rt);
1641
            tcg_gen_sub_tl(t0, t1, t2);
1642
            tcg_gen_ext32s_tl(t0, t0);
1643
            tcg_gen_xor_tl(t2, t1, t2);
1644
            tcg_gen_xor_tl(t1, t0, t1);
1645
            tcg_gen_and_tl(t1, t1, t2);
1646
            tcg_temp_free(t2);
1647
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1648
            tcg_temp_free(t1);
1649
            /* operands of different sign, first operand and result different sign */
1650
            generate_exception(ctx, EXCP_OVERFLOW);
1651
            gen_set_label(l1);
1652
            gen_store_gpr(t0, rd);
1653
            tcg_temp_free(t0);
1654
        }
1655
        opn = "sub";
1656
        break;
1657
    case OPC_SUBU:
1658
        if (rs != 0 && rt != 0) {
1659
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1660
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1661
        } else if (rs == 0 && rt != 0) {
1662
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1663
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1664
        } else if (rs != 0 && rt == 0) {
1665
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1666
        } else {
1667
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1668
        }
1669
        opn = "subu";
1670
        break;
1671
#if defined(TARGET_MIPS64)
1672
    case OPC_DADD:
1673
        {
1674
            TCGv t0 = tcg_temp_local_new();
1675
            TCGv t1 = tcg_temp_new();
1676
            TCGv t2 = tcg_temp_new();
1677
            int l1 = gen_new_label();
1678

    
1679
            gen_load_gpr(t1, rs);
1680
            gen_load_gpr(t2, rt);
1681
            tcg_gen_add_tl(t0, t1, t2);
1682
            tcg_gen_xor_tl(t1, t1, t2);
1683
            tcg_gen_xor_tl(t2, t0, t2);
1684
            tcg_gen_andc_tl(t1, t2, t1);
1685
            tcg_temp_free(t2);
1686
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1687
            tcg_temp_free(t1);
1688
            /* operands of same sign, result different sign */
1689
            generate_exception(ctx, EXCP_OVERFLOW);
1690
            gen_set_label(l1);
1691
            gen_store_gpr(t0, rd);
1692
            tcg_temp_free(t0);
1693
        }
1694
        opn = "dadd";
1695
        break;
1696
    case OPC_DADDU:
1697
        if (rs != 0 && rt != 0) {
1698
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1699
        } else if (rs == 0 && rt != 0) {
1700
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1701
        } else if (rs != 0 && rt == 0) {
1702
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1703
        } else {
1704
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1705
        }
1706
        opn = "daddu";
1707
        break;
1708
    case OPC_DSUB:
1709
        {
1710
            TCGv t0 = tcg_temp_local_new();
1711
            TCGv t1 = tcg_temp_new();
1712
            TCGv t2 = tcg_temp_new();
1713
            int l1 = gen_new_label();
1714

    
1715
            gen_load_gpr(t1, rs);
1716
            gen_load_gpr(t2, rt);
1717
            tcg_gen_sub_tl(t0, t1, t2);
1718
            tcg_gen_xor_tl(t2, t1, t2);
1719
            tcg_gen_xor_tl(t1, t0, t1);
1720
            tcg_gen_and_tl(t1, t1, t2);
1721
            tcg_temp_free(t2);
1722
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1723
            tcg_temp_free(t1);
1724
            /* operands of different sign, first operand and result different sign */
1725
            generate_exception(ctx, EXCP_OVERFLOW);
1726
            gen_set_label(l1);
1727
            gen_store_gpr(t0, rd);
1728
            tcg_temp_free(t0);
1729
        }
1730
        opn = "dsub";
1731
        break;
1732
    case OPC_DSUBU:
1733
        if (rs != 0 && rt != 0) {
1734
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1735
        } else if (rs == 0 && rt != 0) {
1736
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1737
        } else if (rs != 0 && rt == 0) {
1738
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1739
        } else {
1740
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1741
        }
1742
        opn = "dsubu";
1743
        break;
1744
#endif
1745
    case OPC_MUL:
1746
        if (likely(rs != 0 && rt != 0)) {
1747
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1748
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1749
        } else {
1750
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1751
        }
1752
        opn = "mul";
1753
        break;
1754
    }
1755
    (void)opn; /* avoid a compiler warning */
1756
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1757
}
1758

    
1759
/* Conditional move */
1760
static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1761
{
1762
    const char *opn = "cond move";
1763
    int l1;
1764

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

    
1772
    l1 = gen_new_label();
1773
    switch (opc) {
1774
    case OPC_MOVN:
1775
        if (likely(rt != 0))
1776
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1777
        else
1778
            tcg_gen_br(l1);
1779
        opn = "movn";
1780
        break;
1781
    case OPC_MOVZ:
1782
        if (likely(rt != 0))
1783
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1784
        opn = "movz";
1785
        break;
1786
    }
1787
    if (rs != 0)
1788
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1789
    else
1790
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1791
    gen_set_label(l1);
1792

    
1793
    (void)opn; /* avoid a compiler warning */
1794
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1795
}
1796

    
1797
/* Logic */
1798
static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1799
{
1800
    const char *opn = "logic";
1801

    
1802
    if (rd == 0) {
1803
        /* If no destination, treat it as a NOP. */
1804
        MIPS_DEBUG("NOP");
1805
        return;
1806
    }
1807

    
1808
    switch (opc) {
1809
    case OPC_AND:
1810
        if (likely(rs != 0 && rt != 0)) {
1811
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1812
        } else {
1813
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1814
        }
1815
        opn = "and";
1816
        break;
1817
    case OPC_NOR:
1818
        if (rs != 0 && rt != 0) {
1819
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1820
        } else if (rs == 0 && rt != 0) {
1821
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1822
        } else if (rs != 0 && rt == 0) {
1823
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1824
        } else {
1825
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1826
        }
1827
        opn = "nor";
1828
        break;
1829
    case OPC_OR:
1830
        if (likely(rs != 0 && rt != 0)) {
1831
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1832
        } else if (rs == 0 && rt != 0) {
1833
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1834
        } else if (rs != 0 && rt == 0) {
1835
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1836
        } else {
1837
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1838
        }
1839
        opn = "or";
1840
        break;
1841
    case OPC_XOR:
1842
        if (likely(rs != 0 && rt != 0)) {
1843
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1844
        } else if (rs == 0 && rt != 0) {
1845
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1846
        } else if (rs != 0 && rt == 0) {
1847
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1848
        } else {
1849
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1850
        }
1851
        opn = "xor";
1852
        break;
1853
    }
1854
    (void)opn; /* avoid a compiler warning */
1855
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1856
}
1857

    
1858
/* Set on lower than */
1859
static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1860
{
1861
    const char *opn = "slt";
1862
    TCGv t0, t1;
1863

    
1864
    if (rd == 0) {
1865
        /* If no destination, treat it as a NOP. */
1866
        MIPS_DEBUG("NOP");
1867
        return;
1868
    }
1869

    
1870
    t0 = tcg_temp_new();
1871
    t1 = tcg_temp_new();
1872
    gen_load_gpr(t0, rs);
1873
    gen_load_gpr(t1, rt);
1874
    switch (opc) {
1875
    case OPC_SLT:
1876
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1877
        opn = "slt";
1878
        break;
1879
    case OPC_SLTU:
1880
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1881
        opn = "sltu";
1882
        break;
1883
    }
1884
    (void)opn; /* avoid a compiler warning */
1885
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1886
    tcg_temp_free(t0);
1887
    tcg_temp_free(t1);
1888
}
1889

    
1890
/* Shifts */
1891
static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1892
                       int rd, int rs, int rt)
1893
{
1894
    const char *opn = "shifts";
1895
    TCGv t0, t1;
1896

    
1897
    if (rd == 0) {
1898
        /* If no destination, treat it as a NOP.
1899
           For add & sub, we must generate the overflow exception when needed. */
1900
        MIPS_DEBUG("NOP");
1901
        return;
1902
    }
1903

    
1904
    t0 = tcg_temp_new();
1905
    t1 = tcg_temp_new();
1906
    gen_load_gpr(t0, rs);
1907
    gen_load_gpr(t1, rt);
1908
    switch (opc) {
1909
    case OPC_SLLV:
1910
        tcg_gen_andi_tl(t0, t0, 0x1f);
1911
        tcg_gen_shl_tl(t0, t1, t0);
1912
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1913
        opn = "sllv";
1914
        break;
1915
    case OPC_SRAV:
1916
        tcg_gen_andi_tl(t0, t0, 0x1f);
1917
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1918
        opn = "srav";
1919
        break;
1920
    case OPC_SRLV:
1921
        tcg_gen_ext32u_tl(t1, t1);
1922
        tcg_gen_andi_tl(t0, t0, 0x1f);
1923
        tcg_gen_shr_tl(t0, t1, t0);
1924
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1925
        opn = "srlv";
1926
        break;
1927
    case OPC_ROTRV:
1928
        {
1929
            TCGv_i32 t2 = tcg_temp_new_i32();
1930
            TCGv_i32 t3 = tcg_temp_new_i32();
1931

    
1932
            tcg_gen_trunc_tl_i32(t2, t0);
1933
            tcg_gen_trunc_tl_i32(t3, t1);
1934
            tcg_gen_andi_i32(t2, t2, 0x1f);
1935
            tcg_gen_rotr_i32(t2, t3, t2);
1936
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1937
            tcg_temp_free_i32(t2);
1938
            tcg_temp_free_i32(t3);
1939
            opn = "rotrv";
1940
        }
1941
        break;
1942
#if defined(TARGET_MIPS64)
1943
    case OPC_DSLLV:
1944
        tcg_gen_andi_tl(t0, t0, 0x3f);
1945
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1946
        opn = "dsllv";
1947
        break;
1948
    case OPC_DSRAV:
1949
        tcg_gen_andi_tl(t0, t0, 0x3f);
1950
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1951
        opn = "dsrav";
1952
        break;
1953
    case OPC_DSRLV:
1954
        tcg_gen_andi_tl(t0, t0, 0x3f);
1955
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1956
        opn = "dsrlv";
1957
        break;
1958
    case OPC_DROTRV:
1959
        tcg_gen_andi_tl(t0, t0, 0x3f);
1960
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1961
        opn = "drotrv";
1962
        break;
1963
#endif
1964
    }
1965
    (void)opn; /* avoid a compiler warning */
1966
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1967
    tcg_temp_free(t0);
1968
    tcg_temp_free(t1);
1969
}
1970

    
1971
/* Arithmetic on HI/LO registers */
1972
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1973
{
1974
    const char *opn = "hilo";
1975

    
1976
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1977
        /* Treat as NOP. */
1978
        MIPS_DEBUG("NOP");
1979
        return;
1980
    }
1981
    switch (opc) {
1982
    case OPC_MFHI:
1983
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1984
        opn = "mfhi";
1985
        break;
1986
    case OPC_MFLO:
1987
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1988
        opn = "mflo";
1989
        break;
1990
    case OPC_MTHI:
1991
        if (reg != 0)
1992
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1993
        else
1994
            tcg_gen_movi_tl(cpu_HI[0], 0);
1995
        opn = "mthi";
1996
        break;
1997
    case OPC_MTLO:
1998
        if (reg != 0)
1999
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2000
        else
2001
            tcg_gen_movi_tl(cpu_LO[0], 0);
2002
        opn = "mtlo";
2003
        break;
2004
    }
2005
    (void)opn; /* avoid a compiler warning */
2006
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2007
}
2008

    
2009
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2010
                        int rs, int rt)
2011
{
2012
    const char *opn = "mul/div";
2013
    TCGv t0, t1;
2014

    
2015
    switch (opc) {
2016
    case OPC_DIV:
2017
    case OPC_DIVU:
2018
#if defined(TARGET_MIPS64)
2019
    case OPC_DDIV:
2020
    case OPC_DDIVU:
2021
#endif
2022
        t0 = tcg_temp_local_new();
2023
        t1 = tcg_temp_local_new();
2024
        break;
2025
    default:
2026
        t0 = tcg_temp_new();
2027
        t1 = tcg_temp_new();
2028
        break;
2029
    }
2030

    
2031
    gen_load_gpr(t0, rs);
2032
    gen_load_gpr(t1, rt);
2033
    switch (opc) {
2034
    case OPC_DIV:
2035
        {
2036
            int l1 = gen_new_label();
2037
            int l2 = gen_new_label();
2038

    
2039
            tcg_gen_ext32s_tl(t0, t0);
2040
            tcg_gen_ext32s_tl(t1, t1);
2041
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2042
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2043
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2044

    
2045
            tcg_gen_mov_tl(cpu_LO[0], t0);
2046
            tcg_gen_movi_tl(cpu_HI[0], 0);
2047
            tcg_gen_br(l1);
2048
            gen_set_label(l2);
2049
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2050
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2051
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2052
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2053
            gen_set_label(l1);
2054
        }
2055
        opn = "div";
2056
        break;
2057
    case OPC_DIVU:
2058
        {
2059
            int l1 = gen_new_label();
2060

    
2061
            tcg_gen_ext32u_tl(t0, t0);
2062
            tcg_gen_ext32u_tl(t1, t1);
2063
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2064
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2065
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2066
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2067
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2068
            gen_set_label(l1);
2069
        }
2070
        opn = "divu";
2071
        break;
2072
    case OPC_MULT:
2073
        {
2074
            TCGv_i64 t2 = tcg_temp_new_i64();
2075
            TCGv_i64 t3 = tcg_temp_new_i64();
2076

    
2077
            tcg_gen_ext_tl_i64(t2, t0);
2078
            tcg_gen_ext_tl_i64(t3, t1);
2079
            tcg_gen_mul_i64(t2, t2, t3);
2080
            tcg_temp_free_i64(t3);
2081
            tcg_gen_trunc_i64_tl(t0, t2);
2082
            tcg_gen_shri_i64(t2, t2, 32);
2083
            tcg_gen_trunc_i64_tl(t1, t2);
2084
            tcg_temp_free_i64(t2);
2085
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2086
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2087
        }
2088
        opn = "mult";
2089
        break;
2090
    case OPC_MULTU:
2091
        {
2092
            TCGv_i64 t2 = tcg_temp_new_i64();
2093
            TCGv_i64 t3 = tcg_temp_new_i64();
2094

    
2095
            tcg_gen_ext32u_tl(t0, t0);
2096
            tcg_gen_ext32u_tl(t1, t1);
2097
            tcg_gen_extu_tl_i64(t2, t0);
2098
            tcg_gen_extu_tl_i64(t3, t1);
2099
            tcg_gen_mul_i64(t2, t2, t3);
2100
            tcg_temp_free_i64(t3);
2101
            tcg_gen_trunc_i64_tl(t0, t2);
2102
            tcg_gen_shri_i64(t2, t2, 32);
2103
            tcg_gen_trunc_i64_tl(t1, t2);
2104
            tcg_temp_free_i64(t2);
2105
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2106
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2107
        }
2108
        opn = "multu";
2109
        break;
2110
#if defined(TARGET_MIPS64)
2111
    case OPC_DDIV:
2112
        {
2113
            int l1 = gen_new_label();
2114
            int l2 = gen_new_label();
2115

    
2116
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2117
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2118
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2119
            tcg_gen_mov_tl(cpu_LO[0], t0);
2120
            tcg_gen_movi_tl(cpu_HI[0], 0);
2121
            tcg_gen_br(l1);
2122
            gen_set_label(l2);
2123
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2124
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2125
            gen_set_label(l1);
2126
        }
2127
        opn = "ddiv";
2128
        break;
2129
    case OPC_DDIVU:
2130
        {
2131
            int l1 = gen_new_label();
2132

    
2133
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2134
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2135
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2136
            gen_set_label(l1);
2137
        }
2138
        opn = "ddivu";
2139
        break;
2140
    case OPC_DMULT:
2141
        gen_helper_dmult(t0, t1);
2142
        opn = "dmult";
2143
        break;
2144
    case OPC_DMULTU:
2145
        gen_helper_dmultu(t0, t1);
2146
        opn = "dmultu";
2147
        break;
2148
#endif
2149
    case OPC_MADD:
2150
        {
2151
            TCGv_i64 t2 = tcg_temp_new_i64();
2152
            TCGv_i64 t3 = tcg_temp_new_i64();
2153

    
2154
            tcg_gen_ext_tl_i64(t2, t0);
2155
            tcg_gen_ext_tl_i64(t3, t1);
2156
            tcg_gen_mul_i64(t2, t2, t3);
2157
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2158
            tcg_gen_add_i64(t2, t2, t3);
2159
            tcg_temp_free_i64(t3);
2160
            tcg_gen_trunc_i64_tl(t0, t2);
2161
            tcg_gen_shri_i64(t2, t2, 32);
2162
            tcg_gen_trunc_i64_tl(t1, t2);
2163
            tcg_temp_free_i64(t2);
2164
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2165
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2166
        }
2167
        opn = "madd";
2168
        break;
2169
    case OPC_MADDU:
2170
       {
2171
            TCGv_i64 t2 = tcg_temp_new_i64();
2172
            TCGv_i64 t3 = tcg_temp_new_i64();
2173

    
2174
            tcg_gen_ext32u_tl(t0, t0);
2175
            tcg_gen_ext32u_tl(t1, t1);
2176
            tcg_gen_extu_tl_i64(t2, t0);
2177
            tcg_gen_extu_tl_i64(t3, t1);
2178
            tcg_gen_mul_i64(t2, t2, t3);
2179
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2180
            tcg_gen_add_i64(t2, t2, t3);
2181
            tcg_temp_free_i64(t3);
2182
            tcg_gen_trunc_i64_tl(t0, t2);
2183
            tcg_gen_shri_i64(t2, t2, 32);
2184
            tcg_gen_trunc_i64_tl(t1, t2);
2185
            tcg_temp_free_i64(t2);
2186
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2187
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2188
        }
2189
        opn = "maddu";
2190
        break;
2191
    case OPC_MSUB:
2192
        {
2193
            TCGv_i64 t2 = tcg_temp_new_i64();
2194
            TCGv_i64 t3 = tcg_temp_new_i64();
2195

    
2196
            tcg_gen_ext_tl_i64(t2, t0);
2197
            tcg_gen_ext_tl_i64(t3, t1);
2198
            tcg_gen_mul_i64(t2, t2, t3);
2199
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2200
            tcg_gen_sub_i64(t2, t3, t2);
2201
            tcg_temp_free_i64(t3);
2202
            tcg_gen_trunc_i64_tl(t0, t2);
2203
            tcg_gen_shri_i64(t2, t2, 32);
2204
            tcg_gen_trunc_i64_tl(t1, t2);
2205
            tcg_temp_free_i64(t2);
2206
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2207
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2208
        }
2209
        opn = "msub";
2210
        break;
2211
    case OPC_MSUBU:
2212
        {
2213
            TCGv_i64 t2 = tcg_temp_new_i64();
2214
            TCGv_i64 t3 = tcg_temp_new_i64();
2215

    
2216
            tcg_gen_ext32u_tl(t0, t0);
2217
            tcg_gen_ext32u_tl(t1, t1);
2218
            tcg_gen_extu_tl_i64(t2, t0);
2219
            tcg_gen_extu_tl_i64(t3, t1);
2220
            tcg_gen_mul_i64(t2, t2, t3);
2221
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2222
            tcg_gen_sub_i64(t2, t3, t2);
2223
            tcg_temp_free_i64(t3);
2224
            tcg_gen_trunc_i64_tl(t0, t2);
2225
            tcg_gen_shri_i64(t2, t2, 32);
2226
            tcg_gen_trunc_i64_tl(t1, t2);
2227
            tcg_temp_free_i64(t2);
2228
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2229
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2230
        }
2231
        opn = "msubu";
2232
        break;
2233
    default:
2234
        MIPS_INVAL(opn);
2235
        generate_exception(ctx, EXCP_RI);
2236
        goto out;
2237
    }
2238
    (void)opn; /* avoid a compiler warning */
2239
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2240
 out:
2241
    tcg_temp_free(t0);
2242
    tcg_temp_free(t1);
2243
}
2244

    
2245
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2246
                            int rd, int rs, int rt)
2247
{
2248
    const char *opn = "mul vr54xx";
2249
    TCGv t0 = tcg_temp_new();
2250
    TCGv t1 = tcg_temp_new();
2251

    
2252
    gen_load_gpr(t0, rs);
2253
    gen_load_gpr(t1, rt);
2254

    
2255
    switch (opc) {
2256
    case OPC_VR54XX_MULS:
2257
        gen_helper_muls(t0, t0, t1);
2258
        opn = "muls";
2259
        break;
2260
    case OPC_VR54XX_MULSU:
2261
        gen_helper_mulsu(t0, t0, t1);
2262
        opn = "mulsu";
2263
        break;
2264
    case OPC_VR54XX_MACC:
2265
        gen_helper_macc(t0, t0, t1);
2266
        opn = "macc";
2267
        break;
2268
    case OPC_VR54XX_MACCU:
2269
        gen_helper_maccu(t0, t0, t1);
2270
        opn = "maccu";
2271
        break;
2272
    case OPC_VR54XX_MSAC:
2273
        gen_helper_msac(t0, t0, t1);
2274
        opn = "msac";
2275
        break;
2276
    case OPC_VR54XX_MSACU:
2277
        gen_helper_msacu(t0, t0, t1);
2278
        opn = "msacu";
2279
        break;
2280
    case OPC_VR54XX_MULHI:
2281
        gen_helper_mulhi(t0, t0, t1);
2282
        opn = "mulhi";
2283
        break;
2284
    case OPC_VR54XX_MULHIU:
2285
        gen_helper_mulhiu(t0, t0, t1);
2286
        opn = "mulhiu";
2287
        break;
2288
    case OPC_VR54XX_MULSHI:
2289
        gen_helper_mulshi(t0, t0, t1);
2290
        opn = "mulshi";
2291
        break;
2292
    case OPC_VR54XX_MULSHIU:
2293
        gen_helper_mulshiu(t0, t0, t1);
2294
        opn = "mulshiu";
2295
        break;
2296
    case OPC_VR54XX_MACCHI:
2297
        gen_helper_macchi(t0, t0, t1);
2298
        opn = "macchi";
2299
        break;
2300
    case OPC_VR54XX_MACCHIU:
2301
        gen_helper_macchiu(t0, t0, t1);
2302
        opn = "macchiu";
2303
        break;
2304
    case OPC_VR54XX_MSACHI:
2305
        gen_helper_msachi(t0, t0, t1);
2306
        opn = "msachi";
2307
        break;
2308
    case OPC_VR54XX_MSACHIU:
2309
        gen_helper_msachiu(t0, t0, t1);
2310
        opn = "msachiu";
2311
        break;
2312
    default:
2313
        MIPS_INVAL("mul vr54xx");
2314
        generate_exception(ctx, EXCP_RI);
2315
        goto out;
2316
    }
2317
    gen_store_gpr(t0, rd);
2318
    (void)opn; /* avoid a compiler warning */
2319
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2320

    
2321
 out:
2322
    tcg_temp_free(t0);
2323
    tcg_temp_free(t1);
2324
}
2325

    
2326
static void gen_cl (DisasContext *ctx, uint32_t opc,
2327
                    int rd, int rs)
2328
{
2329
    const char *opn = "CLx";
2330
    TCGv t0;
2331

    
2332
    if (rd == 0) {
2333
        /* Treat as NOP. */
2334
        MIPS_DEBUG("NOP");
2335
        return;
2336
    }
2337
    t0 = tcg_temp_new();
2338
    gen_load_gpr(t0, rs);
2339
    switch (opc) {
2340
    case OPC_CLO:
2341
        gen_helper_clo(cpu_gpr[rd], t0);
2342
        opn = "clo";
2343
        break;
2344
    case OPC_CLZ:
2345
        gen_helper_clz(cpu_gpr[rd], t0);
2346
        opn = "clz";
2347
        break;
2348
#if defined(TARGET_MIPS64)
2349
    case OPC_DCLO:
2350
        gen_helper_dclo(cpu_gpr[rd], t0);
2351
        opn = "dclo";
2352
        break;
2353
    case OPC_DCLZ:
2354
        gen_helper_dclz(cpu_gpr[rd], t0);
2355
        opn = "dclz";
2356
        break;
2357
#endif
2358
    }
2359
    (void)opn; /* avoid a compiler warning */
2360
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2361
    tcg_temp_free(t0);
2362
}
2363

    
2364
/* Godson integer instructions */
2365
static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2366
                                int rd, int rs, int rt)
2367
{
2368
    const char *opn = "loongson";
2369
    TCGv t0, t1;
2370

    
2371
    if (rd == 0) {
2372
        /* Treat as NOP. */
2373
        MIPS_DEBUG("NOP");
2374
        return;
2375
    }
2376

    
2377
    switch (opc) {
2378
    case OPC_MULT_G_2E:
2379
    case OPC_MULT_G_2F:
2380
    case OPC_MULTU_G_2E:
2381
    case OPC_MULTU_G_2F:
2382
#if defined(TARGET_MIPS64)
2383
    case OPC_DMULT_G_2E:
2384
    case OPC_DMULT_G_2F:
2385
    case OPC_DMULTU_G_2E:
2386
    case OPC_DMULTU_G_2F:
2387
#endif
2388
        t0 = tcg_temp_new();
2389
        t1 = tcg_temp_new();
2390
        break;
2391
    default:
2392
        t0 = tcg_temp_local_new();
2393
        t1 = tcg_temp_local_new();
2394
        break;
2395
    }
2396

    
2397
    gen_load_gpr(t0, rs);
2398
    gen_load_gpr(t1, rt);
2399

    
2400
    switch (opc) {
2401
    case OPC_MULT_G_2E:
2402
    case OPC_MULT_G_2F:
2403
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2404
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2405
        opn = "mult.g";
2406
        break;
2407
    case OPC_MULTU_G_2E:
2408
    case OPC_MULTU_G_2F:
2409
        tcg_gen_ext32u_tl(t0, t0);
2410
        tcg_gen_ext32u_tl(t1, t1);
2411
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2412
        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2413
        opn = "multu.g";
2414
        break;
2415
    case OPC_DIV_G_2E:
2416
    case OPC_DIV_G_2F:
2417
        {
2418
            int l1 = gen_new_label();
2419
            int l2 = gen_new_label();
2420
            int l3 = gen_new_label();
2421
            tcg_gen_ext32s_tl(t0, t0);
2422
            tcg_gen_ext32s_tl(t1, t1);
2423
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2424
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2425
            tcg_gen_br(l3);
2426
            gen_set_label(l1);
2427
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2428
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2429
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
2430
            tcg_gen_br(l3);
2431
            gen_set_label(l2);
2432
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2433
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2434
            gen_set_label(l3);
2435
        }
2436
        opn = "div.g";
2437
        break;
2438
    case OPC_DIVU_G_2E:
2439
    case OPC_DIVU_G_2F:
2440
        {
2441
            int l1 = gen_new_label();
2442
            int l2 = gen_new_label();
2443
            tcg_gen_ext32u_tl(t0, t0);
2444
            tcg_gen_ext32u_tl(t1, t1);
2445
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2446
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2447
            tcg_gen_br(l2);
2448
            gen_set_label(l1);
2449
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2450
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2451
            gen_set_label(l2);
2452
        }
2453
        opn = "divu.g";
2454
        break;
2455
    case OPC_MOD_G_2E:
2456
    case OPC_MOD_G_2F:
2457
        {
2458
            int l1 = gen_new_label();
2459
            int l2 = gen_new_label();
2460
            int l3 = gen_new_label();
2461
            tcg_gen_ext32u_tl(t0, t0);
2462
            tcg_gen_ext32u_tl(t1, t1);
2463
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2464
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2465
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2466
            gen_set_label(l1);
2467
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2468
            tcg_gen_br(l3);
2469
            gen_set_label(l2);
2470
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2471
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2472
            gen_set_label(l3);
2473
        }
2474
        opn = "mod.g";
2475
        break;
2476
    case OPC_MODU_G_2E:
2477
    case OPC_MODU_G_2F:
2478
        {
2479
            int l1 = gen_new_label();
2480
            int l2 = gen_new_label();
2481
            tcg_gen_ext32u_tl(t0, t0);
2482
            tcg_gen_ext32u_tl(t1, t1);
2483
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2484
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2485
            tcg_gen_br(l2);
2486
            gen_set_label(l1);
2487
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2488
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2489
            gen_set_label(l2);
2490
        }
2491
        opn = "modu.g";
2492
        break;
2493
#if defined(TARGET_MIPS64)
2494
    case OPC_DMULT_G_2E:
2495
    case OPC_DMULT_G_2F:
2496
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2497
        opn = "dmult.g";
2498
        break;
2499
    case OPC_DMULTU_G_2E:
2500
    case OPC_DMULTU_G_2F:
2501
        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2502
        opn = "dmultu.g";
2503
        break;
2504
    case OPC_DDIV_G_2E:
2505
    case OPC_DDIV_G_2F:
2506
        {
2507
            int l1 = gen_new_label();
2508
            int l2 = gen_new_label();
2509
            int l3 = gen_new_label();
2510
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2511
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2512
            tcg_gen_br(l3);
2513
            gen_set_label(l1);
2514
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2515
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2516
            tcg_gen_mov_tl(cpu_gpr[rd], t0);
2517
            tcg_gen_br(l3);
2518
            gen_set_label(l2);
2519
            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2520
            gen_set_label(l3);
2521
        }
2522
        opn = "ddiv.g";
2523
        break;
2524
    case OPC_DDIVU_G_2E:
2525
    case OPC_DDIVU_G_2F:
2526
        {
2527
            int l1 = gen_new_label();
2528
            int l2 = gen_new_label();
2529
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2530
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2531
            tcg_gen_br(l2);
2532
            gen_set_label(l1);
2533
            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2534
            gen_set_label(l2);
2535
        }
2536
        opn = "ddivu.g";
2537
        break;
2538
    case OPC_DMOD_G_2E:
2539
    case OPC_DMOD_G_2F:
2540
        {
2541
            int l1 = gen_new_label();
2542
            int l2 = gen_new_label();
2543
            int l3 = gen_new_label();
2544
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2545
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2546
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2547
            gen_set_label(l1);
2548
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2549
            tcg_gen_br(l3);
2550
            gen_set_label(l2);
2551
            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2552
            gen_set_label(l3);
2553
        }
2554
        opn = "dmod.g";
2555
        break;
2556
    case OPC_DMODU_G_2E:
2557
    case OPC_DMODU_G_2F:
2558
        {
2559
            int l1 = gen_new_label();
2560
            int l2 = gen_new_label();
2561
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2562
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2563
            tcg_gen_br(l2);
2564
            gen_set_label(l1);
2565
            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2566
            gen_set_label(l2);
2567
        }
2568
        opn = "dmodu.g";
2569
        break;
2570
#endif
2571
    }
2572

    
2573
    (void)opn; /* avoid a compiler warning */
2574
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2575
    tcg_temp_free(t0);
2576
    tcg_temp_free(t1);
2577
}
2578

    
2579
/* Traps */
2580
static void gen_trap (DisasContext *ctx, uint32_t opc,
2581
                      int rs, int rt, int16_t imm)
2582
{
2583
    int cond;
2584
    TCGv t0 = tcg_temp_new();
2585
    TCGv t1 = tcg_temp_new();
2586

    
2587
    cond = 0;
2588
    /* Load needed operands */
2589
    switch (opc) {
2590
    case OPC_TEQ:
2591
    case OPC_TGE:
2592
    case OPC_TGEU:
2593
    case OPC_TLT:
2594
    case OPC_TLTU:
2595
    case OPC_TNE:
2596
        /* Compare two registers */
2597
        if (rs != rt) {
2598
            gen_load_gpr(t0, rs);
2599
            gen_load_gpr(t1, rt);
2600
            cond = 1;
2601
        }
2602
        break;
2603
    case OPC_TEQI:
2604
    case OPC_TGEI:
2605
    case OPC_TGEIU:
2606
    case OPC_TLTI:
2607
    case OPC_TLTIU:
2608
    case OPC_TNEI:
2609
        /* Compare register to immediate */
2610
        if (rs != 0 || imm != 0) {
2611
            gen_load_gpr(t0, rs);
2612
            tcg_gen_movi_tl(t1, (int32_t)imm);
2613
            cond = 1;
2614
        }
2615
        break;
2616
    }
2617
    if (cond == 0) {
2618
        switch (opc) {
2619
        case OPC_TEQ:   /* rs == rs */
2620
        case OPC_TEQI:  /* r0 == 0  */
2621
        case OPC_TGE:   /* rs >= rs */
2622
        case OPC_TGEI:  /* r0 >= 0  */
2623
        case OPC_TGEU:  /* rs >= rs unsigned */
2624
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2625
            /* Always trap */
2626
            generate_exception(ctx, EXCP_TRAP);
2627
            break;
2628
        case OPC_TLT:   /* rs < rs           */
2629
        case OPC_TLTI:  /* r0 < 0            */
2630
        case OPC_TLTU:  /* rs < rs unsigned  */
2631
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2632
        case OPC_TNE:   /* rs != rs          */
2633
        case OPC_TNEI:  /* r0 != 0           */
2634
            /* Never trap: treat as NOP. */
2635
            break;
2636
        }
2637
    } else {
2638
        int l1 = gen_new_label();
2639

    
2640
        switch (opc) {
2641
        case OPC_TEQ:
2642
        case OPC_TEQI:
2643
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2644
            break;
2645
        case OPC_TGE:
2646
        case OPC_TGEI:
2647
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2648
            break;
2649
        case OPC_TGEU:
2650
        case OPC_TGEIU:
2651
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2652
            break;
2653
        case OPC_TLT:
2654
        case OPC_TLTI:
2655
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2656
            break;
2657
        case OPC_TLTU:
2658
        case OPC_TLTIU:
2659
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2660
            break;
2661
        case OPC_TNE:
2662
        case OPC_TNEI:
2663
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2664
            break;
2665
        }
2666
        generate_exception(ctx, EXCP_TRAP);
2667
        gen_set_label(l1);
2668
    }
2669
    tcg_temp_free(t0);
2670
    tcg_temp_free(t1);
2671
}
2672

    
2673
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2674
{
2675
    TranslationBlock *tb;
2676
    tb = ctx->tb;
2677
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2678
        likely(!ctx->singlestep_enabled)) {
2679
        tcg_gen_goto_tb(n);
2680
        gen_save_pc(dest);
2681
        tcg_gen_exit_tb((tcg_target_long)tb + n);
2682
    } else {
2683
        gen_save_pc(dest);
2684
        if (ctx->singlestep_enabled) {
2685
            save_cpu_state(ctx, 0);
2686
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2687
        }
2688
        tcg_gen_exit_tb(0);
2689
    }
2690
}
2691

    
2692
/* Branches (before delay slot) */
2693
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2694
                                int insn_bytes,
2695
                                int rs, int rt, int32_t offset)
2696
{
2697
    target_ulong btgt = -1;
2698
    int blink = 0;
2699
    int bcond_compute = 0;
2700
    TCGv t0 = tcg_temp_new();
2701
    TCGv t1 = tcg_temp_new();
2702

    
2703
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2704
#ifdef MIPS_DEBUG_DISAS
2705
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2706
#endif
2707
        generate_exception(ctx, EXCP_RI);
2708
        goto out;
2709
    }
2710

    
2711
    /* Load needed operands */
2712
    switch (opc) {
2713
    case OPC_BEQ:
2714
    case OPC_BEQL:
2715
    case OPC_BNE:
2716
    case OPC_BNEL:
2717
        /* Compare two registers */
2718
        if (rs != rt) {
2719
            gen_load_gpr(t0, rs);
2720
            gen_load_gpr(t1, rt);
2721
            bcond_compute = 1;
2722
        }
2723
        btgt = ctx->pc + insn_bytes + offset;
2724
        break;
2725
    case OPC_BGEZ:
2726
    case OPC_BGEZAL:
2727
    case OPC_BGEZALS:
2728
    case OPC_BGEZALL:
2729
    case OPC_BGEZL:
2730
    case OPC_BGTZ:
2731
    case OPC_BGTZL:
2732
    case OPC_BLEZ:
2733
    case OPC_BLEZL:
2734
    case OPC_BLTZ:
2735
    case OPC_BLTZAL:
2736
    case OPC_BLTZALS:
2737
    case OPC_BLTZALL:
2738
    case OPC_BLTZL:
2739
        /* Compare to zero */
2740
        if (rs != 0) {
2741
            gen_load_gpr(t0, rs);
2742
            bcond_compute = 1;
2743
        }
2744
        btgt = ctx->pc + insn_bytes + offset;
2745
        break;
2746
    case OPC_J:
2747
    case OPC_JAL:
2748
    case OPC_JALX:
2749
    case OPC_JALS:
2750
    case OPC_JALXS:
2751
        /* Jump to immediate */
2752
        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2753
        break;
2754
    case OPC_JR:
2755
    case OPC_JALR:
2756
    case OPC_JALRC:
2757
    case OPC_JALRS:
2758
        /* Jump to register */
2759
        if (offset != 0 && offset != 16) {
2760
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2761
               others are reserved. */
2762
            MIPS_INVAL("jump hint");
2763
            generate_exception(ctx, EXCP_RI);
2764
            goto out;
2765
        }
2766
        gen_load_gpr(btarget, rs);
2767
        break;
2768
    default:
2769
        MIPS_INVAL("branch/jump");
2770
        generate_exception(ctx, EXCP_RI);
2771
        goto out;
2772
    }
2773
    if (bcond_compute == 0) {
2774
        /* No condition to be computed */
2775
        switch (opc) {
2776
        case OPC_BEQ:     /* rx == rx        */
2777
        case OPC_BEQL:    /* rx == rx likely */
2778
        case OPC_BGEZ:    /* 0 >= 0          */
2779
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2780
        case OPC_BLEZ:    /* 0 <= 0          */
2781
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2782
            /* Always take */
2783
            ctx->hflags |= MIPS_HFLAG_B;
2784
            MIPS_DEBUG("balways");
2785
            break;
2786
        case OPC_BGEZALS:
2787
        case OPC_BGEZAL:  /* 0 >= 0          */
2788
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2789
            ctx->hflags |= (opc == OPC_BGEZALS
2790
                            ? MIPS_HFLAG_BDS16
2791
                            : MIPS_HFLAG_BDS32);
2792
            /* Always take and link */
2793
            blink = 31;
2794
            ctx->hflags |= MIPS_HFLAG_B;
2795
            MIPS_DEBUG("balways and link");
2796
            break;
2797
        case OPC_BNE:     /* rx != rx        */
2798
        case OPC_BGTZ:    /* 0 > 0           */
2799
        case OPC_BLTZ:    /* 0 < 0           */
2800
            /* Treat as NOP. */
2801
            MIPS_DEBUG("bnever (NOP)");
2802
            goto out;
2803
        case OPC_BLTZALS:
2804
        case OPC_BLTZAL:  /* 0 < 0           */
2805
            ctx->hflags |= (opc == OPC_BLTZALS
2806
                            ? MIPS_HFLAG_BDS16
2807
                            : MIPS_HFLAG_BDS32);
2808
            /* Handle as an unconditional branch to get correct delay
2809
               slot checking.  */
2810
            blink = 31;
2811
            btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2812
            ctx->hflags |= MIPS_HFLAG_B;
2813
            MIPS_DEBUG("bnever and link");
2814
            break;
2815
        case OPC_BLTZALL: /* 0 < 0 likely */
2816
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2817
            /* Skip the instruction in the delay slot */
2818
            MIPS_DEBUG("bnever, link and skip");
2819
            ctx->pc += 4;
2820
            goto out;
2821
        case OPC_BNEL:    /* rx != rx likely */
2822
        case OPC_BGTZL:   /* 0 > 0 likely */
2823
        case OPC_BLTZL:   /* 0 < 0 likely */
2824
            /* Skip the instruction in the delay slot */
2825
            MIPS_DEBUG("bnever and skip");
2826
            ctx->pc += 4;
2827
            goto out;
2828
        case OPC_J:
2829
            ctx->hflags |= MIPS_HFLAG_B;
2830
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2831
            break;
2832
        case OPC_JALXS:
2833
        case OPC_JALX:
2834
            ctx->hflags |= MIPS_HFLAG_BX;
2835
            /* Fallthrough */
2836
        case OPC_JALS:
2837
        case OPC_JAL:
2838
            blink = 31;
2839
            ctx->hflags |= MIPS_HFLAG_B;
2840
            ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2841
                            ? MIPS_HFLAG_BDS16
2842
                            : MIPS_HFLAG_BDS32);
2843
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2844
            break;
2845
        case OPC_JR:
2846
            ctx->hflags |= MIPS_HFLAG_BR;
2847
            if (insn_bytes == 4)
2848
                ctx->hflags |= MIPS_HFLAG_BDS32;
2849
            MIPS_DEBUG("jr %s", regnames[rs]);
2850
            break;
2851
        case OPC_JALRS:
2852
        case OPC_JALR:
2853
        case OPC_JALRC:
2854
            blink = rt;
2855
            ctx->hflags |= MIPS_HFLAG_BR;
2856
            ctx->hflags |= (opc == OPC_JALRS
2857
                            ? MIPS_HFLAG_BDS16
2858
                            : MIPS_HFLAG_BDS32);
2859
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2860
            break;
2861
        default:
2862
            MIPS_INVAL("branch/jump");
2863
            generate_exception(ctx, EXCP_RI);
2864
            goto out;
2865
        }
2866
    } else {
2867
        switch (opc) {
2868
        case OPC_BEQ:
2869
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2870
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2871
                       regnames[rs], regnames[rt], btgt);
2872
            goto not_likely;
2873
        case OPC_BEQL:
2874
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2875
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2876
                       regnames[rs], regnames[rt], btgt);
2877
            goto likely;
2878
        case OPC_BNE:
2879
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2880
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2881
                       regnames[rs], regnames[rt], btgt);
2882
            goto not_likely;
2883
        case OPC_BNEL:
2884
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2885
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2886
                       regnames[rs], regnames[rt], btgt);
2887
            goto likely;
2888
        case OPC_BGEZ:
2889
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2890
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2891
            goto not_likely;
2892
        case OPC_BGEZL:
2893
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2894
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2895
            goto likely;
2896
        case OPC_BGEZALS:
2897
        case OPC_BGEZAL:
2898
            ctx->hflags |= (opc == OPC_BGEZALS
2899
                            ? MIPS_HFLAG_BDS16
2900
                            : MIPS_HFLAG_BDS32);
2901
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2902
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2903
            blink = 31;
2904
            goto not_likely;
2905
        case OPC_BGEZALL:
2906
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2907
            blink = 31;
2908
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2909
            goto likely;
2910
        case OPC_BGTZ:
2911
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2912
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2913
            goto not_likely;
2914
        case OPC_BGTZL:
2915
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2916
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2917
            goto likely;
2918
        case OPC_BLEZ:
2919
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2920
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2921
            goto not_likely;
2922
        case OPC_BLEZL:
2923
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2924
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2925
            goto likely;
2926
        case OPC_BLTZ:
2927
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2928
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2929
            goto not_likely;
2930
        case OPC_BLTZL:
2931
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2932
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2933
            goto likely;
2934
        case OPC_BLTZALS:
2935
        case OPC_BLTZAL:
2936
            ctx->hflags |= (opc == OPC_BLTZALS
2937
                            ? MIPS_HFLAG_BDS16
2938
                            : MIPS_HFLAG_BDS32);
2939
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2940
            blink = 31;
2941
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2942
        not_likely:
2943
            ctx->hflags |= MIPS_HFLAG_BC;
2944
            break;
2945
        case OPC_BLTZALL:
2946
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2947
            blink = 31;
2948
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2949
        likely:
2950
            ctx->hflags |= MIPS_HFLAG_BL;
2951
            break;
2952
        default:
2953
            MIPS_INVAL("conditional branch/jump");
2954
            generate_exception(ctx, EXCP_RI);
2955
            goto out;
2956
        }
2957
    }
2958
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2959
               blink, ctx->hflags, btgt);
2960

    
2961
    ctx->btarget = btgt;
2962
    if (blink > 0) {
2963
        int post_delay = insn_bytes;
2964
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2965

    
2966
        if (opc != OPC_JALRC)
2967
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2968

    
2969
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2970
    }
2971

    
2972
 out:
2973
    if (insn_bytes == 2)
2974
        ctx->hflags |= MIPS_HFLAG_B16;
2975
    tcg_temp_free(t0);
2976
    tcg_temp_free(t1);
2977
}
2978

    
2979
/* special3 bitfield operations */
2980
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2981
                        int rs, int lsb, int msb)
2982
{
2983
    TCGv t0 = tcg_temp_new();
2984
    TCGv t1 = tcg_temp_new();
2985
    target_ulong mask;
2986

    
2987
    gen_load_gpr(t1, rs);
2988
    switch (opc) {
2989
    case OPC_EXT:
2990
        if (lsb + msb > 31)
2991
            goto fail;
2992
        tcg_gen_shri_tl(t0, t1, lsb);
2993
        if (msb != 31) {
2994
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2995
        } else {
2996
            tcg_gen_ext32s_tl(t0, t0);
2997
        }
2998
        break;
2999
#if defined(TARGET_MIPS64)
3000
    case OPC_DEXTM:
3001
        tcg_gen_shri_tl(t0, t1, lsb);
3002
        if (msb != 31) {
3003
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3004
        }
3005
        break;
3006
    case OPC_DEXTU:
3007
        tcg_gen_shri_tl(t0, t1, lsb + 32);
3008
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3009
        break;
3010
    case OPC_DEXT:
3011
        tcg_gen_shri_tl(t0, t1, lsb);
3012
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3013
        break;
3014
#endif
3015
    case OPC_INS:
3016
        if (lsb > msb)
3017
            goto fail;
3018
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3019
        gen_load_gpr(t0, rt);
3020
        tcg_gen_andi_tl(t0, t0, ~mask);
3021
        tcg_gen_shli_tl(t1, t1, lsb);
3022
        tcg_gen_andi_tl(t1, t1, mask);
3023
        tcg_gen_or_tl(t0, t0, t1);
3024
        tcg_gen_ext32s_tl(t0, t0);
3025
        break;
3026
#if defined(TARGET_MIPS64)
3027
    case OPC_DINSM:
3028
        if (lsb > msb)
3029
            goto fail;
3030
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3031
        gen_load_gpr(t0, rt);
3032
        tcg_gen_andi_tl(t0, t0, ~mask);
3033
        tcg_gen_shli_tl(t1, t1, lsb);
3034
        tcg_gen_andi_tl(t1, t1, mask);
3035
        tcg_gen_or_tl(t0, t0, t1);
3036
        break;
3037
    case OPC_DINSU:
3038
        if (lsb > msb)
3039
            goto fail;
3040
        mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3041
        gen_load_gpr(t0, rt);
3042
        tcg_gen_andi_tl(t0, t0, ~mask);
3043
        tcg_gen_shli_tl(t1, t1, lsb + 32);
3044
        tcg_gen_andi_tl(t1, t1, mask);
3045
        tcg_gen_or_tl(t0, t0, t1);
3046
        break;
3047
    case OPC_DINS:
3048
        if (lsb > msb)
3049
            goto fail;
3050
        gen_load_gpr(t0, rt);
3051
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3052
        gen_load_gpr(t0, rt);
3053
        tcg_gen_andi_tl(t0, t0, ~mask);
3054
        tcg_gen_shli_tl(t1, t1, lsb);
3055
        tcg_gen_andi_tl(t1, t1, mask);
3056
        tcg_gen_or_tl(t0, t0, t1);
3057
        break;
3058
#endif
3059
    default:
3060
fail:
3061
        MIPS_INVAL("bitops");
3062
        generate_exception(ctx, EXCP_RI);
3063
        tcg_temp_free(t0);
3064
        tcg_temp_free(t1);
3065
        return;
3066
    }
3067
    gen_store_gpr(t0, rt);
3068
    tcg_temp_free(t0);
3069
    tcg_temp_free(t1);
3070
}
3071

    
3072
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3073
{
3074
    TCGv t0;
3075

    
3076
    if (rd == 0) {
3077
        /* If no destination, treat it as a NOP. */
3078
        MIPS_DEBUG("NOP");
3079
        return;
3080
    }
3081

    
3082
    t0 = tcg_temp_new();
3083
    gen_load_gpr(t0, rt);
3084
    switch (op2) {
3085
    case OPC_WSBH:
3086
        {
3087
            TCGv t1 = tcg_temp_new();
3088

    
3089
            tcg_gen_shri_tl(t1, t0, 8);
3090
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3091
            tcg_gen_shli_tl(t0, t0, 8);
3092
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3093
            tcg_gen_or_tl(t0, t0, t1);
3094
            tcg_temp_free(t1);
3095
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3096
        }
3097
        break;
3098
    case OPC_SEB:
3099
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3100
        break;
3101
    case OPC_SEH:
3102
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3103
        break;
3104
#if defined(TARGET_MIPS64)
3105
    case OPC_DSBH:
3106
        {
3107
            TCGv t1 = tcg_temp_new();
3108

    
3109
            tcg_gen_shri_tl(t1, t0, 8);
3110
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3111
            tcg_gen_shli_tl(t0, t0, 8);
3112
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3113
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3114
            tcg_temp_free(t1);
3115
        }
3116
        break;
3117
    case OPC_DSHD:
3118
        {
3119
            TCGv t1 = tcg_temp_new();
3120

    
3121
            tcg_gen_shri_tl(t1, t0, 16);
3122
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3123
            tcg_gen_shli_tl(t0, t0, 16);
3124
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3125
            tcg_gen_or_tl(t0, t0, t1);
3126
            tcg_gen_shri_tl(t1, t0, 32);
3127
            tcg_gen_shli_tl(t0, t0, 32);
3128
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3129
            tcg_temp_free(t1);
3130
        }
3131
        break;
3132
#endif
3133
    default:
3134
        MIPS_INVAL("bsfhl");
3135
        generate_exception(ctx, EXCP_RI);
3136
        tcg_temp_free(t0);
3137
        return;
3138
    }
3139
    tcg_temp_free(t0);
3140
}
3141

    
3142
#ifndef CONFIG_USER_ONLY
3143
/* CP0 (MMU and control) */
3144
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3145
{
3146
    TCGv_i32 t0 = tcg_temp_new_i32();
3147

    
3148
    tcg_gen_ld_i32(t0, cpu_env, off);
3149
    tcg_gen_ext_i32_tl(arg, t0);
3150
    tcg_temp_free_i32(t0);
3151
}
3152

    
3153
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3154
{
3155
    tcg_gen_ld_tl(arg, cpu_env, off);
3156
    tcg_gen_ext32s_tl(arg, arg);
3157
}
3158

    
3159
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3160
{
3161
    TCGv_i32 t0 = tcg_temp_new_i32();
3162

    
3163
    tcg_gen_trunc_tl_i32(t0, arg);
3164
    tcg_gen_st_i32(t0, cpu_env, off);
3165
    tcg_temp_free_i32(t0);
3166
}
3167

    
3168
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3169
{
3170
    tcg_gen_ext32s_tl(arg, arg);
3171
    tcg_gen_st_tl(arg, cpu_env, off);
3172
}
3173

    
3174
static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3175
{
3176
    const char *rn = "invalid";
3177

    
3178
    if (sel != 0)
3179
        check_insn(env, ctx, ISA_MIPS32);
3180

    
3181
    switch (reg) {
3182
    case 0:
3183
        switch (sel) {
3184
        case 0:
3185
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
3186
            rn = "Index";
3187
            break;
3188
        case 1:
3189
            check_insn(env, ctx, ASE_MT);
3190
            gen_helper_mfc0_mvpcontrol(arg);
3191
            rn = "MVPControl";
3192
            break;
3193
        case 2:
3194
            check_insn(env, ctx, ASE_MT);
3195
            gen_helper_mfc0_mvpconf0(arg);
3196
            rn = "MVPConf0";
3197
            break;
3198
        case 3:
3199
            check_insn(env, ctx, ASE_MT);
3200
            gen_helper_mfc0_mvpconf1(arg);
3201
            rn = "MVPConf1";
3202
            break;
3203
        default:
3204
            goto die;
3205
        }
3206
        break;
3207
    case 1:
3208
        switch (sel) {
3209
        case 0:
3210
            gen_helper_mfc0_random(arg);
3211
            rn = "Random";
3212
            break;
3213
        case 1:
3214
            check_insn(env, ctx, ASE_MT);
3215
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
3216
            rn = "VPEControl";
3217
            break;
3218
        case 2:
3219
            check_insn(env, ctx, ASE_MT);
3220
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
3221
            rn = "VPEConf0";
3222
            break;
3223
        case 3:
3224
            check_insn(env, ctx, ASE_MT);
3225
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
3226
            rn = "VPEConf1";
3227
            break;
3228
        case 4:
3229
            check_insn(env, ctx, ASE_MT);
3230
            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
3231
            rn = "YQMask";
3232
            break;
3233
        case 5:
3234
            check_insn(env, ctx, ASE_MT);
3235
            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3236
            rn = "VPESchedule";
3237
            break;
3238
        case 6:
3239
            check_insn(env, ctx, ASE_MT);
3240
            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3241
            rn = "VPEScheFBack";
3242
            break;
3243
        case 7:
3244
            check_insn(env, ctx, ASE_MT);
3245
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
3246
            rn = "VPEOpt";
3247
            break;
3248
        default:
3249
            goto die;
3250
        }
3251
        break;
3252
    case 2:
3253
        switch (sel) {
3254
        case 0:
3255
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
3256
            tcg_gen_ext32s_tl(arg, arg);
3257
            rn = "EntryLo0";
3258
            break;
3259
        case 1:
3260
            check_insn(env, ctx, ASE_MT);
3261
            gen_helper_mfc0_tcstatus(arg);
3262
            rn = "TCStatus";
3263
            break;
3264
        case 2:
3265
            check_insn(env, ctx, ASE_MT);
3266
            gen_helper_mfc0_tcbind(arg);
3267
            rn = "TCBind";
3268
            break;
3269
        case 3:
3270
            check_insn(env, ctx, ASE_MT);
3271
            gen_helper_mfc0_tcrestart(arg);
3272
            rn = "TCRestart";
3273
            break;
3274
        case 4:
3275
            check_insn(env, ctx, ASE_MT);
3276
            gen_helper_mfc0_tchalt(arg);
3277
            rn = "TCHalt";
3278
            break;
3279
        case 5:
3280
            check_insn(env, ctx, ASE_MT);
3281
            gen_helper_mfc0_tccontext(arg);
3282
            rn = "TCContext";
3283
            break;
3284
        case 6:
3285
            check_insn(env, ctx, ASE_MT);
3286
            gen_helper_mfc0_tcschedule(arg);
3287
            rn = "TCSchedule";
3288
            break;
3289
        case 7:
3290
            check_insn(env, ctx, ASE_MT);
3291
            gen_helper_mfc0_tcschefback(arg);
3292
            rn = "TCScheFBack";
3293
            break;
3294
        default:
3295
            goto die;
3296
        }
3297
        break;
3298
    case 3:
3299
        switch (sel) {
3300
        case 0:
3301
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
3302
            tcg_gen_ext32s_tl(arg, arg);
3303
            rn = "EntryLo1";
3304
            break;
3305
        default:
3306
            goto die;
3307
        }
3308
        break;
3309
    case 4:
3310
        switch (sel) {
3311
        case 0:
3312
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
3313
            tcg_gen_ext32s_tl(arg, arg);
3314
            rn = "Context";
3315
            break;
3316
        case 1:
3317
//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3318
            rn = "ContextConfig";
3319
//            break;
3320
        default:
3321
            goto die;
3322
        }
3323
        break;
3324
    case 5:
3325
        switch (sel) {
3326
        case 0:
3327
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
3328
            rn = "PageMask";
3329
            break;
3330
        case 1:
3331
            check_insn(env, ctx, ISA_MIPS32R2);
3332
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
3333
            rn = "PageGrain";
3334
            break;
3335
        default:
3336
            goto die;
3337
        }
3338
        break;
3339
    case 6:
3340
        switch (sel) {
3341
        case 0:
3342
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
3343
            rn = "Wired";
3344
            break;
3345
        case 1:
3346
            check_insn(env, ctx, ISA_MIPS32R2);
3347
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
3348
            rn = "SRSConf0";
3349
            break;
3350
        case 2:
3351
            check_insn(env, ctx, ISA_MIPS32R2);
3352
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
3353
            rn = "SRSConf1";
3354
            break;
3355
        case 3:
3356
            check_insn(env, ctx, ISA_MIPS32R2);
3357
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
3358
            rn = "SRSConf2";
3359
            break;
3360
        case 4:
3361
            check_insn(env, ctx, ISA_MIPS32R2);
3362
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
3363
            rn = "SRSConf3";
3364
            break;
3365
        case 5:
3366
            check_insn(env, ctx, ISA_MIPS32R2);
3367
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
3368
            rn = "SRSConf4";
3369
            break;
3370
        default:
3371
            goto die;
3372
        }
3373
        break;
3374
    case 7:
3375
        switch (sel) {
3376
        case 0:
3377
            check_insn(env, ctx, ISA_MIPS32R2);
3378
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
3379
            rn = "HWREna";
3380
            break;
3381
        default:
3382
            goto die;
3383
        }
3384
        break;
3385
    case 8:
3386
        switch (sel) {
3387
        case 0:
3388
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
3389
            tcg_gen_ext32s_tl(arg, arg);
3390
            rn = "BadVAddr";
3391
            break;
3392
        default:
3393
            goto die;
3394
       }
3395
        break;
3396
    case 9:
3397
        switch (sel) {
3398
        case 0:
3399
            /* Mark as an IO operation because we read the time.  */
3400
            if (use_icount)
3401
                gen_io_start();
3402
            gen_helper_mfc0_count(arg);
3403
            if (use_icount) {
3404
                gen_io_end();
3405
            }
3406
            /* Break the TB to be able to take timer interrupts immediately
3407
               after reading count.  */
3408
            ctx->bstate = BS_STOP;
3409
            rn = "Count";
3410
            break;
3411
        /* 6,7 are implementation dependent */
3412
        default:
3413
            goto die;
3414
        }
3415
        break;
3416
    case 10:
3417
        switch (sel) {
3418
        case 0:
3419
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
3420
            tcg_gen_ext32s_tl(arg, arg);
3421
            rn = "EntryHi";
3422
            break;
3423
        default:
3424
            goto die;
3425
        }
3426
        break;
3427
    case 11:
3428
        switch (sel) {
3429
        case 0:
3430
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
3431
            rn = "Compare";
3432
            break;
3433
        /* 6,7 are implementation dependent */
3434
        default:
3435
            goto die;
3436
        }
3437
        break;
3438
    case 12:
3439
        switch (sel) {
3440
        case 0:
3441
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
3442
            rn = "Status";
3443
            break;
3444
        case 1:
3445
            check_insn(env, ctx, ISA_MIPS32R2);
3446
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
3447
            rn = "IntCtl";
3448
            break;
3449
        case 2:
3450
            check_insn(env, ctx, ISA_MIPS32R2);
3451
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
3452
            rn = "SRSCtl";
3453
            break;
3454
        case 3:
3455
            check_insn(env, ctx, ISA_MIPS32R2);
3456
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
3457
            rn = "SRSMap";
3458
            break;
3459
        default:
3460
            goto die;
3461
       }
3462
        break;
3463
    case 13:
3464
        switch (sel) {
3465
        case 0:
3466
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
3467
            rn = "Cause";
3468
            break;
3469
        default:
3470
            goto die;
3471
       }
3472
        break;
3473
    case 14:
3474
        switch (sel) {
3475
        case 0:
3476
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
3477
            tcg_gen_ext32s_tl(arg, arg);
3478
            rn = "EPC";
3479
            break;
3480
        default:
3481
            goto die;
3482
        }
3483
        break;
3484
    case 15:
3485
        switch (sel) {
3486
        case 0:
3487
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
3488
            rn = "PRid";
3489
            break;
3490
        case 1:
3491
            check_insn(env, ctx, ISA_MIPS32R2);
3492
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
3493
            rn = "EBase";
3494
            break;
3495
        default:
3496
            goto die;
3497
       }
3498
        break;
3499
    case 16:
3500
        switch (sel) {
3501
        case 0:
3502
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
3503
            rn = "Config";
3504
            break;
3505
        case 1:
3506
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
3507
            rn = "Config1";
3508
            break;
3509
        case 2:
3510
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
3511
            rn = "Config2";
3512
            break;
3513
        case 3:
3514
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
3515
            rn = "Config3";
3516
            break;
3517
        /* 4,5 are reserved */
3518
        /* 6,7 are implementation dependent */
3519
        case 6:
3520
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
3521
            rn = "Config6";
3522
            break;
3523
        case 7:
3524
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
3525
            rn = "Config7";
3526
            break;
3527
        default:
3528
            goto die;
3529
        }
3530
        break;
3531
    case 17:
3532
        switch (sel) {
3533
        case 0:
3534
            gen_helper_mfc0_lladdr(arg);
3535
            rn = "LLAddr";
3536
            break;
3537
        default:
3538
            goto die;
3539
        }
3540
        break;
3541
    case 18:
3542
        switch (sel) {
3543
        case 0 ... 7:
3544
            gen_helper_1i(mfc0_watchlo, arg, sel);
3545
            rn = "WatchLo";
3546
            break;
3547
        default:
3548
            goto die;
3549
        }
3550
        break;
3551
    case 19:
3552
        switch (sel) {
3553
        case 0 ...7:
3554
            gen_helper_1i(mfc0_watchhi, arg, sel);
3555
            rn = "WatchHi";
3556
            break;
3557
        default:
3558
            goto die;
3559
        }
3560
        break;
3561
    case 20:
3562
        switch (sel) {
3563
        case 0:
3564
#if defined(TARGET_MIPS64)
3565
            check_insn(env, ctx, ISA_MIPS3);
3566
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
3567
            tcg_gen_ext32s_tl(arg, arg);
3568
            rn = "XContext";
3569
            break;
3570
#endif
3571
        default:
3572
            goto die;
3573
        }
3574
        break;
3575
    case 21:
3576
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3577
        switch (sel) {
3578
        case 0:
3579
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
3580
            rn = "Framemask";
3581
            break;
3582
        default:
3583
            goto die;
3584
        }
3585
        break;
3586
    case 22:
3587
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3588
        rn = "'Diagnostic"; /* implementation dependent */
3589
        break;
3590
    case 23:
3591
        switch (sel) {
3592
        case 0:
3593
            gen_helper_mfc0_debug(arg); /* EJTAG support */
3594
            rn = "Debug";
3595
            break;
3596
        case 1:
3597
//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3598
            rn = "TraceControl";
3599
//            break;
3600
        case 2:
3601
//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3602
            rn = "TraceControl2";
3603
//            break;
3604
        case 3:
3605
//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3606
            rn = "UserTraceData";
3607
//            break;
3608
        case 4:
3609
//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3610
            rn = "TraceBPC";
3611
//            break;
3612
        default:
3613
            goto die;
3614
        }
3615
        break;
3616
    case 24:
3617
        switch (sel) {
3618
        case 0:
3619
            /* EJTAG support */
3620
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
3621
            tcg_gen_ext32s_tl(arg, arg);
3622
            rn = "DEPC";
3623
            break;
3624
        default:
3625
            goto die;
3626
        }
3627
        break;
3628
    case 25:
3629
        switch (sel) {
3630
        case 0:
3631
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
3632
            rn = "Performance0";
3633
            break;
3634
        case 1:
3635
//            gen_helper_mfc0_performance1(arg);
3636
            rn = "Performance1";
3637
//            break;
3638
        case 2:
3639
//            gen_helper_mfc0_performance2(arg);
3640
            rn = "Performance2";
3641
//            break;
3642
        case 3:
3643
//            gen_helper_mfc0_performance3(arg);
3644
            rn = "Performance3";
3645
//            break;
3646
        case 4:
3647
//            gen_helper_mfc0_performance4(arg);
3648
            rn = "Performance4";
3649
//            break;
3650
        case 5:
3651
//            gen_helper_mfc0_performance5(arg);
3652
            rn = "Performance5";
3653
//            break;
3654
        case 6:
3655
//            gen_helper_mfc0_performance6(arg);
3656
            rn = "Performance6";
3657
//            break;
3658
        case 7:
3659
//            gen_helper_mfc0_performance7(arg);
3660
            rn = "Performance7";
3661
//            break;
3662
        default:
3663
            goto die;
3664
        }
3665
        break;
3666
    case 26:
3667
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3668
        rn = "ECC";
3669
        break;
3670
    case 27:
3671
        switch (sel) {
3672
        case 0 ... 3:
3673
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
3674
            rn = "CacheErr";
3675
            break;
3676
        default:
3677
            goto die;
3678
        }
3679
        break;
3680
    case 28:
3681
        switch (sel) {
3682
        case 0:
3683
        case 2:
3684
        case 4:
3685
        case 6:
3686
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
3687
            rn = "TagLo";
3688
            break;
3689
        case 1:
3690
        case 3:
3691
        case 5:
3692
        case 7:
3693
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
3694
            rn = "DataLo";
3695
            break;
3696
        default:
3697
            goto die;
3698
        }
3699
        break;
3700
    case 29:
3701
        switch (sel) {
3702
        case 0:
3703
        case 2:
3704
        case 4:
3705
        case 6:
3706
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
3707
            rn = "TagHi";
3708
            break;
3709
        case 1:
3710
        case 3:
3711
        case 5:
3712
        case 7:
3713
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
3714
            rn = "DataHi";
3715
            break;
3716
        default:
3717
            goto die;
3718
        }
3719
        break;
3720
    case 30:
3721
        switch (sel) {
3722
        case 0:
3723
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
3724
            tcg_gen_ext32s_tl(arg, arg);
3725
            rn = "ErrorEPC";
3726
            break;
3727
        default:
3728
            goto die;
3729
        }
3730
        break;
3731
    case 31:
3732
        switch (sel) {
3733
        case 0:
3734
            /* EJTAG support */
3735
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
3736
            rn = "DESAVE";
3737
            break;
3738
        default:
3739
            goto die;
3740
        }
3741
        break;
3742
    default:
3743
       goto die;
3744
    }
3745
    (void)rn; /* avoid a compiler warning */
3746
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3747
    return;
3748

    
3749
die:
3750
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3751
    generate_exception(ctx, EXCP_RI);
3752
}
3753

    
3754
static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3755
{
3756
    const char *rn = "invalid";
3757

    
3758
    if (sel != 0)
3759
        check_insn(env, ctx, ISA_MIPS32);
3760

    
3761
    if (use_icount)
3762
        gen_io_start();
3763

    
3764
    switch (reg) {
3765
    case 0:
3766
        switch (sel) {
3767
        case 0:
3768
            gen_helper_mtc0_index(arg);
3769
            rn = "Index";
3770
            break;
3771
        case 1:
3772
            check_insn(env, ctx, ASE_MT);
3773
            gen_helper_mtc0_mvpcontrol(arg);
3774
            rn = "MVPControl";
3775
            break;
3776
        case 2:
3777
            check_insn(env, ctx, ASE_MT);
3778
            /* ignored */
3779
            rn = "MVPConf0";
3780
            break;
3781
        case 3:
3782
            check_insn(env, ctx, ASE_MT);
3783
            /* ignored */
3784
            rn = "MVPConf1";
3785
            break;
3786
        default:
3787
            goto die;
3788
        }
3789
        break;
3790
    case 1:
3791
        switch (sel) {
3792
        case 0:
3793
            /* ignored */
3794
            rn = "Random";
3795
            break;
3796
        case 1:
3797
            check_insn(env, ctx, ASE_MT);
3798
            gen_helper_mtc0_vpecontrol(arg);
3799
            rn = "VPEControl";
3800
            break;
3801
        case 2:
3802
            check_insn(env, ctx, ASE_MT);
3803
            gen_helper_mtc0_vpeconf0(arg);
3804
            rn = "VPEConf0";
3805
            break;
3806
        case 3:
3807
            check_insn(env, ctx, ASE_MT);
3808
            gen_helper_mtc0_vpeconf1(arg);
3809
            rn = "VPEConf1";
3810
            break;
3811
        case 4:
3812
            check_insn(env, ctx, ASE_MT);
3813
            gen_helper_mtc0_yqmask(arg);
3814
            rn = "YQMask";
3815
            break;
3816
        case 5:
3817
            check_insn(env, ctx, ASE_MT);
3818
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3819
            rn = "VPESchedule";
3820
            break;
3821
        case 6:
3822
            check_insn(env, ctx, ASE_MT);
3823
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3824
            rn = "VPEScheFBack";
3825
            break;
3826
        case 7:
3827
            check_insn(env, ctx, ASE_MT);
3828
            gen_helper_mtc0_vpeopt(arg);
3829
            rn = "VPEOpt";
3830
            break;
3831
        default:
3832
            goto die;
3833
        }
3834
        break;
3835
    case 2:
3836
        switch (sel) {
3837
        case 0:
3838
            gen_helper_mtc0_entrylo0(arg);
3839
            rn = "EntryLo0";
3840
            break;
3841
        case 1:
3842
            check_insn(env, ctx, ASE_MT);
3843
            gen_helper_mtc0_tcstatus(arg);
3844
            rn = "TCStatus";
3845
            break;
3846
        case 2:
3847
            check_insn(env, ctx, ASE_MT);
3848
            gen_helper_mtc0_tcbind(arg);
3849
            rn = "TCBind";
3850
            break;
3851
        case 3:
3852
            check_insn(env, ctx, ASE_MT);
3853
            gen_helper_mtc0_tcrestart(arg);
3854
            rn = "TCRestart";
3855
            break;
3856
        case 4:
3857
            check_insn(env, ctx, ASE_MT);
3858
            gen_helper_mtc0_tchalt(arg);
3859
            rn = "TCHalt";
3860
            break;
3861
        case 5:
3862
            check_insn(env, ctx, ASE_MT);
3863
            gen_helper_mtc0_tccontext(arg);
3864
            rn = "TCContext";
3865
            break;
3866
        case 6:
3867
            check_insn(env, ctx, ASE_MT);
3868
            gen_helper_mtc0_tcschedule(arg);
3869
            rn = "TCSchedule";
3870
            break;
3871
        case 7:
3872
            check_insn(env, ctx, ASE_MT);
3873
            gen_helper_mtc0_tcschefback(arg);
3874
            rn = "TCScheFBack";
3875
            break;
3876
        default:
3877
            goto die;
3878
        }
3879
        break;
3880
    case 3:
3881
        switch (sel) {
3882
        case 0:
3883
            gen_helper_mtc0_entrylo1(arg);
3884
            rn = "EntryLo1";
3885
            break;
3886
        default:
3887
            goto die;
3888
        }
3889
        break;
3890
    case 4:
3891
        switch (sel) {
3892
        case 0:
3893
            gen_helper_mtc0_context(arg);
3894
            rn = "Context";
3895
            break;
3896
        case 1:
3897
//            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3898
            rn = "ContextConfig";
3899
//            break;
3900
        default:
3901
            goto die;
3902
        }
3903
        break;
3904
    case 5:
3905
        switch (sel) {
3906
        case 0:
3907
            gen_helper_mtc0_pagemask(arg);
3908
            rn = "PageMask";
3909
            break;
3910
        case 1:
3911
            check_insn(env, ctx, ISA_MIPS32R2);
3912
            gen_helper_mtc0_pagegrain(arg);
3913
            rn = "PageGrain";
3914
            break;
3915
        default:
3916
            goto die;
3917
        }
3918
        break;
3919
    case 6:
3920
        switch (sel) {
3921
        case 0:
3922
            gen_helper_mtc0_wired(arg);
3923
            rn = "Wired";
3924
            break;
3925
        case 1:
3926
            check_insn(env, ctx, ISA_MIPS32R2);
3927
            gen_helper_mtc0_srsconf0(arg);
3928
            rn = "SRSConf0";
3929
            break;
3930
        case 2:
3931
            check_insn(env, ctx, ISA_MIPS32R2);
3932
            gen_helper_mtc0_srsconf1(arg);
3933
            rn = "SRSConf1";
3934
            break;
3935
        case 3:
3936
            check_insn(env, ctx, ISA_MIPS32R2);
3937
            gen_helper_mtc0_srsconf2(arg);
3938
            rn = "SRSConf2";
3939
            break;
3940
        case 4:
3941
            check_insn(env, ctx, ISA_MIPS32R2);
3942
            gen_helper_mtc0_srsconf3(arg);
3943
            rn = "SRSConf3";
3944
            break;
3945
        case 5:
3946
            check_insn(env, ctx, ISA_MIPS32R2);
3947
            gen_helper_mtc0_srsconf4(arg);
3948
            rn = "SRSConf4";
3949
            break;
3950
        default:
3951
            goto die;
3952
        }
3953
        break;
3954
    case 7:
3955
        switch (sel) {
3956
        case 0:
3957
            check_insn(env, ctx, ISA_MIPS32R2);
3958
            gen_helper_mtc0_hwrena(arg);
3959
            rn = "HWREna";
3960
            break;
3961
        default:
3962
            goto die;
3963
        }
3964
        break;
3965
    case 8:
3966
        /* ignored */
3967
        rn = "BadVAddr";
3968
        break;
3969
    case 9:
3970
        switch (sel) {
3971
        case 0:
3972
            gen_helper_mtc0_count(arg);
3973
            rn = "Count";
3974
            break;
3975
        /* 6,7 are implementation dependent */
3976
        default:
3977
            goto die;
3978
        }
3979
        break;
3980
    case 10:
3981
        switch (sel) {
3982
        case 0:
3983
            gen_helper_mtc0_entryhi(arg);
3984
            rn = "EntryHi";
3985
            break;
3986
        default:
3987
            goto die;
3988
        }
3989
        break;
3990
    case 11:
3991
        switch (sel) {
3992
        case 0:
3993
            gen_helper_mtc0_compare(arg);
3994
            rn = "Compare";
3995
            break;
3996
        /* 6,7 are implementation dependent */
3997
        default:
3998
            goto die;
3999
        }
4000
        break;
4001
    case 12:
4002
        switch (sel) {
4003
        case 0:
4004
            save_cpu_state(ctx, 1);
4005
            gen_helper_mtc0_status(arg);
4006
            /* BS_STOP isn't good enough here, hflags may have changed. */
4007
            gen_save_pc(ctx->pc + 4);
4008
            ctx->bstate = BS_EXCP;
4009
            rn = "Status";
4010
            break;
4011
        case 1:
4012
            check_insn(env, ctx, ISA_MIPS32R2);
4013
            gen_helper_mtc0_intctl(arg);
4014
            /* Stop translation as we may have switched the execution mode */
4015
            ctx->bstate = BS_STOP;
4016
            rn = "IntCtl";
4017
            break;
4018
        case 2:
4019
            check_insn(env, ctx, ISA_MIPS32R2);
4020
            gen_helper_mtc0_srsctl(arg);
4021
            /* Stop translation as we may have switched the execution mode */
4022
            ctx->bstate = BS_STOP;
4023
            rn = "SRSCtl";
4024
            break;
4025
        case 3:
4026
            check_insn(env, ctx, ISA_MIPS32R2);
4027
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4028
            /* Stop translation as we may have switched the execution mode */
4029
            ctx->bstate = BS_STOP;
4030
            rn = "SRSMap";
4031
            break;
4032
        default:
4033
            goto die;
4034
        }
4035
        break;
4036
    case 13:
4037
        switch (sel) {
4038
        case 0:
4039
            save_cpu_state(ctx, 1);
4040
            gen_helper_mtc0_cause(arg);
4041
            rn = "Cause";
4042
            break;
4043
        default:
4044
            goto die;
4045
        }
4046
        break;
4047
    case 14:
4048
        switch (sel) {
4049
        case 0:
4050
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4051
            rn = "EPC";
4052
            break;
4053
        default:
4054
            goto die;
4055
        }
4056
        break;
4057
    case 15:
4058
        switch (sel) {
4059
        case 0:
4060
            /* ignored */
4061
            rn = "PRid";
4062
            break;
4063
        case 1:
4064
            check_insn(env, ctx, ISA_MIPS32R2);
4065
            gen_helper_mtc0_ebase(arg);
4066
            rn = "EBase";
4067
            break;
4068
        default:
4069
            goto die;
4070
        }
4071
        break;
4072
    case 16:
4073
        switch (sel) {
4074
        case 0:
4075
            gen_helper_mtc0_config0(arg);
4076
            rn = "Config";
4077
            /* Stop translation as we may have switched the execution mode */
4078
            ctx->bstate = BS_STOP;
4079
            break;
4080
        case 1:
4081
            /* ignored, read only */
4082
            rn = "Config1";
4083
            break;
4084
        case 2:
4085
            gen_helper_mtc0_config2(arg);
4086
            rn = "Config2";
4087
            /* Stop translation as we may have switched the execution mode */
4088
            ctx->bstate = BS_STOP;
4089
            break;
4090
        case 3:
4091
            /* ignored, read only */
4092
            rn = "Config3";
4093
            break;
4094
        /* 4,5 are reserved */
4095
        /* 6,7 are implementation dependent */
4096
        case 6:
4097
            /* ignored */
4098
            rn = "Config6";
4099
            break;
4100
        case 7:
4101
            /* ignored */
4102
            rn = "Config7";
4103
            break;
4104
        default:
4105
            rn = "Invalid config selector";
4106
            goto die;
4107
        }
4108
        break;
4109
    case 17:
4110
        switch (sel) {
4111
        case 0:
4112
            gen_helper_mtc0_lladdr(arg);
4113
            rn = "LLAddr";
4114
            break;
4115
        default:
4116
            goto die;
4117
        }
4118
        break;
4119
    case 18:
4120
        switch (sel) {
4121
        case 0 ... 7:
4122
            gen_helper_1i(mtc0_watchlo, arg, sel);
4123
            rn = "WatchLo";
4124
            break;
4125
        default:
4126
            goto die;
4127
        }
4128
        break;
4129
    case 19:
4130
        switch (sel) {
4131
        case 0 ... 7:
4132
            gen_helper_1i(mtc0_watchhi, arg, sel);
4133
            rn = "WatchHi";
4134
            break;
4135
        default:
4136
            goto die;
4137
        }
4138
        break;
4139
    case 20:
4140
        switch (sel) {
4141
        case 0:
4142
#if defined(TARGET_MIPS64)
4143
            check_insn(env, ctx, ISA_MIPS3);
4144
            gen_helper_mtc0_xcontext(arg);
4145
            rn = "XContext";
4146
            break;
4147
#endif
4148
        default:
4149
            goto die;
4150
        }
4151
        break;
4152
    case 21:
4153
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4154
        switch (sel) {
4155
        case 0:
4156
            gen_helper_mtc0_framemask(arg);
4157
            rn = "Framemask";
4158
            break;
4159
        default:
4160
            goto die;
4161
        }
4162
        break;
4163
    case 22:
4164
        /* ignored */
4165
        rn = "Diagnostic"; /* implementation dependent */
4166
        break;
4167
    case 23:
4168
        switch (sel) {
4169
        case 0:
4170
            gen_helper_mtc0_debug(arg); /* EJTAG support */
4171
            /* BS_STOP isn't good enough here, hflags may have changed. */
4172
            gen_save_pc(ctx->pc + 4);
4173
            ctx->bstate = BS_EXCP;
4174
            rn = "Debug";
4175
            break;
4176
        case 1:
4177
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4178
            rn = "TraceControl";
4179
            /* Stop translation as we may have switched the execution mode */
4180
            ctx->bstate = BS_STOP;
4181
//            break;
4182
        case 2:
4183
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4184
            rn = "TraceControl2";
4185
            /* Stop translation as we may have switched the execution mode */
4186
            ctx->bstate = BS_STOP;
4187
//            break;
4188
        case 3:
4189
            /* Stop translation as we may have switched the execution mode */
4190
            ctx->bstate = BS_STOP;
4191
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4192
            rn = "UserTraceData";
4193
            /* Stop translation as we may have switched the execution mode */
4194
            ctx->bstate = BS_STOP;
4195
//            break;
4196
        case 4:
4197
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4198
            /* Stop translation as we may have switched the execution mode */
4199
            ctx->bstate = BS_STOP;
4200
            rn = "TraceBPC";
4201
//            break;
4202
        default:
4203
            goto die;
4204
        }
4205
        break;
4206
    case 24:
4207
        switch (sel) {
4208
        case 0:
4209
            /* EJTAG support */
4210
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
4211
            rn = "DEPC";
4212
            break;
4213
        default:
4214
            goto die;
4215
        }
4216
        break;
4217
    case 25:
4218
        switch (sel) {
4219
        case 0:
4220
            gen_helper_mtc0_performance0(arg);
4221
            rn = "Performance0";
4222
            break;
4223
        case 1:
4224
//            gen_helper_mtc0_performance1(arg);
4225
            rn = "Performance1";
4226
//            break;
4227
        case 2:
4228
//            gen_helper_mtc0_performance2(arg);
4229
            rn = "Performance2";
4230
//            break;
4231
        case 3:
4232
//            gen_helper_mtc0_performance3(arg);
4233
            rn = "Performance3";
4234
//            break;
4235
        case 4:
4236
//            gen_helper_mtc0_performance4(arg);
4237
            rn = "Performance4";
4238
//            break;
4239
        case 5:
4240
//            gen_helper_mtc0_performance5(arg);
4241
            rn = "Performance5";
4242
//            break;
4243
        case 6:
4244
//            gen_helper_mtc0_performance6(arg);
4245
            rn = "Performance6";
4246
//            break;
4247
        case 7:
4248
//            gen_helper_mtc0_performance7(arg);
4249
            rn = "Performance7";
4250
//            break;
4251
        default:
4252
            goto die;
4253
        }
4254
       break;
4255
    case 26:
4256
        /* ignored */
4257
        rn = "ECC";
4258
        break;
4259
    case 27:
4260
        switch (sel) {
4261
        case 0 ... 3:
4262
            /* ignored */
4263
            rn = "CacheErr";
4264
            break;
4265
        default:
4266
            goto die;
4267
        }
4268
       break;
4269
    case 28:
4270
        switch (sel) {
4271
        case 0:
4272
        case 2:
4273
        case 4:
4274
        case 6:
4275
            gen_helper_mtc0_taglo(arg);
4276
            rn = "TagLo";
4277
            break;
4278
        case 1:
4279
        case 3:
4280
        case 5:
4281
        case 7:
4282
            gen_helper_mtc0_datalo(arg);
4283
            rn = "DataLo";
4284
            break;
4285
        default:
4286
            goto die;
4287
        }
4288
        break;
4289
    case 29:
4290
        switch (sel) {
4291
        case 0:
4292
        case 2:
4293
        case 4:
4294
        case 6:
4295
            gen_helper_mtc0_taghi(arg);
4296
            rn = "TagHi";
4297
            break;
4298
        case 1:
4299
        case 3:
4300
        case 5:
4301
        case 7:
4302
            gen_helper_mtc0_datahi(arg);
4303
            rn = "DataHi";
4304
            break;
4305
        default:
4306
            rn = "invalid sel";
4307
            goto die;
4308
        }
4309
       break;
4310
    case 30:
4311
        switch (sel) {
4312
        case 0:
4313
            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
4314
            rn = "ErrorEPC";
4315
            break;
4316
        default:
4317
            goto die;
4318
        }
4319
        break;
4320
    case 31:
4321
        switch (sel) {
4322
        case 0:
4323
            /* EJTAG support */
4324
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4325
            rn = "DESAVE";
4326
            break;
4327
        default:
4328
            goto die;
4329
        }
4330
        /* Stop translation as we may have switched the execution mode */
4331
        ctx->bstate = BS_STOP;
4332
        break;
4333
    default:
4334
       goto die;
4335
    }
4336
    (void)rn; /* avoid a compiler warning */
4337
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4338
    /* For simplicity assume that all writes can cause interrupts.  */
4339
    if (use_icount) {
4340
        gen_io_end();
4341
        ctx->bstate = BS_STOP;
4342
    }
4343
    return;
4344

    
4345
die:
4346
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4347
    generate_exception(ctx, EXCP_RI);
4348
}
4349

    
4350
#if defined(TARGET_MIPS64)
4351
static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4352
{
4353
    const char *rn = "invalid";
4354

    
4355
    if (sel != 0)
4356
        check_insn(env, ctx, ISA_MIPS64);
4357

    
4358
    switch (reg) {
4359
    case 0:
4360
        switch (sel) {
4361
        case 0:
4362
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4363
            rn = "Index";
4364
            break;
4365
        case 1:
4366
            check_insn(env, ctx, ASE_MT);
4367
            gen_helper_mfc0_mvpcontrol(arg);
4368
            rn = "MVPControl";
4369
            break;
4370
        case 2:
4371
            check_insn(env, ctx, ASE_MT);
4372
            gen_helper_mfc0_mvpconf0(arg);
4373
            rn = "MVPConf0";
4374
            break;
4375
        case 3:
4376
            check_insn(env, ctx, ASE_MT);
4377
            gen_helper_mfc0_mvpconf1(arg);
4378
            rn = "MVPConf1";
4379
            break;
4380
        default:
4381
            goto die;
4382
        }
4383
        break;
4384
    case 1:
4385
        switch (sel) {
4386
        case 0:
4387
            gen_helper_mfc0_random(arg);
4388
            rn = "Random";
4389
            break;
4390
        case 1:
4391
            check_insn(env, ctx, ASE_MT);
4392
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4393
            rn = "VPEControl";
4394
            break;
4395
        case 2:
4396
            check_insn(env, ctx, ASE_MT);
4397
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4398
            rn = "VPEConf0";
4399
            break;
4400
        case 3:
4401
            check_insn(env, ctx, ASE_MT);
4402
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4403
            rn = "VPEConf1";
4404
            break;
4405
        case 4:
4406
            check_insn(env, ctx, ASE_MT);
4407
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
4408
            rn = "YQMask";
4409
            break;
4410
        case 5:
4411
            check_insn(env, ctx, ASE_MT);
4412
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4413
            rn = "VPESchedule";
4414
            break;
4415
        case 6:
4416
            check_insn(env, ctx, ASE_MT);
4417
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4418
            rn = "VPEScheFBack";
4419
            break;
4420
        case 7:
4421
            check_insn(env, ctx, ASE_MT);
4422
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4423
            rn = "VPEOpt";
4424
            break;
4425
        default:
4426
            goto die;
4427
        }
4428
        break;
4429
    case 2:
4430
        switch (sel) {
4431
        case 0:
4432
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4433
            rn = "EntryLo0";
4434
            break;
4435
        case 1:
4436
            check_insn(env, ctx, ASE_MT);
4437
            gen_helper_mfc0_tcstatus(arg);
4438
            rn = "TCStatus";
4439
            break;
4440
        case 2:
4441
            check_insn(env, ctx, ASE_MT);
4442
            gen_helper_mfc0_tcbind(arg);
4443
            rn = "TCBind";
4444
            break;
4445
        case 3:
4446
            check_insn(env, ctx, ASE_MT);
4447
            gen_helper_dmfc0_tcrestart(arg);
4448
            rn = "TCRestart";
4449
            break;
4450
        case 4:
4451
            check_insn(env, ctx, ASE_MT);
4452
            gen_helper_dmfc0_tchalt(arg);
4453
            rn = "TCHalt";
4454
            break;
4455
        case 5:
4456
            check_insn(env, ctx, ASE_MT);
4457
            gen_helper_dmfc0_tccontext(arg);
4458
            rn = "TCContext";
4459
            break;
4460
        case 6:
4461
            check_insn(env, ctx, ASE_MT);
4462
            gen_helper_dmfc0_tcschedule(arg);
4463
            rn = "TCSchedule";
4464
            break;
4465
        case 7:
4466
            check_insn(env, ctx, ASE_MT);
4467
            gen_helper_dmfc0_tcschefback(arg);
4468
            rn = "TCScheFBack";
4469
            break;
4470
        default:
4471
            goto die;
4472
        }
4473
        break;
4474
    case 3:
4475
        switch (sel) {
4476
        case 0:
4477
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4478
            rn = "EntryLo1";
4479
            break;
4480
        default:
4481
            goto die;
4482
        }
4483
        break;
4484
    case 4:
4485
        switch (sel) {
4486
        case 0:
4487
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4488
            rn = "Context";
4489
            break;
4490
        case 1:
4491
//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4492
            rn = "ContextConfig";
4493
//            break;
4494
        default:
4495
            goto die;
4496
        }
4497
        break;
4498
    case 5:
4499
        switch (sel) {
4500
        case 0:
4501
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4502
            rn = "PageMask";
4503
            break;
4504
        case 1:
4505
            check_insn(env, ctx, ISA_MIPS32R2);
4506
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4507
            rn = "PageGrain";
4508
            break;
4509
        default:
4510
            goto die;
4511
        }
4512
        break;
4513
    case 6:
4514
        switch (sel) {
4515
        case 0:
4516
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4517
            rn = "Wired";
4518
            break;
4519
        case 1:
4520
            check_insn(env, ctx, ISA_MIPS32R2);
4521
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4522
            rn = "SRSConf0";
4523
            break;
4524
        case 2:
4525
            check_insn(env, ctx, ISA_MIPS32R2);
4526
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4527
            rn = "SRSConf1";
4528
            break;
4529
        case 3:
4530
            check_insn(env, ctx, ISA_MIPS32R2);
4531
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4532
            rn = "SRSConf2";
4533
            break;
4534
        case 4:
4535
            check_insn(env, ctx, ISA_MIPS32R2);
4536
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4537
            rn = "SRSConf3";
4538
            break;
4539
        case 5:
4540
            check_insn(env, ctx, ISA_MIPS32R2);
4541
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4542
            rn = "SRSConf4";
4543
            break;
4544
        default:
4545
            goto die;
4546
        }
4547
        break;
4548
    case 7:
4549
        switch (sel) {
4550
        case 0:
4551
            check_insn(env, ctx, ISA_MIPS32R2);
4552
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4553
            rn = "HWREna";
4554
            break;
4555
        default:
4556
            goto die;
4557
        }
4558
        break;
4559
    case 8:
4560
        switch (sel) {
4561
        case 0:
4562
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4563
            rn = "BadVAddr";
4564
            break;
4565
        default:
4566
            goto die;
4567
        }
4568
        break;
4569
    case 9:
4570
        switch (sel) {
4571
        case 0:
4572
            /* Mark as an IO operation because we read the time.  */
4573
            if (use_icount)
4574
                gen_io_start();
4575
            gen_helper_mfc0_count(arg);
4576
            if (use_icount) {
4577
                gen_io_end();
4578
            }
4579
            /* Break the TB to be able to take timer interrupts immediately
4580
               after reading count.  */
4581
            ctx->bstate = BS_STOP;
4582
            rn = "Count";
4583
            break;
4584
        /* 6,7 are implementation dependent */
4585
        default:
4586
            goto die;
4587
        }
4588
        break;
4589
    case 10:
4590
        switch (sel) {
4591
        case 0:
4592
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4593
            rn = "EntryHi";
4594
            break;
4595
        default:
4596
            goto die;
4597
        }
4598
        break;
4599
    case 11:
4600
        switch (sel) {
4601
        case 0:
4602
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4603
            rn = "Compare";
4604
            break;
4605
        /* 6,7 are implementation dependent */
4606
        default:
4607
            goto die;
4608
        }
4609
        break;
4610
    case 12:
4611
        switch (sel) {
4612
        case 0:
4613
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4614
            rn = "Status";
4615
            break;
4616
        case 1:
4617
            check_insn(env, ctx, ISA_MIPS32R2);
4618
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4619
            rn = "IntCtl";
4620
            break;
4621
        case 2:
4622
            check_insn(env, ctx, ISA_MIPS32R2);
4623
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4624
            rn = "SRSCtl";
4625
            break;
4626
        case 3:
4627
            check_insn(env, ctx, ISA_MIPS32R2);
4628
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4629
            rn = "SRSMap";
4630
            break;
4631
        default:
4632
            goto die;
4633
        }
4634
        break;
4635
    case 13:
4636
        switch (sel) {
4637
        case 0:
4638
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4639
            rn = "Cause";
4640
            break;
4641
        default:
4642
            goto die;
4643
        }
4644
        break;
4645
    case 14:
4646
        switch (sel) {
4647
        case 0:
4648
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4649
            rn = "EPC";
4650
            break;
4651
        default:
4652
            goto die;
4653
        }
4654
        break;
4655
    case 15:
4656
        switch (sel) {
4657
        case 0:
4658
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4659
            rn = "PRid";
4660
            break;
4661
        case 1:
4662
            check_insn(env, ctx, ISA_MIPS32R2);
4663
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4664
            rn = "EBase";
4665
            break;
4666
        default:
4667
            goto die;
4668
        }
4669
        break;
4670
    case 16:
4671
        switch (sel) {
4672
        case 0:
4673
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4674
            rn = "Config";
4675
            break;
4676
        case 1:
4677
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4678
            rn = "Config1";
4679
            break;
4680
        case 2:
4681
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4682
            rn = "Config2";
4683
            break;
4684
        case 3:
4685
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4686
            rn = "Config3";
4687
            break;
4688
       /* 6,7 are implementation dependent */
4689
        case 6:
4690
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4691
            rn = "Config6";
4692
            break;
4693
        case 7:
4694
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4695
            rn = "Config7";
4696
            break;
4697
        default:
4698
            goto die;
4699
        }
4700
        break;
4701
    case 17:
4702
        switch (sel) {
4703
        case 0:
4704
            gen_helper_dmfc0_lladdr(arg);
4705
            rn = "LLAddr";
4706
            break;
4707
        default:
4708
            goto die;
4709
        }
4710
        break;
4711
    case 18:
4712
        switch (sel) {
4713
        case 0 ... 7:
4714
            gen_helper_1i(dmfc0_watchlo, arg, sel);
4715
            rn = "WatchLo";
4716
            break;
4717
        default:
4718
            goto die;
4719
        }
4720
        break;
4721
    case 19:
4722
        switch (sel) {
4723
        case 0 ... 7:
4724
            gen_helper_1i(mfc0_watchhi, arg, sel);
4725
            rn = "WatchHi";
4726
            break;
4727
        default:
4728
            goto die;
4729
        }
4730
        break;
4731
    case 20:
4732
        switch (sel) {
4733
        case 0:
4734
            check_insn(env, ctx, ISA_MIPS3);
4735
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4736
            rn = "XContext";
4737
            break;
4738
        default:
4739
            goto die;
4740
        }
4741
        break;
4742
    case 21:
4743
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4744
        switch (sel) {
4745
        case 0:
4746
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4747
            rn = "Framemask";
4748
            break;
4749
        default:
4750
            goto die;
4751
        }
4752
        break;
4753
    case 22:
4754
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4755
        rn = "'Diagnostic"; /* implementation dependent */
4756
        break;
4757
    case 23:
4758
        switch (sel) {
4759
        case 0:
4760
            gen_helper_mfc0_debug(arg); /* EJTAG support */
4761
            rn = "Debug";
4762
            break;
4763
        case 1:
4764
//            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4765
            rn = "TraceControl";
4766
//            break;
4767
        case 2:
4768
//            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4769
            rn = "TraceControl2";
4770
//            break;
4771
        case 3:
4772
//            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4773
            rn = "UserTraceData";
4774
//            break;
4775
        case 4:
4776
//            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4777
            rn = "TraceBPC";
4778
//            break;
4779
        default:
4780
            goto die;
4781
        }
4782
        break;
4783
    case 24:
4784
        switch (sel) {
4785
        case 0:
4786
            /* EJTAG support */
4787
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4788
            rn = "DEPC";
4789
            break;
4790
        default:
4791
            goto die;
4792
        }
4793
        break;
4794
    case 25:
4795
        switch (sel) {
4796
        case 0:
4797
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4798
            rn = "Performance0";
4799
            break;
4800
        case 1:
4801
//            gen_helper_dmfc0_performance1(arg);
4802
            rn = "Performance1";
4803
//            break;
4804
        case 2:
4805
//            gen_helper_dmfc0_performance2(arg);
4806
            rn = "Performance2";
4807
//            break;
4808
        case 3:
4809
//            gen_helper_dmfc0_performance3(arg);
4810
            rn = "Performance3";
4811
//            break;
4812
        case 4:
4813
//            gen_helper_dmfc0_performance4(arg);
4814
            rn = "Performance4";
4815
//            break;
4816
        case 5:
4817
//            gen_helper_dmfc0_performance5(arg);
4818
            rn = "Performance5";
4819
//            break;
4820
        case 6:
4821
//            gen_helper_dmfc0_performance6(arg);
4822
            rn = "Performance6";
4823
//            break;
4824
        case 7:
4825
//            gen_helper_dmfc0_performance7(arg);
4826
            rn = "Performance7";
4827
//            break;
4828
        default:
4829
            goto die;
4830
        }
4831
        break;
4832
    case 26:
4833
        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4834
        rn = "ECC";
4835
        break;
4836
    case 27:
4837
        switch (sel) {
4838
        /* ignored */
4839
        case 0 ... 3:
4840
            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4841
            rn = "CacheErr";
4842
            break;
4843
        default:
4844
            goto die;
4845
        }
4846
        break;
4847
    case 28:
4848
        switch (sel) {
4849
        case 0:
4850
        case 2:
4851
        case 4:
4852
        case 6:
4853
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4854
            rn = "TagLo";
4855
            break;
4856
        case 1:
4857
        case 3:
4858
        case 5:
4859
        case 7:
4860
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4861
            rn = "DataLo";
4862
            break;
4863
        default:
4864
            goto die;
4865
        }
4866
        break;
4867
    case 29:
4868
        switch (sel) {
4869
        case 0:
4870
        case 2:
4871
        case 4:
4872
        case 6:
4873
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4874
            rn = "TagHi";
4875
            break;
4876
        case 1:
4877
        case 3:
4878
        case 5:
4879
        case 7:
4880
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4881
            rn = "DataHi";
4882
            break;
4883
        default:
4884
            goto die;
4885
        }
4886
        break;
4887
    case 30:
4888
        switch (sel) {
4889
        case 0:
4890
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4891
            rn = "ErrorEPC";
4892
            break;
4893
        default:
4894
            goto die;
4895
        }
4896
        break;
4897
    case 31:
4898
        switch (sel) {
4899
        case 0:
4900
            /* EJTAG support */
4901
            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4902
            rn = "DESAVE";
4903
            break;
4904
        default:
4905
            goto die;
4906
        }
4907
        break;
4908
    default:
4909
        goto die;
4910
    }
4911
    (void)rn; /* avoid a compiler warning */
4912
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4913
    return;
4914

    
4915
die:
4916
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4917
    generate_exception(ctx, EXCP_RI);
4918
}
4919

    
4920
static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4921
{
4922
    const char *rn = "invalid";
4923

    
4924
    if (sel != 0)
4925
        check_insn(env, ctx, ISA_MIPS64);
4926

    
4927
    if (use_icount)
4928
        gen_io_start();
4929

    
4930
    switch (reg) {
4931
    case 0:
4932
        switch (sel) {
4933
        case 0:
4934
            gen_helper_mtc0_index(arg);
4935
            rn = "Index";
4936
            break;
4937
        case 1:
4938
            check_insn(env, ctx, ASE_MT);
4939
            gen_helper_mtc0_mvpcontrol(arg);
4940
            rn = "MVPControl";
4941
            break;
4942
        case 2:
4943
            check_insn(env, ctx, ASE_MT);
4944
            /* ignored */
4945
            rn = "MVPConf0";
4946
            break;
4947
        case 3:
4948
            check_insn(env, ctx, ASE_MT);
4949
            /* ignored */
4950
            rn = "MVPConf1";
4951
            break;
4952
        default:
4953
            goto die;
4954
        }
4955
        break;
4956
    case 1:
4957
        switch (sel) {
4958
        case 0:
4959
            /* ignored */
4960
            rn = "Random";
4961
            break;
4962
        case 1:
4963
            check_insn(env, ctx, ASE_MT);
4964
            gen_helper_mtc0_vpecontrol(arg);
4965
            rn = "VPEControl";
4966
            break;
4967
        case 2:
4968
            check_insn(env, ctx, ASE_MT);
4969
            gen_helper_mtc0_vpeconf0(arg);
4970
            rn = "VPEConf0";
4971
            break;
4972
        case 3:
4973
            check_insn(env, ctx, ASE_MT);
4974
            gen_helper_mtc0_vpeconf1(arg);
4975
            rn = "VPEConf1";
4976
            break;
4977
        case 4:
4978
            check_insn(env, ctx, ASE_MT);
4979
            gen_helper_mtc0_yqmask(arg);
4980
            rn = "YQMask";
4981
            break;
4982
        case 5:
4983
            check_insn(env, ctx, ASE_MT);
4984
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4985
            rn = "VPESchedule";
4986
            break;
4987
        case 6:
4988
            check_insn(env, ctx, ASE_MT);
4989
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4990
            rn = "VPEScheFBack";
4991
            break;
4992
        case 7:
4993
            check_insn(env, ctx, ASE_MT);
4994
            gen_helper_mtc0_vpeopt(arg);
4995
            rn = "VPEOpt";
4996
            break;
4997
        default:
4998
            goto die;
4999
        }
5000
        break;
5001
    case 2:
5002
        switch (sel) {
5003
        case 0:
5004
            gen_helper_mtc0_entrylo0(arg);
5005
            rn = "EntryLo0";
5006
            break;
5007
        case 1:
5008
            check_insn(env, ctx, ASE_MT);
5009
            gen_helper_mtc0_tcstatus(arg);
5010
            rn = "TCStatus";
5011
            break;
5012
        case 2:
5013
            check_insn(env, ctx, ASE_MT);
5014
            gen_helper_mtc0_tcbind(arg);
5015
            rn = "TCBind";
5016
            break;
5017
        case 3:
5018
            check_insn(env, ctx, ASE_MT);
5019
            gen_helper_mtc0_tcrestart(arg);
5020
            rn = "TCRestart";
5021
            break;
5022
        case 4:
5023
            check_insn(env, ctx, ASE_MT);
5024
            gen_helper_mtc0_tchalt(arg);
5025
            rn = "TCHalt";
5026
            break;
5027
        case 5:
5028
            check_insn(env, ctx, ASE_MT);
5029
            gen_helper_mtc0_tccontext(arg);
5030
            rn = "TCContext";
5031
            break;
5032
        case 6:
5033
            check_insn(env, ctx, ASE_MT);
5034
            gen_helper_mtc0_tcschedule(arg);
5035
            rn = "TCSchedule";
5036
            break;
5037
        case 7:
5038
            check_insn(env, ctx, ASE_MT);
5039
            gen_helper_mtc0_tcschefback(arg);
5040
            rn = "TCScheFBack";
5041
            break;
5042
        default:
5043
            goto die;
5044
        }
5045
        break;
5046
    case 3:
5047
        switch (sel) {
5048
        case 0:
5049
            gen_helper_mtc0_entrylo1(arg);
5050
            rn = "EntryLo1";
5051
            break;
5052
        default:
5053
            goto die;
5054
        }
5055
        break;
5056
    case 4:
5057
        switch (sel) {
5058
        case 0:
5059
            gen_helper_mtc0_context(arg);
5060
            rn = "Context";
5061
            break;
5062
        case 1:
5063
//           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5064
            rn = "ContextConfig";
5065
//           break;
5066
        default:
5067
            goto die;
5068
        }
5069
        break;
5070
    case 5:
5071
        switch (sel) {
5072
        case 0:
5073
            gen_helper_mtc0_pagemask(arg);
5074
            rn = "PageMask";
5075
            break;
5076
        case 1:
5077
            check_insn(env, ctx, ISA_MIPS32R2);
5078
            gen_helper_mtc0_pagegrain(arg);
5079
            rn = "PageGrain";
5080
            break;
5081
        default:
5082
            goto die;
5083
        }
5084
        break;
5085
    case 6:
5086
        switch (sel) {
5087
        case 0:
5088
            gen_helper_mtc0_wired(arg);
5089
            rn = "Wired";
5090
            break;
5091
        case 1:
5092
            check_insn(env, ctx, ISA_MIPS32R2);
5093
            gen_helper_mtc0_srsconf0(arg);
5094
            rn = "SRSConf0";
5095
            break;
5096
        case 2:
5097
            check_insn(env, ctx, ISA_MIPS32R2);
5098
            gen_helper_mtc0_srsconf1(arg);
5099
            rn = "SRSConf1";
5100
            break;
5101
        case 3:
5102
            check_insn(env, ctx, ISA_MIPS32R2);
5103
            gen_helper_mtc0_srsconf2(arg);
5104
            rn = "SRSConf2";
5105
            break;
5106
        case 4:
5107
            check_insn(env, ctx, ISA_MIPS32R2);
5108
            gen_helper_mtc0_srsconf3(arg);
5109
            rn = "SRSConf3";
5110
            break;
5111
        case 5:
5112
            check_insn(env, ctx, ISA_MIPS32R2);
5113
            gen_helper_mtc0_srsconf4(arg);
5114
            rn = "SRSConf4";
5115
            break;
5116
        default:
5117
            goto die;
5118
        }
5119
        break;
5120
    case 7:
5121
        switch (sel) {
5122
        case 0:
5123
            check_insn(env, ctx, ISA_MIPS32R2);
5124
            gen_helper_mtc0_hwrena(arg);
5125
            rn = "HWREna";
5126
            break;
5127
        default:
5128
            goto die;
5129
        }
5130
        break;
5131
    case 8:
5132
        /* ignored */
5133
        rn = "BadVAddr";
5134
        break;
5135
    case 9:
5136
        switch (sel) {
5137
        case 0:
5138
            gen_helper_mtc0_count(arg);
5139
            rn = "Count";
5140
            break;
5141
        /* 6,7 are implementation dependent */
5142
        default:
5143
            goto die;
5144
        }
5145
        /* Stop translation as we may have switched the execution mode */
5146
        ctx->bstate = BS_STOP;
5147
        break;
5148
    case 10:
5149
        switch (sel) {
5150
        case 0:
5151
            gen_helper_mtc0_entryhi(arg);
5152
            rn = "EntryHi";
5153
            break;
5154
        default:
5155
            goto die;
5156
        }
5157
        break;
5158
    case 11:
5159
        switch (sel) {
5160
        case 0:
5161
            gen_helper_mtc0_compare(arg);
5162
            rn = "Compare";
5163
            break;
5164
        /* 6,7 are implementation dependent */
5165
        default:
5166
            goto die;
5167
        }
5168
        /* Stop translation as we may have switched the execution mode */
5169
        ctx->bstate = BS_STOP;
5170
        break;
5171
    case 12:
5172
        switch (sel) {
5173
        case 0:
5174
            save_cpu_state(ctx, 1);
5175
            gen_helper_mtc0_status(arg);
5176
            /* BS_STOP isn't good enough here, hflags may have changed. */
5177
            gen_save_pc(ctx->pc + 4);
5178
            ctx->bstate = BS_EXCP;
5179
            rn = "Status";
5180
            break;
5181
        case 1:
5182
            check_insn(env, ctx, ISA_MIPS32R2);
5183
            gen_helper_mtc0_intctl(arg);
5184
            /* Stop translation as we may have switched the execution mode */
5185
            ctx->bstate = BS_STOP;
5186
            rn = "IntCtl";
5187
            break;
5188
        case 2:
5189
            check_insn(env, ctx, ISA_MIPS32R2);
5190
            gen_helper_mtc0_srsctl(arg);
5191
            /* Stop translation as we may have switched the execution mode */
5192
            ctx->bstate = BS_STOP;
5193
            rn = "SRSCtl";
5194
            break;
5195
        case 3:
5196
            check_insn(env, ctx, ISA_MIPS32R2);
5197
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5198
            /* Stop translation as we may have switched the execution mode */
5199
            ctx->bstate = BS_STOP;
5200
            rn = "SRSMap";
5201
            break;
5202
        default:
5203
            goto die;
5204
        }
5205
        break;
5206
    case 13:
5207
        switch (sel) {
5208
        case 0:
5209
            save_cpu_state(ctx, 1);
5210
            /* Mark as an IO operation because we may trigger a software
5211
               interrupt.  */
5212
            if (use_icount) {
5213
                gen_io_start();
5214
            }
5215
            gen_helper_mtc0_cause(arg);
5216
            if (use_icount) {
5217
                gen_io_end();
5218
            }
5219
            /* Stop translation as we may have triggered an intetrupt */
5220
            ctx->bstate = BS_STOP;
5221
            rn = "Cause";
5222
            break;
5223
        default:
5224
            goto die;
5225
        }
5226
        break;
5227
    case 14:
5228
        switch (sel) {
5229
        case 0:
5230
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5231
            rn = "EPC";
5232
            break;
5233
        default:
5234
            goto die;
5235
        }
5236
        break;
5237
    case 15:
5238
        switch (sel) {
5239
        case 0:
5240
            /* ignored */
5241
            rn = "PRid";
5242
            break;
5243
        case 1:
5244
            check_insn(env, ctx, ISA_MIPS32R2);
5245
            gen_helper_mtc0_ebase(arg);
5246
            rn = "EBase";
5247
            break;
5248
        default:
5249
            goto die;
5250
        }
5251
        break;
5252
    case 16:
5253
        switch (sel) {
5254
        case 0:
5255
            gen_helper_mtc0_config0(arg);
5256
            rn = "Config";
5257
            /* Stop translation as we may have switched the execution mode */
5258
            ctx->bstate = BS_STOP;
5259
            break;
5260
        case 1:
5261
            /* ignored, read only */
5262
            rn = "Config1";
5263
            break;
5264
        case 2:
5265
            gen_helper_mtc0_config2(arg);
5266
            rn = "Config2";
5267
            /* Stop translation as we may have switched the execution mode */
5268
            ctx->bstate = BS_STOP;
5269
            break;
5270
        case 3:
5271
            /* ignored */
5272
            rn = "Config3";
5273
            break;
5274
        /* 6,7 are implementation dependent */
5275
        default:
5276
            rn = "Invalid config selector";
5277
            goto die;
5278
        }
5279
        break;
5280
    case 17:
5281
        switch (sel) {
5282
        case 0:
5283
            gen_helper_mtc0_lladdr(arg);
5284
            rn = "LLAddr";
5285
            break;
5286
        default:
5287
            goto die;
5288
        }
5289
        break;
5290
    case 18:
5291
        switch (sel) {
5292
        case 0 ... 7:
5293
            gen_helper_1i(mtc0_watchlo, arg, sel);
5294
            rn = "WatchLo";
5295
            break;
5296
        default:
5297
            goto die;
5298
        }
5299
        break;
5300
    case 19:
5301
        switch (sel) {
5302
        case 0 ... 7:
5303
            gen_helper_1i(mtc0_watchhi, arg, sel);
5304
            rn = "WatchHi";
5305
            break;
5306
        default:
5307
            goto die;
5308
        }
5309
        break;
5310
    case 20:
5311
        switch (sel) {
5312
        case 0:
5313
            check_insn(env, ctx, ISA_MIPS3);
5314
            gen_helper_mtc0_xcontext(arg);
5315
            rn = "XContext";
5316
            break;
5317
        default:
5318
            goto die;
5319
        }
5320
        break;
5321
    case 21:
5322
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5323
        switch (sel) {
5324
        case 0:
5325
            gen_helper_mtc0_framemask(arg);
5326
            rn = "Framemask";
5327
            break;
5328
        default:
5329
            goto die;
5330
        }
5331
        break;
5332
    case 22:
5333
        /* ignored */
5334
        rn = "Diagnostic"; /* implementation dependent */
5335
        break;
5336
    case 23:
5337
        switch (sel) {
5338
        case 0:
5339
            gen_helper_mtc0_debug(arg); /* EJTAG support */
5340
            /* BS_STOP isn't good enough here, hflags may have changed. */
5341
            gen_save_pc(ctx->pc + 4);
5342
            ctx->bstate = BS_EXCP;
5343
            rn = "Debug";
5344
            break;
5345
        case 1:
5346
//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5347
            /* Stop translation as we may have switched the execution mode */
5348
            ctx->bstate = BS_STOP;
5349
            rn = "TraceControl";
5350
//            break;
5351
        case 2:
5352
//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5353
            /* Stop translation as we may have switched the execution mode */
5354
            ctx->bstate = BS_STOP;
5355
            rn = "TraceControl2";
5356
//            break;
5357
        case 3:
5358
//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5359
            /* Stop translation as we may have switched the execution mode */
5360
            ctx->bstate = BS_STOP;
5361
            rn = "UserTraceData";
5362
//            break;
5363
        case 4:
5364
//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5365
            /* Stop translation as we may have switched the execution mode */
5366
            ctx->bstate = BS_STOP;
5367
            rn = "TraceBPC";
5368
//            break;
5369
        default:
5370
            goto die;
5371
        }
5372
        break;
5373
    case 24:
5374
        switch (sel) {
5375
        case 0:
5376
            /* EJTAG support */
5377
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5378
            rn = "DEPC";
5379
            break;
5380
        default:
5381
            goto die;
5382
        }
5383
        break;
5384
    case 25:
5385
        switch (sel) {
5386
        case 0:
5387
            gen_helper_mtc0_performance0(arg);
5388
            rn = "Performance0";
5389
            break;
5390
        case 1:
5391
//            gen_helper_mtc0_performance1(arg);
5392
            rn = "Performance1";
5393
//            break;
5394
        case 2:
5395
//            gen_helper_mtc0_performance2(arg);
5396
            rn = "Performance2";
5397
//            break;
5398
        case 3:
5399
//            gen_helper_mtc0_performance3(arg);
5400
            rn = "Performance3";
5401
//            break;
5402
        case 4:
5403
//            gen_helper_mtc0_performance4(arg);
5404
            rn = "Performance4";
5405
//            break;
5406
        case 5:
5407
//            gen_helper_mtc0_performance5(arg);
5408
            rn = "Performance5";
5409
//            break;
5410
        case 6:
5411
//            gen_helper_mtc0_performance6(arg);
5412
            rn = "Performance6";
5413
//            break;
5414
        case 7:
5415
//            gen_helper_mtc0_performance7(arg);
5416
            rn = "Performance7";
5417
//            break;
5418
        default:
5419
            goto die;
5420
        }
5421
        break;
5422
    case 26:
5423
        /* ignored */
5424
        rn = "ECC";
5425
        break;
5426
    case 27:
5427
        switch (sel) {
5428
        case 0 ... 3:
5429
            /* ignored */
5430
            rn = "CacheErr";
5431
            break;
5432
        default:
5433
            goto die;
5434
        }
5435
        break;
5436
    case 28:
5437
        switch (sel) {
5438
        case 0:
5439
        case 2:
5440
        case 4:
5441
        case 6:
5442
            gen_helper_mtc0_taglo(arg);
5443
            rn = "TagLo";
5444
            break;
5445
        case 1:
5446
        case 3:
5447
        case 5:
5448
        case 7:
5449
            gen_helper_mtc0_datalo(arg);
5450
            rn = "DataLo";
5451
            break;
5452
        default:
5453
            goto die;
5454
        }
5455
        break;
5456
    case 29:
5457
        switch (sel) {
5458
        case 0:
5459
        case 2:
5460
        case 4:
5461
        case 6:
5462
            gen_helper_mtc0_taghi(arg);
5463
            rn = "TagHi";
5464
            break;
5465
        case 1:
5466
        case 3:
5467
        case 5:
5468
        case 7:
5469
            gen_helper_mtc0_datahi(arg);
5470
            rn = "DataHi";
5471
            break;
5472
        default:
5473
            rn = "invalid sel";
5474
            goto die;
5475
        }
5476
        break;
5477
    case 30:
5478
        switch (sel) {
5479
        case 0:
5480
            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5481
            rn = "ErrorEPC";
5482
            break;
5483
        default:
5484
            goto die;
5485
        }
5486
        break;
5487
    case 31:
5488
        switch (sel) {
5489
        case 0:
5490
            /* EJTAG support */
5491
            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5492
            rn = "DESAVE";
5493
            break;
5494
        default:
5495
            goto die;
5496
        }
5497
        /* Stop translation as we may have switched the execution mode */
5498
        ctx->bstate = BS_STOP;
5499
        break;
5500
    default:
5501
        goto die;
5502
    }
5503
    (void)rn; /* avoid a compiler warning */
5504
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5505
    /* For simplicity assume that all writes can cause interrupts.  */
5506
    if (use_icount) {
5507
        gen_io_end();
5508
        ctx->bstate = BS_STOP;
5509
    }
5510
    return;
5511

    
5512
die:
5513
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5514
    generate_exception(ctx, EXCP_RI);
5515
}
5516
#endif /* TARGET_MIPS64 */
5517

    
5518
static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
5519
                     int u, int sel, int h)
5520
{
5521
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5522
    TCGv t0 = tcg_temp_local_new();
5523

    
5524
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5525
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5526
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5527
        tcg_gen_movi_tl(t0, -1);
5528
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5529
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5530
        tcg_gen_movi_tl(t0, -1);
5531
    else if (u == 0) {
5532
        switch (rt) {
5533
        case 1:
5534
            switch (sel) {
5535
            case 1:
5536
                gen_helper_mftc0_vpecontrol(t0);
5537
                break;
5538
            case 2:
5539
                gen_helper_mftc0_vpeconf0(t0);
5540
                break;
5541
            default:
5542
                goto die;
5543
                break;
5544
            }
5545
            break;
5546
        case 2:
5547
            switch (sel) {
5548
            case 1:
5549
                gen_helper_mftc0_tcstatus(t0);
5550
                break;
5551
            case 2:
5552
                gen_helper_mftc0_tcbind(t0);
5553
                break;
5554
            case 3:
5555
                gen_helper_mftc0_tcrestart(t0);
5556
                break;
5557
            case 4:
5558
                gen_helper_mftc0_tchalt(t0);
5559
                break;
5560
            case 5:
5561
                gen_helper_mftc0_tccontext(t0);
5562
                break;
5563
            case 6:
5564
                gen_helper_mftc0_tcschedule(t0);
5565
                break;
5566
            case 7:
5567
                gen_helper_mftc0_tcschefback(t0);
5568
                break;
5569
            default:
5570
                gen_mfc0(env, ctx, t0, rt, sel);
5571
                break;
5572
            }
5573
            break;
5574
        case 10:
5575
            switch (sel) {
5576
            case 0:
5577
                gen_helper_mftc0_entryhi(t0);
5578
                break;
5579
            default:
5580
                gen_mfc0(env, ctx, t0, rt, sel);
5581
                break;
5582
            }
5583
        case 12:
5584
            switch (sel) {
5585
            case 0:
5586
                gen_helper_mftc0_status(t0);
5587
                break;
5588
            default:
5589
                gen_mfc0(env, ctx, t0, rt, sel);
5590
                break;
5591
            }
5592
        case 13:
5593
            switch (sel) {
5594
            case 0:
5595
                gen_helper_mftc0_cause(t0);
5596
                break;
5597
            default:
5598
                goto die;
5599
                break;
5600
            }
5601
            break;
5602
        case 14:
5603
            switch (sel) {
5604
            case 0:
5605
                gen_helper_mftc0_epc(t0);
5606
                break;
5607
            default:
5608
                goto die;
5609
                break;
5610
            }
5611
            break;
5612
        case 15:
5613
            switch (sel) {
5614
            case 1:
5615
                gen_helper_mftc0_ebase(t0);
5616
                break;
5617
            default:
5618
                goto die;
5619
                break;
5620
            }
5621
            break;
5622
        case 16:
5623
            switch (sel) {
5624
            case 0 ... 7:
5625
                gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
5626
                break;
5627
            default:
5628
                goto die;
5629
                break;
5630
            }
5631
            break;
5632
        case 23:
5633
            switch (sel) {
5634
            case 0:
5635
                gen_helper_mftc0_debug(t0);
5636
                break;
5637
            default:
5638
                gen_mfc0(env, ctx, t0, rt, sel);
5639
                break;
5640
            }
5641
            break;
5642
        default:
5643
            gen_mfc0(env, ctx, t0, rt, sel);
5644
        }
5645
    } else switch (sel) {
5646
    /* GPR registers. */
5647
    case 0:
5648
        gen_helper_1i(mftgpr, t0, rt);
5649
        break;
5650
    /* Auxiliary CPU registers */
5651
    case 1:
5652
        switch (rt) {
5653
        case 0:
5654
            gen_helper_1i(mftlo, t0, 0);
5655
            break;
5656
        case 1:
5657
            gen_helper_1i(mfthi, t0, 0);
5658
            break;
5659
        case 2:
5660
            gen_helper_1i(mftacx, t0, 0);
5661
            break;
5662
        case 4:
5663
            gen_helper_1i(mftlo, t0, 1);
5664
            break;
5665
        case 5:
5666
            gen_helper_1i(mfthi, t0, 1);
5667
            break;
5668
        case 6:
5669
            gen_helper_1i(mftacx, t0, 1);
5670
            break;
5671
        case 8:
5672
            gen_helper_1i(mftlo, t0, 2);
5673
            break;
5674
        case 9:
5675
            gen_helper_1i(mfthi, t0, 2);
5676
            break;
5677
        case 10:
5678
            gen_helper_1i(mftacx, t0, 2);
5679
            break;
5680
        case 12:
5681
            gen_helper_1i(mftlo, t0, 3);
5682
            break;
5683
        case 13:
5684
            gen_helper_1i(mfthi, t0, 3);
5685
            break;
5686
        case 14:
5687
            gen_helper_1i(mftacx, t0, 3);
5688
            break;
5689
        case 16:
5690
            gen_helper_mftdsp(t0);
5691
            break;
5692
        default:
5693
            goto die;
5694
        }
5695
        break;
5696
    /* Floating point (COP1). */
5697
    case 2:
5698
        /* XXX: For now we support only a single FPU context. */
5699
        if (h == 0) {
5700
            TCGv_i32 fp0 = tcg_temp_new_i32();
5701

    
5702
            gen_load_fpr32(fp0, rt);
5703
            tcg_gen_ext_i32_tl(t0, fp0);
5704
            tcg_temp_free_i32(fp0);
5705
        } else {
5706
            TCGv_i32 fp0 = tcg_temp_new_i32();
5707

    
5708
            gen_load_fpr32h(fp0, rt);
5709
            tcg_gen_ext_i32_tl(t0, fp0);
5710
            tcg_temp_free_i32(fp0);
5711
        }
5712
        break;
5713
    case 3:
5714
        /* XXX: For now we support only a single FPU context. */
5715
        gen_helper_1i(cfc1, t0, rt);
5716
        break;
5717
    /* COP2: Not implemented. */
5718
    case 4:
5719
    case 5:
5720
        /* fall through */
5721
    default:
5722
        goto die;
5723
    }
5724
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5725
    gen_store_gpr(t0, rd);
5726
    tcg_temp_free(t0);
5727
    return;
5728

    
5729
die:
5730
    tcg_temp_free(t0);
5731
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5732
    generate_exception(ctx, EXCP_RI);
5733
}
5734

    
5735
static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
5736
                     int u, int sel, int h)
5737
{
5738
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5739
    TCGv t0 = tcg_temp_local_new();
5740

    
5741
    gen_load_gpr(t0, rt);
5742
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5743
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5744
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5745
        /* NOP */ ;
5746
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5747
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5748
        /* NOP */ ;
5749
    else if (u == 0) {
5750
        switch (rd) {
5751
        case 1:
5752
            switch (sel) {
5753
            case 1:
5754
                gen_helper_mttc0_vpecontrol(t0);
5755
                break;
5756
            case 2:
5757
                gen_helper_mttc0_vpeconf0(t0);
5758
                break;
5759
            default:
5760
                goto die;
5761
                break;
5762
            }
5763
            break;
5764
        case 2:
5765
            switch (sel) {
5766
            case 1:
5767
                gen_helper_mttc0_tcstatus(t0);
5768
                break;
5769
            case 2:
5770
                gen_helper_mttc0_tcbind(t0);
5771
                break;
5772
            case 3:
5773
                gen_helper_mttc0_tcrestart(t0);
5774
                break;
5775
            case 4:
5776
                gen_helper_mttc0_tchalt(t0);
5777
                break;
5778
            case 5:
5779
                gen_helper_mttc0_tccontext(t0);
5780
                break;
5781
            case 6:
5782
                gen_helper_mttc0_tcschedule(t0);
5783
                break;
5784
            case 7:
5785
                gen_helper_mttc0_tcschefback(t0);
5786
                break;
5787
            default:
5788
                gen_mtc0(env, ctx, t0, rd, sel);
5789
                break;
5790
            }
5791
            break;
5792
        case 10:
5793
            switch (sel) {
5794
            case 0:
5795
                gen_helper_mttc0_entryhi(t0);
5796
                break;
5797
            default:
5798
                gen_mtc0(env, ctx, t0, rd, sel);
5799
                break;
5800
            }
5801
        case 12:
5802
            switch (sel) {
5803
            case 0:
5804
                gen_helper_mttc0_status(t0);
5805
                break;
5806
            default:
5807
                gen_mtc0(env, ctx, t0, rd, sel);
5808
                break;
5809
            }
5810
        case 13:
5811
            switch (sel) {
5812
            case 0:
5813
                gen_helper_mttc0_cause(t0);
5814
                break;
5815
            default:
5816
                goto die;
5817
                break;
5818
            }
5819
            break;
5820
        case 15:
5821
            switch (sel) {
5822
            case 1:
5823
                gen_helper_mttc0_ebase(t0);
5824
                break;
5825
            default:
5826
                goto die;
5827
                break;
5828
            }
5829
            break;
5830
        case 23:
5831
            switch (sel) {
5832
            case 0:
5833
                gen_helper_mttc0_debug(t0);
5834
                break;
5835
            default:
5836
                gen_mtc0(env, ctx, t0, rd, sel);
5837
                break;
5838
            }
5839
            break;
5840
        default:
5841
            gen_mtc0(env, ctx, t0, rd, sel);
5842
        }
5843
    } else switch (sel) {
5844
    /* GPR registers. */
5845
    case 0:
5846
        gen_helper_1i(mttgpr, t0, rd);
5847
        break;
5848
    /* Auxiliary CPU registers */
5849
    case 1:
5850
        switch (rd) {
5851
        case 0:
5852
            gen_helper_1i(mttlo, t0, 0);
5853
            break;
5854
        case 1:
5855
            gen_helper_1i(mtthi, t0, 0);
5856
            break;
5857
        case 2:
5858
            gen_helper_1i(mttacx, t0, 0);
5859
            break;
5860
        case 4:
5861
            gen_helper_1i(mttlo, t0, 1);
5862
            break;
5863
        case 5:
5864
            gen_helper_1i(mtthi, t0, 1);
5865
            break;
5866
        case 6:
5867
            gen_helper_1i(mttacx, t0, 1);
5868
            break;
5869
        case 8:
5870
            gen_helper_1i(mttlo, t0, 2);
5871
            break;
5872
        case 9:
5873
            gen_helper_1i(mtthi, t0, 2);
5874
            break;
5875
        case 10:
5876
            gen_helper_1i(mttacx, t0, 2);
5877
            break;
5878
        case 12:
5879
            gen_helper_1i(mttlo, t0, 3);
5880
            break;
5881
        case 13:
5882
            gen_helper_1i(mtthi, t0, 3);
5883
            break;
5884
        case 14:
5885
            gen_helper_1i(mttacx, t0, 3);
5886
            break;
5887
        case 16:
5888
            gen_helper_mttdsp(t0);
5889
            break;
5890
        default:
5891
            goto die;
5892
        }
5893
        break;
5894
    /* Floating point (COP1). */
5895
    case 2:
5896
        /* XXX: For now we support only a single FPU context. */
5897
        if (h == 0) {
5898
            TCGv_i32 fp0 = tcg_temp_new_i32();
5899

    
5900
            tcg_gen_trunc_tl_i32(fp0, t0);
5901
            gen_store_fpr32(fp0, rd);
5902
            tcg_temp_free_i32(fp0);
5903
        } else {
5904
            TCGv_i32 fp0 = tcg_temp_new_i32();
5905

    
5906
            tcg_gen_trunc_tl_i32(fp0, t0);
5907
            gen_store_fpr32h(fp0, rd);
5908
            tcg_temp_free_i32(fp0);
5909
        }
5910
        break;
5911
    case 3:
5912
        /* XXX: For now we support only a single FPU context. */
5913
        gen_helper_1i(ctc1, t0, rd);
5914
        break;
5915
    /* COP2: Not implemented. */
5916
    case 4:
5917
    case 5:
5918
        /* fall through */
5919
    default:
5920
        goto die;
5921
    }
5922
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5923
    tcg_temp_free(t0);
5924
    return;
5925

    
5926
die:
5927
    tcg_temp_free(t0);
5928
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5929
    generate_exception(ctx, EXCP_RI);
5930
}
5931

    
5932
static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5933
{
5934
    const char *opn = "ldst";
5935

    
5936
    check_cp0_enabled(ctx);
5937
    switch (opc) {
5938
    case OPC_MFC0:
5939
        if (rt == 0) {
5940
            /* Treat as NOP. */
5941
            return;
5942
        }
5943
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5944
        opn = "mfc0";
5945
        break;
5946
    case OPC_MTC0:
5947
        {
5948
            TCGv t0 = tcg_temp_new();
5949

    
5950
            gen_load_gpr(t0, rt);
5951
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5952
            tcg_temp_free(t0);
5953
        }
5954
        opn = "mtc0";
5955
        break;
5956
#if defined(TARGET_MIPS64)
5957
    case OPC_DMFC0:
5958
        check_insn(env, ctx, ISA_MIPS3);
5959
        if (rt == 0) {
5960
            /* Treat as NOP. */
5961
            return;
5962
        }
5963
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5964
        opn = "dmfc0";
5965
        break;
5966
    case OPC_DMTC0:
5967
        check_insn(env, ctx, ISA_MIPS3);
5968
        {
5969
            TCGv t0 = tcg_temp_new();
5970

    
5971
            gen_load_gpr(t0, rt);
5972
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5973
            tcg_temp_free(t0);
5974
        }
5975
        opn = "dmtc0";
5976
        break;
5977
#endif
5978
    case OPC_MFTR:
5979
        check_insn(env, ctx, ASE_MT);
5980
        if (rd == 0) {
5981
            /* Treat as NOP. */
5982
            return;
5983
        }
5984
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5985
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5986
        opn = "mftr";
5987
        break;
5988
    case OPC_MTTR:
5989
        check_insn(env, ctx, ASE_MT);
5990
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5991
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5992
        opn = "mttr";
5993
        break;
5994
    case OPC_TLBWI:
5995
        opn = "tlbwi";
5996
        if (!env->tlb->helper_tlbwi)
5997
            goto die;
5998
        gen_helper_tlbwi();
5999
        break;
6000
    case OPC_TLBWR:
6001
        opn = "tlbwr";
6002
        if (!env->tlb->helper_tlbwr)
6003
            goto die;
6004
        gen_helper_tlbwr();
6005
        break;
6006
    case OPC_TLBP:
6007
        opn = "tlbp";
6008
        if (!env->tlb->helper_tlbp)
6009
            goto die;
6010
        gen_helper_tlbp();
6011
        break;
6012
    case OPC_TLBR:
6013
        opn = "tlbr";
6014
        if (!env->tlb->helper_tlbr)
6015
            goto die;
6016
        gen_helper_tlbr();
6017
        break;
6018
    case OPC_ERET:
6019
        opn = "eret";
6020
        check_insn(env, ctx, ISA_MIPS2);
6021
        gen_helper_eret();
6022
        ctx->bstate = BS_EXCP;
6023
        break;
6024
    case OPC_DERET:
6025
        opn = "deret";
6026
        check_insn(env, ctx, ISA_MIPS32);
6027
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6028
            MIPS_INVAL(opn);
6029
            generate_exception(ctx, EXCP_RI);
6030
        } else {
6031
            gen_helper_deret();
6032
            ctx->bstate = BS_EXCP;
6033
        }
6034
        break;
6035
    case OPC_WAIT:
6036
        opn = "wait";
6037
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6038
        /* If we get an exception, we want to restart at next instruction */
6039
        ctx->pc += 4;
6040
        save_cpu_state(ctx, 1);
6041
        ctx->pc -= 4;
6042
        gen_helper_wait();
6043
        ctx->bstate = BS_EXCP;
6044
        break;
6045
    default:
6046
 die:
6047
        MIPS_INVAL(opn);
6048
        generate_exception(ctx, EXCP_RI);
6049
        return;
6050
    }
6051
    (void)opn; /* avoid a compiler warning */
6052
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6053
}
6054
#endif /* !CONFIG_USER_ONLY */
6055

    
6056
/* CP1 Branches (before delay slot) */
6057
static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6058
                                 int32_t cc, int32_t offset)
6059
{
6060
    target_ulong btarget;
6061
    const char *opn = "cp1 cond branch";
6062
    TCGv_i32 t0 = tcg_temp_new_i32();
6063

    
6064
    if (cc != 0)
6065
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6066

    
6067
    btarget = ctx->pc + 4 + offset;
6068

    
6069
    switch (op) {
6070
    case OPC_BC1F:
6071
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6072
        tcg_gen_not_i32(t0, t0);
6073
        tcg_gen_andi_i32(t0, t0, 1);
6074
        tcg_gen_extu_i32_tl(bcond, t0);
6075
        opn = "bc1f";
6076
        goto not_likely;
6077
    case OPC_BC1FL:
6078
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6079
        tcg_gen_not_i32(t0, t0);
6080
        tcg_gen_andi_i32(t0, t0, 1);
6081
        tcg_gen_extu_i32_tl(bcond, t0);
6082
        opn = "bc1fl";
6083
        goto likely;
6084
    case OPC_BC1T:
6085
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6086
        tcg_gen_andi_i32(t0, t0, 1);
6087
        tcg_gen_extu_i32_tl(bcond, t0);
6088
        opn = "bc1t";
6089
        goto not_likely;
6090
    case OPC_BC1TL:
6091
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6092
        tcg_gen_andi_i32(t0, t0, 1);
6093
        tcg_gen_extu_i32_tl(bcond, t0);
6094
        opn = "bc1tl";
6095
    likely:
6096
        ctx->hflags |= MIPS_HFLAG_BL;
6097
        break;
6098
    case OPC_BC1FANY2:
6099
        {
6100
            TCGv_i32 t1 = tcg_temp_new_i32();
6101
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6102
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6103
            tcg_gen_nand_i32(t0, t0, t1);
6104
            tcg_temp_free_i32(t1);
6105
            tcg_gen_andi_i32(t0, t0, 1);
6106
            tcg_gen_extu_i32_tl(bcond, t0);
6107
        }
6108
        opn = "bc1any2f";
6109
        goto not_likely;
6110
    case OPC_BC1TANY2:
6111
        {
6112
            TCGv_i32 t1 = tcg_temp_new_i32();
6113
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6114
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6115
            tcg_gen_or_i32(t0, t0, t1);
6116
            tcg_temp_free_i32(t1);
6117
            tcg_gen_andi_i32(t0, t0, 1);
6118
            tcg_gen_extu_i32_tl(bcond, t0);
6119
        }
6120
        opn = "bc1any2t";
6121
        goto not_likely;
6122
    case OPC_BC1FANY4:
6123
        {
6124
            TCGv_i32 t1 = tcg_temp_new_i32();
6125
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6126
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6127
            tcg_gen_and_i32(t0, t0, t1);
6128
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6129
            tcg_gen_and_i32(t0, t0, t1);
6130
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6131
            tcg_gen_nand_i32(t0, t0, t1);
6132
            tcg_temp_free_i32(t1);
6133
            tcg_gen_andi_i32(t0, t0, 1);
6134
            tcg_gen_extu_i32_tl(bcond, t0);
6135
        }
6136
        opn = "bc1any4f";
6137
        goto not_likely;
6138
    case OPC_BC1TANY4:
6139
        {
6140
            TCGv_i32 t1 = tcg_temp_new_i32();
6141
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6142
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6143
            tcg_gen_or_i32(t0, t0, t1);
6144
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6145
            tcg_gen_or_i32(t0, t0, t1);
6146
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6147
            tcg_gen_or_i32(t0, t0, t1);
6148
            tcg_temp_free_i32(t1);
6149
            tcg_gen_andi_i32(t0, t0, 1);
6150
            tcg_gen_extu_i32_tl(bcond, t0);
6151
        }
6152
        opn = "bc1any4t";
6153
    not_likely:
6154
        ctx->hflags |= MIPS_HFLAG_BC;
6155
        break;
6156
    default:
6157
        MIPS_INVAL(opn);
6158
        generate_exception (ctx, EXCP_RI);
6159
        goto out;
6160
    }
6161
    (void)opn; /* avoid a compiler warning */
6162
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6163
               ctx->hflags, btarget);
6164
    ctx->btarget = btarget;
6165

    
6166
 out:
6167
    tcg_temp_free_i32(t0);
6168
}
6169

    
6170
/* Coprocessor 1 (FPU) */
6171

    
6172
#define FOP(func, fmt) (((fmt) << 21) | (func))
6173

    
6174
enum fopcode {
6175
    OPC_ADD_S = FOP(0, FMT_S),
6176
    OPC_SUB_S = FOP(1, FMT_S),
6177
    OPC_MUL_S = FOP(2, FMT_S),
6178
    OPC_DIV_S = FOP(3, FMT_S),
6179
    OPC_SQRT_S = FOP(4, FMT_S),
6180
    OPC_ABS_S = FOP(5, FMT_S),
6181
    OPC_MOV_S = FOP(6, FMT_S),
6182
    OPC_NEG_S = FOP(7, FMT_S),
6183
    OPC_ROUND_L_S = FOP(8, FMT_S),
6184
    OPC_TRUNC_L_S = FOP(9, FMT_S),
6185
    OPC_CEIL_L_S = FOP(10, FMT_S),
6186
    OPC_FLOOR_L_S = FOP(11, FMT_S),
6187
    OPC_ROUND_W_S = FOP(12, FMT_S),
6188
    OPC_TRUNC_W_S = FOP(13, FMT_S),
6189
    OPC_CEIL_W_S = FOP(14, FMT_S),
6190
    OPC_FLOOR_W_S = FOP(15, FMT_S),
6191
    OPC_MOVCF_S = FOP(17, FMT_S),
6192
    OPC_MOVZ_S = FOP(18, FMT_S),
6193
    OPC_MOVN_S = FOP(19, FMT_S),
6194
    OPC_RECIP_S = FOP(21, FMT_S),
6195
    OPC_RSQRT_S = FOP(22, FMT_S),
6196
    OPC_RECIP2_S = FOP(28, FMT_S),
6197
    OPC_RECIP1_S = FOP(29, FMT_S),
6198
    OPC_RSQRT1_S = FOP(30, FMT_S),
6199
    OPC_RSQRT2_S = FOP(31, FMT_S),
6200
    OPC_CVT_D_S = FOP(33, FMT_S),
6201
    OPC_CVT_W_S = FOP(36, FMT_S),
6202
    OPC_CVT_L_S = FOP(37, FMT_S),
6203
    OPC_CVT_PS_S = FOP(38, FMT_S),
6204
    OPC_CMP_F_S = FOP (48, FMT_S),
6205
    OPC_CMP_UN_S = FOP (49, FMT_S),
6206
    OPC_CMP_EQ_S = FOP (50, FMT_S),
6207
    OPC_CMP_UEQ_S = FOP (51, FMT_S),
6208
    OPC_CMP_OLT_S = FOP (52, FMT_S),
6209
    OPC_CMP_ULT_S = FOP (53, FMT_S),
6210
    OPC_CMP_OLE_S = FOP (54, FMT_S),
6211
    OPC_CMP_ULE_S = FOP (55, FMT_S),
6212
    OPC_CMP_SF_S = FOP (56, FMT_S),
6213
    OPC_CMP_NGLE_S = FOP (57, FMT_S),
6214
    OPC_CMP_SEQ_S = FOP (58, FMT_S),
6215
    OPC_CMP_NGL_S = FOP (59, FMT_S),
6216
    OPC_CMP_LT_S = FOP (60, FMT_S),
6217
    OPC_CMP_NGE_S = FOP (61, FMT_S),
6218
    OPC_CMP_LE_S = FOP (62, FMT_S),
6219
    OPC_CMP_NGT_S = FOP (63, FMT_S),
6220

    
6221
    OPC_ADD_D = FOP(0, FMT_D),
6222
    OPC_SUB_D = FOP(1, FMT_D),
6223
    OPC_MUL_D = FOP(2, FMT_D),
6224
    OPC_DIV_D = FOP(3, FMT_D),
6225
    OPC_SQRT_D = FOP(4, FMT_D),
6226
    OPC_ABS_D = FOP(5, FMT_D),
6227
    OPC_MOV_D = FOP(6, FMT_D),
6228
    OPC_NEG_D = FOP(7, FMT_D),
6229
    OPC_ROUND_L_D = FOP(8, FMT_D),
6230
    OPC_TRUNC_L_D = FOP(9, FMT_D),
6231
    OPC_CEIL_L_D = FOP(10, FMT_D),
6232
    OPC_FLOOR_L_D = FOP(11, FMT_D),
6233
    OPC_ROUND_W_D = FOP(12, FMT_D),
6234
    OPC_TRUNC_W_D = FOP(13, FMT_D),
6235
    OPC_CEIL_W_D = FOP(14, FMT_D),
6236
    OPC_FLOOR_W_D = FOP(15, FMT_D),
6237
    OPC_MOVCF_D = FOP(17, FMT_D),
6238
    OPC_MOVZ_D = FOP(18, FMT_D),
6239
    OPC_MOVN_D = FOP(19, FMT_D),
6240
    OPC_RECIP_D = FOP(21, FMT_D),
6241
    OPC_RSQRT_D = FOP(22, FMT_D),
6242
    OPC_RECIP2_D = FOP(28, FMT_D),
6243
    OPC_RECIP1_D = FOP(29, FMT_D),
6244
    OPC_RSQRT1_D = FOP(30, FMT_D),
6245
    OPC_RSQRT2_D = FOP(31, FMT_D),
6246
    OPC_CVT_S_D = FOP(32, FMT_D),
6247
    OPC_CVT_W_D = FOP(36, FMT_D),
6248
    OPC_CVT_L_D = FOP(37, FMT_D),
6249
    OPC_CMP_F_D = FOP (48, FMT_D),
6250
    OPC_CMP_UN_D = FOP (49, FMT_D),
6251
    OPC_CMP_EQ_D = FOP (50, FMT_D),
6252
    OPC_CMP_UEQ_D = FOP (51, FMT_D),
6253
    OPC_CMP_OLT_D = FOP (52, FMT_D),
6254
    OPC_CMP_ULT_D = FOP (53, FMT_D),
6255
    OPC_CMP_OLE_D = FOP (54, FMT_D),
6256
    OPC_CMP_ULE_D = FOP (55, FMT_D),
6257
    OPC_CMP_SF_D = FOP (56, FMT_D),
6258
    OPC_CMP_NGLE_D = FOP (57, FMT_D),
6259
    OPC_CMP_SEQ_D = FOP (58, FMT_D),
6260
    OPC_CMP_NGL_D = FOP (59, FMT_D),
6261
    OPC_CMP_LT_D = FOP (60, FMT_D),
6262
    OPC_CMP_NGE_D = FOP (61, FMT_D),
6263
    OPC_CMP_LE_D = FOP (62, FMT_D),
6264
    OPC_CMP_NGT_D = FOP (63, FMT_D),
6265

    
6266
    OPC_CVT_S_W = FOP(32, FMT_W),
6267
    OPC_CVT_D_W = FOP(33, FMT_W),
6268
    OPC_CVT_S_L = FOP(32, FMT_L),
6269
    OPC_CVT_D_L = FOP(33, FMT_L),
6270
    OPC_CVT_PS_PW = FOP(38, FMT_W),
6271

    
6272
    OPC_ADD_PS = FOP(0, FMT_PS),
6273
    OPC_SUB_PS = FOP(1, FMT_PS),
6274
    OPC_MUL_PS = FOP(2, FMT_PS),
6275
    OPC_DIV_PS = FOP(3, FMT_PS),
6276
    OPC_ABS_PS = FOP(5, FMT_PS),
6277
    OPC_MOV_PS = FOP(6, FMT_PS),
6278
    OPC_NEG_PS = FOP(7, FMT_PS),
6279
    OPC_MOVCF_PS = FOP(17, FMT_PS),
6280
    OPC_MOVZ_PS = FOP(18, FMT_PS),
6281
    OPC_MOVN_PS = FOP(19, FMT_PS),
6282
    OPC_ADDR_PS = FOP(24, FMT_PS),
6283
    OPC_MULR_PS = FOP(26, FMT_PS),
6284
    OPC_RECIP2_PS = FOP(28, FMT_PS),
6285
    OPC_RECIP1_PS = FOP(29, FMT_PS),
6286
    OPC_RSQRT1_PS = FOP(30, FMT_PS),
6287
    OPC_RSQRT2_PS = FOP(31, FMT_PS),
6288

    
6289
    OPC_CVT_S_PU = FOP(32, FMT_PS),
6290
    OPC_CVT_PW_PS = FOP(36, FMT_PS),
6291
    OPC_CVT_S_PL = FOP(40, FMT_PS),
6292
    OPC_PLL_PS = FOP(44, FMT_PS),
6293
    OPC_PLU_PS = FOP(45, FMT_PS),
6294
    OPC_PUL_PS = FOP(46, FMT_PS),
6295
    OPC_PUU_PS = FOP(47, FMT_PS),
6296
    OPC_CMP_F_PS = FOP (48, FMT_PS),
6297
    OPC_CMP_UN_PS = FOP (49, FMT_PS),
6298
    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6299
    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6300
    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6301
    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6302
    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6303
    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6304
    OPC_CMP_SF_PS = FOP (56, FMT_PS),
6305
    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6306
    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6307
    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6308
    OPC_CMP_LT_PS = FOP (60, FMT_PS),
6309
    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6310
    OPC_CMP_LE_PS = FOP (62, FMT_PS),
6311
    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6312
};
6313

    
6314
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6315
{
6316
    const char *opn = "cp1 move";
6317
    TCGv t0 = tcg_temp_new();
6318

    
6319
    switch (opc) {
6320
    case OPC_MFC1:
6321
        {
6322
            TCGv_i32 fp0 = tcg_temp_new_i32();
6323

    
6324
            gen_load_fpr32(fp0, fs);
6325
            tcg_gen_ext_i32_tl(t0, fp0);
6326
            tcg_temp_free_i32(fp0);
6327
        }
6328
        gen_store_gpr(t0, rt);
6329
        opn = "mfc1";
6330
        break;
6331
    case OPC_MTC1:
6332
        gen_load_gpr(t0, rt);
6333
        {
6334
            TCGv_i32 fp0 = tcg_temp_new_i32();
6335

    
6336
            tcg_gen_trunc_tl_i32(fp0, t0);
6337
            gen_store_fpr32(fp0, fs);
6338
            tcg_temp_free_i32(fp0);
6339
        }
6340
        opn = "mtc1";
6341
        break;
6342
    case OPC_CFC1:
6343
        gen_helper_1i(cfc1, t0, fs);
6344
        gen_store_gpr(t0, rt);
6345
        opn = "cfc1";
6346
        break;
6347
    case OPC_CTC1:
6348
        gen_load_gpr(t0, rt);
6349
        gen_helper_1i(ctc1, t0, fs);
6350
        opn = "ctc1";
6351
        break;
6352
#if defined(TARGET_MIPS64)
6353
    case OPC_DMFC1:
6354
        gen_load_fpr64(ctx, t0, fs);
6355
        gen_store_gpr(t0, rt);
6356
        opn = "dmfc1";
6357
        break;
6358
    case OPC_DMTC1:
6359
        gen_load_gpr(t0, rt);
6360
        gen_store_fpr64(ctx, t0, fs);
6361
        opn = "dmtc1";
6362
        break;
6363
#endif
6364
    case OPC_MFHC1:
6365
        {
6366
            TCGv_i32 fp0 = tcg_temp_new_i32();
6367

    
6368
            gen_load_fpr32h(fp0, fs);
6369
            tcg_gen_ext_i32_tl(t0, fp0);
6370
            tcg_temp_free_i32(fp0);
6371
        }
6372
        gen_store_gpr(t0, rt);
6373
        opn = "mfhc1";
6374
        break;
6375
    case OPC_MTHC1:
6376
        gen_load_gpr(t0, rt);
6377
        {
6378
            TCGv_i32 fp0 = tcg_temp_new_i32();
6379

    
6380
            tcg_gen_trunc_tl_i32(fp0, t0);
6381
            gen_store_fpr32h(fp0, fs);
6382
            tcg_temp_free_i32(fp0);
6383
        }
6384
        opn = "mthc1";
6385
        break;
6386
    default:
6387
        MIPS_INVAL(opn);
6388
        generate_exception (ctx, EXCP_RI);
6389
        goto out;
6390
    }
6391
    (void)opn; /* avoid a compiler warning */
6392
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6393

    
6394
 out:
6395
    tcg_temp_free(t0);
6396
}
6397

    
6398
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6399
{
6400
    int l1;
6401
    TCGCond cond;
6402
    TCGv_i32 t0;
6403

    
6404
    if (rd == 0) {
6405
        /* Treat as NOP. */
6406
        return;
6407
    }
6408

    
6409
    if (tf)
6410
        cond = TCG_COND_EQ;
6411
    else
6412
        cond = TCG_COND_NE;
6413

    
6414
    l1 = gen_new_label();
6415
    t0 = tcg_temp_new_i32();
6416
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6417
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6418
    tcg_temp_free_i32(t0);
6419
    if (rs == 0) {
6420
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
6421
    } else {
6422
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6423
    }
6424
    gen_set_label(l1);
6425
}
6426

    
6427
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6428
{
6429
    int cond;
6430
    TCGv_i32 t0 = tcg_temp_new_i32();
6431
    int l1 = gen_new_label();
6432

    
6433
    if (tf)
6434
        cond = TCG_COND_EQ;
6435
    else
6436
        cond = TCG_COND_NE;
6437

    
6438
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6439
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6440
    gen_load_fpr32(t0, fs);
6441
    gen_store_fpr32(t0, fd);
6442
    gen_set_label(l1);
6443
    tcg_temp_free_i32(t0);
6444
}
6445

    
6446
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6447
{
6448
    int cond;
6449
    TCGv_i32 t0 = tcg_temp_new_i32();
6450
    TCGv_i64 fp0;
6451
    int l1 = gen_new_label();
6452

    
6453
    if (tf)
6454
        cond = TCG_COND_EQ;
6455
    else
6456
        cond = TCG_COND_NE;
6457

    
6458
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6459
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6460
    tcg_temp_free_i32(t0);
6461
    fp0 = tcg_temp_new_i64();
6462
    gen_load_fpr64(ctx, fp0, fs);
6463
    gen_store_fpr64(ctx, fp0, fd);
6464
    tcg_temp_free_i64(fp0);
6465
    gen_set_label(l1);
6466
}
6467

    
6468
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6469
{
6470
    int cond;
6471
    TCGv_i32 t0 = tcg_temp_new_i32();
6472
    int l1 = gen_new_label();
6473
    int l2 = gen_new_label();
6474

    
6475
    if (tf)
6476
        cond = TCG_COND_EQ;
6477
    else
6478
        cond = TCG_COND_NE;
6479

    
6480
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6481
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6482
    gen_load_fpr32(t0, fs);
6483
    gen_store_fpr32(t0, fd);
6484
    gen_set_label(l1);
6485

    
6486
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6487
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
6488
    gen_load_fpr32h(t0, fs);
6489
    gen_store_fpr32h(t0, fd);
6490
    tcg_temp_free_i32(t0);
6491
    gen_set_label(l2);
6492
}
6493

    
6494

    
6495
static void gen_farith (DisasContext *ctx, enum fopcode op1,
6496
                        int ft, int fs, int fd, int cc)
6497
{
6498
    const char *opn = "farith";
6499
    const char *condnames[] = {
6500
            "c.f",
6501
            "c.un",
6502
            "c.eq",
6503
            "c.ueq",
6504
            "c.olt",
6505
            "c.ult",
6506
            "c.ole",
6507
            "c.ule",
6508
            "c.sf",
6509
            "c.ngle",
6510
            "c.seq",
6511
            "c.ngl",
6512
            "c.lt",
6513
            "c.nge",
6514
            "c.le",
6515
            "c.ngt",
6516
    };
6517
    const char *condnames_abs[] = {
6518
            "cabs.f",
6519
            "cabs.un",
6520
            "cabs.eq",
6521
            "cabs.ueq",
6522
            "cabs.olt",
6523
            "cabs.ult",
6524
            "cabs.ole",
6525
            "cabs.ule",
6526
            "cabs.sf",
6527
            "cabs.ngle",
6528
            "cabs.seq",
6529
            "cabs.ngl",
6530
            "cabs.lt",
6531
            "cabs.nge",
6532
            "cabs.le",
6533
            "cabs.ngt",
6534
    };
6535
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6536
    uint32_t func = ctx->opcode & 0x3f;
6537

    
6538
    switch (op1) {
6539
    case OPC_ADD_S:
6540
        {
6541
            TCGv_i32 fp0 = tcg_temp_new_i32();
6542
            TCGv_i32 fp1 = tcg_temp_new_i32();
6543

    
6544
            gen_load_fpr32(fp0, fs);
6545
            gen_load_fpr32(fp1, ft);
6546
            gen_helper_float_add_s(fp0, fp0, fp1);
6547
            tcg_temp_free_i32(fp1);
6548
            gen_store_fpr32(fp0, fd);
6549
            tcg_temp_free_i32(fp0);
6550
        }
6551
        opn = "add.s";
6552
        optype = BINOP;
6553
        break;
6554
    case OPC_SUB_S:
6555
        {
6556
            TCGv_i32 fp0 = tcg_temp_new_i32();
6557
            TCGv_i32 fp1 = tcg_temp_new_i32();
6558

    
6559
            gen_load_fpr32(fp0, fs);
6560
            gen_load_fpr32(fp1, ft);
6561
            gen_helper_float_sub_s(fp0, fp0, fp1);
6562
            tcg_temp_free_i32(fp1);
6563
            gen_store_fpr32(fp0, fd);
6564
            tcg_temp_free_i32(fp0);
6565
        }
6566
        opn = "sub.s";
6567
        optype = BINOP;
6568
        break;
6569
    case OPC_MUL_S:
6570
        {
6571
            TCGv_i32 fp0 = tcg_temp_new_i32();
6572
            TCGv_i32 fp1 = tcg_temp_new_i32();
6573

    
6574
            gen_load_fpr32(fp0, fs);
6575
            gen_load_fpr32(fp1, ft);
6576
            gen_helper_float_mul_s(fp0, fp0, fp1);
6577
            tcg_temp_free_i32(fp1);
6578
            gen_store_fpr32(fp0, fd);
6579
            tcg_temp_free_i32(fp0);
6580
        }
6581
        opn = "mul.s";
6582
        optype = BINOP;
6583
        break;
6584
    case OPC_DIV_S:
6585
        {
6586
            TCGv_i32 fp0 = tcg_temp_new_i32();
6587
            TCGv_i32 fp1 = tcg_temp_new_i32();
6588

    
6589
            gen_load_fpr32(fp0, fs);
6590
            gen_load_fpr32(fp1, ft);
6591
            gen_helper_float_div_s(fp0, fp0, fp1);
6592
            tcg_temp_free_i32(fp1);
6593
            gen_store_fpr32(fp0, fd);
6594
            tcg_temp_free_i32(fp0);
6595
        }
6596
        opn = "div.s";
6597
        optype = BINOP;
6598
        break;
6599
    case OPC_SQRT_S:
6600
        {
6601
            TCGv_i32 fp0 = tcg_temp_new_i32();
6602

    
6603
            gen_load_fpr32(fp0, fs);
6604
            gen_helper_float_sqrt_s(fp0, fp0);
6605
            gen_store_fpr32(fp0, fd);
6606
            tcg_temp_free_i32(fp0);
6607
        }
6608
        opn = "sqrt.s";
6609
        break;
6610
    case OPC_ABS_S:
6611
        {
6612
            TCGv_i32 fp0 = tcg_temp_new_i32();
6613

    
6614
            gen_load_fpr32(fp0, fs);
6615
            gen_helper_float_abs_s(fp0, fp0);
6616
            gen_store_fpr32(fp0, fd);
6617
            tcg_temp_free_i32(fp0);
6618
        }
6619
        opn = "abs.s";
6620
        break;
6621
    case OPC_MOV_S:
6622
        {
6623
            TCGv_i32 fp0 = tcg_temp_new_i32();
6624

    
6625
            gen_load_fpr32(fp0, fs);
6626
            gen_store_fpr32(fp0, fd);
6627
            tcg_temp_free_i32(fp0);
6628
        }
6629
        opn = "mov.s";
6630
        break;
6631
    case OPC_NEG_S:
6632
        {
6633
            TCGv_i32 fp0 = tcg_temp_new_i32();
6634

    
6635
            gen_load_fpr32(fp0, fs);
6636
            gen_helper_float_chs_s(fp0, fp0);
6637
            gen_store_fpr32(fp0, fd);
6638
            tcg_temp_free_i32(fp0);
6639
        }
6640
        opn = "neg.s";
6641
        break;
6642
    case OPC_ROUND_L_S:
6643
        check_cp1_64bitmode(ctx);
6644
        {
6645
            TCGv_i32 fp32 = tcg_temp_new_i32();
6646
            TCGv_i64 fp64 = tcg_temp_new_i64();
6647

    
6648
            gen_load_fpr32(fp32, fs);
6649
            gen_helper_float_roundl_s(fp64, fp32);
6650
            tcg_temp_free_i32(fp32);
6651
            gen_store_fpr64(ctx, fp64, fd);
6652
            tcg_temp_free_i64(fp64);
6653
        }
6654
        opn = "round.l.s";
6655
        break;
6656
    case OPC_TRUNC_L_S:
6657
        check_cp1_64bitmode(ctx);
6658
        {
6659
            TCGv_i32 fp32 = tcg_temp_new_i32();
6660
            TCGv_i64 fp64 = tcg_temp_new_i64();
6661

    
6662
            gen_load_fpr32(fp32, fs);
6663
            gen_helper_float_truncl_s(fp64, fp32);
6664
            tcg_temp_free_i32(fp32);
6665
            gen_store_fpr64(ctx, fp64, fd);
6666
            tcg_temp_free_i64(fp64);
6667
        }
6668
        opn = "trunc.l.s";
6669
        break;
6670
    case OPC_CEIL_L_S:
6671
        check_cp1_64bitmode(ctx);
6672
        {
6673
            TCGv_i32 fp32 = tcg_temp_new_i32();
6674
            TCGv_i64 fp64 = tcg_temp_new_i64();
6675

    
6676
            gen_load_fpr32(fp32, fs);
6677
            gen_helper_float_ceill_s(fp64, fp32);
6678
            tcg_temp_free_i32(fp32);
6679
            gen_store_fpr64(ctx, fp64, fd);
6680
            tcg_temp_free_i64(fp64);
6681
        }
6682
        opn = "ceil.l.s";
6683
        break;
6684
    case OPC_FLOOR_L_S:
6685
        check_cp1_64bitmode(ctx);
6686
        {
6687
            TCGv_i32 fp32 = tcg_temp_new_i32();
6688
            TCGv_i64 fp64 = tcg_temp_new_i64();
6689

    
6690
            gen_load_fpr32(fp32, fs);
6691
            gen_helper_float_floorl_s(fp64, fp32);
6692
            tcg_temp_free_i32(fp32);
6693
            gen_store_fpr64(ctx, fp64, fd);
6694
            tcg_temp_free_i64(fp64);
6695
        }
6696
        opn = "floor.l.s";
6697
        break;
6698
    case OPC_ROUND_W_S:
6699
        {
6700
            TCGv_i32 fp0 = tcg_temp_new_i32();
6701

    
6702
            gen_load_fpr32(fp0, fs);
6703
            gen_helper_float_roundw_s(fp0, fp0);
6704
            gen_store_fpr32(fp0, fd);
6705
            tcg_temp_free_i32(fp0);
6706
        }
6707
        opn = "round.w.s";
6708
        break;
6709
    case OPC_TRUNC_W_S:
6710
        {
6711
            TCGv_i32 fp0 = tcg_temp_new_i32();
6712

    
6713
            gen_load_fpr32(fp0, fs);
6714
            gen_helper_float_truncw_s(fp0, fp0);
6715
            gen_store_fpr32(fp0, fd);
6716
            tcg_temp_free_i32(fp0);
6717
        }
6718
        opn = "trunc.w.s";
6719
        break;
6720
    case OPC_CEIL_W_S:
6721
        {
6722
            TCGv_i32 fp0 = tcg_temp_new_i32();
6723

    
6724
            gen_load_fpr32(fp0, fs);
6725
            gen_helper_float_ceilw_s(fp0, fp0);
6726
            gen_store_fpr32(fp0, fd);
6727
            tcg_temp_free_i32(fp0);
6728
        }
6729
        opn = "ceil.w.s";
6730
        break;
6731
    case OPC_FLOOR_W_S:
6732
        {
6733
            TCGv_i32 fp0 = tcg_temp_new_i32();
6734

    
6735
            gen_load_fpr32(fp0, fs);
6736
            gen_helper_float_floorw_s(fp0, fp0);
6737
            gen_store_fpr32(fp0, fd);
6738
            tcg_temp_free_i32(fp0);
6739
        }
6740
        opn = "floor.w.s";
6741
        break;
6742
    case OPC_MOVCF_S:
6743
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6744
        opn = "movcf.s";
6745
        break;
6746
    case OPC_MOVZ_S:
6747
        {
6748
            int l1 = gen_new_label();
6749
            TCGv_i32 fp0;
6750

    
6751
            if (ft != 0) {
6752
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6753
            }
6754
            fp0 = tcg_temp_new_i32();
6755
            gen_load_fpr32(fp0, fs);
6756
            gen_store_fpr32(fp0, fd);
6757
            tcg_temp_free_i32(fp0);
6758
            gen_set_label(l1);
6759
        }
6760
        opn = "movz.s";
6761
        break;
6762
    case OPC_MOVN_S:
6763
        {
6764
            int l1 = gen_new_label();
6765
            TCGv_i32 fp0;
6766

    
6767
            if (ft != 0) {
6768
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6769
                fp0 = tcg_temp_new_i32();
6770
                gen_load_fpr32(fp0, fs);
6771
                gen_store_fpr32(fp0, fd);
6772
                tcg_temp_free_i32(fp0);
6773
                gen_set_label(l1);
6774
            }
6775
        }
6776
        opn = "movn.s";
6777
        break;
6778
    case OPC_RECIP_S:
6779
        check_cop1x(ctx);
6780
        {
6781
            TCGv_i32 fp0 = tcg_temp_new_i32();
6782

    
6783
            gen_load_fpr32(fp0, fs);
6784
            gen_helper_float_recip_s(fp0, fp0);
6785
            gen_store_fpr32(fp0, fd);
6786
            tcg_temp_free_i32(fp0);
6787
        }
6788
        opn = "recip.s";
6789
        break;
6790
    case OPC_RSQRT_S:
6791
        check_cop1x(ctx);
6792
        {
6793
            TCGv_i32 fp0 = tcg_temp_new_i32();
6794

    
6795
            gen_load_fpr32(fp0, fs);
6796
            gen_helper_float_rsqrt_s(fp0, fp0);
6797
            gen_store_fpr32(fp0, fd);
6798
            tcg_temp_free_i32(fp0);
6799
        }
6800
        opn = "rsqrt.s";
6801
        break;
6802
    case OPC_RECIP2_S:
6803
        check_cp1_64bitmode(ctx);
6804
        {
6805
            TCGv_i32 fp0 = tcg_temp_new_i32();
6806
            TCGv_i32 fp1 = tcg_temp_new_i32();
6807

    
6808
            gen_load_fpr32(fp0, fs);
6809
            gen_load_fpr32(fp1, ft);
6810
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6811
            tcg_temp_free_i32(fp1);
6812
            gen_store_fpr32(fp0, fd);
6813
            tcg_temp_free_i32(fp0);
6814
        }
6815
        opn = "recip2.s";
6816
        break;
6817
    case OPC_RECIP1_S:
6818
        check_cp1_64bitmode(ctx);
6819
        {
6820
            TCGv_i32 fp0 = tcg_temp_new_i32();
6821

    
6822
            gen_load_fpr32(fp0, fs);
6823
            gen_helper_float_recip1_s(fp0, fp0);
6824
            gen_store_fpr32(fp0, fd);
6825
            tcg_temp_free_i32(fp0);
6826
        }
6827
        opn = "recip1.s";
6828
        break;
6829
    case OPC_RSQRT1_S:
6830
        check_cp1_64bitmode(ctx);
6831
        {
6832
            TCGv_i32 fp0 = tcg_temp_new_i32();
6833

    
6834
            gen_load_fpr32(fp0, fs);
6835
            gen_helper_float_rsqrt1_s(fp0, fp0);
6836
            gen_store_fpr32(fp0, fd);
6837
            tcg_temp_free_i32(fp0);
6838
        }
6839
        opn = "rsqrt1.s";
6840
        break;
6841
    case OPC_RSQRT2_S:
6842
        check_cp1_64bitmode(ctx);
6843
        {
6844
            TCGv_i32 fp0 = tcg_temp_new_i32();
6845
            TCGv_i32 fp1 = tcg_temp_new_i32();
6846

    
6847
            gen_load_fpr32(fp0, fs);
6848
            gen_load_fpr32(fp1, ft);
6849
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6850
            tcg_temp_free_i32(fp1);
6851
            gen_store_fpr32(fp0, fd);
6852
            tcg_temp_free_i32(fp0);
6853
        }
6854
        opn = "rsqrt2.s";
6855
        break;
6856
    case OPC_CVT_D_S:
6857
        check_cp1_registers(ctx, fd);
6858
        {
6859
            TCGv_i32 fp32 = tcg_temp_new_i32();
6860
            TCGv_i64 fp64 = tcg_temp_new_i64();
6861

    
6862
            gen_load_fpr32(fp32, fs);
6863
            gen_helper_float_cvtd_s(fp64, fp32);
6864
            tcg_temp_free_i32(fp32);
6865
            gen_store_fpr64(ctx, fp64, fd);
6866
            tcg_temp_free_i64(fp64);
6867
        }
6868
        opn = "cvt.d.s";
6869
        break;
6870
    case OPC_CVT_W_S:
6871
        {
6872
            TCGv_i32 fp0 = tcg_temp_new_i32();
6873

    
6874
            gen_load_fpr32(fp0, fs);
6875
            gen_helper_float_cvtw_s(fp0, fp0);
6876
            gen_store_fpr32(fp0, fd);
6877
            tcg_temp_free_i32(fp0);
6878
        }
6879
        opn = "cvt.w.s";
6880
        break;
6881
    case OPC_CVT_L_S:
6882
        check_cp1_64bitmode(ctx);
6883
        {
6884
            TCGv_i32 fp32 = tcg_temp_new_i32();
6885
            TCGv_i64 fp64 = tcg_temp_new_i64();
6886

    
6887
            gen_load_fpr32(fp32, fs);
6888
            gen_helper_float_cvtl_s(fp64, fp32);
6889
            tcg_temp_free_i32(fp32);
6890
            gen_store_fpr64(ctx, fp64, fd);
6891
            tcg_temp_free_i64(fp64);
6892
        }
6893
        opn = "cvt.l.s";
6894
        break;
6895
    case OPC_CVT_PS_S:
6896
        check_cp1_64bitmode(ctx);
6897
        {
6898
            TCGv_i64 fp64 = tcg_temp_new_i64();
6899
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6900
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6901

    
6902
            gen_load_fpr32(fp32_0, fs);
6903
            gen_load_fpr32(fp32_1, ft);
6904
            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
6905
            tcg_temp_free_i32(fp32_1);
6906
            tcg_temp_free_i32(fp32_0);
6907
            gen_store_fpr64(ctx, fp64, fd);
6908
            tcg_temp_free_i64(fp64);
6909
        }
6910
        opn = "cvt.ps.s";
6911
        break;
6912
    case OPC_CMP_F_S:
6913
    case OPC_CMP_UN_S:
6914
    case OPC_CMP_EQ_S:
6915
    case OPC_CMP_UEQ_S:
6916
    case OPC_CMP_OLT_S:
6917
    case OPC_CMP_ULT_S:
6918
    case OPC_CMP_OLE_S:
6919
    case OPC_CMP_ULE_S:
6920
    case OPC_CMP_SF_S:
6921
    case OPC_CMP_NGLE_S:
6922
    case OPC_CMP_SEQ_S:
6923
    case OPC_CMP_NGL_S:
6924
    case OPC_CMP_LT_S:
6925
    case OPC_CMP_NGE_S:
6926
    case OPC_CMP_LE_S:
6927
    case OPC_CMP_NGT_S:
6928
        if (ctx->opcode & (1 << 6)) {
6929
            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6930
            opn = condnames_abs[func-48];
6931
        } else {
6932
            gen_cmp_s(ctx, func-48, ft, fs, cc);
6933
            opn = condnames[func-48];
6934
        }
6935
        break;
6936
    case OPC_ADD_D:
6937
        check_cp1_registers(ctx, fs | ft | fd);
6938
        {
6939
            TCGv_i64 fp0 = tcg_temp_new_i64();
6940
            TCGv_i64 fp1 = tcg_temp_new_i64();
6941

    
6942
            gen_load_fpr64(ctx, fp0, fs);
6943
            gen_load_fpr64(ctx, fp1, ft);
6944
            gen_helper_float_add_d(fp0, fp0, fp1);
6945
            tcg_temp_free_i64(fp1);
6946
            gen_store_fpr64(ctx, fp0, fd);
6947
            tcg_temp_free_i64(fp0);
6948
        }
6949
        opn = "add.d";
6950
        optype = BINOP;
6951
        break;
6952
    case OPC_SUB_D:
6953
        check_cp1_registers(ctx, fs | ft | fd);
6954
        {
6955
            TCGv_i64 fp0 = tcg_temp_new_i64();
6956
            TCGv_i64 fp1 = tcg_temp_new_i64();
6957

    
6958
            gen_load_fpr64(ctx, fp0, fs);
6959
            gen_load_fpr64(ctx, fp1, ft);
6960
            gen_helper_float_sub_d(fp0, fp0, fp1);
6961
            tcg_temp_free_i64(fp1);
6962
            gen_store_fpr64(ctx, fp0, fd);
6963
            tcg_temp_free_i64(fp0);
6964
        }
6965
        opn = "sub.d";
6966
        optype = BINOP;
6967
        break;
6968
    case OPC_MUL_D:
6969
        check_cp1_registers(ctx, fs | ft | fd);
6970
        {
6971
            TCGv_i64 fp0 = tcg_temp_new_i64();
6972
            TCGv_i64 fp1 = tcg_temp_new_i64();
6973

    
6974
            gen_load_fpr64(ctx, fp0, fs);
6975
            gen_load_fpr64(ctx, fp1, ft);
6976
            gen_helper_float_mul_d(fp0, fp0, fp1);
6977
            tcg_temp_free_i64(fp1);
6978
            gen_store_fpr64(ctx, fp0, fd);
6979
            tcg_temp_free_i64(fp0);
6980
        }
6981
        opn = "mul.d";
6982
        optype = BINOP;
6983
        break;
6984
    case OPC_DIV_D:
6985
        check_cp1_registers(ctx, fs | ft | fd);
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_div_d(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 = "div.d";
6998
        optype = BINOP;
6999
        break;
7000
    case OPC_SQRT_D:
7001
        check_cp1_registers(ctx, fs | fd);
7002
        {
7003
            TCGv_i64 fp0 = tcg_temp_new_i64();
7004

    
7005
            gen_load_fpr64(ctx, fp0, fs);
7006
            gen_helper_float_sqrt_d(fp0, fp0);
7007
            gen_store_fpr64(ctx, fp0, fd);
7008
            tcg_temp_free_i64(fp0);
7009
        }
7010
        opn = "sqrt.d";
7011
        break;
7012
    case OPC_ABS_D:
7013
        check_cp1_registers(ctx, fs | fd);
7014
        {
7015
            TCGv_i64 fp0 = tcg_temp_new_i64();
7016

    
7017
            gen_load_fpr64(ctx, fp0, fs);
7018
            gen_helper_float_abs_d(fp0, fp0);
7019
            gen_store_fpr64(ctx, fp0, fd);
7020
            tcg_temp_free_i64(fp0);
7021
        }
7022
        opn = "abs.d";
7023
        break;
7024
    case OPC_MOV_D:
7025
        check_cp1_registers(ctx, fs | fd);
7026
        {
7027
            TCGv_i64 fp0 = tcg_temp_new_i64();
7028

    
7029
            gen_load_fpr64(ctx, fp0, fs);
7030
            gen_store_fpr64(ctx, fp0, fd);
7031
            tcg_temp_free_i64(fp0);
7032
        }
7033
        opn = "mov.d";
7034
        break;
7035
    case OPC_NEG_D:
7036
        check_cp1_registers(ctx, fs | fd);
7037
        {
7038
            TCGv_i64 fp0 = tcg_temp_new_i64();
7039

    
7040
            gen_load_fpr64(ctx, fp0, fs);
7041
            gen_helper_float_chs_d(fp0, fp0);
7042
            gen_store_fpr64(ctx, fp0, fd);
7043
            tcg_temp_free_i64(fp0);
7044
        }
7045
        opn = "neg.d";
7046
        break;
7047
    case OPC_ROUND_L_D:
7048
        check_cp1_64bitmode(ctx);
7049
        {
7050
            TCGv_i64 fp0 = tcg_temp_new_i64();
7051

    
7052
            gen_load_fpr64(ctx, fp0, fs);
7053
            gen_helper_float_roundl_d(fp0, fp0);
7054
            gen_store_fpr64(ctx, fp0, fd);
7055
            tcg_temp_free_i64(fp0);
7056
        }
7057
        opn = "round.l.d";
7058
        break;
7059
    case OPC_TRUNC_L_D:
7060
        check_cp1_64bitmode(ctx);
7061
        {
7062
            TCGv_i64 fp0 = tcg_temp_new_i64();
7063

    
7064
            gen_load_fpr64(ctx, fp0, fs);
7065
            gen_helper_float_truncl_d(fp0, fp0);
7066
            gen_store_fpr64(ctx, fp0, fd);
7067
            tcg_temp_free_i64(fp0);
7068
        }
7069
        opn = "trunc.l.d";
7070
        break;
7071
    case OPC_CEIL_L_D:
7072
        check_cp1_64bitmode(ctx);
7073
        {
7074
            TCGv_i64 fp0 = tcg_temp_new_i64();
7075

    
7076
            gen_load_fpr64(ctx, fp0, fs);
7077
            gen_helper_float_ceill_d(fp0, fp0);
7078
            gen_store_fpr64(ctx, fp0, fd);
7079
            tcg_temp_free_i64(fp0);
7080
        }
7081
        opn = "ceil.l.d";
7082
        break;
7083
    case OPC_FLOOR_L_D:
7084
        check_cp1_64bitmode(ctx);
7085
        {
7086
            TCGv_i64 fp0 = tcg_temp_new_i64();
7087

    
7088
            gen_load_fpr64(ctx, fp0, fs);
7089
            gen_helper_float_floorl_d(fp0, fp0);
7090
            gen_store_fpr64(ctx, fp0, fd);
7091
            tcg_temp_free_i64(fp0);
7092
        }
7093
        opn = "floor.l.d";
7094
        break;
7095
    case OPC_ROUND_W_D:
7096
        check_cp1_registers(ctx, fs);
7097
        {
7098
            TCGv_i32 fp32 = tcg_temp_new_i32();
7099
            TCGv_i64 fp64 = tcg_temp_new_i64();
7100

    
7101
            gen_load_fpr64(ctx, fp64, fs);
7102
            gen_helper_float_roundw_d(fp32, fp64);
7103
            tcg_temp_free_i64(fp64);
7104
            gen_store_fpr32(fp32, fd);
7105
            tcg_temp_free_i32(fp32);
7106
        }
7107
        opn = "round.w.d";
7108
        break;
7109
    case OPC_TRUNC_W_D:
7110
        check_cp1_registers(ctx, fs);
7111
        {
7112
            TCGv_i32 fp32 = tcg_temp_new_i32();
7113
            TCGv_i64 fp64 = tcg_temp_new_i64();
7114

    
7115
            gen_load_fpr64(ctx, fp64, fs);
7116
            gen_helper_float_truncw_d(fp32, fp64);
7117
            tcg_temp_free_i64(fp64);
7118
            gen_store_fpr32(fp32, fd);
7119
            tcg_temp_free_i32(fp32);
7120
        }
7121
        opn = "trunc.w.d";
7122
        break;
7123
    case OPC_CEIL_W_D:
7124
        check_cp1_registers(ctx, fs);
7125
        {
7126
            TCGv_i32 fp32 = tcg_temp_new_i32();
7127
            TCGv_i64 fp64 = tcg_temp_new_i64();
7128

    
7129
            gen_load_fpr64(ctx, fp64, fs);
7130
            gen_helper_float_ceilw_d(fp32, fp64);
7131
            tcg_temp_free_i64(fp64);
7132
            gen_store_fpr32(fp32, fd);
7133
            tcg_temp_free_i32(fp32);
7134
        }
7135
        opn = "ceil.w.d";
7136
        break;
7137
    case OPC_FLOOR_W_D:
7138
        check_cp1_registers(ctx, fs);
7139
        {
7140
            TCGv_i32 fp32 = tcg_temp_new_i32();
7141
            TCGv_i64 fp64 = tcg_temp_new_i64();
7142

    
7143
            gen_load_fpr64(ctx, fp64, fs);
7144
            gen_helper_float_floorw_d(fp32, fp64);
7145
            tcg_temp_free_i64(fp64);
7146
            gen_store_fpr32(fp32, fd);
7147
            tcg_temp_free_i32(fp32);
7148
        }
7149
        opn = "floor.w.d";
7150
        break;
7151
    case OPC_MOVCF_D:
7152
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7153
        opn = "movcf.d";
7154
        break;
7155
    case OPC_MOVZ_D:
7156
        {
7157
            int l1 = gen_new_label();
7158
            TCGv_i64 fp0;
7159

    
7160
            if (ft != 0) {
7161
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7162
            }
7163
            fp0 = tcg_temp_new_i64();
7164
            gen_load_fpr64(ctx, fp0, fs);
7165
            gen_store_fpr64(ctx, fp0, fd);
7166
            tcg_temp_free_i64(fp0);
7167
            gen_set_label(l1);
7168
        }
7169
        opn = "movz.d";
7170
        break;
7171
    case OPC_MOVN_D:
7172
        {
7173
            int l1 = gen_new_label();
7174
            TCGv_i64 fp0;
7175

    
7176
            if (ft != 0) {
7177
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7178
                fp0 = tcg_temp_new_i64();
7179
                gen_load_fpr64(ctx, fp0, fs);
7180
                gen_store_fpr64(ctx, fp0, fd);
7181
                tcg_temp_free_i64(fp0);
7182
                gen_set_label(l1);
7183
            }
7184
        }
7185
        opn = "movn.d";
7186
        break;
7187
    case OPC_RECIP_D:
7188
        check_cp1_64bitmode(ctx);
7189
        {
7190
            TCGv_i64 fp0 = tcg_temp_new_i64();
7191

    
7192
            gen_load_fpr64(ctx, fp0, fs);
7193
            gen_helper_float_recip_d(fp0, fp0);
7194
            gen_store_fpr64(ctx, fp0, fd);
7195
            tcg_temp_free_i64(fp0);
7196
        }
7197
        opn = "recip.d";
7198
        break;
7199
    case OPC_RSQRT_D:
7200
        check_cp1_64bitmode(ctx);
7201
        {
7202
            TCGv_i64 fp0 = tcg_temp_new_i64();
7203

    
7204
            gen_load_fpr64(ctx, fp0, fs);
7205
            gen_helper_float_rsqrt_d(fp0, fp0);
7206
            gen_store_fpr64(ctx, fp0, fd);
7207
            tcg_temp_free_i64(fp0);
7208
        }
7209
        opn = "rsqrt.d";
7210
        break;
7211
    case OPC_RECIP2_D:
7212
        check_cp1_64bitmode(ctx);
7213
        {
7214
            TCGv_i64 fp0 = tcg_temp_new_i64();
7215
            TCGv_i64 fp1 = tcg_temp_new_i64();
7216

    
7217
            gen_load_fpr64(ctx, fp0, fs);
7218
            gen_load_fpr64(ctx, fp1, ft);
7219
            gen_helper_float_recip2_d(fp0, fp0, fp1);
7220
            tcg_temp_free_i64(fp1);
7221
            gen_store_fpr64(ctx, fp0, fd);
7222
            tcg_temp_free_i64(fp0);
7223
        }
7224
        opn = "recip2.d";
7225
        break;
7226
    case OPC_RECIP1_D:
7227
        check_cp1_64bitmode(ctx);
7228
        {
7229
            TCGv_i64 fp0 = tcg_temp_new_i64();
7230

    
7231
            gen_load_fpr64(ctx, fp0, fs);
7232
            gen_helper_float_recip1_d(fp0, fp0);
7233
            gen_store_fpr64(ctx, fp0, fd);
7234
            tcg_temp_free_i64(fp0);
7235
        }
7236
        opn = "recip1.d";
7237
        break;
7238
    case OPC_RSQRT1_D:
7239
        check_cp1_64bitmode(ctx);
7240
        {
7241
            TCGv_i64 fp0 = tcg_temp_new_i64();
7242

    
7243
            gen_load_fpr64(ctx, fp0, fs);
7244
            gen_helper_float_rsqrt1_d(fp0, fp0);
7245
            gen_store_fpr64(ctx, fp0, fd);
7246
            tcg_temp_free_i64(fp0);
7247
        }
7248
        opn = "rsqrt1.d";
7249
        break;
7250
    case OPC_RSQRT2_D:
7251
        check_cp1_64bitmode(ctx);
7252
        {
7253
            TCGv_i64 fp0 = tcg_temp_new_i64();
7254
            TCGv_i64 fp1 = tcg_temp_new_i64();
7255

    
7256
            gen_load_fpr64(ctx, fp0, fs);
7257
            gen_load_fpr64(ctx, fp1, ft);
7258
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7259
            tcg_temp_free_i64(fp1);
7260
            gen_store_fpr64(ctx, fp0, fd);
7261
            tcg_temp_free_i64(fp0);
7262
        }
7263
        opn = "rsqrt2.d";
7264
        break;
7265
    case OPC_CMP_F_D:
7266
    case OPC_CMP_UN_D:
7267
    case OPC_CMP_EQ_D:
7268
    case OPC_CMP_UEQ_D:
7269
    case OPC_CMP_OLT_D:
7270
    case OPC_CMP_ULT_D:
7271
    case OPC_CMP_OLE_D:
7272
    case OPC_CMP_ULE_D:
7273
    case OPC_CMP_SF_D:
7274
    case OPC_CMP_NGLE_D:
7275
    case OPC_CMP_SEQ_D:
7276
    case OPC_CMP_NGL_D:
7277
    case OPC_CMP_LT_D:
7278
    case OPC_CMP_NGE_D:
7279
    case OPC_CMP_LE_D:
7280
    case OPC_CMP_NGT_D:
7281
        if (ctx->opcode & (1 << 6)) {
7282
            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7283
            opn = condnames_abs[func-48];
7284
        } else {
7285
            gen_cmp_d(ctx, func-48, ft, fs, cc);
7286
            opn = condnames[func-48];
7287
        }
7288
        break;
7289
    case OPC_CVT_S_D:
7290
        check_cp1_registers(ctx, fs);
7291
        {
7292
            TCGv_i32 fp32 = tcg_temp_new_i32();
7293
            TCGv_i64 fp64 = tcg_temp_new_i64();
7294

    
7295
            gen_load_fpr64(ctx, fp64, fs);
7296
            gen_helper_float_cvts_d(fp32, fp64);
7297
            tcg_temp_free_i64(fp64);
7298
            gen_store_fpr32(fp32, fd);
7299
            tcg_temp_free_i32(fp32);
7300
        }
7301
        opn = "cvt.s.d";
7302
        break;
7303
    case OPC_CVT_W_D:
7304
        check_cp1_registers(ctx, fs);
7305
        {
7306
            TCGv_i32 fp32 = tcg_temp_new_i32();
7307
            TCGv_i64 fp64 = tcg_temp_new_i64();
7308

    
7309
            gen_load_fpr64(ctx, fp64, fs);
7310
            gen_helper_float_cvtw_d(fp32, fp64);
7311
            tcg_temp_free_i64(fp64);
7312
            gen_store_fpr32(fp32, fd);
7313
            tcg_temp_free_i32(fp32);
7314
        }
7315
        opn = "cvt.w.d";
7316
        break;
7317
    case OPC_CVT_L_D:
7318
        check_cp1_64bitmode(ctx);
7319
        {
7320
            TCGv_i64 fp0 = tcg_temp_new_i64();
7321

    
7322
            gen_load_fpr64(ctx, fp0, fs);
7323
            gen_helper_float_cvtl_d(fp0, fp0);
7324
            gen_store_fpr64(ctx, fp0, fd);
7325
            tcg_temp_free_i64(fp0);
7326
        }
7327
        opn = "cvt.l.d";
7328
        break;
7329
    case OPC_CVT_S_W:
7330
        {
7331
            TCGv_i32 fp0 = tcg_temp_new_i32();
7332

    
7333
            gen_load_fpr32(fp0, fs);
7334
            gen_helper_float_cvts_w(fp0, fp0);
7335
            gen_store_fpr32(fp0, fd);
7336
            tcg_temp_free_i32(fp0);
7337
        }
7338
        opn = "cvt.s.w";
7339
        break;
7340
    case OPC_CVT_D_W:
7341
        check_cp1_registers(ctx, fd);
7342
        {
7343
            TCGv_i32 fp32 = tcg_temp_new_i32();
7344
            TCGv_i64 fp64 = tcg_temp_new_i64();
7345

    
7346
            gen_load_fpr32(fp32, fs);
7347
            gen_helper_float_cvtd_w(fp64, fp32);
7348
            tcg_temp_free_i32(fp32);
7349
            gen_store_fpr64(ctx, fp64, fd);
7350
            tcg_temp_free_i64(fp64);
7351
        }
7352
        opn = "cvt.d.w";
7353
        break;
7354
    case OPC_CVT_S_L:
7355
        check_cp1_64bitmode(ctx);
7356
        {
7357
            TCGv_i32 fp32 = tcg_temp_new_i32();
7358
            TCGv_i64 fp64 = tcg_temp_new_i64();
7359

    
7360
            gen_load_fpr64(ctx, fp64, fs);
7361
            gen_helper_float_cvts_l(fp32, fp64);
7362
            tcg_temp_free_i64(fp64);
7363
            gen_store_fpr32(fp32, fd);
7364
            tcg_temp_free_i32(fp32);
7365
        }
7366
        opn = "cvt.s.l";
7367
        break;
7368
    case OPC_CVT_D_L:
7369
        check_cp1_64bitmode(ctx);
7370
        {
7371
            TCGv_i64 fp0 = tcg_temp_new_i64();
7372

    
7373
            gen_load_fpr64(ctx, fp0, fs);
7374
            gen_helper_float_cvtd_l(fp0, fp0);
7375
            gen_store_fpr64(ctx, fp0, fd);
7376
            tcg_temp_free_i64(fp0);
7377
        }
7378
        opn = "cvt.d.l";
7379
        break;
7380
    case OPC_CVT_PS_PW:
7381
        check_cp1_64bitmode(ctx);
7382
        {
7383
            TCGv_i64 fp0 = tcg_temp_new_i64();
7384

    
7385
            gen_load_fpr64(ctx, fp0, fs);
7386
            gen_helper_float_cvtps_pw(fp0, fp0);
7387
            gen_store_fpr64(ctx, fp0, fd);
7388
            tcg_temp_free_i64(fp0);
7389
        }
7390
        opn = "cvt.ps.pw";
7391
        break;
7392
    case OPC_ADD_PS:
7393
        check_cp1_64bitmode(ctx);
7394
        {
7395
            TCGv_i64 fp0 = tcg_temp_new_i64();
7396
            TCGv_i64 fp1 = tcg_temp_new_i64();
7397

    
7398
            gen_load_fpr64(ctx, fp0, fs);
7399
            gen_load_fpr64(ctx, fp1, ft);
7400
            gen_helper_float_add_ps(fp0, fp0, fp1);
7401
            tcg_temp_free_i64(fp1);
7402
            gen_store_fpr64(ctx, fp0, fd);
7403
            tcg_temp_free_i64(fp0);
7404
        }
7405
        opn = "add.ps";
7406
        break;
7407
    case OPC_SUB_PS:
7408
        check_cp1_64bitmode(ctx);
7409
        {
7410
            TCGv_i64 fp0 = tcg_temp_new_i64();
7411
            TCGv_i64 fp1 = tcg_temp_new_i64();
7412

    
7413
            gen_load_fpr64(ctx, fp0, fs);
7414
            gen_load_fpr64(ctx, fp1, ft);
7415
            gen_helper_float_sub_ps(fp0, fp0, fp1);
7416
            tcg_temp_free_i64(fp1);
7417
            gen_store_fpr64(ctx, fp0, fd);
7418
            tcg_temp_free_i64(fp0);
7419
        }
7420
        opn = "sub.ps";
7421
        break;
7422
    case OPC_MUL_PS:
7423
        check_cp1_64bitmode(ctx);
7424
        {
7425
            TCGv_i64 fp0 = tcg_temp_new_i64();
7426
            TCGv_i64 fp1 = tcg_temp_new_i64();
7427

    
7428
            gen_load_fpr64(ctx, fp0, fs);
7429
            gen_load_fpr64(ctx, fp1, ft);
7430
            gen_helper_float_mul_ps(fp0, fp0, fp1);
7431
            tcg_temp_free_i64(fp1);
7432
            gen_store_fpr64(ctx, fp0, fd);
7433
            tcg_temp_free_i64(fp0);
7434
        }
7435
        opn = "mul.ps";
7436
        break;
7437
    case OPC_ABS_PS:
7438
        check_cp1_64bitmode(ctx);
7439
        {
7440
            TCGv_i64 fp0 = tcg_temp_new_i64();
7441

    
7442
            gen_load_fpr64(ctx, fp0, fs);
7443
            gen_helper_float_abs_ps(fp0, fp0);
7444
            gen_store_fpr64(ctx, fp0, fd);
7445
            tcg_temp_free_i64(fp0);
7446
        }
7447
        opn = "abs.ps";
7448
        break;
7449
    case OPC_MOV_PS:
7450
        check_cp1_64bitmode(ctx);
7451
        {
7452
            TCGv_i64 fp0 = tcg_temp_new_i64();
7453

    
7454
            gen_load_fpr64(ctx, fp0, fs);
7455
            gen_store_fpr64(ctx, fp0, fd);
7456
            tcg_temp_free_i64(fp0);
7457
        }
7458
        opn = "mov.ps";
7459
        break;
7460
    case OPC_NEG_PS:
7461
        check_cp1_64bitmode(ctx);
7462
        {
7463
            TCGv_i64 fp0 = tcg_temp_new_i64();
7464

    
7465
            gen_load_fpr64(ctx, fp0, fs);
7466
            gen_helper_float_chs_ps(fp0, fp0);
7467
            gen_store_fpr64(ctx, fp0, fd);
7468
            tcg_temp_free_i64(fp0);
7469
        }
7470
        opn = "neg.ps";
7471
        break;
7472
    case OPC_MOVCF_PS:
7473
        check_cp1_64bitmode(ctx);
7474
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7475
        opn = "movcf.ps";
7476
        break;
7477
    case OPC_MOVZ_PS:
7478
        check_cp1_64bitmode(ctx);
7479
        {
7480
            int l1 = gen_new_label();
7481
            TCGv_i64 fp0;
7482

    
7483
            if (ft != 0)
7484
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7485
            fp0 = tcg_temp_new_i64();
7486
            gen_load_fpr64(ctx, fp0, fs);
7487
            gen_store_fpr64(ctx, fp0, fd);
7488
            tcg_temp_free_i64(fp0);
7489
            gen_set_label(l1);
7490
        }
7491
        opn = "movz.ps";
7492
        break;
7493
    case OPC_MOVN_PS:
7494
        check_cp1_64bitmode(ctx);
7495
        {
7496
            int l1 = gen_new_label();
7497
            TCGv_i64 fp0;
7498

    
7499
            if (ft != 0) {
7500
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7501
                fp0 = tcg_temp_new_i64();
7502
                gen_load_fpr64(ctx, fp0, fs);
7503
                gen_store_fpr64(ctx, fp0, fd);
7504
                tcg_temp_free_i64(fp0);
7505
                gen_set_label(l1);
7506
            }
7507
        }
7508
        opn = "movn.ps";
7509
        break;
7510
    case OPC_ADDR_PS:
7511
        check_cp1_64bitmode(ctx);
7512
        {
7513
            TCGv_i64 fp0 = tcg_temp_new_i64();
7514
            TCGv_i64 fp1 = tcg_temp_new_i64();
7515

    
7516
            gen_load_fpr64(ctx, fp0, ft);
7517
            gen_load_fpr64(ctx, fp1, fs);
7518
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7519
            tcg_temp_free_i64(fp1);
7520
            gen_store_fpr64(ctx, fp0, fd);
7521
            tcg_temp_free_i64(fp0);
7522
        }
7523
        opn = "addr.ps";
7524
        break;
7525
    case OPC_MULR_PS:
7526
        check_cp1_64bitmode(ctx);
7527
        {
7528
            TCGv_i64 fp0 = tcg_temp_new_i64();
7529
            TCGv_i64 fp1 = tcg_temp_new_i64();
7530

    
7531
            gen_load_fpr64(ctx, fp0, ft);
7532
            gen_load_fpr64(ctx, fp1, fs);
7533
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7534
            tcg_temp_free_i64(fp1);
7535
            gen_store_fpr64(ctx, fp0, fd);
7536
            tcg_temp_free_i64(fp0);
7537
        }
7538
        opn = "mulr.ps";
7539
        break;
7540
    case OPC_RECIP2_PS:
7541
        check_cp1_64bitmode(ctx);
7542
        {
7543
            TCGv_i64 fp0 = tcg_temp_new_i64();
7544
            TCGv_i64 fp1 = tcg_temp_new_i64();
7545

    
7546
            gen_load_fpr64(ctx, fp0, fs);
7547
            gen_load_fpr64(ctx, fp1, ft);
7548
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7549
            tcg_temp_free_i64(fp1);
7550
            gen_store_fpr64(ctx, fp0, fd);
7551
            tcg_temp_free_i64(fp0);
7552
        }
7553
        opn = "recip2.ps";
7554
        break;
7555
    case OPC_RECIP1_PS:
7556
        check_cp1_64bitmode(ctx);
7557
        {
7558
            TCGv_i64 fp0 = tcg_temp_new_i64();
7559

    
7560
            gen_load_fpr64(ctx, fp0, fs);
7561
            gen_helper_float_recip1_ps(fp0, fp0);
7562
            gen_store_fpr64(ctx, fp0, fd);
7563
            tcg_temp_free_i64(fp0);
7564
        }
7565
        opn = "recip1.ps";
7566
        break;
7567
    case OPC_RSQRT1_PS:
7568
        check_cp1_64bitmode(ctx);
7569
        {
7570
            TCGv_i64 fp0 = tcg_temp_new_i64();
7571

    
7572
            gen_load_fpr64(ctx, fp0, fs);
7573
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7574
            gen_store_fpr64(ctx, fp0, fd);
7575
            tcg_temp_free_i64(fp0);
7576
        }
7577
        opn = "rsqrt1.ps";
7578
        break;
7579
    case OPC_RSQRT2_PS:
7580
        check_cp1_64bitmode(ctx);
7581
        {
7582
            TCGv_i64 fp0 = tcg_temp_new_i64();
7583
            TCGv_i64 fp1 = tcg_temp_new_i64();
7584

    
7585
            gen_load_fpr64(ctx, fp0, fs);
7586
            gen_load_fpr64(ctx, fp1, ft);
7587
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7588
            tcg_temp_free_i64(fp1);
7589
            gen_store_fpr64(ctx, fp0, fd);
7590
            tcg_temp_free_i64(fp0);
7591
        }
7592
        opn = "rsqrt2.ps";
7593
        break;
7594
    case OPC_CVT_S_PU:
7595
        check_cp1_64bitmode(ctx);
7596
        {
7597
            TCGv_i32 fp0 = tcg_temp_new_i32();
7598

    
7599
            gen_load_fpr32h(fp0, fs);
7600
            gen_helper_float_cvts_pu(fp0, fp0);
7601
            gen_store_fpr32(fp0, fd);
7602
            tcg_temp_free_i32(fp0);
7603
        }
7604
        opn = "cvt.s.pu";
7605
        break;
7606
    case OPC_CVT_PW_PS:
7607
        check_cp1_64bitmode(ctx);
7608
        {
7609
            TCGv_i64 fp0 = tcg_temp_new_i64();
7610

    
7611
            gen_load_fpr64(ctx, fp0, fs);
7612
            gen_helper_float_cvtpw_ps(fp0, fp0);
7613
            gen_store_fpr64(ctx, fp0, fd);
7614
            tcg_temp_free_i64(fp0);
7615
        }
7616
        opn = "cvt.pw.ps";
7617
        break;
7618
    case OPC_CVT_S_PL:
7619
        check_cp1_64bitmode(ctx);
7620
        {
7621
            TCGv_i32 fp0 = tcg_temp_new_i32();
7622

    
7623
            gen_load_fpr32(fp0, fs);
7624
            gen_helper_float_cvts_pl(fp0, fp0);
7625
            gen_store_fpr32(fp0, fd);
7626
            tcg_temp_free_i32(fp0);
7627
        }
7628
        opn = "cvt.s.pl";
7629
        break;
7630
    case OPC_PLL_PS:
7631
        check_cp1_64bitmode(ctx);
7632
        {
7633
            TCGv_i32 fp0 = tcg_temp_new_i32();
7634
            TCGv_i32 fp1 = tcg_temp_new_i32();
7635

    
7636
            gen_load_fpr32(fp0, fs);
7637
            gen_load_fpr32(fp1, ft);
7638
            gen_store_fpr32h(fp0, fd);
7639
            gen_store_fpr32(fp1, fd);
7640
            tcg_temp_free_i32(fp0);
7641
            tcg_temp_free_i32(fp1);
7642
        }
7643
        opn = "pll.ps";
7644
        break;
7645
    case OPC_PLU_PS:
7646
        check_cp1_64bitmode(ctx);
7647
        {
7648
            TCGv_i32 fp0 = tcg_temp_new_i32();
7649
            TCGv_i32 fp1 = tcg_temp_new_i32();
7650

    
7651
            gen_load_fpr32(fp0, fs);
7652
            gen_load_fpr32h(fp1, ft);
7653
            gen_store_fpr32(fp1, fd);
7654
            gen_store_fpr32h(fp0, fd);
7655
            tcg_temp_free_i32(fp0);
7656
            tcg_temp_free_i32(fp1);
7657
        }
7658
        opn = "plu.ps";
7659
        break;
7660
    case OPC_PUL_PS:
7661
        check_cp1_64bitmode(ctx);
7662
        {
7663
            TCGv_i32 fp0 = tcg_temp_new_i32();
7664
            TCGv_i32 fp1 = tcg_temp_new_i32();
7665

    
7666
            gen_load_fpr32h(fp0, fs);
7667
            gen_load_fpr32(fp1, ft);
7668
            gen_store_fpr32(fp1, fd);
7669
            gen_store_fpr32h(fp0, fd);
7670
            tcg_temp_free_i32(fp0);
7671
            tcg_temp_free_i32(fp1);
7672
        }
7673
        opn = "pul.ps";
7674
        break;
7675
    case OPC_PUU_PS:
7676
        check_cp1_64bitmode(ctx);
7677
        {
7678
            TCGv_i32 fp0 = tcg_temp_new_i32();
7679
            TCGv_i32 fp1 = tcg_temp_new_i32();
7680

    
7681
            gen_load_fpr32h(fp0, fs);
7682
            gen_load_fpr32h(fp1, ft);
7683
            gen_store_fpr32(fp1, fd);
7684
            gen_store_fpr32h(fp0, fd);
7685
            tcg_temp_free_i32(fp0);
7686
            tcg_temp_free_i32(fp1);
7687
        }
7688
        opn = "puu.ps";
7689
        break;
7690
    case OPC_CMP_F_PS:
7691
    case OPC_CMP_UN_PS:
7692
    case OPC_CMP_EQ_PS:
7693
    case OPC_CMP_UEQ_PS:
7694
    case OPC_CMP_OLT_PS:
7695
    case OPC_CMP_ULT_PS:
7696
    case OPC_CMP_OLE_PS:
7697
    case OPC_CMP_ULE_PS:
7698
    case OPC_CMP_SF_PS:
7699
    case OPC_CMP_NGLE_PS:
7700
    case OPC_CMP_SEQ_PS:
7701
    case OPC_CMP_NGL_PS:
7702
    case OPC_CMP_LT_PS:
7703
    case OPC_CMP_NGE_PS:
7704
    case OPC_CMP_LE_PS:
7705
    case OPC_CMP_NGT_PS:
7706
        if (ctx->opcode & (1 << 6)) {
7707
            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7708
            opn = condnames_abs[func-48];
7709
        } else {
7710
            gen_cmp_ps(ctx, func-48, ft, fs, cc);
7711
            opn = condnames[func-48];
7712
        }
7713
        break;
7714
    default:
7715
        MIPS_INVAL(opn);
7716
        generate_exception (ctx, EXCP_RI);
7717
        return;
7718
    }
7719
    (void)opn; /* avoid a compiler warning */
7720
    switch (optype) {
7721
    case BINOP:
7722
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7723
        break;
7724
    case CMPOP:
7725
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7726
        break;
7727
    default:
7728
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7729
        break;
7730
    }
7731
}
7732

    
7733
/* Coprocessor 3 (FPU) */
7734
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7735
                           int fd, int fs, int base, int index)
7736
{
7737
    const char *opn = "extended float load/store";
7738
    int store = 0;
7739
    TCGv t0 = tcg_temp_new();
7740

    
7741
    if (base == 0) {
7742
        gen_load_gpr(t0, index);
7743
    } else if (index == 0) {
7744
        gen_load_gpr(t0, base);
7745
    } else {
7746
        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
7747
    }
7748
    /* Don't do NOP if destination is zero: we must perform the actual
7749
       memory access. */
7750
    save_cpu_state(ctx, 0);
7751
    switch (opc) {
7752
    case OPC_LWXC1:
7753
        check_cop1x(ctx);
7754
        {
7755
            TCGv_i32 fp0 = tcg_temp_new_i32();
7756

    
7757
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7758
            tcg_gen_trunc_tl_i32(fp0, t0);
7759
            gen_store_fpr32(fp0, fd);
7760
            tcg_temp_free_i32(fp0);
7761
        }
7762
        opn = "lwxc1";
7763
        break;
7764
    case OPC_LDXC1:
7765
        check_cop1x(ctx);
7766
        check_cp1_registers(ctx, fd);
7767
        {
7768
            TCGv_i64 fp0 = tcg_temp_new_i64();
7769

    
7770
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7771
            gen_store_fpr64(ctx, fp0, fd);
7772
            tcg_temp_free_i64(fp0);
7773
        }
7774
        opn = "ldxc1";
7775
        break;
7776
    case OPC_LUXC1:
7777
        check_cp1_64bitmode(ctx);
7778
        tcg_gen_andi_tl(t0, t0, ~0x7);
7779
        {
7780
            TCGv_i64 fp0 = tcg_temp_new_i64();
7781

    
7782
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7783
            gen_store_fpr64(ctx, fp0, fd);
7784
            tcg_temp_free_i64(fp0);
7785
        }
7786
        opn = "luxc1";
7787
        break;
7788
    case OPC_SWXC1:
7789
        check_cop1x(ctx);
7790
        {
7791
            TCGv_i32 fp0 = tcg_temp_new_i32();
7792
            TCGv t1 = tcg_temp_new();
7793

    
7794
            gen_load_fpr32(fp0, fs);
7795
            tcg_gen_extu_i32_tl(t1, fp0);
7796
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7797
            tcg_temp_free_i32(fp0);
7798
            tcg_temp_free(t1);
7799
        }
7800
        opn = "swxc1";
7801
        store = 1;
7802
        break;
7803
    case OPC_SDXC1:
7804
        check_cop1x(ctx);
7805
        check_cp1_registers(ctx, fs);
7806
        {
7807
            TCGv_i64 fp0 = tcg_temp_new_i64();
7808

    
7809
            gen_load_fpr64(ctx, fp0, fs);
7810
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7811
            tcg_temp_free_i64(fp0);
7812
        }
7813
        opn = "sdxc1";
7814
        store = 1;
7815
        break;
7816
    case OPC_SUXC1:
7817
        check_cp1_64bitmode(ctx);
7818
        tcg_gen_andi_tl(t0, t0, ~0x7);
7819
        {
7820
            TCGv_i64 fp0 = tcg_temp_new_i64();
7821

    
7822
            gen_load_fpr64(ctx, fp0, fs);
7823
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7824
            tcg_temp_free_i64(fp0);
7825
        }
7826
        opn = "suxc1";
7827
        store = 1;
7828
        break;
7829
    }
7830
    tcg_temp_free(t0);
7831
    (void)opn; (void)store; /* avoid compiler warnings */
7832
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7833
               regnames[index], regnames[base]);
7834
}
7835

    
7836
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7837
                            int fd, int fr, int fs, int ft)
7838
{
7839
    const char *opn = "flt3_arith";
7840

    
7841
    switch (opc) {
7842
    case OPC_ALNV_PS:
7843
        check_cp1_64bitmode(ctx);
7844
        {
7845
            TCGv t0 = tcg_temp_local_new();
7846
            TCGv_i32 fp = tcg_temp_new_i32();
7847
            TCGv_i32 fph = tcg_temp_new_i32();
7848
            int l1 = gen_new_label();
7849
            int l2 = gen_new_label();
7850

    
7851
            gen_load_gpr(t0, fr);
7852
            tcg_gen_andi_tl(t0, t0, 0x7);
7853

    
7854
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7855
            gen_load_fpr32(fp, fs);
7856
            gen_load_fpr32h(fph, fs);
7857
            gen_store_fpr32(fp, fd);
7858
            gen_store_fpr32h(fph, fd);
7859
            tcg_gen_br(l2);
7860
            gen_set_label(l1);
7861
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7862
            tcg_temp_free(t0);
7863
#ifdef TARGET_WORDS_BIGENDIAN
7864
            gen_load_fpr32(fp, fs);
7865
            gen_load_fpr32h(fph, ft);
7866
            gen_store_fpr32h(fp, fd);
7867
            gen_store_fpr32(fph, fd);
7868
#else
7869
            gen_load_fpr32h(fph, fs);
7870
            gen_load_fpr32(fp, ft);
7871
            gen_store_fpr32(fph, fd);
7872
            gen_store_fpr32h(fp, fd);
7873
#endif
7874
            gen_set_label(l2);
7875
            tcg_temp_free_i32(fp);
7876
            tcg_temp_free_i32(fph);
7877
        }
7878
        opn = "alnv.ps";
7879
        break;
7880
    case OPC_MADD_S:
7881
        check_cop1x(ctx);
7882
        {
7883
            TCGv_i32 fp0 = tcg_temp_new_i32();
7884
            TCGv_i32 fp1 = tcg_temp_new_i32();
7885
            TCGv_i32 fp2 = tcg_temp_new_i32();
7886

    
7887
            gen_load_fpr32(fp0, fs);
7888
            gen_load_fpr32(fp1, ft);
7889
            gen_load_fpr32(fp2, fr);
7890
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7891
            tcg_temp_free_i32(fp0);
7892
            tcg_temp_free_i32(fp1);
7893
            gen_store_fpr32(fp2, fd);
7894
            tcg_temp_free_i32(fp2);
7895
        }
7896
        opn = "madd.s";
7897
        break;
7898
    case OPC_MADD_D:
7899
        check_cop1x(ctx);
7900
        check_cp1_registers(ctx, fd | fs | ft | fr);
7901
        {
7902
            TCGv_i64 fp0 = tcg_temp_new_i64();
7903
            TCGv_i64 fp1 = tcg_temp_new_i64();
7904
            TCGv_i64 fp2 = tcg_temp_new_i64();
7905

    
7906
            gen_load_fpr64(ctx, fp0, fs);
7907
            gen_load_fpr64(ctx, fp1, ft);
7908
            gen_load_fpr64(ctx, fp2, fr);
7909
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7910
            tcg_temp_free_i64(fp0);
7911
            tcg_temp_free_i64(fp1);
7912
            gen_store_fpr64(ctx, fp2, fd);
7913
            tcg_temp_free_i64(fp2);
7914
        }
7915
        opn = "madd.d";
7916
        break;
7917
    case OPC_MADD_PS:
7918
        check_cp1_64bitmode(ctx);
7919
        {
7920
            TCGv_i64 fp0 = tcg_temp_new_i64();
7921
            TCGv_i64 fp1 = tcg_temp_new_i64();
7922
            TCGv_i64 fp2 = tcg_temp_new_i64();
7923

    
7924
            gen_load_fpr64(ctx, fp0, fs);
7925
            gen_load_fpr64(ctx, fp1, ft);
7926
            gen_load_fpr64(ctx, fp2, fr);
7927
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7928
            tcg_temp_free_i64(fp0);
7929
            tcg_temp_free_i64(fp1);
7930
            gen_store_fpr64(ctx, fp2, fd);
7931
            tcg_temp_free_i64(fp2);
7932
        }
7933
        opn = "madd.ps";
7934
        break;
7935
    case OPC_MSUB_S:
7936
        check_cop1x(ctx);
7937
        {
7938
            TCGv_i32 fp0 = tcg_temp_new_i32();
7939
            TCGv_i32 fp1 = tcg_temp_new_i32();
7940
            TCGv_i32 fp2 = tcg_temp_new_i32();
7941

    
7942
            gen_load_fpr32(fp0, fs);
7943
            gen_load_fpr32(fp1, ft);
7944
            gen_load_fpr32(fp2, fr);
7945
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7946
            tcg_temp_free_i32(fp0);
7947
            tcg_temp_free_i32(fp1);
7948
            gen_store_fpr32(fp2, fd);
7949
            tcg_temp_free_i32(fp2);
7950
        }
7951
        opn = "msub.s";
7952
        break;
7953
    case OPC_MSUB_D:
7954
        check_cop1x(ctx);
7955
        check_cp1_registers(ctx, fd | fs | ft | fr);
7956
        {
7957
            TCGv_i64 fp0 = tcg_temp_new_i64();
7958
            TCGv_i64 fp1 = tcg_temp_new_i64();
7959
            TCGv_i64 fp2 = tcg_temp_new_i64();
7960

    
7961
            gen_load_fpr64(ctx, fp0, fs);
7962
            gen_load_fpr64(ctx, fp1, ft);
7963
            gen_load_fpr64(ctx, fp2, fr);
7964
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7965
            tcg_temp_free_i64(fp0);
7966
            tcg_temp_free_i64(fp1);
7967
            gen_store_fpr64(ctx, fp2, fd);
7968
            tcg_temp_free_i64(fp2);
7969
        }
7970
        opn = "msub.d";
7971
        break;
7972
    case OPC_MSUB_PS:
7973
        check_cp1_64bitmode(ctx);
7974
        {
7975
            TCGv_i64 fp0 = tcg_temp_new_i64();
7976
            TCGv_i64 fp1 = tcg_temp_new_i64();
7977
            TCGv_i64 fp2 = tcg_temp_new_i64();
7978

    
7979
            gen_load_fpr64(ctx, fp0, fs);
7980
            gen_load_fpr64(ctx, fp1, ft);
7981
            gen_load_fpr64(ctx, fp2, fr);
7982
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7983
            tcg_temp_free_i64(fp0);
7984
            tcg_temp_free_i64(fp1);
7985
            gen_store_fpr64(ctx, fp2, fd);
7986
            tcg_temp_free_i64(fp2);
7987
        }
7988
        opn = "msub.ps";
7989
        break;
7990
    case OPC_NMADD_S:
7991
        check_cop1x(ctx);
7992
        {
7993
            TCGv_i32 fp0 = tcg_temp_new_i32();
7994
            TCGv_i32 fp1 = tcg_temp_new_i32();
7995
            TCGv_i32 fp2 = tcg_temp_new_i32();
7996

    
7997
            gen_load_fpr32(fp0, fs);
7998
            gen_load_fpr32(fp1, ft);
7999
            gen_load_fpr32(fp2, fr);
8000
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
8001
            tcg_temp_free_i32(fp0);
8002
            tcg_temp_free_i32(fp1);
8003
            gen_store_fpr32(fp2, fd);
8004
            tcg_temp_free_i32(fp2);
8005
        }
8006
        opn = "nmadd.s";
8007
        break;
8008
    case OPC_NMADD_D:
8009
        check_cop1x(ctx);
8010
        check_cp1_registers(ctx, fd | fs | ft | fr);
8011
        {
8012
            TCGv_i64 fp0 = tcg_temp_new_i64();
8013
            TCGv_i64 fp1 = tcg_temp_new_i64();
8014
            TCGv_i64 fp2 = tcg_temp_new_i64();
8015

    
8016
            gen_load_fpr64(ctx, fp0, fs);
8017
            gen_load_fpr64(ctx, fp1, ft);
8018
            gen_load_fpr64(ctx, fp2, fr);
8019
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
8020
            tcg_temp_free_i64(fp0);
8021
            tcg_temp_free_i64(fp1);
8022
            gen_store_fpr64(ctx, fp2, fd);
8023
            tcg_temp_free_i64(fp2);
8024
        }
8025
        opn = "nmadd.d";
8026
        break;
8027
    case OPC_NMADD_PS:
8028
        check_cp1_64bitmode(ctx);
8029
        {
8030
            TCGv_i64 fp0 = tcg_temp_new_i64();
8031
            TCGv_i64 fp1 = tcg_temp_new_i64();
8032
            TCGv_i64 fp2 = tcg_temp_new_i64();
8033

    
8034
            gen_load_fpr64(ctx, fp0, fs);
8035
            gen_load_fpr64(ctx, fp1, ft);
8036
            gen_load_fpr64(ctx, fp2, fr);
8037
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
8038
            tcg_temp_free_i64(fp0);
8039
            tcg_temp_free_i64(fp1);
8040
            gen_store_fpr64(ctx, fp2, fd);
8041
            tcg_temp_free_i64(fp2);
8042
        }
8043
        opn = "nmadd.ps";
8044
        break;
8045
    case OPC_NMSUB_S:
8046
        check_cop1x(ctx);
8047
        {
8048
            TCGv_i32 fp0 = tcg_temp_new_i32();
8049
            TCGv_i32 fp1 = tcg_temp_new_i32();
8050
            TCGv_i32 fp2 = tcg_temp_new_i32();
8051

    
8052
            gen_load_fpr32(fp0, fs);
8053
            gen_load_fpr32(fp1, ft);
8054
            gen_load_fpr32(fp2, fr);
8055
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
8056
            tcg_temp_free_i32(fp0);
8057
            tcg_temp_free_i32(fp1);
8058
            gen_store_fpr32(fp2, fd);
8059
            tcg_temp_free_i32(fp2);
8060
        }
8061
        opn = "nmsub.s";
8062
        break;
8063
    case OPC_NMSUB_D:
8064
        check_cop1x(ctx);
8065
        check_cp1_registers(ctx, fd | fs | ft | fr);
8066
        {
8067
            TCGv_i64 fp0 = tcg_temp_new_i64();
8068
            TCGv_i64 fp1 = tcg_temp_new_i64();
8069
            TCGv_i64 fp2 = tcg_temp_new_i64();
8070

    
8071
            gen_load_fpr64(ctx, fp0, fs);
8072
            gen_load_fpr64(ctx, fp1, ft);
8073
            gen_load_fpr64(ctx, fp2, fr);
8074
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
8075
            tcg_temp_free_i64(fp0);
8076
            tcg_temp_free_i64(fp1);
8077
            gen_store_fpr64(ctx, fp2, fd);
8078
            tcg_temp_free_i64(fp2);
8079
        }
8080
        opn = "nmsub.d";
8081
        break;
8082
    case OPC_NMSUB_PS:
8083
        check_cp1_64bitmode(ctx);
8084
        {
8085
            TCGv_i64 fp0 = tcg_temp_new_i64();
8086
            TCGv_i64 fp1 = tcg_temp_new_i64();
8087
            TCGv_i64 fp2 = tcg_temp_new_i64();
8088

    
8089
            gen_load_fpr64(ctx, fp0, fs);
8090
            gen_load_fpr64(ctx, fp1, ft);
8091
            gen_load_fpr64(ctx, fp2, fr);
8092
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8093
            tcg_temp_free_i64(fp0);
8094
            tcg_temp_free_i64(fp1);
8095
            gen_store_fpr64(ctx, fp2, fd);
8096
            tcg_temp_free_i64(fp2);
8097
        }
8098
        opn = "nmsub.ps";
8099
        break;
8100
    default:
8101
        MIPS_INVAL(opn);
8102
        generate_exception (ctx, EXCP_RI);
8103
        return;
8104
    }
8105
    (void)opn; /* avoid a compiler warning */
8106
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8107
               fregnames[fs], fregnames[ft]);
8108
}
8109

    
8110
static void
8111
gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
8112
{
8113
    TCGv t0;
8114

    
8115
#if !defined(CONFIG_USER_ONLY)
8116
    /* The Linux kernel will emulate rdhwr if it's not supported natively.
8117
       Therefore only check the ISA in system mode.  */
8118
    check_insn(env, ctx, ISA_MIPS32R2);
8119
#endif
8120
    t0 = tcg_temp_new();
8121

    
8122
    switch (rd) {
8123
    case 0:
8124
        save_cpu_state(ctx, 1);
8125
        gen_helper_rdhwr_cpunum(t0);
8126
        gen_store_gpr(t0, rt);
8127
        break;
8128
    case 1:
8129
        save_cpu_state(ctx, 1);
8130
        gen_helper_rdhwr_synci_step(t0);
8131
        gen_store_gpr(t0, rt);
8132
        break;
8133
    case 2:
8134
        save_cpu_state(ctx, 1);
8135
        gen_helper_rdhwr_cc(t0);
8136
        gen_store_gpr(t0, rt);
8137
        break;
8138
    case 3:
8139
        save_cpu_state(ctx, 1);
8140
        gen_helper_rdhwr_ccres(t0);
8141
        gen_store_gpr(t0, rt);
8142
        break;
8143
    case 29:
8144
#if defined(CONFIG_USER_ONLY)
8145
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
8146
        gen_store_gpr(t0, rt);
8147
        break;
8148
#else
8149
        /* XXX: Some CPUs implement this in hardware.
8150
           Not supported yet. */
8151
#endif
8152
    default:            /* Invalid */
8153
        MIPS_INVAL("rdhwr");
8154
        generate_exception(ctx, EXCP_RI);
8155
        break;
8156
    }
8157
    tcg_temp_free(t0);
8158
}
8159

    
8160
static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
8161
                               int insn_bytes)
8162
{
8163
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8164
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8165
        /* Branches completion */
8166
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8167
        ctx->bstate = BS_BRANCH;
8168
        save_cpu_state(ctx, 0);
8169
        /* FIXME: Need to clear can_do_io.  */
8170
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8171
        case MIPS_HFLAG_B:
8172
            /* unconditional branch */
8173
            MIPS_DEBUG("unconditional branch");
8174
            if (proc_hflags & MIPS_HFLAG_BX) {
8175
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8176
            }
8177
            gen_goto_tb(ctx, 0, ctx->btarget);
8178
            break;
8179
        case MIPS_HFLAG_BL:
8180
            /* blikely taken case */
8181
            MIPS_DEBUG("blikely branch taken");
8182
            gen_goto_tb(ctx, 0, ctx->btarget);
8183
            break;
8184
        case MIPS_HFLAG_BC:
8185
            /* Conditional branch */
8186
            MIPS_DEBUG("conditional branch");
8187
            {
8188
                int l1 = gen_new_label();
8189

    
8190
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8191
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8192
                gen_set_label(l1);
8193
                gen_goto_tb(ctx, 0, ctx->btarget);
8194
            }
8195
            break;
8196
        case MIPS_HFLAG_BR:
8197
            /* unconditional branch to register */
8198
            MIPS_DEBUG("branch to register");
8199
            if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8200
                TCGv t0 = tcg_temp_new();
8201
                TCGv_i32 t1 = tcg_temp_new_i32();
8202

    
8203
                tcg_gen_andi_tl(t0, btarget, 0x1);
8204
                tcg_gen_trunc_tl_i32(t1, t0);
8205
                tcg_temp_free(t0);
8206
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8207
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8208
                tcg_gen_or_i32(hflags, hflags, t1);
8209
                tcg_temp_free_i32(t1);
8210

    
8211
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8212
            } else {
8213
                tcg_gen_mov_tl(cpu_PC, btarget);
8214
            }
8215
            if (ctx->singlestep_enabled) {
8216
                save_cpu_state(ctx, 0);
8217
                gen_helper_0i(raise_exception, EXCP_DEBUG);
8218
            }
8219
            tcg_gen_exit_tb(0);
8220
            break;
8221
        default:
8222
            MIPS_DEBUG("unknown branch");
8223
            break;
8224
        }
8225
    }
8226
}
8227

    
8228
/* ISA extensions (ASEs) */
8229
/* MIPS16 extension to MIPS32 */
8230

    
8231
/* MIPS16 major opcodes */
8232
enum {
8233
  M16_OPC_ADDIUSP = 0x00,
8234
  M16_OPC_ADDIUPC = 0x01,
8235
  M16_OPC_B = 0x02,
8236
  M16_OPC_JAL = 0x03,
8237
  M16_OPC_BEQZ = 0x04,
8238
  M16_OPC_BNEQZ = 0x05,
8239
  M16_OPC_SHIFT = 0x06,
8240
  M16_OPC_LD = 0x07,
8241
  M16_OPC_RRIA = 0x08,
8242
  M16_OPC_ADDIU8 = 0x09,
8243
  M16_OPC_SLTI = 0x0a,
8244
  M16_OPC_SLTIU = 0x0b,
8245
  M16_OPC_I8 = 0x0c,
8246
  M16_OPC_LI = 0x0d,
8247
  M16_OPC_CMPI = 0x0e,
8248
  M16_OPC_SD = 0x0f,
8249
  M16_OPC_LB = 0x10,
8250
  M16_OPC_LH = 0x11,
8251
  M16_OPC_LWSP = 0x12,
8252
  M16_OPC_LW = 0x13,
8253
  M16_OPC_LBU = 0x14,
8254
  M16_OPC_LHU = 0x15,
8255
  M16_OPC_LWPC = 0x16,
8256
  M16_OPC_LWU = 0x17,
8257
  M16_OPC_SB = 0x18,
8258
  M16_OPC_SH = 0x19,
8259
  M16_OPC_SWSP = 0x1a,
8260
  M16_OPC_SW = 0x1b,
8261
  M16_OPC_RRR = 0x1c,
8262
  M16_OPC_RR = 0x1d,
8263
  M16_OPC_EXTEND = 0x1e,
8264
  M16_OPC_I64 = 0x1f
8265
};
8266

    
8267
/* I8 funct field */
8268
enum {
8269
  I8_BTEQZ = 0x0,
8270
  I8_BTNEZ = 0x1,
8271
  I8_SWRASP = 0x2,
8272
  I8_ADJSP = 0x3,
8273
  I8_SVRS = 0x4,
8274
  I8_MOV32R = 0x5,
8275
  I8_MOVR32 = 0x7
8276
};
8277

    
8278
/* RRR f field */
8279
enum {
8280
  RRR_DADDU = 0x0,
8281
  RRR_ADDU = 0x1,
8282
  RRR_DSUBU = 0x2,
8283
  RRR_SUBU = 0x3
8284
};
8285

    
8286
/* RR funct field */
8287
enum {
8288
  RR_JR = 0x00,
8289
  RR_SDBBP = 0x01,
8290
  RR_SLT = 0x02,
8291
  RR_SLTU = 0x03,
8292
  RR_SLLV = 0x04,
8293
  RR_BREAK = 0x05,
8294
  RR_SRLV = 0x06,
8295
  RR_SRAV = 0x07,
8296
  RR_DSRL = 0x08,
8297
  RR_CMP = 0x0a,
8298
  RR_NEG = 0x0b,
8299
  RR_AND = 0x0c,
8300
  RR_OR = 0x0d,
8301
  RR_XOR = 0x0e,
8302
  RR_NOT = 0x0f,
8303
  RR_MFHI = 0x10,
8304
  RR_CNVT = 0x11,
8305
  RR_MFLO = 0x12,
8306
  RR_DSRA = 0x13,
8307
  RR_DSLLV = 0x14,
8308
  RR_DSRLV = 0x16,
8309
  RR_DSRAV = 0x17,
8310
  RR_MULT = 0x18,
8311
  RR_MULTU = 0x19,
8312
  RR_DIV = 0x1a,
8313
  RR_DIVU = 0x1b,
8314
  RR_DMULT = 0x1c,
8315
  RR_DMULTU = 0x1d,
8316
  RR_DDIV = 0x1e,
8317
  RR_DDIVU = 0x1f
8318
};
8319

    
8320
/* I64 funct field */
8321
enum {
8322
  I64_LDSP = 0x0,
8323
  I64_SDSP = 0x1,
8324
  I64_SDRASP = 0x2,
8325
  I64_DADJSP = 0x3,
8326
  I64_LDPC = 0x4,
8327
  I64_DADDIU5 = 0x5,
8328
  I64_DADDIUPC = 0x6,
8329
  I64_DADDIUSP = 0x7
8330
};
8331

    
8332
/* RR ry field for CNVT */
8333
enum {
8334
  RR_RY_CNVT_ZEB = 0x0,
8335
  RR_RY_CNVT_ZEH = 0x1,
8336
  RR_RY_CNVT_ZEW = 0x2,
8337
  RR_RY_CNVT_SEB = 0x4,
8338
  RR_RY_CNVT_SEH = 0x5,
8339
  RR_RY_CNVT_SEW = 0x6,
8340
};
8341

    
8342
static int xlat (int r)
8343
{
8344
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8345

    
8346
  return map[r];
8347
}
8348

    
8349
static void gen_mips16_save (DisasContext *ctx,
8350
                             int xsregs, int aregs,
8351
                             int do_ra, int do_s0, int do_s1,
8352
                             int framesize)
8353
{
8354
    TCGv t0 = tcg_temp_new();
8355
    TCGv t1 = tcg_temp_new();
8356
    int args, astatic;
8357

    
8358
    switch (aregs) {
8359
    case 0:
8360
    case 1:
8361
    case 2:
8362
    case 3:
8363
    case 11:
8364
        args = 0;
8365
        break;
8366
    case 4:
8367
    case 5:
8368
    case 6:
8369
    case 7:
8370
        args = 1;
8371
        break;
8372
    case 8:
8373
    case 9:
8374
    case 10:
8375
        args = 2;
8376
        break;
8377
    case 12:
8378
    case 13:
8379
        args = 3;
8380
        break;
8381
    case 14:
8382
        args = 4;
8383
        break;
8384
    default:
8385
        generate_exception(ctx, EXCP_RI);
8386
        return;
8387
    }
8388

    
8389
    switch (args) {
8390
    case 4:
8391
        gen_base_offset_addr(ctx, t0, 29, 12);
8392
        gen_load_gpr(t1, 7);
8393
        op_st_sw(t1, t0, ctx);
8394
        /* Fall through */
8395
    case 3:
8396
        gen_base_offset_addr(ctx, t0, 29, 8);
8397
        gen_load_gpr(t1, 6);
8398
        op_st_sw(t1, t0, ctx);
8399
        /* Fall through */
8400
    case 2:
8401
        gen_base_offset_addr(ctx, t0, 29, 4);
8402
        gen_load_gpr(t1, 5);
8403
        op_st_sw(t1, t0, ctx);
8404
        /* Fall through */
8405
    case 1:
8406
        gen_base_offset_addr(ctx, t0, 29, 0);
8407
        gen_load_gpr(t1, 4);
8408
        op_st_sw(t1, t0, ctx);
8409
    }
8410

    
8411
    gen_load_gpr(t0, 29);
8412

    
8413
#define DECR_AND_STORE(reg) do {                \
8414
        tcg_gen_subi_tl(t0, t0, 4);             \
8415
        gen_load_gpr(t1, reg);                  \
8416
        op_st_sw(t1, t0, ctx);                  \
8417
    } while (0)
8418

    
8419
    if (do_ra) {
8420
        DECR_AND_STORE(31);
8421
    }
8422

    
8423
    switch (xsregs) {
8424
    case 7:
8425
        DECR_AND_STORE(30);
8426
        /* Fall through */
8427
    case 6:
8428
        DECR_AND_STORE(23);
8429
        /* Fall through */
8430
    case 5:
8431
        DECR_AND_STORE(22);
8432
        /* Fall through */
8433
    case 4:
8434
        DECR_AND_STORE(21);
8435
        /* Fall through */
8436
    case 3:
8437
        DECR_AND_STORE(20);
8438
        /* Fall through */
8439
    case 2:
8440
        DECR_AND_STORE(19);
8441
        /* Fall through */
8442
    case 1:
8443
        DECR_AND_STORE(18);
8444
    }
8445

    
8446
    if (do_s1) {
8447
        DECR_AND_STORE(17);
8448
    }
8449
    if (do_s0) {
8450
        DECR_AND_STORE(16);
8451
    }
8452

    
8453
    switch (aregs) {
8454
    case 0:
8455
    case 4:
8456
    case 8:
8457
    case 12:
8458
    case 14:
8459
        astatic = 0;
8460
        break;
8461
    case 1:
8462
    case 5:
8463
    case 9:
8464
    case 13:
8465
        astatic = 1;
8466
        break;
8467
    case 2:
8468
    case 6:
8469
    case 10:
8470
        astatic = 2;
8471
        break;
8472
    case 3:
8473
    case 7:
8474
        astatic = 3;
8475
        break;
8476
    case 11:
8477
        astatic = 4;
8478
        break;
8479
    default:
8480
        generate_exception(ctx, EXCP_RI);
8481
        return;
8482
    }
8483

    
8484
    if (astatic > 0) {
8485
        DECR_AND_STORE(7);
8486
        if (astatic > 1) {
8487
            DECR_AND_STORE(6);
8488
            if (astatic > 2) {
8489
                DECR_AND_STORE(5);
8490
                if (astatic > 3) {
8491
                    DECR_AND_STORE(4);
8492
                }
8493
            }
8494
        }
8495
    }
8496
#undef DECR_AND_STORE
8497

    
8498
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8499
    tcg_temp_free(t0);
8500
    tcg_temp_free(t1);
8501
}
8502

    
8503
static void gen_mips16_restore (DisasContext *ctx,
8504
                                int xsregs, int aregs,
8505
                                int do_ra, int do_s0, int do_s1,
8506
                                int framesize)
8507
{
8508
    int astatic;
8509
    TCGv t0 = tcg_temp_new();
8510
    TCGv t1 = tcg_temp_new();
8511

    
8512
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8513

    
8514
#define DECR_AND_LOAD(reg) do {                 \
8515
        tcg_gen_subi_tl(t0, t0, 4);             \
8516
        op_ld_lw(t1, t0, ctx);                  \
8517
        gen_store_gpr(t1, reg);                 \
8518
    } while (0)
8519

    
8520
    if (do_ra) {
8521
        DECR_AND_LOAD(31);
8522
    }
8523

    
8524
    switch (xsregs) {
8525
    case 7:
8526
        DECR_AND_LOAD(30);
8527
        /* Fall through */
8528
    case 6:
8529
        DECR_AND_LOAD(23);
8530
        /* Fall through */
8531
    case 5:
8532
        DECR_AND_LOAD(22);
8533
        /* Fall through */
8534
    case 4:
8535
        DECR_AND_LOAD(21);
8536
        /* Fall through */
8537
    case 3:
8538
        DECR_AND_LOAD(20);
8539
        /* Fall through */
8540
    case 2:
8541
        DECR_AND_LOAD(19);
8542
        /* Fall through */
8543
    case 1:
8544
        DECR_AND_LOAD(18);
8545
    }
8546

    
8547
    if (do_s1) {
8548
        DECR_AND_LOAD(17);
8549
    }
8550
    if (do_s0) {
8551
        DECR_AND_LOAD(16);
8552
    }
8553

    
8554
    switch (aregs) {
8555
    case 0:
8556
    case 4:
8557
    case 8:
8558
    case 12:
8559
    case 14:
8560
        astatic = 0;
8561
        break;
8562
    case 1:
8563
    case 5:
8564
    case 9:
8565
    case 13:
8566
        astatic = 1;
8567
        break;
8568
    case 2:
8569
    case 6:
8570
    case 10:
8571
        astatic = 2;
8572
        break;
8573
    case 3:
8574
    case 7:
8575
        astatic = 3;
8576
        break;
8577
    case 11:
8578
        astatic = 4;
8579
        break;
8580
    default:
8581
        generate_exception(ctx, EXCP_RI);
8582
        return;
8583
    }
8584

    
8585
    if (astatic > 0) {
8586
        DECR_AND_LOAD(7);
8587
        if (astatic > 1) {
8588
            DECR_AND_LOAD(6);
8589
            if (astatic > 2) {
8590
                DECR_AND_LOAD(5);
8591
                if (astatic > 3) {
8592
                    DECR_AND_LOAD(4);
8593
                }
8594
            }
8595
        }
8596
    }
8597
#undef DECR_AND_LOAD
8598

    
8599
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8600
    tcg_temp_free(t0);
8601
    tcg_temp_free(t1);
8602
}
8603

    
8604
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8605
                         int is_64_bit, int extended)
8606
{
8607
    TCGv t0;
8608

    
8609
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8610
        generate_exception(ctx, EXCP_RI);
8611
        return;
8612
    }
8613

    
8614
    t0 = tcg_temp_new();
8615

    
8616
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8617
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8618
    if (!is_64_bit) {
8619
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8620
    }
8621

    
8622
    tcg_temp_free(t0);
8623
}
8624

    
8625
#if defined(TARGET_MIPS64)
8626
static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
8627
                               int ry, int funct, int16_t offset,
8628
                               int extended)
8629
{
8630
    switch (funct) {
8631
    case I64_LDSP:
8632
        check_mips_64(ctx);
8633
        offset = extended ? offset : offset << 3;
8634
        gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8635
        break;
8636
    case I64_SDSP:
8637
        check_mips_64(ctx);
8638
        offset = extended ? offset : offset << 3;
8639
        gen_st(ctx, OPC_SD, ry, 29, offset);
8640
        break;
8641
    case I64_SDRASP:
8642
        check_mips_64(ctx);
8643
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8644
        gen_st(ctx, OPC_SD, 31, 29, offset);
8645
        break;
8646
    case I64_DADJSP:
8647
        check_mips_64(ctx);
8648
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8649
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8650
        break;
8651
    case I64_LDPC:
8652
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8653
            generate_exception(ctx, EXCP_RI);
8654
        } else {
8655
            offset = extended ? offset : offset << 3;
8656
            gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8657
        }
8658
        break;
8659
    case I64_DADDIU5:
8660
        check_mips_64(ctx);
8661
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8662
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8663
        break;
8664
    case I64_DADDIUPC:
8665
        check_mips_64(ctx);
8666
        offset = extended ? offset : offset << 2;
8667
        gen_addiupc(ctx, ry, offset, 1, extended);
8668
        break;
8669
    case I64_DADDIUSP:
8670
        check_mips_64(ctx);
8671
        offset = extended ? offset : offset << 2;
8672
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8673
        break;
8674
    }
8675
}
8676
#endif
8677

    
8678
static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
8679
                                       int *is_branch)
8680
{
8681
    int extend = lduw_code(ctx->pc + 2);
8682
    int op, rx, ry, funct, sa;
8683
    int16_t imm, offset;
8684

    
8685
    ctx->opcode = (ctx->opcode << 16) | extend;
8686
    op = (ctx->opcode >> 11) & 0x1f;
8687
    sa = (ctx->opcode >> 22) & 0x1f;
8688
    funct = (ctx->opcode >> 8) & 0x7;
8689
    rx = xlat((ctx->opcode >> 8) & 0x7);
8690
    ry = xlat((ctx->opcode >> 5) & 0x7);
8691
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8692
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8693
                              | (ctx->opcode & 0x1f));
8694

    
8695
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8696
       counterparts.  */
8697
    switch (op) {
8698
    case M16_OPC_ADDIUSP:
8699
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8700
        break;
8701
    case M16_OPC_ADDIUPC:
8702
        gen_addiupc(ctx, rx, imm, 0, 1);
8703
        break;
8704
    case M16_OPC_B:
8705
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8706
        /* No delay slot, so just process as a normal instruction */
8707
        break;
8708
    case M16_OPC_BEQZ:
8709
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8710
        /* No delay slot, so just process as a normal instruction */
8711
        break;
8712
    case M16_OPC_BNEQZ:
8713
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8714
        /* No delay slot, so just process as a normal instruction */
8715
        break;
8716
    case M16_OPC_SHIFT:
8717
        switch (ctx->opcode & 0x3) {
8718
        case 0x0:
8719
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8720
            break;
8721
        case 0x1:
8722
#if defined(TARGET_MIPS64)
8723
            check_mips_64(ctx);
8724
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8725
#else
8726
            generate_exception(ctx, EXCP_RI);
8727
#endif
8728
            break;
8729
        case 0x2:
8730
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8731
            break;
8732
        case 0x3:
8733
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8734
            break;
8735
        }
8736
        break;
8737
#if defined(TARGET_MIPS64)
8738
    case M16_OPC_LD:
8739
            check_mips_64(ctx);
8740
        gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8741
        break;
8742
#endif
8743
    case M16_OPC_RRIA:
8744
        imm = ctx->opcode & 0xf;
8745
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8746
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8747
        imm = (int16_t) (imm << 1) >> 1;
8748
        if ((ctx->opcode >> 4) & 0x1) {
8749
#if defined(TARGET_MIPS64)
8750
            check_mips_64(ctx);
8751
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8752
#else
8753
            generate_exception(ctx, EXCP_RI);
8754
#endif
8755
        } else {
8756
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8757
        }
8758
        break;
8759
    case M16_OPC_ADDIU8:
8760
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8761
        break;
8762
    case M16_OPC_SLTI:
8763
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8764
        break;
8765
    case M16_OPC_SLTIU:
8766
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8767
        break;
8768
    case M16_OPC_I8:
8769
        switch (funct) {
8770
        case I8_BTEQZ:
8771
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8772
            break;
8773
        case I8_BTNEZ:
8774
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8775
            break;
8776
        case I8_SWRASP:
8777
            gen_st(ctx, OPC_SW, 31, 29, imm);
8778
            break;
8779
        case I8_ADJSP:
8780
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8781
            break;
8782
        case I8_SVRS:
8783
            {
8784
                int xsregs = (ctx->opcode >> 24) & 0x7;
8785
                int aregs = (ctx->opcode >> 16) & 0xf;
8786
                int do_ra = (ctx->opcode >> 6) & 0x1;
8787
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8788
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8789
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8790
                                 | (ctx->opcode & 0xf)) << 3;
8791

    
8792
                if (ctx->opcode & (1 << 7)) {
8793
                    gen_mips16_save(ctx, xsregs, aregs,
8794
                                    do_ra, do_s0, do_s1,
8795
                                    framesize);
8796
                } else {
8797
                    gen_mips16_restore(ctx, xsregs, aregs,
8798
                                       do_ra, do_s0, do_s1,
8799
                                       framesize);
8800
                }
8801
            }
8802
            break;
8803
        default:
8804
            generate_exception(ctx, EXCP_RI);
8805
            break;
8806
        }
8807
        break;
8808
    case M16_OPC_LI:
8809
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8810
        break;
8811
    case M16_OPC_CMPI:
8812
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8813
        break;
8814
#if defined(TARGET_MIPS64)
8815
    case M16_OPC_SD:
8816
        gen_st(ctx, OPC_SD, ry, rx, offset);
8817
        break;
8818
#endif
8819
    case M16_OPC_LB:
8820
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8821
        break;
8822
    case M16_OPC_LH:
8823
        gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8824
        break;
8825
    case M16_OPC_LWSP:
8826
        gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8827
        break;
8828
    case M16_OPC_LW:
8829
        gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8830
        break;
8831
    case M16_OPC_LBU:
8832
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8833
        break;
8834
    case M16_OPC_LHU:
8835
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8836
        break;
8837
    case M16_OPC_LWPC:
8838
        gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8839
        break;
8840
#if defined(TARGET_MIPS64)
8841
    case M16_OPC_LWU:
8842
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8843
        break;
8844
#endif
8845
    case M16_OPC_SB:
8846
        gen_st(ctx, OPC_SB, ry, rx, offset);
8847
        break;
8848
    case M16_OPC_SH:
8849
        gen_st(ctx, OPC_SH, ry, rx, offset);
8850
        break;
8851
    case M16_OPC_SWSP:
8852
        gen_st(ctx, OPC_SW, rx, 29, offset);
8853
        break;
8854
    case M16_OPC_SW:
8855
        gen_st(ctx, OPC_SW, ry, rx, offset);
8856
        break;
8857
#if defined(TARGET_MIPS64)
8858
    case M16_OPC_I64:
8859
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8860
        break;
8861
#endif
8862
    default:
8863
        generate_exception(ctx, EXCP_RI);
8864
        break;
8865
    }
8866

    
8867
    return 4;
8868
}
8869

    
8870
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
8871
                              int *is_branch)
8872
{
8873
    int rx, ry;
8874
    int sa;
8875
    int op, cnvt_op, op1, offset;
8876
    int funct;
8877
    int n_bytes;
8878

    
8879
    op = (ctx->opcode >> 11) & 0x1f;
8880
    sa = (ctx->opcode >> 2) & 0x7;
8881
    sa = sa == 0 ? 8 : sa;
8882
    rx = xlat((ctx->opcode >> 8) & 0x7);
8883
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8884
    ry = xlat((ctx->opcode >> 5) & 0x7);
8885
    op1 = offset = ctx->opcode & 0x1f;
8886

    
8887
    n_bytes = 2;
8888

    
8889
    switch (op) {
8890
    case M16_OPC_ADDIUSP:
8891
        {
8892
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8893

    
8894
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8895
        }
8896
        break;
8897
    case M16_OPC_ADDIUPC:
8898
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8899
        break;
8900
    case M16_OPC_B:
8901
        offset = (ctx->opcode & 0x7ff) << 1;
8902
        offset = (int16_t)(offset << 4) >> 4;
8903
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8904
        /* No delay slot, so just process as a normal instruction */
8905
        break;
8906
    case M16_OPC_JAL:
8907
        offset = lduw_code(ctx->pc + 2);
8908
        offset = (((ctx->opcode & 0x1f) << 21)
8909
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8910
                  | offset) << 2;
8911
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8912
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8913
        n_bytes = 4;
8914
        *is_branch = 1;
8915
        break;
8916
    case M16_OPC_BEQZ:
8917
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8918
        /* No delay slot, so just process as a normal instruction */
8919
        break;
8920
    case M16_OPC_BNEQZ:
8921
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8922
        /* No delay slot, so just process as a normal instruction */
8923
        break;
8924
    case M16_OPC_SHIFT:
8925
        switch (ctx->opcode & 0x3) {
8926
        case 0x0:
8927
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8928
            break;
8929
        case 0x1:
8930
#if defined(TARGET_MIPS64)
8931
            check_mips_64(ctx);
8932
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8933
#else
8934
            generate_exception(ctx, EXCP_RI);
8935
#endif
8936
            break;
8937
        case 0x2:
8938
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8939
            break;
8940
        case 0x3:
8941
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8942
            break;
8943
        }
8944
        break;
8945
#if defined(TARGET_MIPS64)
8946
    case M16_OPC_LD:
8947
        check_mips_64(ctx);
8948
        gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8949
        break;
8950
#endif
8951
    case M16_OPC_RRIA:
8952
        {
8953
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8954

    
8955
            if ((ctx->opcode >> 4) & 1) {
8956
#if defined(TARGET_MIPS64)
8957
                check_mips_64(ctx);
8958
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8959
#else
8960
                generate_exception(ctx, EXCP_RI);
8961
#endif
8962
            } else {
8963
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8964
            }
8965
        }
8966
        break;
8967
    case M16_OPC_ADDIU8:
8968
        {
8969
            int16_t imm = (int8_t) ctx->opcode;
8970

    
8971
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8972
        }
8973
        break;
8974
    case M16_OPC_SLTI:
8975
        {
8976
            int16_t imm = (uint8_t) ctx->opcode;
8977

    
8978
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8979
        }
8980
        break;
8981
    case M16_OPC_SLTIU:
8982
        {
8983
            int16_t imm = (uint8_t) ctx->opcode;
8984

    
8985
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8986
        }
8987
        break;
8988
    case M16_OPC_I8:
8989
        {
8990
            int reg32;
8991

    
8992
            funct = (ctx->opcode >> 8) & 0x7;
8993
            switch (funct) {
8994
            case I8_BTEQZ:
8995
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8996
                                   ((int8_t)ctx->opcode) << 1);
8997
                break;
8998
            case I8_BTNEZ:
8999
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9000
                                   ((int8_t)ctx->opcode) << 1);
9001
                break;
9002
            case I8_SWRASP:
9003
                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9004
                break;
9005
            case I8_ADJSP:
9006
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9007
                              ((int8_t)ctx->opcode) << 3);
9008
                break;
9009
            case I8_SVRS:
9010
                {
9011
                    int do_ra = ctx->opcode & (1 << 6);
9012
                    int do_s0 = ctx->opcode & (1 << 5);
9013
                    int do_s1 = ctx->opcode & (1 << 4);
9014
                    int framesize = ctx->opcode & 0xf;
9015

    
9016
                    if (framesize == 0) {
9017
                        framesize = 128;
9018
                    } else {
9019
                        framesize = framesize << 3;
9020
                    }
9021

    
9022
                    if (ctx->opcode & (1 << 7)) {
9023
                        gen_mips16_save(ctx, 0, 0,
9024
                                        do_ra, do_s0, do_s1, framesize);
9025
                    } else {
9026
                        gen_mips16_restore(ctx, 0, 0,
9027
                                           do_ra, do_s0, do_s1, framesize);
9028
                    }
9029
                }
9030
                break;
9031
            case I8_MOV32R:
9032
                {
9033
                    int rz = xlat(ctx->opcode & 0x7);
9034

    
9035
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9036
                        ((ctx->opcode >> 5) & 0x7);
9037
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9038
                }
9039
                break;
9040
            case I8_MOVR32:
9041
                reg32 = ctx->opcode & 0x1f;
9042
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9043
                break;
9044
            default:
9045
                generate_exception(ctx, EXCP_RI);
9046
                break;
9047
            }
9048
        }
9049
        break;
9050
    case M16_OPC_LI:
9051
        {
9052
            int16_t imm = (uint8_t) ctx->opcode;
9053

    
9054
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9055
        }
9056
        break;
9057
    case M16_OPC_CMPI:
9058
        {
9059
            int16_t imm = (uint8_t) ctx->opcode;
9060

    
9061
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
9062
        }
9063
        break;
9064
#if defined(TARGET_MIPS64)
9065
    case M16_OPC_SD:
9066
        check_mips_64(ctx);
9067
        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9068
        break;
9069
#endif
9070
    case M16_OPC_LB:
9071
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9072
        break;
9073
    case M16_OPC_LH:
9074
        gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9075
        break;
9076
    case M16_OPC_LWSP:
9077
        gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9078
        break;
9079
    case M16_OPC_LW:
9080
        gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9081
        break;
9082
    case M16_OPC_LBU:
9083
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9084
        break;
9085
    case M16_OPC_LHU:
9086
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9087
        break;
9088
    case M16_OPC_LWPC:
9089
        gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9090
        break;
9091
#if defined (TARGET_MIPS64)
9092
    case M16_OPC_LWU:
9093
        check_mips_64(ctx);
9094
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9095
        break;
9096
#endif
9097
    case M16_OPC_SB:
9098
        gen_st(ctx, OPC_SB, ry, rx, offset);
9099
        break;
9100
    case M16_OPC_SH:
9101
        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9102
        break;
9103
    case M16_OPC_SWSP:
9104
        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9105
        break;
9106
    case M16_OPC_SW:
9107
        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9108
        break;
9109
    case M16_OPC_RRR:
9110
        {
9111
            int rz = xlat((ctx->opcode >> 2) & 0x7);
9112
            int mips32_op;
9113

    
9114
            switch (ctx->opcode & 0x3) {
9115
            case RRR_ADDU:
9116
                mips32_op = OPC_ADDU;
9117
                break;
9118
            case RRR_SUBU:
9119
                mips32_op = OPC_SUBU;
9120
                break;
9121
#if defined(TARGET_MIPS64)
9122
            case RRR_DADDU:
9123
                mips32_op = OPC_DADDU;
9124
                check_mips_64(ctx);
9125
                break;
9126
            case RRR_DSUBU:
9127
                mips32_op = OPC_DSUBU;
9128
                check_mips_64(ctx);
9129
                break;
9130
#endif
9131
            default:
9132
                generate_exception(ctx, EXCP_RI);
9133
                goto done;
9134
            }
9135

    
9136
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
9137
        done:
9138
            ;
9139
        }
9140
        break;
9141
    case M16_OPC_RR:
9142
        switch (op1) {
9143
        case RR_JR:
9144
            {
9145
                int nd = (ctx->opcode >> 7) & 0x1;
9146
                int link = (ctx->opcode >> 6) & 0x1;
9147
                int ra = (ctx->opcode >> 5) & 0x1;
9148

    
9149
                if (link) {
9150
                    op = nd ? OPC_JALRC : OPC_JALRS;
9151
                } else {
9152
                    op = OPC_JR;
9153
                }
9154

    
9155
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9156
                if (!nd) {
9157
                    *is_branch = 1;
9158
                }
9159
            }
9160
            break;
9161
        case RR_SDBBP:
9162
            /* XXX: not clear which exception should be raised
9163
             *      when in debug mode...
9164
             */
9165
            check_insn(env, ctx, ISA_MIPS32);
9166
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9167
                generate_exception(ctx, EXCP_DBp);
9168
            } else {
9169
                generate_exception(ctx, EXCP_DBp);
9170
            }
9171
            break;
9172
        case RR_SLT:
9173
            gen_slt(env, OPC_SLT, 24, rx, ry);
9174
            break;
9175
        case RR_SLTU:
9176
            gen_slt(env, OPC_SLTU, 24, rx, ry);
9177
            break;
9178
        case RR_BREAK:
9179
            generate_exception(ctx, EXCP_BREAK);
9180
            break;
9181
        case RR_SLLV:
9182
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9183
            break;
9184
        case RR_SRLV:
9185
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9186
            break;
9187
        case RR_SRAV:
9188
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9189
            break;
9190
#if defined (TARGET_MIPS64)
9191
        case RR_DSRL:
9192
            check_mips_64(ctx);
9193
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9194
            break;
9195
#endif
9196
        case RR_CMP:
9197
            gen_logic(env, OPC_XOR, 24, rx, ry);
9198
            break;
9199
        case RR_NEG:
9200
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9201
            break;
9202
        case RR_AND:
9203
            gen_logic(env, OPC_AND, rx, rx, ry);
9204
            break;
9205
        case RR_OR:
9206
            gen_logic(env, OPC_OR, rx, rx, ry);
9207
            break;
9208
        case RR_XOR:
9209
            gen_logic(env, OPC_XOR, rx, rx, ry);
9210
            break;
9211
        case RR_NOT:
9212
            gen_logic(env, OPC_NOR, rx, ry, 0);
9213
            break;
9214
        case RR_MFHI:
9215
            gen_HILO(ctx, OPC_MFHI, rx);
9216
            break;
9217
        case RR_CNVT:
9218
            switch (cnvt_op) {
9219
            case RR_RY_CNVT_ZEB:
9220
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9221
                break;
9222
            case RR_RY_CNVT_ZEH:
9223
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9224
                break;
9225
            case RR_RY_CNVT_SEB:
9226
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9227
                break;
9228
            case RR_RY_CNVT_SEH:
9229
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9230
                break;
9231
#if defined (TARGET_MIPS64)
9232
            case RR_RY_CNVT_ZEW:
9233
                check_mips_64(ctx);
9234
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9235
                break;
9236
            case RR_RY_CNVT_SEW:
9237
                check_mips_64(ctx);
9238
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9239
                break;
9240
#endif
9241
            default:
9242
                generate_exception(ctx, EXCP_RI);
9243
                break;
9244
            }
9245
            break;
9246
        case RR_MFLO:
9247
            gen_HILO(ctx, OPC_MFLO, rx);
9248
            break;
9249
#if defined (TARGET_MIPS64)
9250
        case RR_DSRA:
9251
            check_mips_64(ctx);
9252
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9253
            break;
9254
        case RR_DSLLV:
9255
            check_mips_64(ctx);
9256
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9257
            break;
9258
        case RR_DSRLV:
9259
            check_mips_64(ctx);
9260
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9261
            break;
9262
        case RR_DSRAV:
9263
            check_mips_64(ctx);
9264
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9265
            break;
9266
#endif
9267
        case RR_MULT:
9268
            gen_muldiv(ctx, OPC_MULT, rx, ry);
9269
            break;
9270
        case RR_MULTU:
9271
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
9272
            break;
9273
        case RR_DIV:
9274
            gen_muldiv(ctx, OPC_DIV, rx, ry);
9275
            break;
9276
        case RR_DIVU:
9277
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
9278
            break;
9279
#if defined (TARGET_MIPS64)
9280
        case RR_DMULT:
9281
            check_mips_64(ctx);
9282
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
9283
            break;
9284
        case RR_DMULTU:
9285
            check_mips_64(ctx);
9286
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9287
            break;
9288
        case RR_DDIV:
9289
            check_mips_64(ctx);
9290
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
9291
            break;
9292
        case RR_DDIVU:
9293
            check_mips_64(ctx);
9294
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9295
            break;
9296
#endif
9297
        default:
9298
            generate_exception(ctx, EXCP_RI);
9299
            break;
9300
        }
9301
        break;
9302
    case M16_OPC_EXTEND:
9303
        decode_extended_mips16_opc(env, ctx, is_branch);
9304
        n_bytes = 4;
9305
        break;
9306
#if defined(TARGET_MIPS64)
9307
    case M16_OPC_I64:
9308
        funct = (ctx->opcode >> 8) & 0x7;
9309
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9310
        break;
9311
#endif
9312
    default:
9313
        generate_exception(ctx, EXCP_RI);
9314
        break;
9315
    }
9316

    
9317
    return n_bytes;
9318
}
9319

    
9320
/* microMIPS extension to MIPS32 */
9321

    
9322
/* microMIPS32 major opcodes */
9323

    
9324
enum {
9325
    POOL32A = 0x00,
9326
    POOL16A = 0x01,
9327
    LBU16 = 0x02,
9328
    MOVE16 = 0x03,
9329
    ADDI32 = 0x04,
9330
    LBU32 = 0x05,
9331
    SB32 = 0x06,
9332
    LB32 = 0x07,
9333

    
9334
    POOL32B = 0x08,
9335
    POOL16B = 0x09,
9336
    LHU16 = 0x0a,
9337
    ANDI16 = 0x0b,
9338
    ADDIU32 = 0x0c,
9339
    LHU32 = 0x0d,
9340
    SH32 = 0x0e,
9341
    LH32 = 0x0f,
9342

    
9343
    POOL32I = 0x10,
9344
    POOL16C = 0x11,
9345
    LWSP16 = 0x12,
9346
    POOL16D = 0x13,
9347
    ORI32 = 0x14,
9348
    POOL32F = 0x15,
9349
    POOL32S = 0x16,
9350
    DADDIU32 = 0x17,
9351

    
9352
    POOL32C = 0x18,
9353
    LWGP16 = 0x19,
9354
    LW16 = 0x1a,
9355
    POOL16E = 0x1b,
9356
    XORI32 = 0x1c,
9357
    JALS32 = 0x1d,
9358
    ADDIUPC = 0x1e,
9359
    POOL48A = 0x1f,
9360

    
9361
    /* 0x20 is reserved */
9362
    RES_20 = 0x20,
9363
    POOL16F = 0x21,
9364
    SB16 = 0x22,
9365
    BEQZ16 = 0x23,
9366
    SLTI32 = 0x24,
9367
    BEQ32 = 0x25,
9368
    SWC132 = 0x26,
9369
    LWC132 = 0x27,
9370

    
9371
    /* 0x28 and 0x29 are reserved */
9372
    RES_28 = 0x28,
9373
    RES_29 = 0x29,
9374
    SH16 = 0x2a,
9375
    BNEZ16 = 0x2b,
9376
    SLTIU32 = 0x2c,
9377
    BNE32 = 0x2d,
9378
    SDC132 = 0x2e,
9379
    LDC132 = 0x2f,
9380

    
9381
    /* 0x30 and 0x31 are reserved */
9382
    RES_30 = 0x30,
9383
    RES_31 = 0x31,
9384
    SWSP16 = 0x32,
9385
    B16 = 0x33,
9386
    ANDI32 = 0x34,
9387
    J32 = 0x35,
9388
    SD32 = 0x36,
9389
    LD32 = 0x37,
9390

    
9391
    /* 0x38 and 0x39 are reserved */
9392
    RES_38 = 0x38,
9393
    RES_39 = 0x39,
9394
    SW16 = 0x3a,
9395
    LI16 = 0x3b,
9396
    JALX32 = 0x3c,
9397
    JAL32 = 0x3d,
9398
    SW32 = 0x3e,
9399
    LW32 = 0x3f
9400
};
9401

    
9402
/* POOL32A encoding of minor opcode field */
9403

    
9404
enum {
9405
    /* These opcodes are distinguished only by bits 9..6; those bits are
9406
     * what are recorded below. */
9407
    SLL32 = 0x0,
9408
    SRL32 = 0x1,
9409
    SRA = 0x2,
9410
    ROTR = 0x3,
9411

    
9412
    SLLV = 0x0,
9413
    SRLV = 0x1,
9414
    SRAV = 0x2,
9415
    ROTRV = 0x3,
9416
    ADD = 0x4,
9417
    ADDU32 = 0x5,
9418
    SUB = 0x6,
9419
    SUBU32 = 0x7,
9420
    MUL = 0x8,
9421
    AND = 0x9,
9422
    OR32 = 0xa,
9423
    NOR = 0xb,
9424
    XOR32 = 0xc,
9425
    SLT = 0xd,
9426
    SLTU = 0xe,
9427

    
9428
    MOVN = 0x0,
9429
    MOVZ = 0x1,
9430
    LWXS = 0x4,
9431

    
9432
    /* The following can be distinguished by their lower 6 bits. */
9433
    INS = 0x0c,
9434
    EXT = 0x2c,
9435
    POOL32AXF = 0x3c
9436
};
9437

    
9438
/* POOL32AXF encoding of minor opcode field extension */
9439

    
9440
enum {
9441
    /* bits 11..6 */
9442
    TEQ = 0x00,
9443
    TGE = 0x08,
9444
    TGEU = 0x10,
9445
    TLT = 0x20,
9446
    TLTU = 0x28,
9447
    TNE = 0x30,
9448

    
9449
    MFC0 = 0x03,
9450
    MTC0 = 0x0b,
9451

    
9452
    /* bits 13..12 for 0x01 */
9453
    MFHI_ACC = 0x0,
9454
    MFLO_ACC = 0x1,
9455
    MTHI_ACC = 0x2,
9456
    MTLO_ACC = 0x3,
9457

    
9458
    /* bits 13..12 for 0x2a */
9459
    MADD_ACC = 0x0,
9460
    MADDU_ACC = 0x1,
9461
    MSUB_ACC = 0x2,
9462
    MSUBU_ACC = 0x3,
9463

    
9464
    /* bits 13..12 for 0x32 */
9465
    MULT_ACC = 0x0,
9466
    MULTU_ACC = 0x0,
9467

    
9468
    /* bits 15..12 for 0x2c */
9469
    SEB = 0x2,
9470
    SEH = 0x3,
9471
    CLO = 0x4,
9472
    CLZ = 0x5,
9473
    RDHWR = 0x6,
9474
    WSBH = 0x7,
9475
    MULT = 0x8,
9476
    MULTU = 0x9,
9477
    DIV = 0xa,
9478
    DIVU = 0xb,
9479
    MADD = 0xc,
9480
    MADDU = 0xd,
9481
    MSUB = 0xe,
9482
    MSUBU = 0xf,
9483

    
9484
    /* bits 15..12 for 0x34 */
9485
    MFC2 = 0x4,
9486
    MTC2 = 0x5,
9487
    MFHC2 = 0x8,
9488
    MTHC2 = 0x9,
9489
    CFC2 = 0xc,
9490
    CTC2 = 0xd,
9491

    
9492
    /* bits 15..12 for 0x3c */
9493
    JALR = 0x0,
9494
    JR = 0x0,                   /* alias */
9495
    JALR_HB = 0x1,
9496
    JALRS = 0x4,
9497
    JALRS_HB = 0x5,
9498

    
9499
    /* bits 15..12 for 0x05 */
9500
    RDPGPR = 0xe,
9501
    WRPGPR = 0xf,
9502

    
9503
    /* bits 15..12 for 0x0d */
9504
    TLBP = 0x0,
9505
    TLBR = 0x1,
9506
    TLBWI = 0x2,
9507
    TLBWR = 0x3,
9508
    WAIT = 0x9,
9509
    IRET = 0xd,
9510
    DERET = 0xe,
9511
    ERET = 0xf,
9512

    
9513
    /* bits 15..12 for 0x15 */
9514
    DMT = 0x0,
9515
    DVPE = 0x1,
9516
    EMT = 0x2,
9517
    EVPE = 0x3,
9518

    
9519
    /* bits 15..12 for 0x1d */
9520
    DI = 0x4,
9521
    EI = 0x5,
9522

    
9523
    /* bits 15..12 for 0x2d */
9524
    SYNC = 0x6,
9525
    SYSCALL = 0x8,
9526
    SDBBP = 0xd,
9527

    
9528
    /* bits 15..12 for 0x35 */
9529
    MFHI32 = 0x0,
9530
    MFLO32 = 0x1,
9531
    MTHI32 = 0x2,
9532
    MTLO32 = 0x3,
9533
};
9534

    
9535
/* POOL32B encoding of minor opcode field (bits 15..12) */
9536

    
9537
enum {
9538
    LWC2 = 0x0,
9539
    LWP = 0x1,
9540
    LDP = 0x4,
9541
    LWM32 = 0x5,
9542
    CACHE = 0x6,
9543
    LDM = 0x7,
9544
    SWC2 = 0x8,
9545
    SWP = 0x9,
9546
    SDP = 0xc,
9547
    SWM32 = 0xd,
9548
    SDM = 0xf
9549
};
9550

    
9551
/* POOL32C encoding of minor opcode field (bits 15..12) */
9552

    
9553
enum {
9554
    LWL = 0x0,
9555
    SWL = 0x8,
9556
    LWR = 0x1,
9557
    SWR = 0x9,
9558
    PREF = 0x2,
9559
    /* 0xa is reserved */
9560
    LL = 0x3,
9561
    SC = 0xb,
9562
    LDL = 0x4,
9563
    SDL = 0xc,
9564
    LDR = 0x5,
9565
    SDR = 0xd,
9566
    /* 0x6 is reserved */
9567
    LWU = 0xe,
9568
    LLD = 0x7,
9569
    SCD = 0xf
9570
};
9571

    
9572
/* POOL32F encoding of minor opcode field (bits 5..0) */
9573

    
9574
enum {
9575
    /* These are the bit 7..6 values */
9576
    ADD_FMT = 0x0,
9577
    MOVN_FMT = 0x0,
9578

    
9579
    SUB_FMT = 0x1,
9580
    MOVZ_FMT = 0x1,
9581

    
9582
    MUL_FMT = 0x2,
9583

    
9584
    DIV_FMT = 0x3,
9585

    
9586
    /* These are the bit 8..6 values */
9587
    RSQRT2_FMT = 0x0,
9588
    MOVF_FMT = 0x0,
9589

    
9590
    LWXC1 = 0x1,
9591
    MOVT_FMT = 0x1,
9592

    
9593
    PLL_PS = 0x2,
9594
    SWXC1 = 0x2,
9595

    
9596
    PLU_PS = 0x3,
9597
    LDXC1 = 0x3,
9598

    
9599
    PUL_PS = 0x4,
9600
    SDXC1 = 0x4,
9601
    RECIP2_FMT = 0x4,
9602

    
9603
    PUU_PS = 0x5,
9604
    LUXC1 = 0x5,
9605

    
9606
    CVT_PS_S = 0x6,
9607
    SUXC1 = 0x6,
9608
    ADDR_PS = 0x6,
9609
    PREFX = 0x6,
9610

    
9611
    MULR_PS = 0x7,
9612

    
9613
    MADD_S = 0x01,
9614
    MADD_D = 0x09,
9615
    MADD_PS = 0x11,
9616
    ALNV_PS = 0x19,
9617
    MSUB_S = 0x21,
9618
    MSUB_D = 0x29,
9619
    MSUB_PS = 0x31,
9620

    
9621
    NMADD_S = 0x02,
9622
    NMADD_D = 0x0a,
9623
    NMADD_PS = 0x12,
9624
    NMSUB_S = 0x22,
9625
    NMSUB_D = 0x2a,
9626
    NMSUB_PS = 0x32,
9627

    
9628
    POOL32FXF = 0x3b,
9629

    
9630
    CABS_COND_FMT = 0x1c,              /* MIPS3D */
9631
    C_COND_FMT = 0x3c
9632
};
9633

    
9634
/* POOL32Fxf encoding of minor opcode extension field */
9635

    
9636
enum {
9637
    CVT_L = 0x04,
9638
    RSQRT_FMT = 0x08,
9639
    FLOOR_L = 0x0c,
9640
    CVT_PW_PS = 0x1c,
9641
    CVT_W = 0x24,
9642
    SQRT_FMT = 0x28,
9643
    FLOOR_W = 0x2c,
9644
    CVT_PS_PW = 0x3c,
9645
    CFC1 = 0x40,
9646
    RECIP_FMT = 0x48,
9647
    CEIL_L = 0x4c,
9648
    CTC1 = 0x60,
9649
    CEIL_W = 0x6c,
9650
    MFC1 = 0x80,
9651
    CVT_S_PL = 0x84,
9652
    TRUNC_L = 0x8c,
9653
    MTC1 = 0xa0,
9654
    CVT_S_PU = 0xa4,
9655
    TRUNC_W = 0xac,
9656
    MFHC1 = 0xc0,
9657
    ROUND_L = 0xcc,
9658
    MTHC1 = 0xe0,
9659
    ROUND_W = 0xec,
9660

    
9661
    MOV_FMT = 0x01,
9662
    MOVF = 0x05,
9663
    ABS_FMT = 0x0d,
9664
    RSQRT1_FMT = 0x1d,
9665
    MOVT = 0x25,
9666
    NEG_FMT = 0x2d,
9667
    CVT_D = 0x4d,
9668
    RECIP1_FMT = 0x5d,
9669
    CVT_S = 0x6d
9670
};
9671

    
9672
/* POOL32I encoding of minor opcode field (bits 25..21) */
9673

    
9674
enum {
9675
    BLTZ = 0x00,
9676
    BLTZAL = 0x01,
9677
    BGEZ = 0x02,
9678
    BGEZAL = 0x03,
9679
    BLEZ = 0x04,
9680
    BNEZC = 0x05,
9681
    BGTZ = 0x06,
9682
    BEQZC = 0x07,
9683
    TLTI = 0x08,
9684
    TGEI = 0x09,
9685
    TLTIU = 0x0a,
9686
    TGEIU = 0x0b,
9687
    TNEI = 0x0c,
9688
    LUI = 0x0d,
9689
    TEQI = 0x0e,
9690
    SYNCI = 0x10,
9691
    BLTZALS = 0x11,
9692
    BGEZALS = 0x13,
9693
    BC2F = 0x14,
9694
    BC2T = 0x15,
9695
    BPOSGE64 = 0x1a,
9696
    BPOSGE32 = 0x1b,
9697
    /* These overlap and are distinguished by bit16 of the instruction */
9698
    BC1F = 0x1c,
9699
    BC1T = 0x1d,
9700
    BC1ANY2F = 0x1c,
9701
    BC1ANY2T = 0x1d,
9702
    BC1ANY4F = 0x1e,
9703
    BC1ANY4T = 0x1f
9704
};
9705

    
9706
/* POOL16A encoding of minor opcode field */
9707

    
9708
enum {
9709
    ADDU16 = 0x0,
9710
    SUBU16 = 0x1
9711
};
9712

    
9713
/* POOL16B encoding of minor opcode field */
9714

    
9715
enum {
9716
    SLL16 = 0x0,
9717
    SRL16 = 0x1
9718
};
9719

    
9720
/* POOL16C encoding of minor opcode field */
9721

    
9722
enum {
9723
    NOT16 = 0x00,
9724
    XOR16 = 0x04,
9725
    AND16 = 0x08,
9726
    OR16 = 0x0c,
9727
    LWM16 = 0x10,
9728
    SWM16 = 0x14,
9729
    JR16 = 0x18,
9730
    JRC16 = 0x1a,
9731
    JALR16 = 0x1c,
9732
    JALR16S = 0x1e,
9733
    MFHI16 = 0x20,
9734
    MFLO16 = 0x24,
9735
    BREAK16 = 0x28,
9736
    SDBBP16 = 0x2c,
9737
    JRADDIUSP = 0x30
9738
};
9739

    
9740
/* POOL16D encoding of minor opcode field */
9741

    
9742
enum {
9743
    ADDIUS5 = 0x0,
9744
    ADDIUSP = 0x1
9745
};
9746

    
9747
/* POOL16E encoding of minor opcode field */
9748

    
9749
enum {
9750
    ADDIUR2 = 0x0,
9751
    ADDIUR1SP = 0x1
9752
};
9753

    
9754
static int mmreg (int r)
9755
{
9756
    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9757

    
9758
    return map[r];
9759
}
9760

    
9761
/* Used for 16-bit store instructions.  */
9762
static int mmreg2 (int r)
9763
{
9764
    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9765

    
9766
    return map[r];
9767
}
9768

    
9769
#define uMIPS_RD(op) ((op >> 7) & 0x7)
9770
#define uMIPS_RS(op) ((op >> 4) & 0x7)
9771
#define uMIPS_RS2(op) uMIPS_RS(op)
9772
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
9773
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9774
#define uMIPS_RS5(op) (op & 0x1f)
9775

    
9776
/* Signed immediate */
9777
#define SIMM(op, start, width)                                          \
9778
    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
9779
               << (32-width))                                           \
9780
     >> (32-width))
9781
/* Zero-extended immediate */
9782
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9783

    
9784
static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
9785
{
9786
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9787

    
9788
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9789
}
9790

    
9791
static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
9792
{
9793
    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9794
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9795
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9796

    
9797
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9798
}
9799

    
9800
static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
9801
{
9802
    int encoded = ZIMM(ctx->opcode, 1, 9);
9803
    int decoded;
9804

    
9805
    if (encoded <= 1) {
9806
        decoded = 256 + encoded;
9807
    } else if (encoded <= 255) {
9808
        decoded = encoded;
9809
    } else if (encoded <= 509) {
9810
        decoded = encoded - 512;
9811
    } else {
9812
        decoded = encoded - 768;
9813
    }
9814

    
9815
    gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9816
}
9817

    
9818
static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
9819
{
9820
    int imm = SIMM(ctx->opcode, 1, 4);
9821
    int rd = (ctx->opcode >> 5) & 0x1f;
9822

    
9823
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9824
}
9825

    
9826
static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
9827
{
9828
    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9829
                                 31, 32, 63, 64, 255, 32768, 65535 };
9830
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9831
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9832
    int encoded = ZIMM(ctx->opcode, 0, 4);
9833

    
9834
    gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9835
}
9836

    
9837
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9838
                               int base, int16_t offset)
9839
{
9840
    TCGv t0, t1;
9841
    TCGv_i32 t2;
9842

    
9843
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9844
        generate_exception(ctx, EXCP_RI);
9845
        return;
9846
    }
9847

    
9848
    t0 = tcg_temp_new();
9849

    
9850
    gen_base_offset_addr(ctx, t0, base, offset);
9851

    
9852
    t1 = tcg_const_tl(reglist);
9853
    t2 = tcg_const_i32(ctx->mem_idx);
9854

    
9855
    save_cpu_state(ctx, 1);
9856
    switch (opc) {
9857
    case LWM32:
9858
        gen_helper_lwm(t0, t1, t2);
9859
        break;
9860
    case SWM32:
9861
        gen_helper_swm(t0, t1, t2);
9862
        break;
9863
#ifdef TARGET_MIPS64
9864
    case LDM:
9865
        gen_helper_ldm(t0, t1, t2);
9866
        break;
9867
    case SDM:
9868
        gen_helper_sdm(t0, t1, t2);
9869
        break;
9870
#endif
9871
    }
9872
    MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9873
    tcg_temp_free(t0);
9874
    tcg_temp_free(t1);
9875
    tcg_temp_free_i32(t2);
9876
}
9877

    
9878

    
9879
static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
9880
{
9881
    int rd = mmreg((ctx->opcode >> 3) & 0x7);
9882
    int rs = mmreg(ctx->opcode & 0x7);
9883
    int opc;
9884

    
9885
    switch (((ctx->opcode) >> 4) & 0x3f) {
9886
    case NOT16 + 0:
9887
    case NOT16 + 1:
9888
    case NOT16 + 2:
9889
    case NOT16 + 3:
9890
        gen_logic(env, OPC_NOR, rd, rs, 0);
9891
        break;
9892
    case XOR16 + 0:
9893
    case XOR16 + 1:
9894
    case XOR16 + 2:
9895
    case XOR16 + 3:
9896
        gen_logic(env, OPC_XOR, rd, rd, rs);
9897
        break;
9898
    case AND16 + 0:
9899
    case AND16 + 1:
9900
    case AND16 + 2:
9901
    case AND16 + 3:
9902
        gen_logic(env, OPC_AND, rd, rd, rs);
9903
        break;
9904
    case OR16 + 0:
9905
    case OR16 + 1:
9906
    case OR16 + 2:
9907
    case OR16 + 3:
9908
        gen_logic(env, OPC_OR, rd, rd, rs);
9909
        break;
9910
    case LWM16 + 0:
9911
    case LWM16 + 1:
9912
    case LWM16 + 2:
9913
    case LWM16 + 3:
9914
        {
9915
            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9916
            int offset = ZIMM(ctx->opcode, 0, 4);
9917

    
9918
            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9919
                              29, offset << 2);
9920
        }
9921
        break;
9922
    case SWM16 + 0:
9923
    case SWM16 + 1:
9924
    case SWM16 + 2:
9925
    case SWM16 + 3:
9926
        {
9927
            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9928
            int offset = ZIMM(ctx->opcode, 0, 4);
9929

    
9930
            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9931
                              29, offset << 2);
9932
        }
9933
        break;
9934
    case JR16 + 0:
9935
    case JR16 + 1:
9936
        {
9937
            int reg = ctx->opcode & 0x1f;
9938

    
9939
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9940
        }
9941
        *is_branch = 1;
9942
        break;
9943
    case JRC16 + 0:
9944
    case JRC16 + 1:
9945
        {
9946
            int reg = ctx->opcode & 0x1f;
9947

    
9948
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9949
            /* Let normal delay slot handling in our caller take us
9950
               to the branch target.  */
9951
        }
9952
        break;
9953
    case JALR16 + 0:
9954
    case JALR16 + 1:
9955
        opc = OPC_JALR;
9956
        goto do_jalr;
9957
    case JALR16S + 0:
9958
    case JALR16S + 1:
9959
        opc = OPC_JALRS;
9960
    do_jalr:
9961
        {
9962
            int reg = ctx->opcode & 0x1f;
9963

    
9964
            gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9965
        }
9966
        *is_branch = 1;
9967
        break;
9968
    case MFHI16 + 0:
9969
    case MFHI16 + 1:
9970
        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9971
        break;
9972
    case MFLO16 + 0:
9973
    case MFLO16 + 1:
9974
        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9975
        break;
9976
    case BREAK16:
9977
        generate_exception(ctx, EXCP_BREAK);
9978
        break;
9979
    case SDBBP16:
9980
        /* XXX: not clear which exception should be raised
9981
         *      when in debug mode...
9982
         */
9983
        check_insn(env, ctx, ISA_MIPS32);
9984
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9985
            generate_exception(ctx, EXCP_DBp);
9986
        } else {
9987
            generate_exception(ctx, EXCP_DBp);
9988
        }
9989
        break;
9990
    case JRADDIUSP + 0:
9991
    case JRADDIUSP + 1:
9992
        {
9993
            int imm = ZIMM(ctx->opcode, 0, 5);
9994

    
9995
            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9996
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9997
            /* Let normal delay slot handling in our caller take us
9998
               to the branch target.  */
9999
        }
10000
        break;
10001
    default:
10002
        generate_exception(ctx, EXCP_RI);
10003
        break;
10004
    }
10005
}
10006

    
10007
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10008
{
10009
    TCGv t0 = tcg_temp_new();
10010
    TCGv t1 = tcg_temp_new();
10011

    
10012
    gen_load_gpr(t0, base);
10013

    
10014
    if (index != 0) {
10015
        gen_load_gpr(t1, index);
10016
        tcg_gen_shli_tl(t1, t1, 2);
10017
        gen_op_addr_add(ctx, t0, t1, t0);
10018
    }
10019

    
10020
    save_cpu_state(ctx, 0);
10021
    op_ld_lw(t1, t0, ctx);
10022
    gen_store_gpr(t1, rd);
10023

    
10024
    tcg_temp_free(t0);
10025
    tcg_temp_free(t1);
10026
}
10027

    
10028
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10029
                           int base, int16_t offset)
10030
{
10031
    const char *opn = "ldst_pair";
10032
    TCGv t0, t1;
10033

    
10034
    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
10035
        generate_exception(ctx, EXCP_RI);
10036
        return;
10037
    }
10038

    
10039
    t0 = tcg_temp_new();
10040
    t1 = tcg_temp_new();
10041

    
10042
    gen_base_offset_addr(ctx, t0, base, offset);
10043

    
10044
    switch (opc) {
10045
    case LWP:
10046
        save_cpu_state(ctx, 0);
10047
        op_ld_lw(t1, t0, ctx);
10048
        gen_store_gpr(t1, rd);
10049
        tcg_gen_movi_tl(t1, 4);
10050
        gen_op_addr_add(ctx, t0, t0, t1);
10051
        op_ld_lw(t1, t0, ctx);
10052
        gen_store_gpr(t1, rd+1);
10053
        opn = "lwp";
10054
        break;
10055
    case SWP:
10056
        save_cpu_state(ctx, 0);
10057
        gen_load_gpr(t1, rd);
10058
        op_st_sw(t1, t0, ctx);
10059
        tcg_gen_movi_tl(t1, 4);
10060
        gen_op_addr_add(ctx, t0, t0, t1);
10061
        gen_load_gpr(t1, rd+1);
10062
        op_st_sw(t1, t0, ctx);
10063
        opn = "swp";
10064
        break;
10065
#ifdef TARGET_MIPS64
10066
    case LDP:
10067
        save_cpu_state(ctx, 0);
10068
        op_ld_ld(t1, t0, ctx);
10069
        gen_store_gpr(t1, rd);
10070
        tcg_gen_movi_tl(t1, 8);
10071
        gen_op_addr_add(ctx, t0, t0, t1);
10072
        op_ld_ld(t1, t0, ctx);
10073
        gen_store_gpr(t1, rd+1);
10074
        opn = "ldp";
10075
        break;
10076
    case SDP:
10077
        save_cpu_state(ctx, 0);
10078
        gen_load_gpr(t1, rd);
10079
        op_st_sd(t1, t0, ctx);
10080
        tcg_gen_movi_tl(t1, 8);
10081
        gen_op_addr_add(ctx, t0, t0, t1);
10082
        gen_load_gpr(t1, rd+1);
10083
        op_st_sd(t1, t0, ctx);
10084
        opn = "sdp";
10085
        break;
10086
#endif
10087
    }
10088
    (void)opn; /* avoid a compiler warning */
10089
    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10090
    tcg_temp_free(t0);
10091
    tcg_temp_free(t1);
10092
}
10093

    
10094
static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
10095
                           int *is_branch)
10096
{
10097
    int extension = (ctx->opcode >> 6) & 0x3f;
10098
    int minor = (ctx->opcode >> 12) & 0xf;
10099
    uint32_t mips32_op;
10100

    
10101
    switch (extension) {
10102
    case TEQ:
10103
        mips32_op = OPC_TEQ;
10104
        goto do_trap;
10105
    case TGE:
10106
        mips32_op = OPC_TGE;
10107
        goto do_trap;
10108
    case TGEU:
10109
        mips32_op = OPC_TGEU;
10110
        goto do_trap;
10111
    case TLT:
10112
        mips32_op = OPC_TLT;
10113
        goto do_trap;
10114
    case TLTU:
10115
        mips32_op = OPC_TLTU;
10116
        goto do_trap;
10117
    case TNE:
10118
        mips32_op = OPC_TNE;
10119
    do_trap:
10120
        gen_trap(ctx, mips32_op, rs, rt, -1);
10121
        break;
10122
#ifndef CONFIG_USER_ONLY
10123
    case MFC0:
10124
    case MFC0 + 32:
10125
        check_cp0_enabled(ctx);
10126
        if (rt == 0) {
10127
            /* Treat as NOP. */
10128
            break;
10129
        }
10130
        gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10131
        break;
10132
    case MTC0:
10133
    case MTC0 + 32:
10134
        check_cp0_enabled(ctx);
10135
        {
10136
            TCGv t0 = tcg_temp_new();
10137

    
10138
            gen_load_gpr(t0, rt);
10139
            gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10140
            tcg_temp_free(t0);
10141
        }
10142
        break;
10143
#endif
10144
    case 0x2c:
10145
        switch (minor) {
10146
        case SEB:
10147
            gen_bshfl(ctx, OPC_SEB, rs, rt);
10148
            break;
10149
        case SEH:
10150
            gen_bshfl(ctx, OPC_SEH, rs, rt);
10151
            break;
10152
        case CLO:
10153
            mips32_op = OPC_CLO;
10154
            goto do_cl;
10155
        case CLZ:
10156
            mips32_op = OPC_CLZ;
10157
        do_cl:
10158
            check_insn(env, ctx, ISA_MIPS32);
10159
            gen_cl(ctx, mips32_op, rt, rs);
10160
            break;
10161
        case RDHWR:
10162
            gen_rdhwr(env, ctx, rt, rs);
10163
            break;
10164
        case WSBH:
10165
            gen_bshfl(ctx, OPC_WSBH, rs, rt);
10166
            break;
10167
        case MULT:
10168
            mips32_op = OPC_MULT;
10169
            goto do_muldiv;
10170
        case MULTU:
10171
            mips32_op = OPC_MULTU;
10172
            goto do_muldiv;
10173
        case DIV:
10174
            mips32_op = OPC_DIV;
10175
            goto do_muldiv;
10176
        case DIVU:
10177
            mips32_op = OPC_DIVU;
10178
            goto do_muldiv;
10179
        case MADD:
10180
            mips32_op = OPC_MADD;
10181
            goto do_muldiv;
10182
        case MADDU:
10183
            mips32_op = OPC_MADDU;
10184
            goto do_muldiv;
10185
        case MSUB:
10186
            mips32_op = OPC_MSUB;
10187
            goto do_muldiv;
10188
        case MSUBU:
10189
            mips32_op = OPC_MSUBU;
10190
        do_muldiv:
10191
            check_insn(env, ctx, ISA_MIPS32);
10192
            gen_muldiv(ctx, mips32_op, rs, rt);
10193
            break;
10194
        default:
10195
            goto pool32axf_invalid;
10196
        }
10197
        break;
10198
    case 0x34:
10199
        switch (minor) {
10200
        case MFC2:
10201
        case MTC2:
10202
        case MFHC2:
10203
        case MTHC2:
10204
        case CFC2:
10205
        case CTC2:
10206
            generate_exception_err(ctx, EXCP_CpU, 2);
10207
            break;
10208
        default:
10209
            goto pool32axf_invalid;
10210
        }
10211
        break;
10212
    case 0x3c:
10213
        switch (minor) {
10214
        case JALR:
10215
        case JALR_HB:
10216
            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10217
            *is_branch = 1;
10218
            break;
10219
        case JALRS:
10220
        case JALRS_HB:
10221
            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10222
            *is_branch = 1;
10223
            break;
10224
        default:
10225
            goto pool32axf_invalid;
10226
        }
10227
        break;
10228
    case 0x05:
10229
        switch (minor) {
10230
        case RDPGPR:
10231
            check_cp0_enabled(ctx);
10232
            check_insn(env, ctx, ISA_MIPS32R2);
10233
            gen_load_srsgpr(rt, rs);
10234
            break;
10235
        case WRPGPR:
10236
            check_cp0_enabled(ctx);
10237
            check_insn(env, ctx, ISA_MIPS32R2);
10238
            gen_store_srsgpr(rt, rs);
10239
            break;
10240
        default:
10241
            goto pool32axf_invalid;
10242
        }
10243
        break;
10244
#ifndef CONFIG_USER_ONLY
10245
    case 0x0d:
10246
        switch (minor) {
10247
        case TLBP:
10248
            mips32_op = OPC_TLBP;
10249
            goto do_cp0;
10250
        case TLBR:
10251
            mips32_op = OPC_TLBR;
10252
            goto do_cp0;
10253
        case TLBWI:
10254
            mips32_op = OPC_TLBWI;
10255
            goto do_cp0;
10256
        case TLBWR:
10257
            mips32_op = OPC_TLBWR;
10258
            goto do_cp0;
10259
        case WAIT:
10260
            mips32_op = OPC_WAIT;
10261
            goto do_cp0;
10262
        case DERET:
10263
            mips32_op = OPC_DERET;
10264
            goto do_cp0;
10265
        case ERET:
10266
            mips32_op = OPC_ERET;
10267
        do_cp0:
10268
            gen_cp0(env, ctx, mips32_op, rt, rs);
10269
            break;
10270
        default:
10271
            goto pool32axf_invalid;
10272
        }
10273
        break;
10274
    case 0x1d:
10275
        switch (minor) {
10276
        case DI:
10277
            check_cp0_enabled(ctx);
10278
            {
10279
                TCGv t0 = tcg_temp_new();
10280

    
10281
                save_cpu_state(ctx, 1);
10282
                gen_helper_di(t0);
10283
                gen_store_gpr(t0, rs);
10284
                /* Stop translation as we may have switched the execution mode */
10285
                ctx->bstate = BS_STOP;
10286
                tcg_temp_free(t0);
10287
            }
10288
            break;
10289
        case EI:
10290
            check_cp0_enabled(ctx);
10291
            {
10292
                TCGv t0 = tcg_temp_new();
10293

    
10294
                save_cpu_state(ctx, 1);
10295
                gen_helper_ei(t0);
10296
                gen_store_gpr(t0, rs);
10297
                /* Stop translation as we may have switched the execution mode */
10298
                ctx->bstate = BS_STOP;
10299
                tcg_temp_free(t0);
10300
            }
10301
            break;
10302
        default:
10303
            goto pool32axf_invalid;
10304
        }
10305
        break;
10306
#endif
10307
    case 0x2d:
10308
        switch (minor) {
10309
        case SYNC:
10310
            /* NOP */
10311
            break;
10312
        case SYSCALL:
10313
            generate_exception(ctx, EXCP_SYSCALL);
10314
            ctx->bstate = BS_STOP;
10315
            break;
10316
        case SDBBP:
10317
            check_insn(env, ctx, ISA_MIPS32);
10318
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10319
                generate_exception(ctx, EXCP_DBp);
10320
            } else {
10321
                generate_exception(ctx, EXCP_DBp);
10322
            }
10323
            break;
10324
        default:
10325
            goto pool32axf_invalid;
10326
        }
10327
        break;
10328
    case 0x35:
10329
        switch (minor) {
10330
        case MFHI32:
10331
            gen_HILO(ctx, OPC_MFHI, rs);
10332
            break;
10333
        case MFLO32:
10334
            gen_HILO(ctx, OPC_MFLO, rs);
10335
            break;
10336
        case MTHI32:
10337
            gen_HILO(ctx, OPC_MTHI, rs);
10338
            break;
10339
        case MTLO32:
10340
            gen_HILO(ctx, OPC_MTLO, rs);
10341
            break;
10342
        default:
10343
            goto pool32axf_invalid;
10344
        }
10345
        break;
10346
    default:
10347
    pool32axf_invalid:
10348
        MIPS_INVAL("pool32axf");
10349
        generate_exception(ctx, EXCP_RI);
10350
        break;
10351
    }
10352
}
10353

    
10354
/* Values for microMIPS fmt field.  Variable-width, depending on which
10355
   formats the instruction supports.  */
10356

    
10357
enum {
10358
    FMT_SD_S = 0,
10359
    FMT_SD_D = 1,
10360

    
10361
    FMT_SDPS_S = 0,
10362
    FMT_SDPS_D = 1,
10363
    FMT_SDPS_PS = 2,
10364

    
10365
    FMT_SWL_S = 0,
10366
    FMT_SWL_W = 1,
10367
    FMT_SWL_L = 2,
10368

    
10369
    FMT_DWL_D = 0,
10370
    FMT_DWL_W = 1,
10371
    FMT_DWL_L = 2
10372
};
10373

    
10374
static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
10375
{
10376
    int extension = (ctx->opcode >> 6) & 0x3ff;
10377
    uint32_t mips32_op;
10378

    
10379
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10380
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10381
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10382

    
10383
    switch (extension) {
10384
    case FLOAT_1BIT_FMT(CFC1, 0):
10385
        mips32_op = OPC_CFC1;
10386
        goto do_cp1;
10387
    case FLOAT_1BIT_FMT(CTC1, 0):
10388
        mips32_op = OPC_CTC1;
10389
        goto do_cp1;
10390
    case FLOAT_1BIT_FMT(MFC1, 0):
10391
        mips32_op = OPC_MFC1;
10392
        goto do_cp1;
10393
    case FLOAT_1BIT_FMT(MTC1, 0):
10394
        mips32_op = OPC_MTC1;
10395
        goto do_cp1;
10396
    case FLOAT_1BIT_FMT(MFHC1, 0):
10397
        mips32_op = OPC_MFHC1;
10398
        goto do_cp1;
10399
    case FLOAT_1BIT_FMT(MTHC1, 0):
10400
        mips32_op = OPC_MTHC1;
10401
    do_cp1:
10402
        gen_cp1(ctx, mips32_op, rt, rs);
10403
        break;
10404

    
10405
        /* Reciprocal square root */
10406
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10407
        mips32_op = OPC_RSQRT_S;
10408
        goto do_unaryfp;
10409
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10410
        mips32_op = OPC_RSQRT_D;
10411
        goto do_unaryfp;
10412

    
10413
        /* Square root */
10414
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10415
        mips32_op = OPC_SQRT_S;
10416
        goto do_unaryfp;
10417
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10418
        mips32_op = OPC_SQRT_D;
10419
        goto do_unaryfp;
10420

    
10421
        /* Reciprocal */
10422
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10423
        mips32_op = OPC_RECIP_S;
10424
        goto do_unaryfp;
10425
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10426
        mips32_op = OPC_RECIP_D;
10427
        goto do_unaryfp;
10428

    
10429
        /* Floor */
10430
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10431
        mips32_op = OPC_FLOOR_L_S;
10432
        goto do_unaryfp;
10433
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10434
        mips32_op = OPC_FLOOR_L_D;
10435
        goto do_unaryfp;
10436
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10437
        mips32_op = OPC_FLOOR_W_S;
10438
        goto do_unaryfp;
10439
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10440
        mips32_op = OPC_FLOOR_W_D;
10441
        goto do_unaryfp;
10442

    
10443
        /* Ceiling */
10444
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10445
        mips32_op = OPC_CEIL_L_S;
10446
        goto do_unaryfp;
10447
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10448
        mips32_op = OPC_CEIL_L_D;
10449
        goto do_unaryfp;
10450
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10451
        mips32_op = OPC_CEIL_W_S;
10452
        goto do_unaryfp;
10453
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10454
        mips32_op = OPC_CEIL_W_D;
10455
        goto do_unaryfp;
10456

    
10457
        /* Truncation */
10458
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10459
        mips32_op = OPC_TRUNC_L_S;
10460
        goto do_unaryfp;
10461
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10462
        mips32_op = OPC_TRUNC_L_D;
10463
        goto do_unaryfp;
10464
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10465
        mips32_op = OPC_TRUNC_W_S;
10466
        goto do_unaryfp;
10467
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10468
        mips32_op = OPC_TRUNC_W_D;
10469
        goto do_unaryfp;
10470

    
10471
        /* Round */
10472
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10473
        mips32_op = OPC_ROUND_L_S;
10474
        goto do_unaryfp;
10475
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10476
        mips32_op = OPC_ROUND_L_D;
10477
        goto do_unaryfp;
10478
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10479
        mips32_op = OPC_ROUND_W_S;
10480
        goto do_unaryfp;
10481
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10482
        mips32_op = OPC_ROUND_W_D;
10483
        goto do_unaryfp;
10484

    
10485
        /* Integer to floating-point conversion */
10486
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10487
        mips32_op = OPC_CVT_L_S;
10488
        goto do_unaryfp;
10489
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10490
        mips32_op = OPC_CVT_L_D;
10491
        goto do_unaryfp;
10492
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10493
        mips32_op = OPC_CVT_W_S;
10494
        goto do_unaryfp;
10495
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10496
        mips32_op = OPC_CVT_W_D;
10497
        goto do_unaryfp;
10498

    
10499
        /* Paired-foo conversions */
10500
    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10501
        mips32_op = OPC_CVT_S_PL;
10502
        goto do_unaryfp;
10503
    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10504
        mips32_op = OPC_CVT_S_PU;
10505
        goto do_unaryfp;
10506
    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10507
        mips32_op = OPC_CVT_PW_PS;
10508
        goto do_unaryfp;
10509
    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10510
        mips32_op = OPC_CVT_PS_PW;
10511
        goto do_unaryfp;
10512

    
10513
        /* Floating-point moves */
10514
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10515
        mips32_op = OPC_MOV_S;
10516
        goto do_unaryfp;
10517
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10518
        mips32_op = OPC_MOV_D;
10519
        goto do_unaryfp;
10520
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10521
        mips32_op = OPC_MOV_PS;
10522
        goto do_unaryfp;
10523

    
10524
        /* Absolute value */
10525
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10526
        mips32_op = OPC_ABS_S;
10527
        goto do_unaryfp;
10528
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10529
        mips32_op = OPC_ABS_D;
10530
        goto do_unaryfp;
10531
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10532
        mips32_op = OPC_ABS_PS;
10533
        goto do_unaryfp;
10534

    
10535
        /* Negation */
10536
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10537
        mips32_op = OPC_NEG_S;
10538
        goto do_unaryfp;
10539
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10540
        mips32_op = OPC_NEG_D;
10541
        goto do_unaryfp;
10542
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10543
        mips32_op = OPC_NEG_PS;
10544
        goto do_unaryfp;
10545

    
10546
        /* Reciprocal square root step */
10547
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10548
        mips32_op = OPC_RSQRT1_S;
10549
        goto do_unaryfp;
10550
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10551
        mips32_op = OPC_RSQRT1_D;
10552
        goto do_unaryfp;
10553
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10554
        mips32_op = OPC_RSQRT1_PS;
10555
        goto do_unaryfp;
10556

    
10557
        /* Reciprocal step */
10558
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10559
        mips32_op = OPC_RECIP1_S;
10560
        goto do_unaryfp;
10561
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10562
        mips32_op = OPC_RECIP1_S;
10563
        goto do_unaryfp;
10564
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10565
        mips32_op = OPC_RECIP1_PS;
10566
        goto do_unaryfp;
10567

    
10568
        /* Conversions from double */
10569
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10570
        mips32_op = OPC_CVT_D_S;
10571
        goto do_unaryfp;
10572
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10573
        mips32_op = OPC_CVT_D_W;
10574
        goto do_unaryfp;
10575
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10576
        mips32_op = OPC_CVT_D_L;
10577
        goto do_unaryfp;
10578

    
10579
        /* Conversions from single */
10580
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10581
        mips32_op = OPC_CVT_S_D;
10582
        goto do_unaryfp;
10583
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10584
        mips32_op = OPC_CVT_S_W;
10585
        goto do_unaryfp;
10586
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10587
        mips32_op = OPC_CVT_S_L;
10588
    do_unaryfp:
10589
        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10590
        break;
10591

    
10592
        /* Conditional moves on floating-point codes */
10593
    case COND_FLOAT_MOV(MOVT, 0):
10594
    case COND_FLOAT_MOV(MOVT, 1):
10595
    case COND_FLOAT_MOV(MOVT, 2):
10596
    case COND_FLOAT_MOV(MOVT, 3):
10597
    case COND_FLOAT_MOV(MOVT, 4):
10598
    case COND_FLOAT_MOV(MOVT, 5):
10599
    case COND_FLOAT_MOV(MOVT, 6):
10600
    case COND_FLOAT_MOV(MOVT, 7):
10601
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10602
        break;
10603
    case COND_FLOAT_MOV(MOVF, 0):
10604
    case COND_FLOAT_MOV(MOVF, 1):
10605
    case COND_FLOAT_MOV(MOVF, 2):
10606
    case COND_FLOAT_MOV(MOVF, 3):
10607
    case COND_FLOAT_MOV(MOVF, 4):
10608
    case COND_FLOAT_MOV(MOVF, 5):
10609
    case COND_FLOAT_MOV(MOVF, 6):
10610
    case COND_FLOAT_MOV(MOVF, 7):
10611
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10612
        break;
10613
    default:
10614
        MIPS_INVAL("pool32fxf");
10615
        generate_exception(ctx, EXCP_RI);
10616
        break;
10617
    }
10618
}
10619

    
10620
static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
10621
                                    uint16_t insn_hw1, int *is_branch)
10622
{
10623
    int32_t offset;
10624
    uint16_t insn;
10625
    int rt, rs, rd, rr;
10626
    int16_t imm;
10627
    uint32_t op, minor, mips32_op;
10628
    uint32_t cond, fmt, cc;
10629

    
10630
    insn = lduw_code(ctx->pc + 2);
10631
    ctx->opcode = (ctx->opcode << 16) | insn;
10632

    
10633
    rt = (ctx->opcode >> 21) & 0x1f;
10634
    rs = (ctx->opcode >> 16) & 0x1f;
10635
    rd = (ctx->opcode >> 11) & 0x1f;
10636
    rr = (ctx->opcode >> 6) & 0x1f;
10637
    imm = (int16_t) ctx->opcode;
10638

    
10639
    op = (ctx->opcode >> 26) & 0x3f;
10640
    switch (op) {
10641
    case POOL32A:
10642
        minor = ctx->opcode & 0x3f;
10643
        switch (minor) {
10644
        case 0x00:
10645
            minor = (ctx->opcode >> 6) & 0xf;
10646
            switch (minor) {
10647
            case SLL32:
10648
                mips32_op = OPC_SLL;
10649
                goto do_shifti;
10650
            case SRA:
10651
                mips32_op = OPC_SRA;
10652
                goto do_shifti;
10653
            case SRL32:
10654
                mips32_op = OPC_SRL;
10655
                goto do_shifti;
10656
            case ROTR:
10657
                mips32_op = OPC_ROTR;
10658
            do_shifti:
10659
                gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10660
                break;
10661
            default:
10662
                goto pool32a_invalid;
10663
            }
10664
            break;
10665
        case 0x10:
10666
            minor = (ctx->opcode >> 6) & 0xf;
10667
            switch (minor) {
10668
                /* Arithmetic */
10669
            case ADD:
10670
                mips32_op = OPC_ADD;
10671
                goto do_arith;
10672
            case ADDU32:
10673
                mips32_op = OPC_ADDU;
10674
                goto do_arith;
10675
            case SUB:
10676
                mips32_op = OPC_SUB;
10677
                goto do_arith;
10678
            case SUBU32:
10679
                mips32_op = OPC_SUBU;
10680
                goto do_arith;
10681
            case MUL:
10682
                mips32_op = OPC_MUL;
10683
            do_arith:
10684
                gen_arith(env, ctx, mips32_op, rd, rs, rt);
10685
                break;
10686
                /* Shifts */
10687
            case SLLV:
10688
                mips32_op = OPC_SLLV;
10689
                goto do_shift;
10690
            case SRLV:
10691
                mips32_op = OPC_SRLV;
10692
                goto do_shift;
10693
            case SRAV:
10694
                mips32_op = OPC_SRAV;
10695
                goto do_shift;
10696
            case ROTRV:
10697
                mips32_op = OPC_ROTRV;
10698
            do_shift:
10699
                gen_shift(env, ctx, mips32_op, rd, rs, rt);
10700
                break;
10701
                /* Logical operations */
10702
            case AND:
10703
                mips32_op = OPC_AND;
10704
                goto do_logic;
10705
            case OR32:
10706
                mips32_op = OPC_OR;
10707
                goto do_logic;
10708
            case NOR:
10709
                mips32_op = OPC_NOR;
10710
                goto do_logic;
10711
            case XOR32:
10712
                mips32_op = OPC_XOR;
10713
            do_logic:
10714
                gen_logic(env, mips32_op, rd, rs, rt);
10715
                break;
10716
                /* Set less than */
10717
            case SLT:
10718
                mips32_op = OPC_SLT;
10719
                goto do_slt;
10720
            case SLTU:
10721
                mips32_op = OPC_SLTU;
10722
            do_slt:
10723
                gen_slt(env, mips32_op, rd, rs, rt);
10724
                break;
10725
            default:
10726
                goto pool32a_invalid;
10727
            }
10728
            break;
10729
        case 0x18:
10730
            minor = (ctx->opcode >> 6) & 0xf;
10731
            switch (minor) {
10732
                /* Conditional moves */
10733
            case MOVN:
10734
                mips32_op = OPC_MOVN;
10735
                goto do_cmov;
10736
            case MOVZ:
10737
                mips32_op = OPC_MOVZ;
10738
            do_cmov:
10739
                gen_cond_move(env, mips32_op, rd, rs, rt);
10740
                break;
10741
            case LWXS:
10742
                gen_ldxs(ctx, rs, rt, rd);
10743
                break;
10744
            default:
10745
                goto pool32a_invalid;
10746
            }
10747
            break;
10748
        case INS:
10749
            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10750
            return;
10751
        case EXT:
10752
            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10753
            return;
10754
        case POOL32AXF:
10755
            gen_pool32axf(env, ctx, rt, rs, is_branch);
10756
            break;
10757
        case 0x07:
10758
            generate_exception(ctx, EXCP_BREAK);
10759
            break;
10760
        default:
10761
        pool32a_invalid:
10762
                MIPS_INVAL("pool32a");
10763
                generate_exception(ctx, EXCP_RI);
10764
                break;
10765
        }
10766
        break;
10767
    case POOL32B:
10768
        minor = (ctx->opcode >> 12) & 0xf;
10769
        switch (minor) {
10770
        case CACHE:
10771
            check_cp0_enabled(ctx);
10772
            /* Treat as no-op. */
10773
            break;
10774
        case LWC2:
10775
        case SWC2:
10776
            /* COP2: Not implemented. */
10777
            generate_exception_err(ctx, EXCP_CpU, 2);
10778
            break;
10779
        case LWP:
10780
        case SWP:
10781
#ifdef TARGET_MIPS64
10782
        case LDP:
10783
        case SDP:
10784
#endif
10785
            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10786
            break;
10787
        case LWM32:
10788
        case SWM32:
10789
#ifdef TARGET_MIPS64
10790
        case LDM:
10791
        case SDM:
10792
#endif
10793
            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10794
            break;
10795
        default:
10796
            MIPS_INVAL("pool32b");
10797
            generate_exception(ctx, EXCP_RI);
10798
            break;
10799
        }
10800
        break;
10801
    case POOL32F:
10802
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10803
            minor = ctx->opcode & 0x3f;
10804
            check_cp1_enabled(ctx);
10805
            switch (minor) {
10806
            case ALNV_PS:
10807
                mips32_op = OPC_ALNV_PS;
10808
                goto do_madd;
10809
            case MADD_S:
10810
                mips32_op = OPC_MADD_S;
10811
                goto do_madd;
10812
            case MADD_D:
10813
                mips32_op = OPC_MADD_D;
10814
                goto do_madd;
10815
            case MADD_PS:
10816
                mips32_op = OPC_MADD_PS;
10817
                goto do_madd;
10818
            case MSUB_S:
10819
                mips32_op = OPC_MSUB_S;
10820
                goto do_madd;
10821
            case MSUB_D:
10822
                mips32_op = OPC_MSUB_D;
10823
                goto do_madd;
10824
            case MSUB_PS:
10825
                mips32_op = OPC_MSUB_PS;
10826
                goto do_madd;
10827
            case NMADD_S:
10828
                mips32_op = OPC_NMADD_S;
10829
                goto do_madd;
10830
            case NMADD_D:
10831
                mips32_op = OPC_NMADD_D;
10832
                goto do_madd;
10833
            case NMADD_PS:
10834
                mips32_op = OPC_NMADD_PS;
10835
                goto do_madd;
10836
            case NMSUB_S:
10837
                mips32_op = OPC_NMSUB_S;
10838
                goto do_madd;
10839
            case NMSUB_D:
10840
                mips32_op = OPC_NMSUB_D;
10841
                goto do_madd;
10842
            case NMSUB_PS:
10843
                mips32_op = OPC_NMSUB_PS;
10844
            do_madd:
10845
                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10846
                break;
10847
            case CABS_COND_FMT:
10848
                cond = (ctx->opcode >> 6) & 0xf;
10849
                cc = (ctx->opcode >> 13) & 0x7;
10850
                fmt = (ctx->opcode >> 10) & 0x3;
10851
                switch (fmt) {
10852
                case 0x0:
10853
                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
10854
                    break;
10855
                case 0x1:
10856
                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
10857
                    break;
10858
                case 0x2:
10859
                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10860
                    break;
10861
                default:
10862
                    goto pool32f_invalid;
10863
                }
10864
                break;
10865
            case C_COND_FMT:
10866
                cond = (ctx->opcode >> 6) & 0xf;
10867
                cc = (ctx->opcode >> 13) & 0x7;
10868
                fmt = (ctx->opcode >> 10) & 0x3;
10869
                switch (fmt) {
10870
                case 0x0:
10871
                    gen_cmp_s(ctx, cond, rt, rs, cc);
10872
                    break;
10873
                case 0x1:
10874
                    gen_cmp_d(ctx, cond, rt, rs, cc);
10875
                    break;
10876
                case 0x2:
10877
                    gen_cmp_ps(ctx, cond, rt, rs, cc);
10878
                    break;
10879
                default:
10880
                    goto pool32f_invalid;
10881
                }
10882
                break;
10883
            case POOL32FXF:
10884
                gen_pool32fxf(env, ctx, rt, rs);
10885
                break;
10886
            case 0x00:
10887
                /* PLL foo */
10888
                switch ((ctx->opcode >> 6) & 0x7) {
10889
                case PLL_PS:
10890
                    mips32_op = OPC_PLL_PS;
10891
                    goto do_ps;
10892
                case PLU_PS:
10893
                    mips32_op = OPC_PLU_PS;
10894
                    goto do_ps;
10895
                case PUL_PS:
10896
                    mips32_op = OPC_PUL_PS;
10897
                    goto do_ps;
10898
                case PUU_PS:
10899
                    mips32_op = OPC_PUU_PS;
10900
                    goto do_ps;
10901
                case CVT_PS_S:
10902
                    mips32_op = OPC_CVT_PS_S;
10903
                do_ps:
10904
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10905
                    break;
10906
                default:
10907
                    goto pool32f_invalid;
10908
                }
10909
                break;
10910
            case 0x08:
10911
                /* [LS][WDU]XC1 */
10912
                switch ((ctx->opcode >> 6) & 0x7) {
10913
                case LWXC1:
10914
                    mips32_op = OPC_LWXC1;
10915
                    goto do_ldst_cp1;
10916
                case SWXC1:
10917
                    mips32_op = OPC_SWXC1;
10918
                    goto do_ldst_cp1;
10919
                case LDXC1:
10920
                    mips32_op = OPC_LDXC1;
10921
                    goto do_ldst_cp1;
10922
                case SDXC1:
10923
                    mips32_op = OPC_SDXC1;
10924
                    goto do_ldst_cp1;
10925
                case LUXC1:
10926
                    mips32_op = OPC_LUXC1;
10927
                    goto do_ldst_cp1;
10928
                case SUXC1:
10929
                    mips32_op = OPC_SUXC1;
10930
                do_ldst_cp1:
10931
                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10932
                    break;
10933
                default:
10934
                    goto pool32f_invalid;
10935
                }
10936
                break;
10937
            case 0x18:
10938
                /* 3D insns */
10939
                fmt = (ctx->opcode >> 9) & 0x3;
10940
                switch ((ctx->opcode >> 6) & 0x7) {
10941
                case RSQRT2_FMT:
10942
                    switch (fmt) {
10943
                    case FMT_SDPS_S:
10944
                        mips32_op = OPC_RSQRT2_S;
10945
                        goto do_3d;
10946
                    case FMT_SDPS_D:
10947
                        mips32_op = OPC_RSQRT2_D;
10948
                        goto do_3d;
10949
                    case FMT_SDPS_PS:
10950
                        mips32_op = OPC_RSQRT2_PS;
10951
                        goto do_3d;
10952
                    default:
10953
                        goto pool32f_invalid;
10954
                    }
10955
                    break;
10956
                case RECIP2_FMT:
10957
                    switch (fmt) {
10958
                    case FMT_SDPS_S:
10959
                        mips32_op = OPC_RECIP2_S;
10960
                        goto do_3d;
10961
                    case FMT_SDPS_D:
10962
                        mips32_op = OPC_RECIP2_D;
10963
                        goto do_3d;
10964
                    case FMT_SDPS_PS:
10965
                        mips32_op = OPC_RECIP2_PS;
10966
                        goto do_3d;
10967
                    default:
10968
                        goto pool32f_invalid;
10969
                    }
10970
                    break;
10971
                case ADDR_PS:
10972
                    mips32_op = OPC_ADDR_PS;
10973
                    goto do_3d;
10974
                case MULR_PS:
10975
                    mips32_op = OPC_MULR_PS;
10976
                do_3d:
10977
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10978
                    break;
10979
                default:
10980
                    goto pool32f_invalid;
10981
                }
10982
                break;
10983
            case 0x20:
10984
                /* MOV[FT].fmt and PREFX */
10985
                cc = (ctx->opcode >> 13) & 0x7;
10986
                fmt = (ctx->opcode >> 9) & 0x3;
10987
                switch ((ctx->opcode >> 6) & 0x7) {
10988
                case MOVF_FMT:
10989
                    switch (fmt) {
10990
                    case FMT_SDPS_S:
10991
                        gen_movcf_s(rs, rt, cc, 0);
10992
                        break;
10993
                    case FMT_SDPS_D:
10994
                        gen_movcf_d(ctx, rs, rt, cc, 0);
10995
                        break;
10996
                    case FMT_SDPS_PS:
10997
                        gen_movcf_ps(rs, rt, cc, 0);
10998
                        break;
10999
                    default:
11000
                        goto pool32f_invalid;
11001
                    }
11002
                    break;
11003
                case MOVT_FMT:
11004
                    switch (fmt) {
11005
                    case FMT_SDPS_S:
11006
                        gen_movcf_s(rs, rt, cc, 1);
11007
                        break;
11008
                    case FMT_SDPS_D:
11009
                        gen_movcf_d(ctx, rs, rt, cc, 1);
11010
                        break;
11011
                    case FMT_SDPS_PS:
11012
                        gen_movcf_ps(rs, rt, cc, 1);
11013
                        break;
11014
                    default:
11015
                        goto pool32f_invalid;
11016
                    }
11017
                    break;
11018
                case PREFX:
11019
                    break;
11020
                default:
11021
                    goto pool32f_invalid;
11022
                }
11023
                break;
11024
#define FINSN_3ARG_SDPS(prfx)                           \
11025
                switch ((ctx->opcode >> 8) & 0x3) {     \
11026
                case FMT_SDPS_S:                        \
11027
                    mips32_op = OPC_##prfx##_S;         \
11028
                    goto do_fpop;                       \
11029
                case FMT_SDPS_D:                        \
11030
                    mips32_op = OPC_##prfx##_D;         \
11031
                    goto do_fpop;                       \
11032
                case FMT_SDPS_PS:                       \
11033
                    mips32_op = OPC_##prfx##_PS;        \
11034
                    goto do_fpop;                       \
11035
                default:                                \
11036
                    goto pool32f_invalid;               \
11037
                }
11038
            case 0x30:
11039
                /* regular FP ops */
11040
                switch ((ctx->opcode >> 6) & 0x3) {
11041
                case ADD_FMT:
11042
                    FINSN_3ARG_SDPS(ADD);
11043
                    break;
11044
                case SUB_FMT:
11045
                    FINSN_3ARG_SDPS(SUB);
11046
                    break;
11047
                case MUL_FMT:
11048
                    FINSN_3ARG_SDPS(MUL);
11049
                    break;
11050
                case DIV_FMT:
11051
                    fmt = (ctx->opcode >> 8) & 0x3;
11052
                    if (fmt == 1) {
11053
                        mips32_op = OPC_DIV_D;
11054
                    } else if (fmt == 0) {
11055
                        mips32_op = OPC_DIV_S;
11056
                    } else {
11057
                        goto pool32f_invalid;
11058
                    }
11059
                    goto do_fpop;
11060
                default:
11061
                    goto pool32f_invalid;
11062
                }
11063
                break;
11064
            case 0x38:
11065
                /* cmovs */
11066
                switch ((ctx->opcode >> 6) & 0x3) {
11067
                case MOVN_FMT:
11068
                    FINSN_3ARG_SDPS(MOVN);
11069
                    break;
11070
                case MOVZ_FMT:
11071
                    FINSN_3ARG_SDPS(MOVZ);
11072
                    break;
11073
                default:
11074
                    goto pool32f_invalid;
11075
                }
11076
                break;
11077
            do_fpop:
11078
                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11079
                break;
11080
            default:
11081
            pool32f_invalid:
11082
                MIPS_INVAL("pool32f");
11083
                generate_exception(ctx, EXCP_RI);
11084
                break;
11085
            }
11086
        } else {
11087
            generate_exception_err(ctx, EXCP_CpU, 1);
11088
        }
11089
        break;
11090
    case POOL32I:
11091
        minor = (ctx->opcode >> 21) & 0x1f;
11092
        switch (minor) {
11093
        case BLTZ:
11094
            mips32_op = OPC_BLTZ;
11095
            goto do_branch;
11096
        case BLTZAL:
11097
            mips32_op = OPC_BLTZAL;
11098
            goto do_branch;
11099
        case BLTZALS:
11100
            mips32_op = OPC_BLTZALS;
11101
            goto do_branch;
11102
        case BGEZ:
11103
            mips32_op = OPC_BGEZ;
11104
            goto do_branch;
11105
        case BGEZAL:
11106
            mips32_op = OPC_BGEZAL;
11107
            goto do_branch;
11108
        case BGEZALS:
11109
            mips32_op = OPC_BGEZALS;
11110
            goto do_branch;
11111
        case BLEZ:
11112
            mips32_op = OPC_BLEZ;
11113
            goto do_branch;
11114
        case BGTZ:
11115
            mips32_op = OPC_BGTZ;
11116
        do_branch:
11117
            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11118
            *is_branch = 1;
11119
            break;
11120

    
11121
            /* Traps */
11122
        case TLTI:
11123
            mips32_op = OPC_TLTI;
11124
            goto do_trapi;
11125
        case TGEI:
11126
            mips32_op = OPC_TGEI;
11127
            goto do_trapi;
11128
        case TLTIU:
11129
            mips32_op = OPC_TLTIU;
11130
            goto do_trapi;
11131
        case TGEIU:
11132
            mips32_op = OPC_TGEIU;
11133
            goto do_trapi;
11134
        case TNEI:
11135
            mips32_op = OPC_TNEI;
11136
            goto do_trapi;
11137
        case TEQI:
11138
            mips32_op = OPC_TEQI;
11139
        do_trapi:
11140
            gen_trap(ctx, mips32_op, rs, -1, imm);
11141
            break;
11142

    
11143
        case BNEZC:
11144
        case BEQZC:
11145
            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11146
                               4, rs, 0, imm << 1);
11147
            /* Compact branches don't have a delay slot, so just let
11148
               the normal delay slot handling take us to the branch
11149
               target. */
11150
            break;
11151
        case LUI:
11152
            gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11153
            break;
11154
        case SYNCI:
11155
            break;
11156
        case BC2F:
11157
        case BC2T:
11158
            /* COP2: Not implemented. */
11159
            generate_exception_err(ctx, EXCP_CpU, 2);
11160
            break;
11161
        case BC1F:
11162
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11163
            goto do_cp1branch;
11164
        case BC1T:
11165
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11166
            goto do_cp1branch;
11167
        case BC1ANY4F:
11168
            mips32_op = OPC_BC1FANY4;
11169
            goto do_cp1mips3d;
11170
        case BC1ANY4T:
11171
            mips32_op = OPC_BC1TANY4;
11172
        do_cp1mips3d:
11173
            check_cop1x(ctx);
11174
            check_insn(env, ctx, ASE_MIPS3D);
11175
            /* Fall through */
11176
        do_cp1branch:
11177
            gen_compute_branch1(env, ctx, mips32_op,
11178
                                (ctx->opcode >> 18) & 0x7, imm << 1);
11179
            *is_branch = 1;
11180
            break;
11181
        case BPOSGE64:
11182
        case BPOSGE32:
11183
            /* MIPS DSP: not implemented */
11184
            /* Fall through */
11185
        default:
11186
            MIPS_INVAL("pool32i");
11187
            generate_exception(ctx, EXCP_RI);
11188
            break;
11189
        }
11190
        break;
11191
    case POOL32C:
11192
        minor = (ctx->opcode >> 12) & 0xf;
11193
        switch (minor) {
11194
        case LWL:
11195
            mips32_op = OPC_LWL;
11196
            goto do_ld_lr;
11197
        case SWL:
11198
            mips32_op = OPC_SWL;
11199
            goto do_st_lr;
11200
        case LWR:
11201
            mips32_op = OPC_LWR;
11202
            goto do_ld_lr;
11203
        case SWR:
11204
            mips32_op = OPC_SWR;
11205
            goto do_st_lr;
11206
#if defined(TARGET_MIPS64)
11207
        case LDL:
11208
            mips32_op = OPC_LDL;
11209
            goto do_ld_lr;
11210
        case SDL:
11211
            mips32_op = OPC_SDL;
11212
            goto do_st_lr;
11213
        case LDR:
11214
            mips32_op = OPC_LDR;
11215
            goto do_ld_lr;
11216
        case SDR:
11217
            mips32_op = OPC_SDR;
11218
            goto do_st_lr;
11219
        case LWU:
11220
            mips32_op = OPC_LWU;
11221
            goto do_ld_lr;
11222
        case LLD:
11223
            mips32_op = OPC_LLD;
11224
            goto do_ld_lr;
11225
#endif
11226
        case LL:
11227
            mips32_op = OPC_LL;
11228
            goto do_ld_lr;
11229
        do_ld_lr:
11230
            gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11231
            break;
11232
        do_st_lr:
11233
            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11234
            break;
11235
        case SC:
11236
            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11237
            break;
11238
#if defined(TARGET_MIPS64)
11239
        case SCD:
11240
            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11241
            break;
11242
#endif
11243
        case PREF:
11244
            /* Treat as no-op */
11245
            break;
11246
        default:
11247
            MIPS_INVAL("pool32c");
11248
            generate_exception(ctx, EXCP_RI);
11249
            break;
11250
        }
11251
        break;
11252
    case ADDI32:
11253
        mips32_op = OPC_ADDI;
11254
        goto do_addi;
11255
    case ADDIU32:
11256
        mips32_op = OPC_ADDIU;
11257
    do_addi:
11258
        gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11259
        break;
11260

    
11261
        /* Logical operations */
11262
    case ORI32:
11263
        mips32_op = OPC_ORI;
11264
        goto do_logici;
11265
    case XORI32:
11266
        mips32_op = OPC_XORI;
11267
        goto do_logici;
11268
    case ANDI32:
11269
        mips32_op = OPC_ANDI;
11270
    do_logici:
11271
        gen_logic_imm(env, mips32_op, rt, rs, imm);
11272
        break;
11273

    
11274
        /* Set less than immediate */
11275
    case SLTI32:
11276
        mips32_op = OPC_SLTI;
11277
        goto do_slti;
11278
    case SLTIU32:
11279
        mips32_op = OPC_SLTIU;
11280
    do_slti:
11281
        gen_slt_imm(env, mips32_op, rt, rs, imm);
11282
        break;
11283
    case JALX32:
11284
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11285
        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11286
        *is_branch = 1;
11287
        break;
11288
    case JALS32:
11289
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11290
        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11291
        *is_branch = 1;
11292
        break;
11293
    case BEQ32:
11294
        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11295
        *is_branch = 1;
11296
        break;
11297
    case BNE32:
11298
        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11299
        *is_branch = 1;
11300
        break;
11301
    case J32:
11302
        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11303
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11304
        *is_branch = 1;
11305
        break;
11306
    case JAL32:
11307
        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11308
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11309
        *is_branch = 1;
11310
        break;
11311
        /* Floating point (COP1) */
11312
    case LWC132:
11313
        mips32_op = OPC_LWC1;
11314
        goto do_cop1;
11315
    case LDC132:
11316
        mips32_op = OPC_LDC1;
11317
        goto do_cop1;
11318
    case SWC132:
11319
        mips32_op = OPC_SWC1;
11320
        goto do_cop1;
11321
    case SDC132:
11322
        mips32_op = OPC_SDC1;
11323
    do_cop1:
11324
        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11325
        break;
11326
    case ADDIUPC:
11327
        {
11328
            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11329
            int offset = SIMM(ctx->opcode, 0, 23) << 2;
11330

    
11331
            gen_addiupc(ctx, reg, offset, 0, 0);
11332
        }
11333
        break;
11334
        /* Loads and stores */
11335
    case LB32:
11336
        mips32_op = OPC_LB;
11337
        goto do_ld;
11338
    case LBU32:
11339
        mips32_op = OPC_LBU;
11340
        goto do_ld;
11341
    case LH32:
11342
        mips32_op = OPC_LH;
11343
        goto do_ld;
11344
    case LHU32:
11345
        mips32_op = OPC_LHU;
11346
        goto do_ld;
11347
    case LW32:
11348
        mips32_op = OPC_LW;
11349
        goto do_ld;
11350
#ifdef TARGET_MIPS64
11351
    case LD32:
11352
        mips32_op = OPC_LD;
11353
        goto do_ld;
11354
    case SD32:
11355
        mips32_op = OPC_SD;
11356
        goto do_st;
11357
#endif
11358
    case SB32:
11359
        mips32_op = OPC_SB;
11360
        goto do_st;
11361
    case SH32:
11362
        mips32_op = OPC_SH;
11363
        goto do_st;
11364
    case SW32:
11365
        mips32_op = OPC_SW;
11366
        goto do_st;
11367
    do_ld:
11368
        gen_ld(env, ctx, mips32_op, rt, rs, imm);
11369
        break;
11370
    do_st:
11371
        gen_st(ctx, mips32_op, rt, rs, imm);
11372
        break;
11373
    default:
11374
        generate_exception(ctx, EXCP_RI);
11375
        break;
11376
    }
11377
}
11378

    
11379
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11380
{
11381
    uint32_t op;
11382

    
11383
    /* make sure instructions are on a halfword boundary */
11384
    if (ctx->pc & 0x1) {
11385
        env->CP0_BadVAddr = ctx->pc;
11386
        generate_exception(ctx, EXCP_AdEL);
11387
        ctx->bstate = BS_STOP;
11388
        return 2;
11389
    }
11390

    
11391
    op = (ctx->opcode >> 10) & 0x3f;
11392
    /* Enforce properly-sized instructions in a delay slot */
11393
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11394
        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11395

    
11396
        switch (op) {
11397
        case POOL32A:
11398
        case POOL32B:
11399
        case POOL32I:
11400
        case POOL32C:
11401
        case ADDI32:
11402
        case ADDIU32:
11403
        case ORI32:
11404
        case XORI32:
11405
        case SLTI32:
11406
        case SLTIU32:
11407
        case ANDI32:
11408
        case JALX32:
11409
        case LBU32:
11410
        case LHU32:
11411
        case POOL32F:
11412
        case JALS32:
11413
        case BEQ32:
11414
        case BNE32:
11415
        case J32:
11416
        case JAL32:
11417
        case SB32:
11418
        case SH32:
11419
        case POOL32S:
11420
        case ADDIUPC:
11421
        case SWC132:
11422
        case SDC132:
11423
        case SD32:
11424
        case SW32:
11425
        case LB32:
11426
        case LH32:
11427
        case DADDIU32:
11428
        case POOL48A:           /* ??? */
11429
        case LWC132:
11430
        case LDC132:
11431
        case LD32:
11432
        case LW32:
11433
            if (bits & MIPS_HFLAG_BDS16) {
11434
                generate_exception(ctx, EXCP_RI);
11435
                /* Just stop translation; the user is confused.  */
11436
                ctx->bstate = BS_STOP;
11437
                return 2;
11438
            }
11439
            break;
11440
        case POOL16A:
11441
        case POOL16B:
11442
        case POOL16C:
11443
        case LWGP16:
11444
        case POOL16F:
11445
        case LBU16:
11446
        case LHU16:
11447
        case LWSP16:
11448
        case LW16:
11449
        case SB16:
11450
        case SH16:
11451
        case SWSP16:
11452
        case SW16:
11453
        case MOVE16:
11454
        case ANDI16:
11455
        case POOL16D:
11456
        case POOL16E:
11457
        case BEQZ16:
11458
        case BNEZ16:
11459
        case B16:
11460
        case LI16:
11461
            if (bits & MIPS_HFLAG_BDS32) {
11462
                generate_exception(ctx, EXCP_RI);
11463
                /* Just stop translation; the user is confused.  */
11464
                ctx->bstate = BS_STOP;
11465
                return 2;
11466
            }
11467
            break;
11468
        default:
11469
            break;
11470
        }
11471
    }
11472
    switch (op) {
11473
    case POOL16A:
11474
        {
11475
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11476
            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11477
            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11478
            uint32_t opc = 0;
11479

    
11480
            switch (ctx->opcode & 0x1) {
11481
            case ADDU16:
11482
                opc = OPC_ADDU;
11483
                break;
11484
            case SUBU16:
11485
                opc = OPC_SUBU;
11486
                break;
11487
            }
11488

    
11489
            gen_arith(env, ctx, opc, rd, rs1, rs2);
11490
        }
11491
        break;
11492
    case POOL16B:
11493
        {
11494
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11495
            int rs = mmreg(uMIPS_RS(ctx->opcode));
11496
            int amount = (ctx->opcode >> 1) & 0x7;
11497
            uint32_t opc = 0;
11498
            amount = amount == 0 ? 8 : amount;
11499

    
11500
            switch (ctx->opcode & 0x1) {
11501
            case SLL16:
11502
                opc = OPC_SLL;
11503
                break;
11504
            case SRL16:
11505
                opc = OPC_SRL;
11506
                break;
11507
            }
11508

    
11509
            gen_shift_imm(env, ctx, opc, rd, rs, amount);
11510
        }
11511
        break;
11512
    case POOL16C:
11513
        gen_pool16c_insn(env, ctx, is_branch);
11514
        break;
11515
    case LWGP16:
11516
        {
11517
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11518
            int rb = 28;            /* GP */
11519
            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11520

    
11521
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11522
        }
11523
        break;
11524
    case POOL16F:
11525
        if (ctx->opcode & 1) {
11526
            generate_exception(ctx, EXCP_RI);
11527
        } else {
11528
            /* MOVEP */
11529
            int enc_dest = uMIPS_RD(ctx->opcode);
11530
            int enc_rt = uMIPS_RS2(ctx->opcode);
11531
            int enc_rs = uMIPS_RS1(ctx->opcode);
11532
            int rd, rs, re, rt;
11533
            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11534
            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11535
            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11536

    
11537
            rd = rd_enc[enc_dest];
11538
            re = re_enc[enc_dest];
11539
            rs = rs_rt_enc[enc_rs];
11540
            rt = rs_rt_enc[enc_rt];
11541

    
11542
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11543
            gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11544
        }
11545
        break;
11546
    case LBU16:
11547
        {
11548
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11549
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11550
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11551
            offset = (offset == 0xf ? -1 : offset);
11552

    
11553
            gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11554
        }
11555
        break;
11556
    case LHU16:
11557
        {
11558
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11559
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11560
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11561

    
11562
            gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11563
        }
11564
        break;
11565
    case LWSP16:
11566
        {
11567
            int rd = (ctx->opcode >> 5) & 0x1f;
11568
            int rb = 29;            /* SP */
11569
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11570

    
11571
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11572
        }
11573
        break;
11574
    case LW16:
11575
        {
11576
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11577
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11578
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11579

    
11580
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11581
        }
11582
        break;
11583
    case SB16:
11584
        {
11585
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11586
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11587
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11588

    
11589
            gen_st(ctx, OPC_SB, rd, rb, offset);
11590
        }
11591
        break;
11592
    case SH16:
11593
        {
11594
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11595
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11596
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11597

    
11598
            gen_st(ctx, OPC_SH, rd, rb, offset);
11599
        }
11600
        break;
11601
    case SWSP16:
11602
        {
11603
            int rd = (ctx->opcode >> 5) & 0x1f;
11604
            int rb = 29;            /* SP */
11605
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11606

    
11607
            gen_st(ctx, OPC_SW, rd, rb, offset);
11608
        }
11609
        break;
11610
    case SW16:
11611
        {
11612
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11613
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11614
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11615

    
11616
            gen_st(ctx, OPC_SW, rd, rb, offset);
11617
        }
11618
        break;
11619
    case MOVE16:
11620
        {
11621
            int rd = uMIPS_RD5(ctx->opcode);
11622
            int rs = uMIPS_RS5(ctx->opcode);
11623

    
11624
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11625
        }
11626
        break;
11627
    case ANDI16:
11628
        gen_andi16(env, ctx);
11629
        break;
11630
    case POOL16D:
11631
        switch (ctx->opcode & 0x1) {
11632
        case ADDIUS5:
11633
            gen_addius5(env, ctx);
11634
            break;
11635
        case ADDIUSP:
11636
            gen_addiusp(env, ctx);
11637
            break;
11638
        }
11639
        break;
11640
    case POOL16E:
11641
        switch (ctx->opcode & 0x1) {
11642
        case ADDIUR2:
11643
            gen_addiur2(env, ctx);
11644
            break;
11645
        case ADDIUR1SP:
11646
            gen_addiur1sp(env, ctx);
11647
            break;
11648
        }
11649
        break;
11650
    case B16:
11651
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11652
                           SIMM(ctx->opcode, 0, 10) << 1);
11653
        *is_branch = 1;
11654
        break;
11655
    case BNEZ16:
11656
    case BEQZ16:
11657
        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11658
                           mmreg(uMIPS_RD(ctx->opcode)),
11659
                           0, SIMM(ctx->opcode, 0, 7) << 1);
11660
        *is_branch = 1;
11661
        break;
11662
    case LI16:
11663
        {
11664
            int reg = mmreg(uMIPS_RD(ctx->opcode));
11665
            int imm = ZIMM(ctx->opcode, 0, 7);
11666

    
11667
            imm = (imm == 0x7f ? -1 : imm);
11668
            tcg_gen_movi_tl(cpu_gpr[reg], imm);
11669
        }
11670
        break;
11671
    case RES_20:
11672
    case RES_28:
11673
    case RES_29:
11674
    case RES_30:
11675
    case RES_31:
11676
    case RES_38:
11677
    case RES_39:
11678
        generate_exception(ctx, EXCP_RI);
11679
        break;
11680
    default:
11681
        decode_micromips32_opc (env, ctx, op, is_branch);
11682
        return 4;
11683
    }
11684

    
11685
    return 2;
11686
}
11687

    
11688
/* SmartMIPS extension to MIPS32 */
11689

    
11690
#if defined(TARGET_MIPS64)
11691

    
11692
/* MDMX extension to MIPS64 */
11693

    
11694
#endif
11695

    
11696
static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11697
{
11698
    int32_t offset;
11699
    int rs, rt, rd, sa;
11700
    uint32_t op, op1, op2;
11701
    int16_t imm;
11702

    
11703
    /* make sure instructions are on a word boundary */
11704
    if (ctx->pc & 0x3) {
11705
        env->CP0_BadVAddr = ctx->pc;
11706
        generate_exception(ctx, EXCP_AdEL);
11707
        return;
11708
    }
11709

    
11710
    /* Handle blikely not taken case */
11711
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11712
        int l1 = gen_new_label();
11713

    
11714
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11715
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11716
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11717
        gen_goto_tb(ctx, 1, ctx->pc + 4);
11718
        gen_set_label(l1);
11719
    }
11720

    
11721
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11722
        tcg_gen_debug_insn_start(ctx->pc);
11723

    
11724
    op = MASK_OP_MAJOR(ctx->opcode);
11725
    rs = (ctx->opcode >> 21) & 0x1f;
11726
    rt = (ctx->opcode >> 16) & 0x1f;
11727
    rd = (ctx->opcode >> 11) & 0x1f;
11728
    sa = (ctx->opcode >> 6) & 0x1f;
11729
    imm = (int16_t)ctx->opcode;
11730
    switch (op) {
11731
    case OPC_SPECIAL:
11732
        op1 = MASK_SPECIAL(ctx->opcode);
11733
        switch (op1) {
11734
        case OPC_SLL:          /* Shift with immediate */
11735
        case OPC_SRA:
11736
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11737
            break;
11738
        case OPC_SRL:
11739
            switch ((ctx->opcode >> 21) & 0x1f) {
11740
            case 1:
11741
                /* rotr is decoded as srl on non-R2 CPUs */
11742
                if (env->insn_flags & ISA_MIPS32R2) {
11743
                    op1 = OPC_ROTR;
11744
                }
11745
                /* Fallthrough */
11746
            case 0:
11747
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11748
                break;
11749
            default:
11750
                generate_exception(ctx, EXCP_RI);
11751
                break;
11752
            }
11753
            break;
11754
        case OPC_MOVN:         /* Conditional move */
11755
        case OPC_MOVZ:
11756
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11757
                                 INSN_LOONGSON2E | INSN_LOONGSON2F);
11758
            gen_cond_move(env, op1, rd, rs, rt);
11759
            break;
11760
        case OPC_ADD ... OPC_SUBU:
11761
            gen_arith(env, ctx, op1, rd, rs, rt);
11762
            break;
11763
        case OPC_SLLV:         /* Shifts */
11764
        case OPC_SRAV:
11765
            gen_shift(env, ctx, op1, rd, rs, rt);
11766
            break;
11767
        case OPC_SRLV:
11768
            switch ((ctx->opcode >> 6) & 0x1f) {
11769
            case 1:
11770
                /* rotrv is decoded as srlv on non-R2 CPUs */
11771
                if (env->insn_flags & ISA_MIPS32R2) {
11772
                    op1 = OPC_ROTRV;
11773
                }
11774
                /* Fallthrough */
11775
            case 0:
11776
                gen_shift(env, ctx, op1, rd, rs, rt);
11777
                break;
11778
            default:
11779
                generate_exception(ctx, EXCP_RI);
11780
                break;
11781
            }
11782
            break;
11783
        case OPC_SLT:          /* Set on less than */
11784
        case OPC_SLTU:
11785
            gen_slt(env, op1, rd, rs, rt);
11786
            break;
11787
        case OPC_AND:          /* Logic*/
11788
        case OPC_OR:
11789
        case OPC_NOR:
11790
        case OPC_XOR:
11791
            gen_logic(env, op1, rd, rs, rt);
11792
            break;
11793
        case OPC_MULT ... OPC_DIVU:
11794
            if (sa) {
11795
                check_insn(env, ctx, INSN_VR54XX);
11796
                op1 = MASK_MUL_VR54XX(ctx->opcode);
11797
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11798
            } else
11799
                gen_muldiv(ctx, op1, rs, rt);
11800
            break;
11801
        case OPC_JR ... OPC_JALR:
11802
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11803
            *is_branch = 1;
11804
            break;
11805
        case OPC_TGE ... OPC_TEQ: /* Traps */
11806
        case OPC_TNE:
11807
            gen_trap(ctx, op1, rs, rt, -1);
11808
            break;
11809
        case OPC_MFHI:          /* Move from HI/LO */
11810
        case OPC_MFLO:
11811
            gen_HILO(ctx, op1, rd);
11812
            break;
11813
        case OPC_MTHI:
11814
        case OPC_MTLO:          /* Move to HI/LO */
11815
            gen_HILO(ctx, op1, rs);
11816
            break;
11817
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
11818
#ifdef MIPS_STRICT_STANDARD
11819
            MIPS_INVAL("PMON / selsl");
11820
            generate_exception(ctx, EXCP_RI);
11821
#else
11822
            gen_helper_0i(pmon, sa);
11823
#endif
11824
            break;
11825
        case OPC_SYSCALL:
11826
            generate_exception(ctx, EXCP_SYSCALL);
11827
            ctx->bstate = BS_STOP;
11828
            break;
11829
        case OPC_BREAK:
11830
            generate_exception(ctx, EXCP_BREAK);
11831
            break;
11832
        case OPC_SPIM:
11833
#ifdef MIPS_STRICT_STANDARD
11834
            MIPS_INVAL("SPIM");
11835
            generate_exception(ctx, EXCP_RI);
11836
#else
11837
           /* Implemented as RI exception for now. */
11838
            MIPS_INVAL("spim (unofficial)");
11839
            generate_exception(ctx, EXCP_RI);
11840
#endif
11841
            break;
11842
        case OPC_SYNC:
11843
            /* Treat as NOP. */
11844
            break;
11845

    
11846
        case OPC_MOVCI:
11847
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11848
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11849
                check_cp1_enabled(ctx);
11850
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11851
                          (ctx->opcode >> 16) & 1);
11852
            } else {
11853
                generate_exception_err(ctx, EXCP_CpU, 1);
11854
            }
11855
            break;
11856

    
11857
#if defined(TARGET_MIPS64)
11858
       /* MIPS64 specific opcodes */
11859
        case OPC_DSLL:
11860
        case OPC_DSRA:
11861
        case OPC_DSLL32:
11862
        case OPC_DSRA32:
11863
            check_insn(env, ctx, ISA_MIPS3);
11864
            check_mips_64(ctx);
11865
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11866
            break;
11867
        case OPC_DSRL:
11868
            switch ((ctx->opcode >> 21) & 0x1f) {
11869
            case 1:
11870
                /* drotr is decoded as dsrl on non-R2 CPUs */
11871
                if (env->insn_flags & ISA_MIPS32R2) {
11872
                    op1 = OPC_DROTR;
11873
                }
11874
                /* Fallthrough */
11875
            case 0:
11876
                check_insn(env, ctx, ISA_MIPS3);
11877
                check_mips_64(ctx);
11878
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11879
                break;
11880
            default:
11881
                generate_exception(ctx, EXCP_RI);
11882
                break;
11883
            }
11884
            break;
11885
        case OPC_DSRL32:
11886
            switch ((ctx->opcode >> 21) & 0x1f) {
11887
            case 1:
11888
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11889
                if (env->insn_flags & ISA_MIPS32R2) {
11890
                    op1 = OPC_DROTR32;
11891
                }
11892
                /* Fallthrough */
11893
            case 0:
11894
                check_insn(env, ctx, ISA_MIPS3);
11895
                check_mips_64(ctx);
11896
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11897
                break;
11898
            default:
11899
                generate_exception(ctx, EXCP_RI);
11900
                break;
11901
            }
11902
            break;
11903
        case OPC_DADD ... OPC_DSUBU:
11904
            check_insn(env, ctx, ISA_MIPS3);
11905
            check_mips_64(ctx);
11906
            gen_arith(env, ctx, op1, rd, rs, rt);
11907
            break;
11908
        case OPC_DSLLV:
11909
        case OPC_DSRAV:
11910
            check_insn(env, ctx, ISA_MIPS3);
11911
            check_mips_64(ctx);
11912
            gen_shift(env, ctx, op1, rd, rs, rt);
11913
            break;
11914
        case OPC_DSRLV:
11915
            switch ((ctx->opcode >> 6) & 0x1f) {
11916
            case 1:
11917
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
11918
                if (env->insn_flags & ISA_MIPS32R2) {
11919
                    op1 = OPC_DROTRV;
11920
                }
11921
                /* Fallthrough */
11922
            case 0:
11923
                check_insn(env, ctx, ISA_MIPS3);
11924
                check_mips_64(ctx);
11925
                gen_shift(env, ctx, op1, rd, rs, rt);
11926
                break;
11927
            default:
11928
                generate_exception(ctx, EXCP_RI);
11929
                break;
11930
            }
11931
            break;
11932
        case OPC_DMULT ... OPC_DDIVU:
11933
            check_insn(env, ctx, ISA_MIPS3);
11934
            check_mips_64(ctx);
11935
            gen_muldiv(ctx, op1, rs, rt);
11936
            break;
11937
#endif
11938
        default:            /* Invalid */
11939
            MIPS_INVAL("special");
11940
            generate_exception(ctx, EXCP_RI);
11941
            break;
11942
        }
11943
        break;
11944
    case OPC_SPECIAL2:
11945
        op1 = MASK_SPECIAL2(ctx->opcode);
11946
        switch (op1) {
11947
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11948
        case OPC_MSUB ... OPC_MSUBU:
11949
            check_insn(env, ctx, ISA_MIPS32);
11950
            gen_muldiv(ctx, op1, rs, rt);
11951
            break;
11952
        case OPC_MUL:
11953
            gen_arith(env, ctx, op1, rd, rs, rt);
11954
            break;
11955
        case OPC_CLO:
11956
        case OPC_CLZ:
11957
            check_insn(env, ctx, ISA_MIPS32);
11958
            gen_cl(ctx, op1, rd, rs);
11959
            break;
11960
        case OPC_SDBBP:
11961
            /* XXX: not clear which exception should be raised
11962
             *      when in debug mode...
11963
             */
11964
            check_insn(env, ctx, ISA_MIPS32);
11965
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11966
                generate_exception(ctx, EXCP_DBp);
11967
            } else {
11968
                generate_exception(ctx, EXCP_DBp);
11969
            }
11970
            /* Treat as NOP. */
11971
            break;
11972
        case OPC_DIV_G_2F:
11973
        case OPC_DIVU_G_2F:
11974
        case OPC_MULT_G_2F:
11975
        case OPC_MULTU_G_2F:
11976
        case OPC_MOD_G_2F:
11977
        case OPC_MODU_G_2F:
11978
            check_insn(env, ctx, INSN_LOONGSON2F);
11979
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11980
            break;
11981
#if defined(TARGET_MIPS64)
11982
        case OPC_DCLO:
11983
        case OPC_DCLZ:
11984
            check_insn(env, ctx, ISA_MIPS64);
11985
            check_mips_64(ctx);
11986
            gen_cl(ctx, op1, rd, rs);
11987
            break;
11988
        case OPC_DMULT_G_2F:
11989
        case OPC_DMULTU_G_2F:
11990
        case OPC_DDIV_G_2F:
11991
        case OPC_DDIVU_G_2F:
11992
        case OPC_DMOD_G_2F:
11993
        case OPC_DMODU_G_2F:
11994
            check_insn(env, ctx, INSN_LOONGSON2F);
11995
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11996
            break;
11997
#endif
11998
        default:            /* Invalid */
11999
            MIPS_INVAL("special2");
12000
            generate_exception(ctx, EXCP_RI);
12001
            break;
12002
        }
12003
        break;
12004
    case OPC_SPECIAL3:
12005
        op1 = MASK_SPECIAL3(ctx->opcode);
12006
        switch (op1) {
12007
        case OPC_EXT:
12008
        case OPC_INS:
12009
            check_insn(env, ctx, ISA_MIPS32R2);
12010
            gen_bitops(ctx, op1, rt, rs, sa, rd);
12011
            break;
12012
        case OPC_BSHFL:
12013
            check_insn(env, ctx, ISA_MIPS32R2);
12014
            op2 = MASK_BSHFL(ctx->opcode);
12015
            gen_bshfl(ctx, op2, rt, rd);
12016
            break;
12017
        case OPC_RDHWR:
12018
            gen_rdhwr(env, ctx, rt, rd);
12019
            break;
12020
        case OPC_FORK:
12021
            check_insn(env, ctx, ASE_MT);
12022
            {
12023
                TCGv t0 = tcg_temp_new();
12024
                TCGv t1 = tcg_temp_new();
12025

    
12026
                gen_load_gpr(t0, rt);
12027
                gen_load_gpr(t1, rs);
12028
                gen_helper_fork(t0, t1);
12029
                tcg_temp_free(t0);
12030
                tcg_temp_free(t1);
12031
            }
12032
            break;
12033
        case OPC_YIELD:
12034
            check_insn(env, ctx, ASE_MT);
12035
            {
12036
                TCGv t0 = tcg_temp_new();
12037

    
12038
                save_cpu_state(ctx, 1);
12039
                gen_load_gpr(t0, rs);
12040
                gen_helper_yield(t0, t0);
12041
                gen_store_gpr(t0, rd);
12042
                tcg_temp_free(t0);
12043
            }
12044
            break;
12045
        case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
12046
        case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
12047
        case OPC_MOD_G_2E ... OPC_MODU_G_2E:
12048
            check_insn(env, ctx, INSN_LOONGSON2E);
12049
            gen_loongson_integer(ctx, op1, rd, rs, rt);
12050
            break;
12051
#if defined(TARGET_MIPS64)
12052
        case OPC_DEXTM ... OPC_DEXT:
12053
        case OPC_DINSM ... OPC_DINS:
12054
            check_insn(env, ctx, ISA_MIPS64R2);
12055
            check_mips_64(ctx);
12056
            gen_bitops(ctx, op1, rt, rs, sa, rd);
12057
            break;
12058
        case OPC_DBSHFL:
12059
            check_insn(env, ctx, ISA_MIPS64R2);
12060
            check_mips_64(ctx);
12061
            op2 = MASK_DBSHFL(ctx->opcode);
12062
            gen_bshfl(ctx, op2, rt, rd);
12063
            break;
12064
        case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
12065
        case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
12066
        case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
12067
            check_insn(env, ctx, INSN_LOONGSON2E);
12068
            gen_loongson_integer(ctx, op1, rd, rs, rt);
12069
            break;
12070
#endif
12071
        default:            /* Invalid */
12072
            MIPS_INVAL("special3");
12073
            generate_exception(ctx, EXCP_RI);
12074
            break;
12075
        }
12076
        break;
12077
    case OPC_REGIMM:
12078
        op1 = MASK_REGIMM(ctx->opcode);
12079
        switch (op1) {
12080
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
12081
        case OPC_BLTZAL ... OPC_BGEZALL:
12082
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
12083
            *is_branch = 1;
12084
            break;
12085
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
12086
        case OPC_TNEI:
12087
            gen_trap(ctx, op1, rs, -1, imm);
12088
            break;
12089
        case OPC_SYNCI:
12090
            check_insn(env, ctx, ISA_MIPS32R2);
12091
            /* Treat as NOP. */
12092
            break;
12093
        default:            /* Invalid */
12094
            MIPS_INVAL("regimm");
12095
            generate_exception(ctx, EXCP_RI);
12096
            break;
12097
        }
12098
        break;
12099
    case OPC_CP0:
12100
        check_cp0_enabled(ctx);
12101
        op1 = MASK_CP0(ctx->opcode);
12102
        switch (op1) {
12103
        case OPC_MFC0:
12104
        case OPC_MTC0:
12105
        case OPC_MFTR:
12106
        case OPC_MTTR:
12107
#if defined(TARGET_MIPS64)
12108
        case OPC_DMFC0:
12109
        case OPC_DMTC0:
12110
#endif
12111
#ifndef CONFIG_USER_ONLY
12112
            gen_cp0(env, ctx, op1, rt, rd);
12113
#endif /* !CONFIG_USER_ONLY */
12114
            break;
12115
        case OPC_C0_FIRST ... OPC_C0_LAST:
12116
#ifndef CONFIG_USER_ONLY
12117
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12118
#endif /* !CONFIG_USER_ONLY */
12119
            break;
12120
        case OPC_MFMC0:
12121
#ifndef CONFIG_USER_ONLY
12122
            {
12123
                TCGv t0 = tcg_temp_new();
12124

    
12125
                op2 = MASK_MFMC0(ctx->opcode);
12126
                switch (op2) {
12127
                case OPC_DMT:
12128
                    check_insn(env, ctx, ASE_MT);
12129
                    gen_helper_dmt(t0);
12130
                    gen_store_gpr(t0, rt);
12131
                    break;
12132
                case OPC_EMT:
12133
                    check_insn(env, ctx, ASE_MT);
12134
                    gen_helper_emt(t0);
12135
                    gen_store_gpr(t0, rt);
12136
                    break;
12137
                case OPC_DVPE:
12138
                    check_insn(env, ctx, ASE_MT);
12139
                    gen_helper_dvpe(t0);
12140
                    gen_store_gpr(t0, rt);
12141
                    break;
12142
                case OPC_EVPE:
12143
                    check_insn(env, ctx, ASE_MT);
12144
                    gen_helper_evpe(t0);
12145
                    gen_store_gpr(t0, rt);
12146
                    break;
12147
                case OPC_DI:
12148
                    check_insn(env, ctx, ISA_MIPS32R2);
12149
                    save_cpu_state(ctx, 1);
12150
                    gen_helper_di(t0);
12151
                    gen_store_gpr(t0, rt);
12152
                    /* Stop translation as we may have switched the execution mode */
12153
                    ctx->bstate = BS_STOP;
12154
                    break;
12155
                case OPC_EI:
12156
                    check_insn(env, ctx, ISA_MIPS32R2);
12157
                    save_cpu_state(ctx, 1);
12158
                    gen_helper_ei(t0);
12159
                    gen_store_gpr(t0, rt);
12160
                    /* Stop translation as we may have switched the execution mode */
12161
                    ctx->bstate = BS_STOP;
12162
                    break;
12163
                default:            /* Invalid */
12164
                    MIPS_INVAL("mfmc0");
12165
                    generate_exception(ctx, EXCP_RI);
12166
                    break;
12167
                }
12168
                tcg_temp_free(t0);
12169
            }
12170
#endif /* !CONFIG_USER_ONLY */
12171
            break;
12172
        case OPC_RDPGPR:
12173
            check_insn(env, ctx, ISA_MIPS32R2);
12174
            gen_load_srsgpr(rt, rd);
12175
            break;
12176
        case OPC_WRPGPR:
12177
            check_insn(env, ctx, ISA_MIPS32R2);
12178
            gen_store_srsgpr(rt, rd);
12179
            break;
12180
        default:
12181
            MIPS_INVAL("cp0");
12182
            generate_exception(ctx, EXCP_RI);
12183
            break;
12184
        }
12185
        break;
12186
    case OPC_ADDI: /* Arithmetic with immediate opcode */
12187
    case OPC_ADDIU:
12188
         gen_arith_imm(env, ctx, op, rt, rs, imm);
12189
         break;
12190
    case OPC_SLTI: /* Set on less than with immediate opcode */
12191
    case OPC_SLTIU:
12192
         gen_slt_imm(env, op, rt, rs, imm);
12193
         break;
12194
    case OPC_ANDI: /* Arithmetic with immediate opcode */
12195
    case OPC_LUI:
12196
    case OPC_ORI:
12197
    case OPC_XORI:
12198
         gen_logic_imm(env, op, rt, rs, imm);
12199
         break;
12200
    case OPC_J ... OPC_JAL: /* Jump */
12201
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12202
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
12203
         *is_branch = 1;
12204
         break;
12205
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
12206
    case OPC_BEQL ... OPC_BGTZL:
12207
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12208
         *is_branch = 1;
12209
         break;
12210
    case OPC_LB ... OPC_LWR: /* Load and stores */
12211
    case OPC_LL:
12212
         gen_ld(env, ctx, op, rt, rs, imm);
12213
         break;
12214
    case OPC_SB ... OPC_SW:
12215
    case OPC_SWR:
12216
         gen_st(ctx, op, rt, rs, imm);
12217
         break;
12218
    case OPC_SC:
12219
         gen_st_cond(ctx, op, rt, rs, imm);
12220
         break;
12221
    case OPC_CACHE:
12222
        check_cp0_enabled(ctx);
12223
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12224
        /* Treat as NOP. */
12225
        break;
12226
    case OPC_PREF:
12227
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12228
        /* Treat as NOP. */
12229
        break;
12230

    
12231
    /* Floating point (COP1). */
12232
    case OPC_LWC1:
12233
    case OPC_LDC1:
12234
    case OPC_SWC1:
12235
    case OPC_SDC1:
12236
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12237
        break;
12238

    
12239
    case OPC_CP1:
12240
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12241
            check_cp1_enabled(ctx);
12242
            op1 = MASK_CP1(ctx->opcode);
12243
            switch (op1) {
12244
            case OPC_MFHC1:
12245
            case OPC_MTHC1:
12246
                check_insn(env, ctx, ISA_MIPS32R2);
12247
            case OPC_MFC1:
12248
            case OPC_CFC1:
12249
            case OPC_MTC1:
12250
            case OPC_CTC1:
12251
                gen_cp1(ctx, op1, rt, rd);
12252
                break;
12253
#if defined(TARGET_MIPS64)
12254
            case OPC_DMFC1:
12255
            case OPC_DMTC1:
12256
                check_insn(env, ctx, ISA_MIPS3);
12257
                gen_cp1(ctx, op1, rt, rd);
12258
                break;
12259
#endif
12260
            case OPC_BC1ANY2:
12261
            case OPC_BC1ANY4:
12262
                check_cop1x(ctx);
12263
                check_insn(env, ctx, ASE_MIPS3D);
12264
                /* fall through */
12265
            case OPC_BC1:
12266
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12267
                                    (rt >> 2) & 0x7, imm << 2);
12268
                *is_branch = 1;
12269
                break;
12270
            case OPC_S_FMT:
12271
            case OPC_D_FMT:
12272
            case OPC_W_FMT:
12273
            case OPC_L_FMT:
12274
            case OPC_PS_FMT:
12275
                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12276
                           (imm >> 8) & 0x7);
12277
                break;
12278
            default:
12279
                MIPS_INVAL("cp1");
12280
                generate_exception (ctx, EXCP_RI);
12281
                break;
12282
            }
12283
        } else {
12284
            generate_exception_err(ctx, EXCP_CpU, 1);
12285
        }
12286
        break;
12287

    
12288
    /* COP2.  */
12289
    case OPC_LWC2:
12290
    case OPC_LDC2:
12291
    case OPC_SWC2:
12292
    case OPC_SDC2:
12293
    case OPC_CP2:
12294
        /* COP2: Not implemented. */
12295
        generate_exception_err(ctx, EXCP_CpU, 2);
12296
        break;
12297

    
12298
    case OPC_CP3:
12299
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12300
            check_cp1_enabled(ctx);
12301
            op1 = MASK_CP3(ctx->opcode);
12302
            switch (op1) {
12303
            case OPC_LWXC1:
12304
            case OPC_LDXC1:
12305
            case OPC_LUXC1:
12306
            case OPC_SWXC1:
12307
            case OPC_SDXC1:
12308
            case OPC_SUXC1:
12309
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12310
                break;
12311
            case OPC_PREFX:
12312
                /* Treat as NOP. */
12313
                break;
12314
            case OPC_ALNV_PS:
12315
            case OPC_MADD_S:
12316
            case OPC_MADD_D:
12317
            case OPC_MADD_PS:
12318
            case OPC_MSUB_S:
12319
            case OPC_MSUB_D:
12320
            case OPC_MSUB_PS:
12321
            case OPC_NMADD_S:
12322
            case OPC_NMADD_D:
12323
            case OPC_NMADD_PS:
12324
            case OPC_NMSUB_S:
12325
            case OPC_NMSUB_D:
12326
            case OPC_NMSUB_PS:
12327
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12328
                break;
12329
            default:
12330
                MIPS_INVAL("cp3");
12331
                generate_exception (ctx, EXCP_RI);
12332
                break;
12333
            }
12334
        } else {
12335
            generate_exception_err(ctx, EXCP_CpU, 1);
12336
        }
12337
        break;
12338

    
12339
#if defined(TARGET_MIPS64)
12340
    /* MIPS64 opcodes */
12341
    case OPC_LWU:
12342
    case OPC_LDL ... OPC_LDR:
12343
    case OPC_LLD:
12344
    case OPC_LD:
12345
        check_insn(env, ctx, ISA_MIPS3);
12346
        check_mips_64(ctx);
12347
        gen_ld(env, ctx, op, rt, rs, imm);
12348
        break;
12349
    case OPC_SDL ... OPC_SDR:
12350
    case OPC_SD:
12351
        check_insn(env, ctx, ISA_MIPS3);
12352
        check_mips_64(ctx);
12353
        gen_st(ctx, op, rt, rs, imm);
12354
        break;
12355
    case OPC_SCD:
12356
        check_insn(env, ctx, ISA_MIPS3);
12357
        check_mips_64(ctx);
12358
        gen_st_cond(ctx, op, rt, rs, imm);
12359
        break;
12360
    case OPC_DADDI:
12361
    case OPC_DADDIU:
12362
        check_insn(env, ctx, ISA_MIPS3);
12363
        check_mips_64(ctx);
12364
        gen_arith_imm(env, ctx, op, rt, rs, imm);
12365
        break;
12366
#endif
12367
    case OPC_JALX:
12368
        check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12369
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12370
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
12371
        *is_branch = 1;
12372
        break;
12373
    case OPC_MDMX:
12374
        check_insn(env, ctx, ASE_MDMX);
12375
        /* MDMX: Not implemented. */
12376
    default:            /* Invalid */
12377
        MIPS_INVAL("major opcode");
12378
        generate_exception(ctx, EXCP_RI);
12379
        break;
12380
    }
12381
}
12382

    
12383
static inline void
12384
gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
12385
                                int search_pc)
12386
{
12387
    DisasContext ctx;
12388
    target_ulong pc_start;
12389
    uint16_t *gen_opc_end;
12390
    CPUBreakpoint *bp;
12391
    int j, lj = -1;
12392
    int num_insns;
12393
    int max_insns;
12394
    int insn_bytes;
12395
    int is_branch;
12396

    
12397
    if (search_pc)
12398
        qemu_log("search pc %d\n", search_pc);
12399

    
12400
    pc_start = tb->pc;
12401
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12402
    ctx.pc = pc_start;
12403
    ctx.saved_pc = -1;
12404
    ctx.singlestep_enabled = env->singlestep_enabled;
12405
    ctx.tb = tb;
12406
    ctx.bstate = BS_NONE;
12407
    /* Restore delay slot state from the tb context.  */
12408
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12409
    restore_cpu_state(env, &ctx);
12410
#ifdef CONFIG_USER_ONLY
12411
        ctx.mem_idx = MIPS_HFLAG_UM;
12412
#else
12413
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12414
#endif
12415
    num_insns = 0;
12416
    max_insns = tb->cflags & CF_COUNT_MASK;
12417
    if (max_insns == 0)
12418
        max_insns = CF_COUNT_MASK;
12419
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12420
    gen_icount_start();
12421
    while (ctx.bstate == BS_NONE) {
12422
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12423
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12424
                if (bp->pc == ctx.pc) {
12425
                    save_cpu_state(&ctx, 1);
12426
                    ctx.bstate = BS_BRANCH;
12427
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
12428
                    /* Include the breakpoint location or the tb won't
12429
                     * be flushed when it must be.  */
12430
                    ctx.pc += 4;
12431
                    goto done_generating;
12432
                }
12433
            }
12434
        }
12435

    
12436
        if (search_pc) {
12437
            j = gen_opc_ptr - gen_opc_buf;
12438
            if (lj < j) {
12439
                lj++;
12440
                while (lj < j)
12441
                    gen_opc_instr_start[lj++] = 0;
12442
            }
12443
            gen_opc_pc[lj] = ctx.pc;
12444
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12445
            gen_opc_instr_start[lj] = 1;
12446
            gen_opc_icount[lj] = num_insns;
12447
        }
12448
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12449
            gen_io_start();
12450

    
12451
        is_branch = 0;
12452
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12453
            ctx.opcode = ldl_code(ctx.pc);
12454
            insn_bytes = 4;
12455
            decode_opc(env, &ctx, &is_branch);
12456
        } else if (env->insn_flags & ASE_MICROMIPS) {
12457
            ctx.opcode = lduw_code(ctx.pc);
12458
            insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12459
        } else if (env->insn_flags & ASE_MIPS16) {
12460
            ctx.opcode = lduw_code(ctx.pc);
12461
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12462
        } else {
12463
            generate_exception(&ctx, EXCP_RI);
12464
            ctx.bstate = BS_STOP;
12465
            break;
12466
        }
12467
        if (!is_branch) {
12468
            handle_delay_slot(env, &ctx, insn_bytes);
12469
        }
12470
        ctx.pc += insn_bytes;
12471

    
12472
        num_insns++;
12473

    
12474
        /* Execute a branch and its delay slot as a single instruction.
12475
           This is what GDB expects and is consistent with what the
12476
           hardware does (e.g. if a delay slot instruction faults, the
12477
           reported PC is the PC of the branch).  */
12478
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12479
            break;
12480

    
12481
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12482
            break;
12483

    
12484
        if (gen_opc_ptr >= gen_opc_end)
12485
            break;
12486

    
12487
        if (num_insns >= max_insns)
12488
            break;
12489

    
12490
        if (singlestep)
12491
            break;
12492
    }
12493
    if (tb->cflags & CF_LAST_IO)
12494
        gen_io_end();
12495
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12496
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12497
        gen_helper_0i(raise_exception, EXCP_DEBUG);
12498
    } else {
12499
        switch (ctx.bstate) {
12500
        case BS_STOP:
12501
            gen_goto_tb(&ctx, 0, ctx.pc);
12502
            break;
12503
        case BS_NONE:
12504
            save_cpu_state(&ctx, 0);
12505
            gen_goto_tb(&ctx, 0, ctx.pc);
12506
            break;
12507
        case BS_EXCP:
12508
            tcg_gen_exit_tb(0);
12509
            break;
12510
        case BS_BRANCH:
12511
        default:
12512
            break;
12513
        }
12514
    }
12515
done_generating:
12516
    gen_icount_end(tb, num_insns);
12517
    *gen_opc_ptr = INDEX_op_end;
12518
    if (search_pc) {
12519
        j = gen_opc_ptr - gen_opc_buf;
12520
        lj++;
12521
        while (lj <= j)
12522
            gen_opc_instr_start[lj++] = 0;
12523
    } else {
12524
        tb->size = ctx.pc - pc_start;
12525
        tb->icount = num_insns;
12526
    }
12527
#ifdef DEBUG_DISAS
12528
    LOG_DISAS("\n");
12529
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12530
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
12531
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
12532
        qemu_log("\n");
12533
    }
12534
#endif
12535
}
12536

    
12537
void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
12538
{
12539
    gen_intermediate_code_internal(env, tb, 0);
12540
}
12541

    
12542
void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
12543
{
12544
    gen_intermediate_code_internal(env, tb, 1);
12545
}
12546

    
12547
static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
12548
                           int flags)
12549
{
12550
    int i;
12551
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12552

    
12553
#define printfpr(fp)                                                    \
12554
    do {                                                                \
12555
        if (is_fpu64)                                                   \
12556
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12557
                        " fd:%13g fs:%13g psu: %13g\n",                 \
12558
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
12559
                        (double)(fp)->fd,                               \
12560
                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
12561
                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
12562
        else {                                                          \
12563
            fpr_t tmp;                                                  \
12564
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
12565
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
12566
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12567
                        " fd:%13g fs:%13g psu:%13g\n",                  \
12568
                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
12569
                        (double)tmp.fd,                                 \
12570
                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
12571
                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
12572
        }                                                               \
12573
    } while(0)
12574

    
12575

    
12576
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
12577
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12578
                get_float_exception_flags(&env->active_fpu.fp_status));
12579
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12580
        fpu_fprintf(f, "%3s: ", fregnames[i]);
12581
        printfpr(&env->active_fpu.fpr[i]);
12582
    }
12583

    
12584
#undef printfpr
12585
}
12586

    
12587
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12588
/* Debug help: The architecture requires 32bit code to maintain proper
12589
   sign-extended values on 64bit machines.  */
12590

    
12591
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12592

    
12593
static void
12594
cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
12595
                                fprintf_function cpu_fprintf,
12596
                                int flags)
12597
{
12598
    int i;
12599

    
12600
    if (!SIGN_EXT_P(env->active_tc.PC))
12601
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12602
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
12603
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12604
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
12605
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12606
    if (!SIGN_EXT_P(env->btarget))
12607
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12608

    
12609
    for (i = 0; i < 32; i++) {
12610
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12611
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12612
    }
12613

    
12614
    if (!SIGN_EXT_P(env->CP0_EPC))
12615
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12616
    if (!SIGN_EXT_P(env->lladdr))
12617
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12618
}
12619
#endif
12620

    
12621
void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
12622
                     int flags)
12623
{
12624
    int i;
12625

    
12626
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12627
                " LO=0x" TARGET_FMT_lx " ds %04x "
12628
                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12629
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12630
                env->hflags, env->btarget, env->bcond);
12631
    for (i = 0; i < 32; i++) {
12632
        if ((i & 3) == 0)
12633
            cpu_fprintf(f, "GPR%02d:", i);
12634
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12635
        if ((i & 3) == 3)
12636
            cpu_fprintf(f, "\n");
12637
    }
12638

    
12639
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
12640
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12641
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12642
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
12643
    if (env->hflags & MIPS_HFLAG_FPU)
12644
        fpu_dump_state(env, f, cpu_fprintf, flags);
12645
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12646
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12647
#endif
12648
}
12649

    
12650
static void mips_tcg_init(void)
12651
{
12652
    int i;
12653
    static int inited;
12654

    
12655
    /* Initialize various static tables. */
12656
    if (inited)
12657
        return;
12658

    
12659
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12660
    TCGV_UNUSED(cpu_gpr[0]);
12661
    for (i = 1; i < 32; i++)
12662
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12663
                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
12664
                                        regnames[i]);
12665
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
12666
                                offsetof(CPUMIPSState, active_tc.PC), "PC");
12667
    for (i = 0; i < MIPS_DSP_ACC; i++) {
12668
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12669
                                       offsetof(CPUMIPSState, active_tc.HI[i]),
12670
                                       regnames_HI[i]);
12671
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12672
                                       offsetof(CPUMIPSState, active_tc.LO[i]),
12673
                                       regnames_LO[i]);
12674
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12675
                                        offsetof(CPUMIPSState, active_tc.ACX[i]),
12676
                                        regnames_ACX[i]);
12677
    }
12678
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12679
                                     offsetof(CPUMIPSState, active_tc.DSPControl),
12680
                                     "DSPControl");
12681
    bcond = tcg_global_mem_new(TCG_AREG0,
12682
                               offsetof(CPUMIPSState, bcond), "bcond");
12683
    btarget = tcg_global_mem_new(TCG_AREG0,
12684
                                 offsetof(CPUMIPSState, btarget), "btarget");
12685
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
12686
                                    offsetof(CPUMIPSState, hflags), "hflags");
12687

    
12688
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12689
                                      offsetof(CPUMIPSState, active_fpu.fcr0),
12690
                                      "fcr0");
12691
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12692
                                       offsetof(CPUMIPSState, active_fpu.fcr31),
12693
                                       "fcr31");
12694

    
12695
    /* register helpers */
12696
#define GEN_HELPER 2
12697
#include "helper.h"
12698

    
12699
    inited = 1;
12700
}
12701

    
12702
#include "translate_init.c"
12703

    
12704
MIPSCPU *cpu_mips_init(const char *cpu_model)
12705
{
12706
    MIPSCPU *cpu;
12707
    CPUMIPSState *env;
12708
    const mips_def_t *def;
12709

    
12710
    def = cpu_mips_find_by_name(cpu_model);
12711
    if (!def)
12712
        return NULL;
12713
    cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
12714
    env = &cpu->env;
12715
    env->cpu_model = def;
12716
    env->cpu_model_str = cpu_model;
12717

    
12718
#ifndef CONFIG_USER_ONLY
12719
    mmu_init(env, def);
12720
#endif
12721
    fpu_init(env, def);
12722
    mvp_init(env, def);
12723
    mips_tcg_init();
12724
    cpu_reset(CPU(cpu));
12725
    qemu_init_vcpu(env);
12726
    return cpu;
12727
}
12728

    
12729
void cpu_state_reset(CPUMIPSState *env)
12730
{
12731
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12732
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12733
        log_cpu_state(env, 0);
12734
    }
12735

    
12736
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12737
    tlb_flush(env, 1);
12738

    
12739
    /* Reset registers to their default values */
12740
    env->CP0_PRid = env->cpu_model->CP0_PRid;
12741
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
12742
#ifdef TARGET_WORDS_BIGENDIAN
12743
    env->CP0_Config0 |= (1 << CP0C0_BE);
12744
#endif
12745
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
12746
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
12747
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
12748
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
12749
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
12750
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12751
                                 << env->cpu_model->CP0_LLAddr_shift;
12752
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12753
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12754
    env->CCRes = env->cpu_model->CCRes;
12755
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12756
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12757
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12758
    env->current_tc = 0;
12759
    env->SEGBITS = env->cpu_model->SEGBITS;
12760
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12761
#if defined(TARGET_MIPS64)
12762
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12763
        env->SEGMask |= 3ULL << 62;
12764
    }
12765
#endif
12766
    env->PABITS = env->cpu_model->PABITS;
12767
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12768
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12769
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12770
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12771
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12772
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12773
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12774
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12775
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12776
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12777
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12778
    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
12779
    env->insn_flags = env->cpu_model->insn_flags;
12780

    
12781
#if defined(CONFIG_USER_ONLY)
12782
    env->hflags = MIPS_HFLAG_UM;
12783
    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
12784
       hardware registers.  */
12785
    env->CP0_HWREna |= 0x0000000F;
12786
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12787
        env->hflags |= MIPS_HFLAG_FPU;
12788
    }
12789
#ifdef TARGET_MIPS64
12790
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12791
        env->hflags |= MIPS_HFLAG_F64;
12792
    }
12793
#endif
12794
#else
12795
    if (env->hflags & MIPS_HFLAG_BMASK) {
12796
        /* If the exception was raised from a delay slot,
12797
           come back to the jump.  */
12798
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
12799
    } else {
12800
        env->CP0_ErrorEPC = env->active_tc.PC;
12801
    }
12802
    env->active_tc.PC = (int32_t)0xBFC00000;
12803
    env->CP0_Random = env->tlb->nb_tlb - 1;
12804
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
12805
    env->CP0_Wired = 0;
12806
    env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12807
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12808
    /* vectored interrupts not implemented, timer on int 7,
12809
       no performance counters. */
12810
    env->CP0_IntCtl = 0xe0000000;
12811
    {
12812
        int i;
12813

    
12814
        for (i = 0; i < 7; i++) {
12815
            env->CP0_WatchLo[i] = 0;
12816
            env->CP0_WatchHi[i] = 0x80000000;
12817
        }
12818
        env->CP0_WatchLo[7] = 0;
12819
        env->CP0_WatchHi[7] = 0;
12820
    }
12821
    /* Count register increments in debug mode, EJTAG version 1 */
12822
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12823
    env->hflags = MIPS_HFLAG_CP0;
12824

    
12825
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
12826
        int i;
12827

    
12828
        /* Only TC0 on VPE 0 starts as active.  */
12829
        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
12830
            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
12831
            env->tcs[i].CP0_TCHalt = 1;
12832
        }
12833
        env->active_tc.CP0_TCHalt = 1;
12834
        env->halted = 1;
12835

    
12836
        if (!env->cpu_index) {
12837
            /* VPE0 starts up enabled.  */
12838
            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
12839
            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
12840

    
12841
            /* TC0 starts up unhalted.  */
12842
            env->halted = 0;
12843
            env->active_tc.CP0_TCHalt = 0;
12844
            env->tcs[0].CP0_TCHalt = 0;
12845
            /* With thread 0 active.  */
12846
            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
12847
            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
12848
        }
12849
    }
12850
#endif
12851
#if defined(TARGET_MIPS64)
12852
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12853
        env->hflags |= MIPS_HFLAG_64;
12854
    }
12855
#endif
12856
    env->exception_index = EXCP_NONE;
12857
}
12858

    
12859
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
12860
{
12861
    env->active_tc.PC = gen_opc_pc[pc_pos];
12862
    env->hflags &= ~MIPS_HFLAG_BMASK;
12863
    env->hflags |= gen_opc_hflags[pc_pos];
12864
}