Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 7267c094

History | View | Annotate | Download (361.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 <stdarg.h>
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <inttypes.h>
28

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

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

    
38
//#define MIPS_DEBUG_DISAS
39
//#define MIPS_DEBUG_SIGN_EXTENSIONS
40

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

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

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

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

    
198
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
199

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

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

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

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

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

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

    
259
/* Special2 opcodes */
260
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
261

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

    
291
/* Special3 opcodes */
292
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
293

    
294
enum {
295
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
296
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
297
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
298
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
299
    OPC_INS      = 0x04 | OPC_SPECIAL3,
300
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
301
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
302
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
303
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
304
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
305
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
306
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
307
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
308

    
309
    /* Loongson 2E */
310
    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
311
    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
312
    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
313
    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
314
    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
315
    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
316
    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
317
    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
318
    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
319
    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
320
    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
321
    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
322
};
323

    
324
/* BSHFL opcodes */
325
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
326

    
327
enum {
328
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
329
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
330
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
331
};
332

    
333
/* DBSHFL opcodes */
334
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
335

    
336
enum {
337
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
338
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
339
};
340

    
341
/* Coprocessor 0 (rs field) */
342
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
343

    
344
enum {
345
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
346
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
347
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
348
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
349
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
350
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
351
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
352
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
353
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
354
    OPC_C0       = (0x10 << 21) | OPC_CP0,
355
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
356
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
357
};
358

    
359
/* MFMC0 opcodes */
360
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
361

    
362
enum {
363
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
364
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
365
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
366
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
367
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
368
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
369
};
370

    
371
/* Coprocessor 0 (with rs == C0) */
372
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
373

    
374
enum {
375
    OPC_TLBR     = 0x01 | OPC_C0,
376
    OPC_TLBWI    = 0x02 | OPC_C0,
377
    OPC_TLBWR    = 0x06 | OPC_C0,
378
    OPC_TLBP     = 0x08 | OPC_C0,
379
    OPC_RFE      = 0x10 | OPC_C0,
380
    OPC_ERET     = 0x18 | OPC_C0,
381
    OPC_DERET    = 0x1F | OPC_C0,
382
    OPC_WAIT     = 0x20 | OPC_C0,
383
};
384

    
385
/* Coprocessor 1 (rs field) */
386
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387

    
388
/* Values for the fmt field in FP instructions */
389
enum {
390
    /* 0 - 15 are reserved */
391
    FMT_S = 16,          /* single fp */
392
    FMT_D = 17,          /* double fp */
393
    FMT_E = 18,          /* extended fp */
394
    FMT_Q = 19,          /* quad fp */
395
    FMT_W = 20,          /* 32-bit fixed */
396
    FMT_L = 21,          /* 64-bit fixed */
397
    FMT_PS = 22,         /* paired single fp */
398
    /* 23 - 31 are reserved */
399
};
400

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

    
422
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
423
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
424

    
425
enum {
426
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
427
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
428
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
429
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
430
};
431

    
432
enum {
433
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
434
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
435
};
436

    
437
enum {
438
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
439
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
440
};
441

    
442
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
443

    
444
enum {
445
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
446
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
447
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
448
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
449
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
450
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
451
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
452
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
453
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
454
};
455

    
456
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
457

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

    
481
/* global register indices */
482
static TCGv_ptr cpu_env;
483
static TCGv cpu_gpr[32], cpu_PC;
484
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
485
static TCGv cpu_dspctrl, btarget, bcond;
486
static TCGv_i32 hflags;
487
static TCGv_i32 fpu_fcr0, fpu_fcr31;
488

    
489
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
490

    
491
#include "gen-icount.h"
492

    
493
#define gen_helper_0i(name, arg) do {                             \
494
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
495
    gen_helper_##name(helper_tmp);                                \
496
    tcg_temp_free_i32(helper_tmp);                                \
497
    } while(0)
498

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

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

    
511
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
512
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
513
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
514
    tcg_temp_free_i32(helper_tmp);                                \
515
    } while(0)
516

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

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

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

    
543
static const char *regnames_HI[] =
544
    { "HI0", "HI1", "HI2", "HI3", };
545

    
546
static const char *regnames_LO[] =
547
    { "LO0", "LO1", "LO2", "LO3", };
548

    
549
static const char *regnames_ACX[] =
550
    { "ACX0", "ACX1", "ACX2", "ACX3", };
551

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

    
558
#ifdef MIPS_DEBUG_DISAS
559
#define MIPS_DEBUG(fmt, ...)                         \
560
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
561
                       TARGET_FMT_lx ": %08x " fmt "\n", \
562
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
563
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
564
#else
565
#define MIPS_DEBUG(fmt, ...) do { } while(0)
566
#define LOG_DISAS(...) do { } while (0)
567
#endif
568

    
569
#define MIPS_INVAL(op)                                                        \
570
do {                                                                          \
571
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
572
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
573
} while (0)
574

    
575
/* General purpose registers moves. */
576
static inline void gen_load_gpr (TCGv t, int reg)
577
{
578
    if (reg == 0)
579
        tcg_gen_movi_tl(t, 0);
580
    else
581
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
582
}
583

    
584
static inline void gen_store_gpr (TCGv t, int reg)
585
{
586
    if (reg != 0)
587
        tcg_gen_mov_tl(cpu_gpr[reg], t);
588
}
589

    
590
/* Moves to/from ACX register.  */
591
static inline void gen_load_ACX (TCGv t, int reg)
592
{
593
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
594
}
595

    
596
static inline void gen_store_ACX (TCGv t, int reg)
597
{
598
    tcg_gen_mov_tl(cpu_ACX[reg], t);
599
}
600

    
601
/* Moves to/from shadow registers. */
602
static inline void gen_load_srsgpr (int from, int to)
603
{
604
    TCGv t0 = tcg_temp_new();
605

    
606
    if (from == 0)
607
        tcg_gen_movi_tl(t0, 0);
608
    else {
609
        TCGv_i32 t2 = tcg_temp_new_i32();
610
        TCGv_ptr addr = tcg_temp_new_ptr();
611

    
612
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
613
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
614
        tcg_gen_andi_i32(t2, t2, 0xf);
615
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
616
        tcg_gen_ext_i32_ptr(addr, t2);
617
        tcg_gen_add_ptr(addr, cpu_env, addr);
618

    
619
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
620
        tcg_temp_free_ptr(addr);
621
        tcg_temp_free_i32(t2);
622
    }
623
    gen_store_gpr(t0, to);
624
    tcg_temp_free(t0);
625
}
626

    
627
static inline void gen_store_srsgpr (int from, int to)
628
{
629
    if (to != 0) {
630
        TCGv t0 = tcg_temp_new();
631
        TCGv_i32 t2 = tcg_temp_new_i32();
632
        TCGv_ptr addr = tcg_temp_new_ptr();
633

    
634
        gen_load_gpr(t0, from);
635
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
636
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
637
        tcg_gen_andi_i32(t2, t2, 0xf);
638
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
639
        tcg_gen_ext_i32_ptr(addr, t2);
640
        tcg_gen_add_ptr(addr, cpu_env, addr);
641

    
642
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
643
        tcg_temp_free_ptr(addr);
644
        tcg_temp_free_i32(t2);
645
        tcg_temp_free(t0);
646
    }
647
}
648

    
649
/* Floating point register moves. */
650
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
651
{
652
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
653
}
654

    
655
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
656
{
657
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
658
}
659

    
660
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
661
{
662
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
663
}
664

    
665
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
666
{
667
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
668
}
669

    
670
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
671
{
672
    if (ctx->hflags & MIPS_HFLAG_F64) {
673
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
674
    } else {
675
        TCGv_i32 t0 = tcg_temp_new_i32();
676
        TCGv_i32 t1 = tcg_temp_new_i32();
677
        gen_load_fpr32(t0, reg & ~1);
678
        gen_load_fpr32(t1, reg | 1);
679
        tcg_gen_concat_i32_i64(t, t0, t1);
680
        tcg_temp_free_i32(t0);
681
        tcg_temp_free_i32(t1);
682
    }
683
}
684

    
685
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
686
{
687
    if (ctx->hflags & MIPS_HFLAG_F64) {
688
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
689
    } else {
690
        TCGv_i64 t0 = tcg_temp_new_i64();
691
        TCGv_i32 t1 = tcg_temp_new_i32();
692
        tcg_gen_trunc_i64_i32(t1, t);
693
        gen_store_fpr32(t1, reg & ~1);
694
        tcg_gen_shri_i64(t0, t, 32);
695
        tcg_gen_trunc_i64_i32(t1, t0);
696
        gen_store_fpr32(t1, reg | 1);
697
        tcg_temp_free_i32(t1);
698
        tcg_temp_free_i64(t0);
699
    }
700
}
701

    
702
static inline int get_fp_bit (int cc)
703
{
704
    if (cc)
705
        return 24 + cc;
706
    else
707
        return 23;
708
}
709

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
903
FOP_CONDS(, 0, d, FMT_D, 64)
904
FOP_CONDS(abs, 1, d, FMT_D, 64)
905
FOP_CONDS(, 0, s, FMT_S, 32)
906
FOP_CONDS(abs, 1, s, FMT_S, 32)
907
FOP_CONDS(, 0, ps, FMT_PS, 64)
908
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
909
#undef FOP_CONDS
910
#undef gen_ldcmp_fpr32
911
#undef gen_ldcmp_fpr64
912

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

    
930
#define OP_ST(insn,fname)                                                  \
931
static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
932
{                                                                          \
933
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
934
}
935
OP_ST(sb,st8);
936
OP_ST(sh,st16);
937
OP_ST(sw,st32);
938
#if defined(TARGET_MIPS64)
939
OP_ST(sd,st64);
940
#endif
941
#undef OP_ST
942

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

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

    
1007
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1008
                                  int base, int16_t offset)
1009
{
1010
    if (base == 0) {
1011
        tcg_gen_movi_tl(addr, offset);
1012
    } else if (offset == 0) {
1013
        gen_load_gpr(addr, base);
1014
    } else {
1015
        tcg_gen_movi_tl(addr, offset);
1016
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1017
    }
1018
}
1019

    
1020
static target_ulong pc_relative_pc (DisasContext *ctx)
1021
{
1022
    target_ulong pc = ctx->pc;
1023

    
1024
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1025
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1026

    
1027
        pc -= branch_bytes;
1028
    }
1029

    
1030
    pc &= ~(target_ulong)3;
1031
    return pc;
1032
}
1033

    
1034
/* Load */
1035
static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
1036
                    int rt, int base, int16_t offset)
1037
{
1038
    const char *opn = "ld";
1039
    TCGv t0, t1;
1040

    
1041
    if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1042
        /* Loongson CPU uses a load to zero register for prefetch.
1043
           We emulate it as a NOP. On other CPU we must perform the
1044
           actual memory access. */
1045
        MIPS_DEBUG("NOP");
1046
        return;
1047
    }
1048

    
1049
    t0 = tcg_temp_new();
1050
    t1 = tcg_temp_new();
1051
    gen_base_offset_addr(ctx, t0, base, offset);
1052

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

    
1161
/* Store */
1162
static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1163
                    int base, int16_t offset)
1164
{
1165
    const char *opn = "st";
1166
    TCGv t0 = tcg_temp_new();
1167
    TCGv t1 = tcg_temp_new();
1168

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

    
1221

    
1222
/* Store conditional */
1223
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1224
                         int base, int16_t offset)
1225
{
1226
    const char *opn = "st_cond";
1227
    TCGv t0, t1;
1228

    
1229
    t0 = tcg_temp_local_new();
1230

    
1231
    gen_base_offset_addr(ctx, t0, base, offset);
1232
    /* Don't do NOP if destination is zero: we must perform the actual
1233
       memory access. */
1234

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

    
1257
/* Load and store */
1258
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1259
                          int base, int16_t offset)
1260
{
1261
    const char *opn = "flt_ldst";
1262
    TCGv t0 = tcg_temp_new();
1263

    
1264
    gen_base_offset_addr(ctx, t0, base, offset);
1265
    /* Don't do NOP if destination is zero: we must perform the actual
1266
       memory access. */
1267
    switch (opc) {
1268
    case OPC_LWC1:
1269
        {
1270
            TCGv_i32 fp0 = tcg_temp_new_i32();
1271

    
1272
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1273
            tcg_gen_trunc_tl_i32(fp0, t0);
1274
            gen_store_fpr32(fp0, ft);
1275
            tcg_temp_free_i32(fp0);
1276
        }
1277
        opn = "lwc1";
1278
        break;
1279
    case OPC_SWC1:
1280
        {
1281
            TCGv_i32 fp0 = tcg_temp_new_i32();
1282
            TCGv t1 = tcg_temp_new();
1283

    
1284
            gen_load_fpr32(fp0, ft);
1285
            tcg_gen_extu_i32_tl(t1, fp0);
1286
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1287
            tcg_temp_free(t1);
1288
            tcg_temp_free_i32(fp0);
1289
        }
1290
        opn = "swc1";
1291
        break;
1292
    case OPC_LDC1:
1293
        {
1294
            TCGv_i64 fp0 = tcg_temp_new_i64();
1295

    
1296
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1297
            gen_store_fpr64(ctx, fp0, ft);
1298
            tcg_temp_free_i64(fp0);
1299
        }
1300
        opn = "ldc1";
1301
        break;
1302
    case OPC_SDC1:
1303
        {
1304
            TCGv_i64 fp0 = tcg_temp_new_i64();
1305

    
1306
            gen_load_fpr64(ctx, fp0, ft);
1307
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1308
            tcg_temp_free_i64(fp0);
1309
        }
1310
        opn = "sdc1";
1311
        break;
1312
    default:
1313
        MIPS_INVAL(opn);
1314
        generate_exception(ctx, EXCP_RI);
1315
        goto out;
1316
    }
1317
    (void)opn; /* avoid a compiler warning */
1318
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1319
 out:
1320
    tcg_temp_free(t0);
1321
}
1322

    
1323
static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1324
                          uint32_t op, int rt, int rs, int16_t imm)
1325
{
1326
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1327
        check_cp1_enabled(ctx);
1328
        gen_flt_ldst(ctx, op, rt, rs, imm);
1329
    } else {
1330
        generate_exception_err(ctx, EXCP_CpU, 1);
1331
    }
1332
}
1333

    
1334
/* Arithmetic with immediate operand */
1335
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1336
                           int rt, int rs, int16_t imm)
1337
{
1338
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1339
    const char *opn = "imm arith";
1340

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

    
1355
            gen_load_gpr(t1, rs);
1356
            tcg_gen_addi_tl(t0, t1, uimm);
1357
            tcg_gen_ext32s_tl(t0, t0);
1358

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

    
1391
            gen_load_gpr(t1, rs);
1392
            tcg_gen_addi_tl(t0, t1, uimm);
1393

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

    
1422
/* Logic with immediate operand */
1423
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1424
{
1425
    target_ulong uimm;
1426
    const char *opn = "imm logic";
1427

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

    
1465
/* Set on less than with immediate operand */
1466
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1467
{
1468
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1469
    const char *opn = "imm arith";
1470
    TCGv t0;
1471

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

    
1494
/* Shifts with immediate operand */
1495
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1496
                          int rt, int rs, int16_t imm)
1497
{
1498
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1499
    const char *opn = "imm shift";
1500
    TCGv t0;
1501

    
1502
    if (rt == 0) {
1503
        /* If no destination, treat it as a NOP. */
1504
        MIPS_DEBUG("NOP");
1505
        return;
1506
    }
1507

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

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

    
1586
/* Arithmetic */
1587
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1588
                       int rd, int rs, int rt)
1589
{
1590
    const char *opn = "arith";
1591

    
1592
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1593
       && opc != OPC_DADD && opc != OPC_DSUB) {
1594
        /* If no destination, treat it as a NOP.
1595
           For add & sub, we must generate the overflow exception when needed. */
1596
        MIPS_DEBUG("NOP");
1597
        return;
1598
    }
1599

    
1600
    switch (opc) {
1601
    case OPC_ADD:
1602
        {
1603
            TCGv t0 = tcg_temp_local_new();
1604
            TCGv t1 = tcg_temp_new();
1605
            TCGv t2 = tcg_temp_new();
1606
            int l1 = gen_new_label();
1607

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

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

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

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

    
1766
/* Conditional move */
1767
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1768
{
1769
    const char *opn = "cond move";
1770
    int l1;
1771

    
1772
    if (rd == 0) {
1773
        /* If no destination, treat it as a NOP.
1774
           For add & sub, we must generate the overflow exception when needed. */
1775
        MIPS_DEBUG("NOP");
1776
        return;
1777
    }
1778

    
1779
    l1 = gen_new_label();
1780
    switch (opc) {
1781
    case OPC_MOVN:
1782
        if (likely(rt != 0))
1783
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1784
        else
1785
            tcg_gen_br(l1);
1786
        opn = "movn";
1787
        break;
1788
    case OPC_MOVZ:
1789
        if (likely(rt != 0))
1790
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1791
        opn = "movz";
1792
        break;
1793
    }
1794
    if (rs != 0)
1795
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1796
    else
1797
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1798
    gen_set_label(l1);
1799

    
1800
    (void)opn; /* avoid a compiler warning */
1801
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1802
}
1803

    
1804
/* Logic */
1805
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1806
{
1807
    const char *opn = "logic";
1808

    
1809
    if (rd == 0) {
1810
        /* If no destination, treat it as a NOP. */
1811
        MIPS_DEBUG("NOP");
1812
        return;
1813
    }
1814

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

    
1865
/* Set on lower than */
1866
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1867
{
1868
    const char *opn = "slt";
1869
    TCGv t0, t1;
1870

    
1871
    if (rd == 0) {
1872
        /* If no destination, treat it as a NOP. */
1873
        MIPS_DEBUG("NOP");
1874
        return;
1875
    }
1876

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

    
1897
/* Shifts */
1898
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1899
                       int rd, int rs, int rt)
1900
{
1901
    const char *opn = "shifts";
1902
    TCGv t0, t1;
1903

    
1904
    if (rd == 0) {
1905
        /* If no destination, treat it as a NOP.
1906
           For add & sub, we must generate the overflow exception when needed. */
1907
        MIPS_DEBUG("NOP");
1908
        return;
1909
    }
1910

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

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

    
1978
/* Arithmetic on HI/LO registers */
1979
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1980
{
1981
    const char *opn = "hilo";
1982

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

    
2016
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2017
                        int rs, int rt)
2018
{
2019
    const char *opn = "mul/div";
2020
    TCGv t0, t1;
2021

    
2022
    switch (opc) {
2023
    case OPC_DIV:
2024
    case OPC_DIVU:
2025
#if defined(TARGET_MIPS64)
2026
    case OPC_DDIV:
2027
    case OPC_DDIVU:
2028
#endif
2029
        t0 = tcg_temp_local_new();
2030
        t1 = tcg_temp_local_new();
2031
        break;
2032
    default:
2033
        t0 = tcg_temp_new();
2034
        t1 = tcg_temp_new();
2035
        break;
2036
    }
2037

    
2038
    gen_load_gpr(t0, rs);
2039
    gen_load_gpr(t1, rt);
2040
    switch (opc) {
2041
    case OPC_DIV:
2042
        {
2043
            int l1 = gen_new_label();
2044
            int l2 = gen_new_label();
2045

    
2046
            tcg_gen_ext32s_tl(t0, t0);
2047
            tcg_gen_ext32s_tl(t1, t1);
2048
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2049
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2050
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2051

    
2052
            tcg_gen_mov_tl(cpu_LO[0], t0);
2053
            tcg_gen_movi_tl(cpu_HI[0], 0);
2054
            tcg_gen_br(l1);
2055
            gen_set_label(l2);
2056
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2057
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2058
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2059
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2060
            gen_set_label(l1);
2061
        }
2062
        opn = "div";
2063
        break;
2064
    case OPC_DIVU:
2065
        {
2066
            int l1 = gen_new_label();
2067

    
2068
            tcg_gen_ext32u_tl(t0, t0);
2069
            tcg_gen_ext32u_tl(t1, t1);
2070
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2071
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2072
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2073
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2074
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2075
            gen_set_label(l1);
2076
        }
2077
        opn = "divu";
2078
        break;
2079
    case OPC_MULT:
2080
        {
2081
            TCGv_i64 t2 = tcg_temp_new_i64();
2082
            TCGv_i64 t3 = tcg_temp_new_i64();
2083

    
2084
            tcg_gen_ext_tl_i64(t2, t0);
2085
            tcg_gen_ext_tl_i64(t3, t1);
2086
            tcg_gen_mul_i64(t2, t2, t3);
2087
            tcg_temp_free_i64(t3);
2088
            tcg_gen_trunc_i64_tl(t0, t2);
2089
            tcg_gen_shri_i64(t2, t2, 32);
2090
            tcg_gen_trunc_i64_tl(t1, t2);
2091
            tcg_temp_free_i64(t2);
2092
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2093
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2094
        }
2095
        opn = "mult";
2096
        break;
2097
    case OPC_MULTU:
2098
        {
2099
            TCGv_i64 t2 = tcg_temp_new_i64();
2100
            TCGv_i64 t3 = tcg_temp_new_i64();
2101

    
2102
            tcg_gen_ext32u_tl(t0, t0);
2103
            tcg_gen_ext32u_tl(t1, t1);
2104
            tcg_gen_extu_tl_i64(t2, t0);
2105
            tcg_gen_extu_tl_i64(t3, t1);
2106
            tcg_gen_mul_i64(t2, t2, t3);
2107
            tcg_temp_free_i64(t3);
2108
            tcg_gen_trunc_i64_tl(t0, t2);
2109
            tcg_gen_shri_i64(t2, t2, 32);
2110
            tcg_gen_trunc_i64_tl(t1, t2);
2111
            tcg_temp_free_i64(t2);
2112
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2113
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2114
        }
2115
        opn = "multu";
2116
        break;
2117
#if defined(TARGET_MIPS64)
2118
    case OPC_DDIV:
2119
        {
2120
            int l1 = gen_new_label();
2121
            int l2 = gen_new_label();
2122

    
2123
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2124
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2125
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2126
            tcg_gen_mov_tl(cpu_LO[0], t0);
2127
            tcg_gen_movi_tl(cpu_HI[0], 0);
2128
            tcg_gen_br(l1);
2129
            gen_set_label(l2);
2130
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2131
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2132
            gen_set_label(l1);
2133
        }
2134
        opn = "ddiv";
2135
        break;
2136
    case OPC_DDIVU:
2137
        {
2138
            int l1 = gen_new_label();
2139

    
2140
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2141
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2142
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2143
            gen_set_label(l1);
2144
        }
2145
        opn = "ddivu";
2146
        break;
2147
    case OPC_DMULT:
2148
        gen_helper_dmult(t0, t1);
2149
        opn = "dmult";
2150
        break;
2151
    case OPC_DMULTU:
2152
        gen_helper_dmultu(t0, t1);
2153
        opn = "dmultu";
2154
        break;
2155
#endif
2156
    case OPC_MADD:
2157
        {
2158
            TCGv_i64 t2 = tcg_temp_new_i64();
2159
            TCGv_i64 t3 = tcg_temp_new_i64();
2160

    
2161
            tcg_gen_ext_tl_i64(t2, t0);
2162
            tcg_gen_ext_tl_i64(t3, t1);
2163
            tcg_gen_mul_i64(t2, t2, t3);
2164
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2165
            tcg_gen_add_i64(t2, t2, t3);
2166
            tcg_temp_free_i64(t3);
2167
            tcg_gen_trunc_i64_tl(t0, t2);
2168
            tcg_gen_shri_i64(t2, t2, 32);
2169
            tcg_gen_trunc_i64_tl(t1, t2);
2170
            tcg_temp_free_i64(t2);
2171
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2172
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2173
        }
2174
        opn = "madd";
2175
        break;
2176
    case OPC_MADDU:
2177
       {
2178
            TCGv_i64 t2 = tcg_temp_new_i64();
2179
            TCGv_i64 t3 = tcg_temp_new_i64();
2180

    
2181
            tcg_gen_ext32u_tl(t0, t0);
2182
            tcg_gen_ext32u_tl(t1, t1);
2183
            tcg_gen_extu_tl_i64(t2, t0);
2184
            tcg_gen_extu_tl_i64(t3, t1);
2185
            tcg_gen_mul_i64(t2, t2, t3);
2186
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2187
            tcg_gen_add_i64(t2, t2, t3);
2188
            tcg_temp_free_i64(t3);
2189
            tcg_gen_trunc_i64_tl(t0, t2);
2190
            tcg_gen_shri_i64(t2, t2, 32);
2191
            tcg_gen_trunc_i64_tl(t1, t2);
2192
            tcg_temp_free_i64(t2);
2193
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2194
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2195
        }
2196
        opn = "maddu";
2197
        break;
2198
    case OPC_MSUB:
2199
        {
2200
            TCGv_i64 t2 = tcg_temp_new_i64();
2201
            TCGv_i64 t3 = tcg_temp_new_i64();
2202

    
2203
            tcg_gen_ext_tl_i64(t2, t0);
2204
            tcg_gen_ext_tl_i64(t3, t1);
2205
            tcg_gen_mul_i64(t2, t2, t3);
2206
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2207
            tcg_gen_sub_i64(t2, t3, t2);
2208
            tcg_temp_free_i64(t3);
2209
            tcg_gen_trunc_i64_tl(t0, t2);
2210
            tcg_gen_shri_i64(t2, t2, 32);
2211
            tcg_gen_trunc_i64_tl(t1, t2);
2212
            tcg_temp_free_i64(t2);
2213
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2214
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2215
        }
2216
        opn = "msub";
2217
        break;
2218
    case OPC_MSUBU:
2219
        {
2220
            TCGv_i64 t2 = tcg_temp_new_i64();
2221
            TCGv_i64 t3 = tcg_temp_new_i64();
2222

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

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

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

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

    
2328
 out:
2329
    tcg_temp_free(t0);
2330
    tcg_temp_free(t1);
2331
}
2332

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

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

    
2371
/* Godson integer instructions */
2372
static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2373
                                int rd, int rs, int rt)
2374
{
2375
    const char *opn = "loongson";
2376
    TCGv t0, t1;
2377

    
2378
    if (rd == 0) {
2379
        /* Treat as NOP. */
2380
        MIPS_DEBUG("NOP");
2381
        return;
2382
    }
2383

    
2384
    switch (opc) {
2385
    case OPC_MULT_G_2E:
2386
    case OPC_MULT_G_2F:
2387
    case OPC_MULTU_G_2E:
2388
    case OPC_MULTU_G_2F:
2389
#if defined(TARGET_MIPS64)
2390
    case OPC_DMULT_G_2E:
2391
    case OPC_DMULT_G_2F:
2392
    case OPC_DMULTU_G_2E:
2393
    case OPC_DMULTU_G_2F:
2394
#endif
2395
        t0 = tcg_temp_new();
2396
        t1 = tcg_temp_new();
2397
        break;
2398
    default:
2399
        t0 = tcg_temp_local_new();
2400
        t1 = tcg_temp_local_new();
2401
        break;
2402
    }
2403

    
2404
    gen_load_gpr(t0, rs);
2405
    gen_load_gpr(t1, rt);
2406

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

    
2580
    (void)opn; /* avoid a compiler warning */
2581
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2582
    tcg_temp_free(t0);
2583
    tcg_temp_free(t1);
2584
}
2585

    
2586
/* Traps */
2587
static void gen_trap (DisasContext *ctx, uint32_t opc,
2588
                      int rs, int rt, int16_t imm)
2589
{
2590
    int cond;
2591
    TCGv t0 = tcg_temp_new();
2592
    TCGv t1 = tcg_temp_new();
2593

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

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

    
2680
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2681
{
2682
    TranslationBlock *tb;
2683
    tb = ctx->tb;
2684
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2685
        likely(!ctx->singlestep_enabled)) {
2686
        tcg_gen_goto_tb(n);
2687
        gen_save_pc(dest);
2688
        tcg_gen_exit_tb((tcg_target_long)tb + n);
2689
    } else {
2690
        gen_save_pc(dest);
2691
        if (ctx->singlestep_enabled) {
2692
            save_cpu_state(ctx, 0);
2693
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2694
        }
2695
        tcg_gen_exit_tb(0);
2696
    }
2697
}
2698

    
2699
/* Branches (before delay slot) */
2700
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2701
                                int insn_bytes,
2702
                                int rs, int rt, int32_t offset)
2703
{
2704
    target_ulong btgt = -1;
2705
    int blink = 0;
2706
    int bcond_compute = 0;
2707
    TCGv t0 = tcg_temp_new();
2708
    TCGv t1 = tcg_temp_new();
2709

    
2710
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2711
#ifdef MIPS_DEBUG_DISAS
2712
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2713
#endif
2714
        generate_exception(ctx, EXCP_RI);
2715
        goto out;
2716
    }
2717

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

    
2968
    ctx->btarget = btgt;
2969
    if (blink > 0) {
2970
        int post_delay = insn_bytes;
2971
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2972

    
2973
        if (opc != OPC_JALRC)
2974
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2975

    
2976
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2977
    }
2978

    
2979
 out:
2980
    if (insn_bytes == 2)
2981
        ctx->hflags |= MIPS_HFLAG_B16;
2982
    tcg_temp_free(t0);
2983
    tcg_temp_free(t1);
2984
}
2985

    
2986
/* special3 bitfield operations */
2987
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2988
                        int rs, int lsb, int msb)
2989
{
2990
    TCGv t0 = tcg_temp_new();
2991
    TCGv t1 = tcg_temp_new();
2992
    target_ulong mask;
2993

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

    
3079
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3080
{
3081
    TCGv t0;
3082

    
3083
    if (rd == 0) {
3084
        /* If no destination, treat it as a NOP. */
3085
        MIPS_DEBUG("NOP");
3086
        return;
3087
    }
3088

    
3089
    t0 = tcg_temp_new();
3090
    gen_load_gpr(t0, rt);
3091
    switch (op2) {
3092
    case OPC_WSBH:
3093
        {
3094
            TCGv t1 = tcg_temp_new();
3095

    
3096
            tcg_gen_shri_tl(t1, t0, 8);
3097
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3098
            tcg_gen_shli_tl(t0, t0, 8);
3099
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3100
            tcg_gen_or_tl(t0, t0, t1);
3101
            tcg_temp_free(t1);
3102
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3103
        }
3104
        break;
3105
    case OPC_SEB:
3106
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3107
        break;
3108
    case OPC_SEH:
3109
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3110
        break;
3111
#if defined(TARGET_MIPS64)
3112
    case OPC_DSBH:
3113
        {
3114
            TCGv t1 = tcg_temp_new();
3115

    
3116
            tcg_gen_shri_tl(t1, t0, 8);
3117
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3118
            tcg_gen_shli_tl(t0, t0, 8);
3119
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3120
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3121
            tcg_temp_free(t1);
3122
        }
3123
        break;
3124
    case OPC_DSHD:
3125
        {
3126
            TCGv t1 = tcg_temp_new();
3127

    
3128
            tcg_gen_shri_tl(t1, t0, 16);
3129
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3130
            tcg_gen_shli_tl(t0, t0, 16);
3131
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3132
            tcg_gen_or_tl(t0, t0, t1);
3133
            tcg_gen_shri_tl(t1, t0, 32);
3134
            tcg_gen_shli_tl(t0, t0, 32);
3135
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3136
            tcg_temp_free(t1);
3137
        }
3138
        break;
3139
#endif
3140
    default:
3141
        MIPS_INVAL("bsfhl");
3142
        generate_exception(ctx, EXCP_RI);
3143
        tcg_temp_free(t0);
3144
        return;
3145
    }
3146
    tcg_temp_free(t0);
3147
}
3148

    
3149
#ifndef CONFIG_USER_ONLY
3150
/* CP0 (MMU and control) */
3151
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3152
{
3153
    TCGv_i32 t0 = tcg_temp_new_i32();
3154

    
3155
    tcg_gen_ld_i32(t0, cpu_env, off);
3156
    tcg_gen_ext_i32_tl(arg, t0);
3157
    tcg_temp_free_i32(t0);
3158
}
3159

    
3160
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3161
{
3162
    tcg_gen_ld_tl(arg, cpu_env, off);
3163
    tcg_gen_ext32s_tl(arg, arg);
3164
}
3165

    
3166
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3167
{
3168
    TCGv_i32 t0 = tcg_temp_new_i32();
3169

    
3170
    tcg_gen_trunc_tl_i32(t0, arg);
3171
    tcg_gen_st_i32(t0, cpu_env, off);
3172
    tcg_temp_free_i32(t0);
3173
}
3174

    
3175
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3176
{
3177
    tcg_gen_ext32s_tl(arg, arg);
3178
    tcg_gen_st_tl(arg, cpu_env, off);
3179
}
3180

    
3181
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3182
{
3183
    const char *rn = "invalid";
3184

    
3185
    if (sel != 0)
3186
        check_insn(env, ctx, ISA_MIPS32);
3187

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

    
3756
die:
3757
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3758
    generate_exception(ctx, EXCP_RI);
3759
}
3760

    
3761
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3762
{
3763
    const char *rn = "invalid";
3764

    
3765
    if (sel != 0)
3766
        check_insn(env, ctx, ISA_MIPS32);
3767

    
3768
    if (use_icount)
3769
        gen_io_start();
3770

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

    
4352
die:
4353
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4354
    generate_exception(ctx, EXCP_RI);
4355
}
4356

    
4357
#if defined(TARGET_MIPS64)
4358
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4359
{
4360
    const char *rn = "invalid";
4361

    
4362
    if (sel != 0)
4363
        check_insn(env, ctx, ISA_MIPS64);
4364

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

    
4922
die:
4923
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924
    generate_exception(ctx, EXCP_RI);
4925
}
4926

    
4927
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4928
{
4929
    const char *rn = "invalid";
4930

    
4931
    if (sel != 0)
4932
        check_insn(env, ctx, ISA_MIPS64);
4933

    
4934
    if (use_icount)
4935
        gen_io_start();
4936

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

    
5519
die:
5520
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5521
    generate_exception(ctx, EXCP_RI);
5522
}
5523
#endif /* TARGET_MIPS64 */
5524

    
5525
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5526
                     int u, int sel, int h)
5527
{
5528
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5529
    TCGv t0 = tcg_temp_local_new();
5530

    
5531
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5532
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5533
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5534
        tcg_gen_movi_tl(t0, -1);
5535
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5536
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5537
        tcg_gen_movi_tl(t0, -1);
5538
    else if (u == 0) {
5539
        switch (rt) {
5540
        case 2:
5541
            switch (sel) {
5542
            case 1:
5543
                gen_helper_mftc0_tcstatus(t0);
5544
                break;
5545
            case 2:
5546
                gen_helper_mftc0_tcbind(t0);
5547
                break;
5548
            case 3:
5549
                gen_helper_mftc0_tcrestart(t0);
5550
                break;
5551
            case 4:
5552
                gen_helper_mftc0_tchalt(t0);
5553
                break;
5554
            case 5:
5555
                gen_helper_mftc0_tccontext(t0);
5556
                break;
5557
            case 6:
5558
                gen_helper_mftc0_tcschedule(t0);
5559
                break;
5560
            case 7:
5561
                gen_helper_mftc0_tcschefback(t0);
5562
                break;
5563
            default:
5564
                gen_mfc0(env, ctx, t0, rt, sel);
5565
                break;
5566
            }
5567
            break;
5568
        case 10:
5569
            switch (sel) {
5570
            case 0:
5571
                gen_helper_mftc0_entryhi(t0);
5572
                break;
5573
            default:
5574
                gen_mfc0(env, ctx, t0, rt, sel);
5575
                break;
5576
            }
5577
        case 12:
5578
            switch (sel) {
5579
            case 0:
5580
                gen_helper_mftc0_status(t0);
5581
                break;
5582
            default:
5583
                gen_mfc0(env, ctx, t0, rt, sel);
5584
                break;
5585
            }
5586
        case 23:
5587
            switch (sel) {
5588
            case 0:
5589
                gen_helper_mftc0_debug(t0);
5590
                break;
5591
            default:
5592
                gen_mfc0(env, ctx, t0, rt, sel);
5593
                break;
5594
            }
5595
            break;
5596
        default:
5597
            gen_mfc0(env, ctx, t0, rt, sel);
5598
        }
5599
    } else switch (sel) {
5600
    /* GPR registers. */
5601
    case 0:
5602
        gen_helper_1i(mftgpr, t0, rt);
5603
        break;
5604
    /* Auxiliary CPU registers */
5605
    case 1:
5606
        switch (rt) {
5607
        case 0:
5608
            gen_helper_1i(mftlo, t0, 0);
5609
            break;
5610
        case 1:
5611
            gen_helper_1i(mfthi, t0, 0);
5612
            break;
5613
        case 2:
5614
            gen_helper_1i(mftacx, t0, 0);
5615
            break;
5616
        case 4:
5617
            gen_helper_1i(mftlo, t0, 1);
5618
            break;
5619
        case 5:
5620
            gen_helper_1i(mfthi, t0, 1);
5621
            break;
5622
        case 6:
5623
            gen_helper_1i(mftacx, t0, 1);
5624
            break;
5625
        case 8:
5626
            gen_helper_1i(mftlo, t0, 2);
5627
            break;
5628
        case 9:
5629
            gen_helper_1i(mfthi, t0, 2);
5630
            break;
5631
        case 10:
5632
            gen_helper_1i(mftacx, t0, 2);
5633
            break;
5634
        case 12:
5635
            gen_helper_1i(mftlo, t0, 3);
5636
            break;
5637
        case 13:
5638
            gen_helper_1i(mfthi, t0, 3);
5639
            break;
5640
        case 14:
5641
            gen_helper_1i(mftacx, t0, 3);
5642
            break;
5643
        case 16:
5644
            gen_helper_mftdsp(t0);
5645
            break;
5646
        default:
5647
            goto die;
5648
        }
5649
        break;
5650
    /* Floating point (COP1). */
5651
    case 2:
5652
        /* XXX: For now we support only a single FPU context. */
5653
        if (h == 0) {
5654
            TCGv_i32 fp0 = tcg_temp_new_i32();
5655

    
5656
            gen_load_fpr32(fp0, rt);
5657
            tcg_gen_ext_i32_tl(t0, fp0);
5658
            tcg_temp_free_i32(fp0);
5659
        } else {
5660
            TCGv_i32 fp0 = tcg_temp_new_i32();
5661

    
5662
            gen_load_fpr32h(fp0, rt);
5663
            tcg_gen_ext_i32_tl(t0, fp0);
5664
            tcg_temp_free_i32(fp0);
5665
        }
5666
        break;
5667
    case 3:
5668
        /* XXX: For now we support only a single FPU context. */
5669
        gen_helper_1i(cfc1, t0, rt);
5670
        break;
5671
    /* COP2: Not implemented. */
5672
    case 4:
5673
    case 5:
5674
        /* fall through */
5675
    default:
5676
        goto die;
5677
    }
5678
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5679
    gen_store_gpr(t0, rd);
5680
    tcg_temp_free(t0);
5681
    return;
5682

    
5683
die:
5684
    tcg_temp_free(t0);
5685
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5686
    generate_exception(ctx, EXCP_RI);
5687
}
5688

    
5689
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5690
                     int u, int sel, int h)
5691
{
5692
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5693
    TCGv t0 = tcg_temp_local_new();
5694

    
5695
    gen_load_gpr(t0, rt);
5696
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5697
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5698
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5699
        /* NOP */ ;
5700
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5701
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5702
        /* NOP */ ;
5703
    else if (u == 0) {
5704
        switch (rd) {
5705
        case 2:
5706
            switch (sel) {
5707
            case 1:
5708
                gen_helper_mttc0_tcstatus(t0);
5709
                break;
5710
            case 2:
5711
                gen_helper_mttc0_tcbind(t0);
5712
                break;
5713
            case 3:
5714
                gen_helper_mttc0_tcrestart(t0);
5715
                break;
5716
            case 4:
5717
                gen_helper_mttc0_tchalt(t0);
5718
                break;
5719
            case 5:
5720
                gen_helper_mttc0_tccontext(t0);
5721
                break;
5722
            case 6:
5723
                gen_helper_mttc0_tcschedule(t0);
5724
                break;
5725
            case 7:
5726
                gen_helper_mttc0_tcschefback(t0);
5727
                break;
5728
            default:
5729
                gen_mtc0(env, ctx, t0, rd, sel);
5730
                break;
5731
            }
5732
            break;
5733
        case 10:
5734
            switch (sel) {
5735
            case 0:
5736
                gen_helper_mttc0_entryhi(t0);
5737
                break;
5738
            default:
5739
                gen_mtc0(env, ctx, t0, rd, sel);
5740
                break;
5741
            }
5742
        case 12:
5743
            switch (sel) {
5744
            case 0:
5745
                gen_helper_mttc0_status(t0);
5746
                break;
5747
            default:
5748
                gen_mtc0(env, ctx, t0, rd, sel);
5749
                break;
5750
            }
5751
        case 23:
5752
            switch (sel) {
5753
            case 0:
5754
                gen_helper_mttc0_debug(t0);
5755
                break;
5756
            default:
5757
                gen_mtc0(env, ctx, t0, rd, sel);
5758
                break;
5759
            }
5760
            break;
5761
        default:
5762
            gen_mtc0(env, ctx, t0, rd, sel);
5763
        }
5764
    } else switch (sel) {
5765
    /* GPR registers. */
5766
    case 0:
5767
        gen_helper_1i(mttgpr, t0, rd);
5768
        break;
5769
    /* Auxiliary CPU registers */
5770
    case 1:
5771
        switch (rd) {
5772
        case 0:
5773
            gen_helper_1i(mttlo, t0, 0);
5774
            break;
5775
        case 1:
5776
            gen_helper_1i(mtthi, t0, 0);
5777
            break;
5778
        case 2:
5779
            gen_helper_1i(mttacx, t0, 0);
5780
            break;
5781
        case 4:
5782
            gen_helper_1i(mttlo, t0, 1);
5783
            break;
5784
        case 5:
5785
            gen_helper_1i(mtthi, t0, 1);
5786
            break;
5787
        case 6:
5788
            gen_helper_1i(mttacx, t0, 1);
5789
            break;
5790
        case 8:
5791
            gen_helper_1i(mttlo, t0, 2);
5792
            break;
5793
        case 9:
5794
            gen_helper_1i(mtthi, t0, 2);
5795
            break;
5796
        case 10:
5797
            gen_helper_1i(mttacx, t0, 2);
5798
            break;
5799
        case 12:
5800
            gen_helper_1i(mttlo, t0, 3);
5801
            break;
5802
        case 13:
5803
            gen_helper_1i(mtthi, t0, 3);
5804
            break;
5805
        case 14:
5806
            gen_helper_1i(mttacx, t0, 3);
5807
            break;
5808
        case 16:
5809
            gen_helper_mttdsp(t0);
5810
            break;
5811
        default:
5812
            goto die;
5813
        }
5814
        break;
5815
    /* Floating point (COP1). */
5816
    case 2:
5817
        /* XXX: For now we support only a single FPU context. */
5818
        if (h == 0) {
5819
            TCGv_i32 fp0 = tcg_temp_new_i32();
5820

    
5821
            tcg_gen_trunc_tl_i32(fp0, t0);
5822
            gen_store_fpr32(fp0, rd);
5823
            tcg_temp_free_i32(fp0);
5824
        } else {
5825
            TCGv_i32 fp0 = tcg_temp_new_i32();
5826

    
5827
            tcg_gen_trunc_tl_i32(fp0, t0);
5828
            gen_store_fpr32h(fp0, rd);
5829
            tcg_temp_free_i32(fp0);
5830
        }
5831
        break;
5832
    case 3:
5833
        /* XXX: For now we support only a single FPU context. */
5834
        gen_helper_1i(ctc1, t0, rd);
5835
        break;
5836
    /* COP2: Not implemented. */
5837
    case 4:
5838
    case 5:
5839
        /* fall through */
5840
    default:
5841
        goto die;
5842
    }
5843
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5844
    tcg_temp_free(t0);
5845
    return;
5846

    
5847
die:
5848
    tcg_temp_free(t0);
5849
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5850
    generate_exception(ctx, EXCP_RI);
5851
}
5852

    
5853
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5854
{
5855
    const char *opn = "ldst";
5856

    
5857
    switch (opc) {
5858
    case OPC_MFC0:
5859
        if (rt == 0) {
5860
            /* Treat as NOP. */
5861
            return;
5862
        }
5863
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5864
        opn = "mfc0";
5865
        break;
5866
    case OPC_MTC0:
5867
        {
5868
            TCGv t0 = tcg_temp_new();
5869

    
5870
            gen_load_gpr(t0, rt);
5871
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5872
            tcg_temp_free(t0);
5873
        }
5874
        opn = "mtc0";
5875
        break;
5876
#if defined(TARGET_MIPS64)
5877
    case OPC_DMFC0:
5878
        check_insn(env, ctx, ISA_MIPS3);
5879
        if (rt == 0) {
5880
            /* Treat as NOP. */
5881
            return;
5882
        }
5883
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5884
        opn = "dmfc0";
5885
        break;
5886
    case OPC_DMTC0:
5887
        check_insn(env, ctx, ISA_MIPS3);
5888
        {
5889
            TCGv t0 = tcg_temp_new();
5890

    
5891
            gen_load_gpr(t0, rt);
5892
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5893
            tcg_temp_free(t0);
5894
        }
5895
        opn = "dmtc0";
5896
        break;
5897
#endif
5898
    case OPC_MFTR:
5899
        check_insn(env, ctx, ASE_MT);
5900
        if (rd == 0) {
5901
            /* Treat as NOP. */
5902
            return;
5903
        }
5904
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5905
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5906
        opn = "mftr";
5907
        break;
5908
    case OPC_MTTR:
5909
        check_insn(env, ctx, ASE_MT);
5910
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5911
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5912
        opn = "mttr";
5913
        break;
5914
    case OPC_TLBWI:
5915
        opn = "tlbwi";
5916
        if (!env->tlb->helper_tlbwi)
5917
            goto die;
5918
        gen_helper_tlbwi();
5919
        break;
5920
    case OPC_TLBWR:
5921
        opn = "tlbwr";
5922
        if (!env->tlb->helper_tlbwr)
5923
            goto die;
5924
        gen_helper_tlbwr();
5925
        break;
5926
    case OPC_TLBP:
5927
        opn = "tlbp";
5928
        if (!env->tlb->helper_tlbp)
5929
            goto die;
5930
        gen_helper_tlbp();
5931
        break;
5932
    case OPC_TLBR:
5933
        opn = "tlbr";
5934
        if (!env->tlb->helper_tlbr)
5935
            goto die;
5936
        gen_helper_tlbr();
5937
        break;
5938
    case OPC_ERET:
5939
        opn = "eret";
5940
        check_insn(env, ctx, ISA_MIPS2);
5941
        gen_helper_eret();
5942
        ctx->bstate = BS_EXCP;
5943
        break;
5944
    case OPC_DERET:
5945
        opn = "deret";
5946
        check_insn(env, ctx, ISA_MIPS32);
5947
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5948
            MIPS_INVAL(opn);
5949
            generate_exception(ctx, EXCP_RI);
5950
        } else {
5951
            gen_helper_deret();
5952
            ctx->bstate = BS_EXCP;
5953
        }
5954
        break;
5955
    case OPC_WAIT:
5956
        opn = "wait";
5957
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5958
        /* If we get an exception, we want to restart at next instruction */
5959
        ctx->pc += 4;
5960
        save_cpu_state(ctx, 1);
5961
        ctx->pc -= 4;
5962
        gen_helper_wait();
5963
        ctx->bstate = BS_EXCP;
5964
        break;
5965
    default:
5966
 die:
5967
        MIPS_INVAL(opn);
5968
        generate_exception(ctx, EXCP_RI);
5969
        return;
5970
    }
5971
    (void)opn; /* avoid a compiler warning */
5972
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5973
}
5974
#endif /* !CONFIG_USER_ONLY */
5975

    
5976
/* CP1 Branches (before delay slot) */
5977
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5978
                                 int32_t cc, int32_t offset)
5979
{
5980
    target_ulong btarget;
5981
    const char *opn = "cp1 cond branch";
5982
    TCGv_i32 t0 = tcg_temp_new_i32();
5983

    
5984
    if (cc != 0)
5985
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5986

    
5987
    btarget = ctx->pc + 4 + offset;
5988

    
5989
    switch (op) {
5990
    case OPC_BC1F:
5991
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5992
        tcg_gen_not_i32(t0, t0);
5993
        tcg_gen_andi_i32(t0, t0, 1);
5994
        tcg_gen_extu_i32_tl(bcond, t0);
5995
        opn = "bc1f";
5996
        goto not_likely;
5997
    case OPC_BC1FL:
5998
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5999
        tcg_gen_not_i32(t0, t0);
6000
        tcg_gen_andi_i32(t0, t0, 1);
6001
        tcg_gen_extu_i32_tl(bcond, t0);
6002
        opn = "bc1fl";
6003
        goto likely;
6004
    case OPC_BC1T:
6005
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6006
        tcg_gen_andi_i32(t0, t0, 1);
6007
        tcg_gen_extu_i32_tl(bcond, t0);
6008
        opn = "bc1t";
6009
        goto not_likely;
6010
    case OPC_BC1TL:
6011
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6012
        tcg_gen_andi_i32(t0, t0, 1);
6013
        tcg_gen_extu_i32_tl(bcond, t0);
6014
        opn = "bc1tl";
6015
    likely:
6016
        ctx->hflags |= MIPS_HFLAG_BL;
6017
        break;
6018
    case OPC_BC1FANY2:
6019
        {
6020
            TCGv_i32 t1 = tcg_temp_new_i32();
6021
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6022
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6023
            tcg_gen_nor_i32(t0, t0, t1);
6024
            tcg_temp_free_i32(t1);
6025
            tcg_gen_andi_i32(t0, t0, 1);
6026
            tcg_gen_extu_i32_tl(bcond, t0);
6027
        }
6028
        opn = "bc1any2f";
6029
        goto not_likely;
6030
    case OPC_BC1TANY2:
6031
        {
6032
            TCGv_i32 t1 = tcg_temp_new_i32();
6033
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6034
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6035
            tcg_gen_or_i32(t0, t0, t1);
6036
            tcg_temp_free_i32(t1);
6037
            tcg_gen_andi_i32(t0, t0, 1);
6038
            tcg_gen_extu_i32_tl(bcond, t0);
6039
        }
6040
        opn = "bc1any2t";
6041
        goto not_likely;
6042
    case OPC_BC1FANY4:
6043
        {
6044
            TCGv_i32 t1 = tcg_temp_new_i32();
6045
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6046
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6047
            tcg_gen_or_i32(t0, t0, t1);
6048
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6049
            tcg_gen_or_i32(t0, t0, t1);
6050
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6051
            tcg_gen_nor_i32(t0, t0, t1);
6052
            tcg_temp_free_i32(t1);
6053
            tcg_gen_andi_i32(t0, t0, 1);
6054
            tcg_gen_extu_i32_tl(bcond, t0);
6055
        }
6056
        opn = "bc1any4f";
6057
        goto not_likely;
6058
    case OPC_BC1TANY4:
6059
        {
6060
            TCGv_i32 t1 = tcg_temp_new_i32();
6061
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6062
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6063
            tcg_gen_or_i32(t0, t0, t1);
6064
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6065
            tcg_gen_or_i32(t0, t0, t1);
6066
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6067
            tcg_gen_or_i32(t0, t0, t1);
6068
            tcg_temp_free_i32(t1);
6069
            tcg_gen_andi_i32(t0, t0, 1);
6070
            tcg_gen_extu_i32_tl(bcond, t0);
6071
        }
6072
        opn = "bc1any4t";
6073
    not_likely:
6074
        ctx->hflags |= MIPS_HFLAG_BC;
6075
        break;
6076
    default:
6077
        MIPS_INVAL(opn);
6078
        generate_exception (ctx, EXCP_RI);
6079
        goto out;
6080
    }
6081
    (void)opn; /* avoid a compiler warning */
6082
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6083
               ctx->hflags, btarget);
6084
    ctx->btarget = btarget;
6085

    
6086
 out:
6087
    tcg_temp_free_i32(t0);
6088
}
6089

    
6090
/* Coprocessor 1 (FPU) */
6091

    
6092
#define FOP(func, fmt) (((fmt) << 21) | (func))
6093

    
6094
enum fopcode {
6095
    OPC_ADD_S = FOP(0, FMT_S),
6096
    OPC_SUB_S = FOP(1, FMT_S),
6097
    OPC_MUL_S = FOP(2, FMT_S),
6098
    OPC_DIV_S = FOP(3, FMT_S),
6099
    OPC_SQRT_S = FOP(4, FMT_S),
6100
    OPC_ABS_S = FOP(5, FMT_S),
6101
    OPC_MOV_S = FOP(6, FMT_S),
6102
    OPC_NEG_S = FOP(7, FMT_S),
6103
    OPC_ROUND_L_S = FOP(8, FMT_S),
6104
    OPC_TRUNC_L_S = FOP(9, FMT_S),
6105
    OPC_CEIL_L_S = FOP(10, FMT_S),
6106
    OPC_FLOOR_L_S = FOP(11, FMT_S),
6107
    OPC_ROUND_W_S = FOP(12, FMT_S),
6108
    OPC_TRUNC_W_S = FOP(13, FMT_S),
6109
    OPC_CEIL_W_S = FOP(14, FMT_S),
6110
    OPC_FLOOR_W_S = FOP(15, FMT_S),
6111
    OPC_MOVCF_S = FOP(17, FMT_S),
6112
    OPC_MOVZ_S = FOP(18, FMT_S),
6113
    OPC_MOVN_S = FOP(19, FMT_S),
6114
    OPC_RECIP_S = FOP(21, FMT_S),
6115
    OPC_RSQRT_S = FOP(22, FMT_S),
6116
    OPC_RECIP2_S = FOP(28, FMT_S),
6117
    OPC_RECIP1_S = FOP(29, FMT_S),
6118
    OPC_RSQRT1_S = FOP(30, FMT_S),
6119
    OPC_RSQRT2_S = FOP(31, FMT_S),
6120
    OPC_CVT_D_S = FOP(33, FMT_S),
6121
    OPC_CVT_W_S = FOP(36, FMT_S),
6122
    OPC_CVT_L_S = FOP(37, FMT_S),
6123
    OPC_CVT_PS_S = FOP(38, FMT_S),
6124
    OPC_CMP_F_S = FOP (48, FMT_S),
6125
    OPC_CMP_UN_S = FOP (49, FMT_S),
6126
    OPC_CMP_EQ_S = FOP (50, FMT_S),
6127
    OPC_CMP_UEQ_S = FOP (51, FMT_S),
6128
    OPC_CMP_OLT_S = FOP (52, FMT_S),
6129
    OPC_CMP_ULT_S = FOP (53, FMT_S),
6130
    OPC_CMP_OLE_S = FOP (54, FMT_S),
6131
    OPC_CMP_ULE_S = FOP (55, FMT_S),
6132
    OPC_CMP_SF_S = FOP (56, FMT_S),
6133
    OPC_CMP_NGLE_S = FOP (57, FMT_S),
6134
    OPC_CMP_SEQ_S = FOP (58, FMT_S),
6135
    OPC_CMP_NGL_S = FOP (59, FMT_S),
6136
    OPC_CMP_LT_S = FOP (60, FMT_S),
6137
    OPC_CMP_NGE_S = FOP (61, FMT_S),
6138
    OPC_CMP_LE_S = FOP (62, FMT_S),
6139
    OPC_CMP_NGT_S = FOP (63, FMT_S),
6140

    
6141
    OPC_ADD_D = FOP(0, FMT_D),
6142
    OPC_SUB_D = FOP(1, FMT_D),
6143
    OPC_MUL_D = FOP(2, FMT_D),
6144
    OPC_DIV_D = FOP(3, FMT_D),
6145
    OPC_SQRT_D = FOP(4, FMT_D),
6146
    OPC_ABS_D = FOP(5, FMT_D),
6147
    OPC_MOV_D = FOP(6, FMT_D),
6148
    OPC_NEG_D = FOP(7, FMT_D),
6149
    OPC_ROUND_L_D = FOP(8, FMT_D),
6150
    OPC_TRUNC_L_D = FOP(9, FMT_D),
6151
    OPC_CEIL_L_D = FOP(10, FMT_D),
6152
    OPC_FLOOR_L_D = FOP(11, FMT_D),
6153
    OPC_ROUND_W_D = FOP(12, FMT_D),
6154
    OPC_TRUNC_W_D = FOP(13, FMT_D),
6155
    OPC_CEIL_W_D = FOP(14, FMT_D),
6156
    OPC_FLOOR_W_D = FOP(15, FMT_D),
6157
    OPC_MOVCF_D = FOP(17, FMT_D),
6158
    OPC_MOVZ_D = FOP(18, FMT_D),
6159
    OPC_MOVN_D = FOP(19, FMT_D),
6160
    OPC_RECIP_D = FOP(21, FMT_D),
6161
    OPC_RSQRT_D = FOP(22, FMT_D),
6162
    OPC_RECIP2_D = FOP(28, FMT_D),
6163
    OPC_RECIP1_D = FOP(29, FMT_D),
6164
    OPC_RSQRT1_D = FOP(30, FMT_D),
6165
    OPC_RSQRT2_D = FOP(31, FMT_D),
6166
    OPC_CVT_S_D = FOP(32, FMT_D),
6167
    OPC_CVT_W_D = FOP(36, FMT_D),
6168
    OPC_CVT_L_D = FOP(37, FMT_D),
6169
    OPC_CMP_F_D = FOP (48, FMT_D),
6170
    OPC_CMP_UN_D = FOP (49, FMT_D),
6171
    OPC_CMP_EQ_D = FOP (50, FMT_D),
6172
    OPC_CMP_UEQ_D = FOP (51, FMT_D),
6173
    OPC_CMP_OLT_D = FOP (52, FMT_D),
6174
    OPC_CMP_ULT_D = FOP (53, FMT_D),
6175
    OPC_CMP_OLE_D = FOP (54, FMT_D),
6176
    OPC_CMP_ULE_D = FOP (55, FMT_D),
6177
    OPC_CMP_SF_D = FOP (56, FMT_D),
6178
    OPC_CMP_NGLE_D = FOP (57, FMT_D),
6179
    OPC_CMP_SEQ_D = FOP (58, FMT_D),
6180
    OPC_CMP_NGL_D = FOP (59, FMT_D),
6181
    OPC_CMP_LT_D = FOP (60, FMT_D),
6182
    OPC_CMP_NGE_D = FOP (61, FMT_D),
6183
    OPC_CMP_LE_D = FOP (62, FMT_D),
6184
    OPC_CMP_NGT_D = FOP (63, FMT_D),
6185

    
6186
    OPC_CVT_S_W = FOP(32, FMT_W),
6187
    OPC_CVT_D_W = FOP(33, FMT_W),
6188
    OPC_CVT_S_L = FOP(32, FMT_L),
6189
    OPC_CVT_D_L = FOP(33, FMT_L),
6190
    OPC_CVT_PS_PW = FOP(38, FMT_W),
6191

    
6192
    OPC_ADD_PS = FOP(0, FMT_PS),
6193
    OPC_SUB_PS = FOP(1, FMT_PS),
6194
    OPC_MUL_PS = FOP(2, FMT_PS),
6195
    OPC_DIV_PS = FOP(3, FMT_PS),
6196
    OPC_ABS_PS = FOP(5, FMT_PS),
6197
    OPC_MOV_PS = FOP(6, FMT_PS),
6198
    OPC_NEG_PS = FOP(7, FMT_PS),
6199
    OPC_MOVCF_PS = FOP(17, FMT_PS),
6200
    OPC_MOVZ_PS = FOP(18, FMT_PS),
6201
    OPC_MOVN_PS = FOP(19, FMT_PS),
6202
    OPC_ADDR_PS = FOP(24, FMT_PS),
6203
    OPC_MULR_PS = FOP(26, FMT_PS),
6204
    OPC_RECIP2_PS = FOP(28, FMT_PS),
6205
    OPC_RECIP1_PS = FOP(29, FMT_PS),
6206
    OPC_RSQRT1_PS = FOP(30, FMT_PS),
6207
    OPC_RSQRT2_PS = FOP(31, FMT_PS),
6208

    
6209
    OPC_CVT_S_PU = FOP(32, FMT_PS),
6210
    OPC_CVT_PW_PS = FOP(36, FMT_PS),
6211
    OPC_CVT_S_PL = FOP(40, FMT_PS),
6212
    OPC_PLL_PS = FOP(44, FMT_PS),
6213
    OPC_PLU_PS = FOP(45, FMT_PS),
6214
    OPC_PUL_PS = FOP(46, FMT_PS),
6215
    OPC_PUU_PS = FOP(47, FMT_PS),
6216
    OPC_CMP_F_PS = FOP (48, FMT_PS),
6217
    OPC_CMP_UN_PS = FOP (49, FMT_PS),
6218
    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6219
    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6220
    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6221
    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6222
    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6223
    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6224
    OPC_CMP_SF_PS = FOP (56, FMT_PS),
6225
    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6226
    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6227
    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6228
    OPC_CMP_LT_PS = FOP (60, FMT_PS),
6229
    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6230
    OPC_CMP_LE_PS = FOP (62, FMT_PS),
6231
    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6232
};
6233

    
6234
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6235
{
6236
    const char *opn = "cp1 move";
6237
    TCGv t0 = tcg_temp_new();
6238

    
6239
    switch (opc) {
6240
    case OPC_MFC1:
6241
        {
6242
            TCGv_i32 fp0 = tcg_temp_new_i32();
6243

    
6244
            gen_load_fpr32(fp0, fs);
6245
            tcg_gen_ext_i32_tl(t0, fp0);
6246
            tcg_temp_free_i32(fp0);
6247
        }
6248
        gen_store_gpr(t0, rt);
6249
        opn = "mfc1";
6250
        break;
6251
    case OPC_MTC1:
6252
        gen_load_gpr(t0, rt);
6253
        {
6254
            TCGv_i32 fp0 = tcg_temp_new_i32();
6255

    
6256
            tcg_gen_trunc_tl_i32(fp0, t0);
6257
            gen_store_fpr32(fp0, fs);
6258
            tcg_temp_free_i32(fp0);
6259
        }
6260
        opn = "mtc1";
6261
        break;
6262
    case OPC_CFC1:
6263
        gen_helper_1i(cfc1, t0, fs);
6264
        gen_store_gpr(t0, rt);
6265
        opn = "cfc1";
6266
        break;
6267
    case OPC_CTC1:
6268
        gen_load_gpr(t0, rt);
6269
        gen_helper_1i(ctc1, t0, fs);
6270
        opn = "ctc1";
6271
        break;
6272
#if defined(TARGET_MIPS64)
6273
    case OPC_DMFC1:
6274
        gen_load_fpr64(ctx, t0, fs);
6275
        gen_store_gpr(t0, rt);
6276
        opn = "dmfc1";
6277
        break;
6278
    case OPC_DMTC1:
6279
        gen_load_gpr(t0, rt);
6280
        gen_store_fpr64(ctx, t0, fs);
6281
        opn = "dmtc1";
6282
        break;
6283
#endif
6284
    case OPC_MFHC1:
6285
        {
6286
            TCGv_i32 fp0 = tcg_temp_new_i32();
6287

    
6288
            gen_load_fpr32h(fp0, fs);
6289
            tcg_gen_ext_i32_tl(t0, fp0);
6290
            tcg_temp_free_i32(fp0);
6291
        }
6292
        gen_store_gpr(t0, rt);
6293
        opn = "mfhc1";
6294
        break;
6295
    case OPC_MTHC1:
6296
        gen_load_gpr(t0, rt);
6297
        {
6298
            TCGv_i32 fp0 = tcg_temp_new_i32();
6299

    
6300
            tcg_gen_trunc_tl_i32(fp0, t0);
6301
            gen_store_fpr32h(fp0, fs);
6302
            tcg_temp_free_i32(fp0);
6303
        }
6304
        opn = "mthc1";
6305
        break;
6306
    default:
6307
        MIPS_INVAL(opn);
6308
        generate_exception (ctx, EXCP_RI);
6309
        goto out;
6310
    }
6311
    (void)opn; /* avoid a compiler warning */
6312
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6313

    
6314
 out:
6315
    tcg_temp_free(t0);
6316
}
6317

    
6318
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6319
{
6320
    int l1;
6321
    TCGCond cond;
6322
    TCGv_i32 t0;
6323

    
6324
    if (rd == 0) {
6325
        /* Treat as NOP. */
6326
        return;
6327
    }
6328

    
6329
    if (tf)
6330
        cond = TCG_COND_EQ;
6331
    else
6332
        cond = TCG_COND_NE;
6333

    
6334
    l1 = gen_new_label();
6335
    t0 = tcg_temp_new_i32();
6336
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6337
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6338
    tcg_temp_free_i32(t0);
6339
    if (rs == 0) {
6340
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
6341
    } else {
6342
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6343
    }
6344
    gen_set_label(l1);
6345
}
6346

    
6347
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6348
{
6349
    int cond;
6350
    TCGv_i32 t0 = tcg_temp_new_i32();
6351
    int l1 = gen_new_label();
6352

    
6353
    if (tf)
6354
        cond = TCG_COND_EQ;
6355
    else
6356
        cond = TCG_COND_NE;
6357

    
6358
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6359
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6360
    gen_load_fpr32(t0, fs);
6361
    gen_store_fpr32(t0, fd);
6362
    gen_set_label(l1);
6363
    tcg_temp_free_i32(t0);
6364
}
6365

    
6366
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6367
{
6368
    int cond;
6369
    TCGv_i32 t0 = tcg_temp_new_i32();
6370
    TCGv_i64 fp0;
6371
    int l1 = gen_new_label();
6372

    
6373
    if (tf)
6374
        cond = TCG_COND_EQ;
6375
    else
6376
        cond = TCG_COND_NE;
6377

    
6378
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6379
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6380
    tcg_temp_free_i32(t0);
6381
    fp0 = tcg_temp_new_i64();
6382
    gen_load_fpr64(ctx, fp0, fs);
6383
    gen_store_fpr64(ctx, fp0, fd);
6384
    tcg_temp_free_i64(fp0);
6385
    gen_set_label(l1);
6386
}
6387

    
6388
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6389
{
6390
    int cond;
6391
    TCGv_i32 t0 = tcg_temp_new_i32();
6392
    int l1 = gen_new_label();
6393
    int l2 = gen_new_label();
6394

    
6395
    if (tf)
6396
        cond = TCG_COND_EQ;
6397
    else
6398
        cond = TCG_COND_NE;
6399

    
6400
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6401
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6402
    gen_load_fpr32(t0, fs);
6403
    gen_store_fpr32(t0, fd);
6404
    gen_set_label(l1);
6405

    
6406
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6407
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
6408
    gen_load_fpr32h(t0, fs);
6409
    gen_store_fpr32h(t0, fd);
6410
    tcg_temp_free_i32(t0);
6411
    gen_set_label(l2);
6412
}
6413

    
6414

    
6415
static void gen_farith (DisasContext *ctx, enum fopcode op1,
6416
                        int ft, int fs, int fd, int cc)
6417
{
6418
    const char *opn = "farith";
6419
    const char *condnames[] = {
6420
            "c.f",
6421
            "c.un",
6422
            "c.eq",
6423
            "c.ueq",
6424
            "c.olt",
6425
            "c.ult",
6426
            "c.ole",
6427
            "c.ule",
6428
            "c.sf",
6429
            "c.ngle",
6430
            "c.seq",
6431
            "c.ngl",
6432
            "c.lt",
6433
            "c.nge",
6434
            "c.le",
6435
            "c.ngt",
6436
    };
6437
    const char *condnames_abs[] = {
6438
            "cabs.f",
6439
            "cabs.un",
6440
            "cabs.eq",
6441
            "cabs.ueq",
6442
            "cabs.olt",
6443
            "cabs.ult",
6444
            "cabs.ole",
6445
            "cabs.ule",
6446
            "cabs.sf",
6447
            "cabs.ngle",
6448
            "cabs.seq",
6449
            "cabs.ngl",
6450
            "cabs.lt",
6451
            "cabs.nge",
6452
            "cabs.le",
6453
            "cabs.ngt",
6454
    };
6455
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6456
    uint32_t func = ctx->opcode & 0x3f;
6457

    
6458
    switch (op1) {
6459
    case OPC_ADD_S:
6460
        {
6461
            TCGv_i32 fp0 = tcg_temp_new_i32();
6462
            TCGv_i32 fp1 = tcg_temp_new_i32();
6463

    
6464
            gen_load_fpr32(fp0, fs);
6465
            gen_load_fpr32(fp1, ft);
6466
            gen_helper_float_add_s(fp0, fp0, fp1);
6467
            tcg_temp_free_i32(fp1);
6468
            gen_store_fpr32(fp0, fd);
6469
            tcg_temp_free_i32(fp0);
6470
        }
6471
        opn = "add.s";
6472
        optype = BINOP;
6473
        break;
6474
    case OPC_SUB_S:
6475
        {
6476
            TCGv_i32 fp0 = tcg_temp_new_i32();
6477
            TCGv_i32 fp1 = tcg_temp_new_i32();
6478

    
6479
            gen_load_fpr32(fp0, fs);
6480
            gen_load_fpr32(fp1, ft);
6481
            gen_helper_float_sub_s(fp0, fp0, fp1);
6482
            tcg_temp_free_i32(fp1);
6483
            gen_store_fpr32(fp0, fd);
6484
            tcg_temp_free_i32(fp0);
6485
        }
6486
        opn = "sub.s";
6487
        optype = BINOP;
6488
        break;
6489
    case OPC_MUL_S:
6490
        {
6491
            TCGv_i32 fp0 = tcg_temp_new_i32();
6492
            TCGv_i32 fp1 = tcg_temp_new_i32();
6493

    
6494
            gen_load_fpr32(fp0, fs);
6495
            gen_load_fpr32(fp1, ft);
6496
            gen_helper_float_mul_s(fp0, fp0, fp1);
6497
            tcg_temp_free_i32(fp1);
6498
            gen_store_fpr32(fp0, fd);
6499
            tcg_temp_free_i32(fp0);
6500
        }
6501
        opn = "mul.s";
6502
        optype = BINOP;
6503
        break;
6504
    case OPC_DIV_S:
6505
        {
6506
            TCGv_i32 fp0 = tcg_temp_new_i32();
6507
            TCGv_i32 fp1 = tcg_temp_new_i32();
6508

    
6509
            gen_load_fpr32(fp0, fs);
6510
            gen_load_fpr32(fp1, ft);
6511
            gen_helper_float_div_s(fp0, fp0, fp1);
6512
            tcg_temp_free_i32(fp1);
6513
            gen_store_fpr32(fp0, fd);
6514
            tcg_temp_free_i32(fp0);
6515
        }
6516
        opn = "div.s";
6517
        optype = BINOP;
6518
        break;
6519
    case OPC_SQRT_S:
6520
        {
6521
            TCGv_i32 fp0 = tcg_temp_new_i32();
6522

    
6523
            gen_load_fpr32(fp0, fs);
6524
            gen_helper_float_sqrt_s(fp0, fp0);
6525
            gen_store_fpr32(fp0, fd);
6526
            tcg_temp_free_i32(fp0);
6527
        }
6528
        opn = "sqrt.s";
6529
        break;
6530
    case OPC_ABS_S:
6531
        {
6532
            TCGv_i32 fp0 = tcg_temp_new_i32();
6533

    
6534
            gen_load_fpr32(fp0, fs);
6535
            gen_helper_float_abs_s(fp0, fp0);
6536
            gen_store_fpr32(fp0, fd);
6537
            tcg_temp_free_i32(fp0);
6538
        }
6539
        opn = "abs.s";
6540
        break;
6541
    case OPC_MOV_S:
6542
        {
6543
            TCGv_i32 fp0 = tcg_temp_new_i32();
6544

    
6545
            gen_load_fpr32(fp0, fs);
6546
            gen_store_fpr32(fp0, fd);
6547
            tcg_temp_free_i32(fp0);
6548
        }
6549
        opn = "mov.s";
6550
        break;
6551
    case OPC_NEG_S:
6552
        {
6553
            TCGv_i32 fp0 = tcg_temp_new_i32();
6554

    
6555
            gen_load_fpr32(fp0, fs);
6556
            gen_helper_float_chs_s(fp0, fp0);
6557
            gen_store_fpr32(fp0, fd);
6558
            tcg_temp_free_i32(fp0);
6559
        }
6560
        opn = "neg.s";
6561
        break;
6562
    case OPC_ROUND_L_S:
6563
        check_cp1_64bitmode(ctx);
6564
        {
6565
            TCGv_i32 fp32 = tcg_temp_new_i32();
6566
            TCGv_i64 fp64 = tcg_temp_new_i64();
6567

    
6568
            gen_load_fpr32(fp32, fs);
6569
            gen_helper_float_roundl_s(fp64, fp32);
6570
            tcg_temp_free_i32(fp32);
6571
            gen_store_fpr64(ctx, fp64, fd);
6572
            tcg_temp_free_i64(fp64);
6573
        }
6574
        opn = "round.l.s";
6575
        break;
6576
    case OPC_TRUNC_L_S:
6577
        check_cp1_64bitmode(ctx);
6578
        {
6579
            TCGv_i32 fp32 = tcg_temp_new_i32();
6580
            TCGv_i64 fp64 = tcg_temp_new_i64();
6581

    
6582
            gen_load_fpr32(fp32, fs);
6583
            gen_helper_float_truncl_s(fp64, fp32);
6584
            tcg_temp_free_i32(fp32);
6585
            gen_store_fpr64(ctx, fp64, fd);
6586
            tcg_temp_free_i64(fp64);
6587
        }
6588
        opn = "trunc.l.s";
6589
        break;
6590
    case OPC_CEIL_L_S:
6591
        check_cp1_64bitmode(ctx);
6592
        {
6593
            TCGv_i32 fp32 = tcg_temp_new_i32();
6594
            TCGv_i64 fp64 = tcg_temp_new_i64();
6595

    
6596
            gen_load_fpr32(fp32, fs);
6597
            gen_helper_float_ceill_s(fp64, fp32);
6598
            tcg_temp_free_i32(fp32);
6599
            gen_store_fpr64(ctx, fp64, fd);
6600
            tcg_temp_free_i64(fp64);
6601
        }
6602
        opn = "ceil.l.s";
6603
        break;
6604
    case OPC_FLOOR_L_S:
6605
        check_cp1_64bitmode(ctx);
6606
        {
6607
            TCGv_i32 fp32 = tcg_temp_new_i32();
6608
            TCGv_i64 fp64 = tcg_temp_new_i64();
6609

    
6610
            gen_load_fpr32(fp32, fs);
6611
            gen_helper_float_floorl_s(fp64, fp32);
6612
            tcg_temp_free_i32(fp32);
6613
            gen_store_fpr64(ctx, fp64, fd);
6614
            tcg_temp_free_i64(fp64);
6615
        }
6616
        opn = "floor.l.s";
6617
        break;
6618
    case OPC_ROUND_W_S:
6619
        {
6620
            TCGv_i32 fp0 = tcg_temp_new_i32();
6621

    
6622
            gen_load_fpr32(fp0, fs);
6623
            gen_helper_float_roundw_s(fp0, fp0);
6624
            gen_store_fpr32(fp0, fd);
6625
            tcg_temp_free_i32(fp0);
6626
        }
6627
        opn = "round.w.s";
6628
        break;
6629
    case OPC_TRUNC_W_S:
6630
        {
6631
            TCGv_i32 fp0 = tcg_temp_new_i32();
6632

    
6633
            gen_load_fpr32(fp0, fs);
6634
            gen_helper_float_truncw_s(fp0, fp0);
6635
            gen_store_fpr32(fp0, fd);
6636
            tcg_temp_free_i32(fp0);
6637
        }
6638
        opn = "trunc.w.s";
6639
        break;
6640
    case OPC_CEIL_W_S:
6641
        {
6642
            TCGv_i32 fp0 = tcg_temp_new_i32();
6643

    
6644
            gen_load_fpr32(fp0, fs);
6645
            gen_helper_float_ceilw_s(fp0, fp0);
6646
            gen_store_fpr32(fp0, fd);
6647
            tcg_temp_free_i32(fp0);
6648
        }
6649
        opn = "ceil.w.s";
6650
        break;
6651
    case OPC_FLOOR_W_S:
6652
        {
6653
            TCGv_i32 fp0 = tcg_temp_new_i32();
6654

    
6655
            gen_load_fpr32(fp0, fs);
6656
            gen_helper_float_floorw_s(fp0, fp0);
6657
            gen_store_fpr32(fp0, fd);
6658
            tcg_temp_free_i32(fp0);
6659
        }
6660
        opn = "floor.w.s";
6661
        break;
6662
    case OPC_MOVCF_S:
6663
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6664
        opn = "movcf.s";
6665
        break;
6666
    case OPC_MOVZ_S:
6667
        {
6668
            int l1 = gen_new_label();
6669
            TCGv_i32 fp0;
6670

    
6671
            if (ft != 0) {
6672
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6673
            }
6674
            fp0 = tcg_temp_new_i32();
6675
            gen_load_fpr32(fp0, fs);
6676
            gen_store_fpr32(fp0, fd);
6677
            tcg_temp_free_i32(fp0);
6678
            gen_set_label(l1);
6679
        }
6680
        opn = "movz.s";
6681
        break;
6682
    case OPC_MOVN_S:
6683
        {
6684
            int l1 = gen_new_label();
6685
            TCGv_i32 fp0;
6686

    
6687
            if (ft != 0) {
6688
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6689
                fp0 = tcg_temp_new_i32();
6690
                gen_load_fpr32(fp0, fs);
6691
                gen_store_fpr32(fp0, fd);
6692
                tcg_temp_free_i32(fp0);
6693
                gen_set_label(l1);
6694
            }
6695
        }
6696
        opn = "movn.s";
6697
        break;
6698
    case OPC_RECIP_S:
6699
        check_cop1x(ctx);
6700
        {
6701
            TCGv_i32 fp0 = tcg_temp_new_i32();
6702

    
6703
            gen_load_fpr32(fp0, fs);
6704
            gen_helper_float_recip_s(fp0, fp0);
6705
            gen_store_fpr32(fp0, fd);
6706
            tcg_temp_free_i32(fp0);
6707
        }
6708
        opn = "recip.s";
6709
        break;
6710
    case OPC_RSQRT_S:
6711
        check_cop1x(ctx);
6712
        {
6713
            TCGv_i32 fp0 = tcg_temp_new_i32();
6714

    
6715
            gen_load_fpr32(fp0, fs);
6716
            gen_helper_float_rsqrt_s(fp0, fp0);
6717
            gen_store_fpr32(fp0, fd);
6718
            tcg_temp_free_i32(fp0);
6719
        }
6720
        opn = "rsqrt.s";
6721
        break;
6722
    case OPC_RECIP2_S:
6723
        check_cp1_64bitmode(ctx);
6724
        {
6725
            TCGv_i32 fp0 = tcg_temp_new_i32();
6726
            TCGv_i32 fp1 = tcg_temp_new_i32();
6727

    
6728
            gen_load_fpr32(fp0, fs);
6729
            gen_load_fpr32(fp1, fd);
6730
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6731
            tcg_temp_free_i32(fp1);
6732
            gen_store_fpr32(fp0, fd);
6733
            tcg_temp_free_i32(fp0);
6734
        }
6735
        opn = "recip2.s";
6736
        break;
6737
    case OPC_RECIP1_S:
6738
        check_cp1_64bitmode(ctx);
6739
        {
6740
            TCGv_i32 fp0 = tcg_temp_new_i32();
6741

    
6742
            gen_load_fpr32(fp0, fs);
6743
            gen_helper_float_recip1_s(fp0, fp0);
6744
            gen_store_fpr32(fp0, fd);
6745
            tcg_temp_free_i32(fp0);
6746
        }
6747
        opn = "recip1.s";
6748
        break;
6749
    case OPC_RSQRT1_S:
6750
        check_cp1_64bitmode(ctx);
6751
        {
6752
            TCGv_i32 fp0 = tcg_temp_new_i32();
6753

    
6754
            gen_load_fpr32(fp0, fs);
6755
            gen_helper_float_rsqrt1_s(fp0, fp0);
6756
            gen_store_fpr32(fp0, fd);
6757
            tcg_temp_free_i32(fp0);
6758
        }
6759
        opn = "rsqrt1.s";
6760
        break;
6761
    case OPC_RSQRT2_S:
6762
        check_cp1_64bitmode(ctx);
6763
        {
6764
            TCGv_i32 fp0 = tcg_temp_new_i32();
6765
            TCGv_i32 fp1 = tcg_temp_new_i32();
6766

    
6767
            gen_load_fpr32(fp0, fs);
6768
            gen_load_fpr32(fp1, ft);
6769
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6770
            tcg_temp_free_i32(fp1);
6771
            gen_store_fpr32(fp0, fd);
6772
            tcg_temp_free_i32(fp0);
6773
        }
6774
        opn = "rsqrt2.s";
6775
        break;
6776
    case OPC_CVT_D_S:
6777
        check_cp1_registers(ctx, fd);
6778
        {
6779
            TCGv_i32 fp32 = tcg_temp_new_i32();
6780
            TCGv_i64 fp64 = tcg_temp_new_i64();
6781

    
6782
            gen_load_fpr32(fp32, fs);
6783
            gen_helper_float_cvtd_s(fp64, fp32);
6784
            tcg_temp_free_i32(fp32);
6785
            gen_store_fpr64(ctx, fp64, fd);
6786
            tcg_temp_free_i64(fp64);
6787
        }
6788
        opn = "cvt.d.s";
6789
        break;
6790
    case OPC_CVT_W_S:
6791
        {
6792
            TCGv_i32 fp0 = tcg_temp_new_i32();
6793

    
6794
            gen_load_fpr32(fp0, fs);
6795
            gen_helper_float_cvtw_s(fp0, fp0);
6796
            gen_store_fpr32(fp0, fd);
6797
            tcg_temp_free_i32(fp0);
6798
        }
6799
        opn = "cvt.w.s";
6800
        break;
6801
    case OPC_CVT_L_S:
6802
        check_cp1_64bitmode(ctx);
6803
        {
6804
            TCGv_i32 fp32 = tcg_temp_new_i32();
6805
            TCGv_i64 fp64 = tcg_temp_new_i64();
6806

    
6807
            gen_load_fpr32(fp32, fs);
6808
            gen_helper_float_cvtl_s(fp64, fp32);
6809
            tcg_temp_free_i32(fp32);
6810
            gen_store_fpr64(ctx, fp64, fd);
6811
            tcg_temp_free_i64(fp64);
6812
        }
6813
        opn = "cvt.l.s";
6814
        break;
6815
    case OPC_CVT_PS_S:
6816
        check_cp1_64bitmode(ctx);
6817
        {
6818
            TCGv_i64 fp64 = tcg_temp_new_i64();
6819
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6820
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6821

    
6822
            gen_load_fpr32(fp32_0, fs);
6823
            gen_load_fpr32(fp32_1, ft);
6824
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6825
            tcg_temp_free_i32(fp32_1);
6826
            tcg_temp_free_i32(fp32_0);
6827
            gen_store_fpr64(ctx, fp64, fd);
6828
            tcg_temp_free_i64(fp64);
6829
        }
6830
        opn = "cvt.ps.s";
6831
        break;
6832
    case OPC_CMP_F_S:
6833
    case OPC_CMP_UN_S:
6834
    case OPC_CMP_EQ_S:
6835
    case OPC_CMP_UEQ_S:
6836
    case OPC_CMP_OLT_S:
6837
    case OPC_CMP_ULT_S:
6838
    case OPC_CMP_OLE_S:
6839
    case OPC_CMP_ULE_S:
6840
    case OPC_CMP_SF_S:
6841
    case OPC_CMP_NGLE_S:
6842
    case OPC_CMP_SEQ_S:
6843
    case OPC_CMP_NGL_S:
6844
    case OPC_CMP_LT_S:
6845
    case OPC_CMP_NGE_S:
6846
    case OPC_CMP_LE_S:
6847
    case OPC_CMP_NGT_S:
6848
        if (ctx->opcode & (1 << 6)) {
6849
            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6850
            opn = condnames_abs[func-48];
6851
        } else {
6852
            gen_cmp_s(ctx, func-48, ft, fs, cc);
6853
            opn = condnames[func-48];
6854
        }
6855
        break;
6856
    case OPC_ADD_D:
6857
        check_cp1_registers(ctx, fs | ft | fd);
6858
        {
6859
            TCGv_i64 fp0 = tcg_temp_new_i64();
6860
            TCGv_i64 fp1 = tcg_temp_new_i64();
6861

    
6862
            gen_load_fpr64(ctx, fp0, fs);
6863
            gen_load_fpr64(ctx, fp1, ft);
6864
            gen_helper_float_add_d(fp0, fp0, fp1);
6865
            tcg_temp_free_i64(fp1);
6866
            gen_store_fpr64(ctx, fp0, fd);
6867
            tcg_temp_free_i64(fp0);
6868
        }
6869
        opn = "add.d";
6870
        optype = BINOP;
6871
        break;
6872
    case OPC_SUB_D:
6873
        check_cp1_registers(ctx, fs | ft | fd);
6874
        {
6875
            TCGv_i64 fp0 = tcg_temp_new_i64();
6876
            TCGv_i64 fp1 = tcg_temp_new_i64();
6877

    
6878
            gen_load_fpr64(ctx, fp0, fs);
6879
            gen_load_fpr64(ctx, fp1, ft);
6880
            gen_helper_float_sub_d(fp0, fp0, fp1);
6881
            tcg_temp_free_i64(fp1);
6882
            gen_store_fpr64(ctx, fp0, fd);
6883
            tcg_temp_free_i64(fp0);
6884
        }
6885
        opn = "sub.d";
6886
        optype = BINOP;
6887
        break;
6888
    case OPC_MUL_D:
6889
        check_cp1_registers(ctx, fs | ft | fd);
6890
        {
6891
            TCGv_i64 fp0 = tcg_temp_new_i64();
6892
            TCGv_i64 fp1 = tcg_temp_new_i64();
6893

    
6894
            gen_load_fpr64(ctx, fp0, fs);
6895
            gen_load_fpr64(ctx, fp1, ft);
6896
            gen_helper_float_mul_d(fp0, fp0, fp1);
6897
            tcg_temp_free_i64(fp1);
6898
            gen_store_fpr64(ctx, fp0, fd);
6899
            tcg_temp_free_i64(fp0);
6900
        }
6901
        opn = "mul.d";
6902
        optype = BINOP;
6903
        break;
6904
    case OPC_DIV_D:
6905
        check_cp1_registers(ctx, fs | ft | fd);
6906
        {
6907
            TCGv_i64 fp0 = tcg_temp_new_i64();
6908
            TCGv_i64 fp1 = tcg_temp_new_i64();
6909

    
6910
            gen_load_fpr64(ctx, fp0, fs);
6911
            gen_load_fpr64(ctx, fp1, ft);
6912
            gen_helper_float_div_d(fp0, fp0, fp1);
6913
            tcg_temp_free_i64(fp1);
6914
            gen_store_fpr64(ctx, fp0, fd);
6915
            tcg_temp_free_i64(fp0);
6916
        }
6917
        opn = "div.d";
6918
        optype = BINOP;
6919
        break;
6920
    case OPC_SQRT_D:
6921
        check_cp1_registers(ctx, fs | fd);
6922
        {
6923
            TCGv_i64 fp0 = tcg_temp_new_i64();
6924

    
6925
            gen_load_fpr64(ctx, fp0, fs);
6926
            gen_helper_float_sqrt_d(fp0, fp0);
6927
            gen_store_fpr64(ctx, fp0, fd);
6928
            tcg_temp_free_i64(fp0);
6929
        }
6930
        opn = "sqrt.d";
6931
        break;
6932
    case OPC_ABS_D:
6933
        check_cp1_registers(ctx, fs | fd);
6934
        {
6935
            TCGv_i64 fp0 = tcg_temp_new_i64();
6936

    
6937
            gen_load_fpr64(ctx, fp0, fs);
6938
            gen_helper_float_abs_d(fp0, fp0);
6939
            gen_store_fpr64(ctx, fp0, fd);
6940
            tcg_temp_free_i64(fp0);
6941
        }
6942
        opn = "abs.d";
6943
        break;
6944
    case OPC_MOV_D:
6945
        check_cp1_registers(ctx, fs | fd);
6946
        {
6947
            TCGv_i64 fp0 = tcg_temp_new_i64();
6948

    
6949
            gen_load_fpr64(ctx, fp0, fs);
6950
            gen_store_fpr64(ctx, fp0, fd);
6951
            tcg_temp_free_i64(fp0);
6952
        }
6953
        opn = "mov.d";
6954
        break;
6955
    case OPC_NEG_D:
6956
        check_cp1_registers(ctx, fs | fd);
6957
        {
6958
            TCGv_i64 fp0 = tcg_temp_new_i64();
6959

    
6960
            gen_load_fpr64(ctx, fp0, fs);
6961
            gen_helper_float_chs_d(fp0, fp0);
6962
            gen_store_fpr64(ctx, fp0, fd);
6963
            tcg_temp_free_i64(fp0);
6964
        }
6965
        opn = "neg.d";
6966
        break;
6967
    case OPC_ROUND_L_D:
6968
        check_cp1_64bitmode(ctx);
6969
        {
6970
            TCGv_i64 fp0 = tcg_temp_new_i64();
6971

    
6972
            gen_load_fpr64(ctx, fp0, fs);
6973
            gen_helper_float_roundl_d(fp0, fp0);
6974
            gen_store_fpr64(ctx, fp0, fd);
6975
            tcg_temp_free_i64(fp0);
6976
        }
6977
        opn = "round.l.d";
6978
        break;
6979
    case OPC_TRUNC_L_D:
6980
        check_cp1_64bitmode(ctx);
6981
        {
6982
            TCGv_i64 fp0 = tcg_temp_new_i64();
6983

    
6984
            gen_load_fpr64(ctx, fp0, fs);
6985
            gen_helper_float_truncl_d(fp0, fp0);
6986
            gen_store_fpr64(ctx, fp0, fd);
6987
            tcg_temp_free_i64(fp0);
6988
        }
6989
        opn = "trunc.l.d";
6990
        break;
6991
    case OPC_CEIL_L_D:
6992
        check_cp1_64bitmode(ctx);
6993
        {
6994
            TCGv_i64 fp0 = tcg_temp_new_i64();
6995

    
6996
            gen_load_fpr64(ctx, fp0, fs);
6997
            gen_helper_float_ceill_d(fp0, fp0);
6998
            gen_store_fpr64(ctx, fp0, fd);
6999
            tcg_temp_free_i64(fp0);
7000
        }
7001
        opn = "ceil.l.d";
7002
        break;
7003
    case OPC_FLOOR_L_D:
7004
        check_cp1_64bitmode(ctx);
7005
        {
7006
            TCGv_i64 fp0 = tcg_temp_new_i64();
7007

    
7008
            gen_load_fpr64(ctx, fp0, fs);
7009
            gen_helper_float_floorl_d(fp0, fp0);
7010
            gen_store_fpr64(ctx, fp0, fd);
7011
            tcg_temp_free_i64(fp0);
7012
        }
7013
        opn = "floor.l.d";
7014
        break;
7015
    case OPC_ROUND_W_D:
7016
        check_cp1_registers(ctx, fs);
7017
        {
7018
            TCGv_i32 fp32 = tcg_temp_new_i32();
7019
            TCGv_i64 fp64 = tcg_temp_new_i64();
7020

    
7021
            gen_load_fpr64(ctx, fp64, fs);
7022
            gen_helper_float_roundw_d(fp32, fp64);
7023
            tcg_temp_free_i64(fp64);
7024
            gen_store_fpr32(fp32, fd);
7025
            tcg_temp_free_i32(fp32);
7026
        }
7027
        opn = "round.w.d";
7028
        break;
7029
    case OPC_TRUNC_W_D:
7030
        check_cp1_registers(ctx, fs);
7031
        {
7032
            TCGv_i32 fp32 = tcg_temp_new_i32();
7033
            TCGv_i64 fp64 = tcg_temp_new_i64();
7034

    
7035
            gen_load_fpr64(ctx, fp64, fs);
7036
            gen_helper_float_truncw_d(fp32, fp64);
7037
            tcg_temp_free_i64(fp64);
7038
            gen_store_fpr32(fp32, fd);
7039
            tcg_temp_free_i32(fp32);
7040
        }
7041
        opn = "trunc.w.d";
7042
        break;
7043
    case OPC_CEIL_W_D:
7044
        check_cp1_registers(ctx, fs);
7045
        {
7046
            TCGv_i32 fp32 = tcg_temp_new_i32();
7047
            TCGv_i64 fp64 = tcg_temp_new_i64();
7048

    
7049
            gen_load_fpr64(ctx, fp64, fs);
7050
            gen_helper_float_ceilw_d(fp32, fp64);
7051
            tcg_temp_free_i64(fp64);
7052
            gen_store_fpr32(fp32, fd);
7053
            tcg_temp_free_i32(fp32);
7054
        }
7055
        opn = "ceil.w.d";
7056
        break;
7057
    case OPC_FLOOR_W_D:
7058
        check_cp1_registers(ctx, fs);
7059
        {
7060
            TCGv_i32 fp32 = tcg_temp_new_i32();
7061
            TCGv_i64 fp64 = tcg_temp_new_i64();
7062

    
7063
            gen_load_fpr64(ctx, fp64, fs);
7064
            gen_helper_float_floorw_d(fp32, fp64);
7065
            tcg_temp_free_i64(fp64);
7066
            gen_store_fpr32(fp32, fd);
7067
            tcg_temp_free_i32(fp32);
7068
        }
7069
        opn = "floor.w.d";
7070
        break;
7071
    case OPC_MOVCF_D:
7072
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7073
        opn = "movcf.d";
7074
        break;
7075
    case OPC_MOVZ_D:
7076
        {
7077
            int l1 = gen_new_label();
7078
            TCGv_i64 fp0;
7079

    
7080
            if (ft != 0) {
7081
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7082
            }
7083
            fp0 = tcg_temp_new_i64();
7084
            gen_load_fpr64(ctx, fp0, fs);
7085
            gen_store_fpr64(ctx, fp0, fd);
7086
            tcg_temp_free_i64(fp0);
7087
            gen_set_label(l1);
7088
        }
7089
        opn = "movz.d";
7090
        break;
7091
    case OPC_MOVN_D:
7092
        {
7093
            int l1 = gen_new_label();
7094
            TCGv_i64 fp0;
7095

    
7096
            if (ft != 0) {
7097
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7098
                fp0 = tcg_temp_new_i64();
7099
                gen_load_fpr64(ctx, fp0, fs);
7100
                gen_store_fpr64(ctx, fp0, fd);
7101
                tcg_temp_free_i64(fp0);
7102
                gen_set_label(l1);
7103
            }
7104
        }
7105
        opn = "movn.d";
7106
        break;
7107
    case OPC_RECIP_D:
7108
        check_cp1_64bitmode(ctx);
7109
        {
7110
            TCGv_i64 fp0 = tcg_temp_new_i64();
7111

    
7112
            gen_load_fpr64(ctx, fp0, fs);
7113
            gen_helper_float_recip_d(fp0, fp0);
7114
            gen_store_fpr64(ctx, fp0, fd);
7115
            tcg_temp_free_i64(fp0);
7116
        }
7117
        opn = "recip.d";
7118
        break;
7119
    case OPC_RSQRT_D:
7120
        check_cp1_64bitmode(ctx);
7121
        {
7122
            TCGv_i64 fp0 = tcg_temp_new_i64();
7123

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

    
7137
            gen_load_fpr64(ctx, fp0, fs);
7138
            gen_load_fpr64(ctx, fp1, ft);
7139
            gen_helper_float_recip2_d(fp0, fp0, fp1);
7140
            tcg_temp_free_i64(fp1);
7141
            gen_store_fpr64(ctx, fp0, fd);
7142
            tcg_temp_free_i64(fp0);
7143
        }
7144
        opn = "recip2.d";
7145
        break;
7146
    case OPC_RECIP1_D:
7147
        check_cp1_64bitmode(ctx);
7148
        {
7149
            TCGv_i64 fp0 = tcg_temp_new_i64();
7150

    
7151
            gen_load_fpr64(ctx, fp0, fs);
7152
            gen_helper_float_recip1_d(fp0, fp0);
7153
            gen_store_fpr64(ctx, fp0, fd);
7154
            tcg_temp_free_i64(fp0);
7155
        }
7156
        opn = "recip1.d";
7157
        break;
7158
    case OPC_RSQRT1_D:
7159
        check_cp1_64bitmode(ctx);
7160
        {
7161
            TCGv_i64 fp0 = tcg_temp_new_i64();
7162

    
7163
            gen_load_fpr64(ctx, fp0, fs);
7164
            gen_helper_float_rsqrt1_d(fp0, fp0);
7165
            gen_store_fpr64(ctx, fp0, fd);
7166
            tcg_temp_free_i64(fp0);
7167
        }
7168
        opn = "rsqrt1.d";
7169
        break;
7170
    case OPC_RSQRT2_D:
7171
        check_cp1_64bitmode(ctx);
7172
        {
7173
            TCGv_i64 fp0 = tcg_temp_new_i64();
7174
            TCGv_i64 fp1 = tcg_temp_new_i64();
7175

    
7176
            gen_load_fpr64(ctx, fp0, fs);
7177
            gen_load_fpr64(ctx, fp1, ft);
7178
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7179
            tcg_temp_free_i64(fp1);
7180
            gen_store_fpr64(ctx, fp0, fd);
7181
            tcg_temp_free_i64(fp0);
7182
        }
7183
        opn = "rsqrt2.d";
7184
        break;
7185
    case OPC_CMP_F_D:
7186
    case OPC_CMP_UN_D:
7187
    case OPC_CMP_EQ_D:
7188
    case OPC_CMP_UEQ_D:
7189
    case OPC_CMP_OLT_D:
7190
    case OPC_CMP_ULT_D:
7191
    case OPC_CMP_OLE_D:
7192
    case OPC_CMP_ULE_D:
7193
    case OPC_CMP_SF_D:
7194
    case OPC_CMP_NGLE_D:
7195
    case OPC_CMP_SEQ_D:
7196
    case OPC_CMP_NGL_D:
7197
    case OPC_CMP_LT_D:
7198
    case OPC_CMP_NGE_D:
7199
    case OPC_CMP_LE_D:
7200
    case OPC_CMP_NGT_D:
7201
        if (ctx->opcode & (1 << 6)) {
7202
            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7203
            opn = condnames_abs[func-48];
7204
        } else {
7205
            gen_cmp_d(ctx, func-48, ft, fs, cc);
7206
            opn = condnames[func-48];
7207
        }
7208
        break;
7209
    case OPC_CVT_S_D:
7210
        check_cp1_registers(ctx, fs);
7211
        {
7212
            TCGv_i32 fp32 = tcg_temp_new_i32();
7213
            TCGv_i64 fp64 = tcg_temp_new_i64();
7214

    
7215
            gen_load_fpr64(ctx, fp64, fs);
7216
            gen_helper_float_cvts_d(fp32, fp64);
7217
            tcg_temp_free_i64(fp64);
7218
            gen_store_fpr32(fp32, fd);
7219
            tcg_temp_free_i32(fp32);
7220
        }
7221
        opn = "cvt.s.d";
7222
        break;
7223
    case OPC_CVT_W_D:
7224
        check_cp1_registers(ctx, fs);
7225
        {
7226
            TCGv_i32 fp32 = tcg_temp_new_i32();
7227
            TCGv_i64 fp64 = tcg_temp_new_i64();
7228

    
7229
            gen_load_fpr64(ctx, fp64, fs);
7230
            gen_helper_float_cvtw_d(fp32, fp64);
7231
            tcg_temp_free_i64(fp64);
7232
            gen_store_fpr32(fp32, fd);
7233
            tcg_temp_free_i32(fp32);
7234
        }
7235
        opn = "cvt.w.d";
7236
        break;
7237
    case OPC_CVT_L_D:
7238
        check_cp1_64bitmode(ctx);
7239
        {
7240
            TCGv_i64 fp0 = tcg_temp_new_i64();
7241

    
7242
            gen_load_fpr64(ctx, fp0, fs);
7243
            gen_helper_float_cvtl_d(fp0, fp0);
7244
            gen_store_fpr64(ctx, fp0, fd);
7245
            tcg_temp_free_i64(fp0);
7246
        }
7247
        opn = "cvt.l.d";
7248
        break;
7249
    case OPC_CVT_S_W:
7250
        {
7251
            TCGv_i32 fp0 = tcg_temp_new_i32();
7252

    
7253
            gen_load_fpr32(fp0, fs);
7254
            gen_helper_float_cvts_w(fp0, fp0);
7255
            gen_store_fpr32(fp0, fd);
7256
            tcg_temp_free_i32(fp0);
7257
        }
7258
        opn = "cvt.s.w";
7259
        break;
7260
    case OPC_CVT_D_W:
7261
        check_cp1_registers(ctx, fd);
7262
        {
7263
            TCGv_i32 fp32 = tcg_temp_new_i32();
7264
            TCGv_i64 fp64 = tcg_temp_new_i64();
7265

    
7266
            gen_load_fpr32(fp32, fs);
7267
            gen_helper_float_cvtd_w(fp64, fp32);
7268
            tcg_temp_free_i32(fp32);
7269
            gen_store_fpr64(ctx, fp64, fd);
7270
            tcg_temp_free_i64(fp64);
7271
        }
7272
        opn = "cvt.d.w";
7273
        break;
7274
    case OPC_CVT_S_L:
7275
        check_cp1_64bitmode(ctx);
7276
        {
7277
            TCGv_i32 fp32 = tcg_temp_new_i32();
7278
            TCGv_i64 fp64 = tcg_temp_new_i64();
7279

    
7280
            gen_load_fpr64(ctx, fp64, fs);
7281
            gen_helper_float_cvts_l(fp32, fp64);
7282
            tcg_temp_free_i64(fp64);
7283
            gen_store_fpr32(fp32, fd);
7284
            tcg_temp_free_i32(fp32);
7285
        }
7286
        opn = "cvt.s.l";
7287
        break;
7288
    case OPC_CVT_D_L:
7289
        check_cp1_64bitmode(ctx);
7290
        {
7291
            TCGv_i64 fp0 = tcg_temp_new_i64();
7292

    
7293
            gen_load_fpr64(ctx, fp0, fs);
7294
            gen_helper_float_cvtd_l(fp0, fp0);
7295
            gen_store_fpr64(ctx, fp0, fd);
7296
            tcg_temp_free_i64(fp0);
7297
        }
7298
        opn = "cvt.d.l";
7299
        break;
7300
    case OPC_CVT_PS_PW:
7301
        check_cp1_64bitmode(ctx);
7302
        {
7303
            TCGv_i64 fp0 = tcg_temp_new_i64();
7304

    
7305
            gen_load_fpr64(ctx, fp0, fs);
7306
            gen_helper_float_cvtps_pw(fp0, fp0);
7307
            gen_store_fpr64(ctx, fp0, fd);
7308
            tcg_temp_free_i64(fp0);
7309
        }
7310
        opn = "cvt.ps.pw";
7311
        break;
7312
    case OPC_ADD_PS:
7313
        check_cp1_64bitmode(ctx);
7314
        {
7315
            TCGv_i64 fp0 = tcg_temp_new_i64();
7316
            TCGv_i64 fp1 = tcg_temp_new_i64();
7317

    
7318
            gen_load_fpr64(ctx, fp0, fs);
7319
            gen_load_fpr64(ctx, fp1, ft);
7320
            gen_helper_float_add_ps(fp0, fp0, fp1);
7321
            tcg_temp_free_i64(fp1);
7322
            gen_store_fpr64(ctx, fp0, fd);
7323
            tcg_temp_free_i64(fp0);
7324
        }
7325
        opn = "add.ps";
7326
        break;
7327
    case OPC_SUB_PS:
7328
        check_cp1_64bitmode(ctx);
7329
        {
7330
            TCGv_i64 fp0 = tcg_temp_new_i64();
7331
            TCGv_i64 fp1 = tcg_temp_new_i64();
7332

    
7333
            gen_load_fpr64(ctx, fp0, fs);
7334
            gen_load_fpr64(ctx, fp1, ft);
7335
            gen_helper_float_sub_ps(fp0, fp0, fp1);
7336
            tcg_temp_free_i64(fp1);
7337
            gen_store_fpr64(ctx, fp0, fd);
7338
            tcg_temp_free_i64(fp0);
7339
        }
7340
        opn = "sub.ps";
7341
        break;
7342
    case OPC_MUL_PS:
7343
        check_cp1_64bitmode(ctx);
7344
        {
7345
            TCGv_i64 fp0 = tcg_temp_new_i64();
7346
            TCGv_i64 fp1 = tcg_temp_new_i64();
7347

    
7348
            gen_load_fpr64(ctx, fp0, fs);
7349
            gen_load_fpr64(ctx, fp1, ft);
7350
            gen_helper_float_mul_ps(fp0, fp0, fp1);
7351
            tcg_temp_free_i64(fp1);
7352
            gen_store_fpr64(ctx, fp0, fd);
7353
            tcg_temp_free_i64(fp0);
7354
        }
7355
        opn = "mul.ps";
7356
        break;
7357
    case OPC_ABS_PS:
7358
        check_cp1_64bitmode(ctx);
7359
        {
7360
            TCGv_i64 fp0 = tcg_temp_new_i64();
7361

    
7362
            gen_load_fpr64(ctx, fp0, fs);
7363
            gen_helper_float_abs_ps(fp0, fp0);
7364
            gen_store_fpr64(ctx, fp0, fd);
7365
            tcg_temp_free_i64(fp0);
7366
        }
7367
        opn = "abs.ps";
7368
        break;
7369
    case OPC_MOV_PS:
7370
        check_cp1_64bitmode(ctx);
7371
        {
7372
            TCGv_i64 fp0 = tcg_temp_new_i64();
7373

    
7374
            gen_load_fpr64(ctx, fp0, fs);
7375
            gen_store_fpr64(ctx, fp0, fd);
7376
            tcg_temp_free_i64(fp0);
7377
        }
7378
        opn = "mov.ps";
7379
        break;
7380
    case OPC_NEG_PS:
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_chs_ps(fp0, fp0);
7387
            gen_store_fpr64(ctx, fp0, fd);
7388
            tcg_temp_free_i64(fp0);
7389
        }
7390
        opn = "neg.ps";
7391
        break;
7392
    case OPC_MOVCF_PS:
7393
        check_cp1_64bitmode(ctx);
7394
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7395
        opn = "movcf.ps";
7396
        break;
7397
    case OPC_MOVZ_PS:
7398
        check_cp1_64bitmode(ctx);
7399
        {
7400
            int l1 = gen_new_label();
7401
            TCGv_i64 fp0;
7402

    
7403
            if (ft != 0)
7404
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7405
            fp0 = tcg_temp_new_i64();
7406
            gen_load_fpr64(ctx, fp0, fs);
7407
            gen_store_fpr64(ctx, fp0, fd);
7408
            tcg_temp_free_i64(fp0);
7409
            gen_set_label(l1);
7410
        }
7411
        opn = "movz.ps";
7412
        break;
7413
    case OPC_MOVN_PS:
7414
        check_cp1_64bitmode(ctx);
7415
        {
7416
            int l1 = gen_new_label();
7417
            TCGv_i64 fp0;
7418

    
7419
            if (ft != 0) {
7420
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7421
                fp0 = tcg_temp_new_i64();
7422
                gen_load_fpr64(ctx, fp0, fs);
7423
                gen_store_fpr64(ctx, fp0, fd);
7424
                tcg_temp_free_i64(fp0);
7425
                gen_set_label(l1);
7426
            }
7427
        }
7428
        opn = "movn.ps";
7429
        break;
7430
    case OPC_ADDR_PS:
7431
        check_cp1_64bitmode(ctx);
7432
        {
7433
            TCGv_i64 fp0 = tcg_temp_new_i64();
7434
            TCGv_i64 fp1 = tcg_temp_new_i64();
7435

    
7436
            gen_load_fpr64(ctx, fp0, ft);
7437
            gen_load_fpr64(ctx, fp1, fs);
7438
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7439
            tcg_temp_free_i64(fp1);
7440
            gen_store_fpr64(ctx, fp0, fd);
7441
            tcg_temp_free_i64(fp0);
7442
        }
7443
        opn = "addr.ps";
7444
        break;
7445
    case OPC_MULR_PS:
7446
        check_cp1_64bitmode(ctx);
7447
        {
7448
            TCGv_i64 fp0 = tcg_temp_new_i64();
7449
            TCGv_i64 fp1 = tcg_temp_new_i64();
7450

    
7451
            gen_load_fpr64(ctx, fp0, ft);
7452
            gen_load_fpr64(ctx, fp1, fs);
7453
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7454
            tcg_temp_free_i64(fp1);
7455
            gen_store_fpr64(ctx, fp0, fd);
7456
            tcg_temp_free_i64(fp0);
7457
        }
7458
        opn = "mulr.ps";
7459
        break;
7460
    case OPC_RECIP2_PS:
7461
        check_cp1_64bitmode(ctx);
7462
        {
7463
            TCGv_i64 fp0 = tcg_temp_new_i64();
7464
            TCGv_i64 fp1 = tcg_temp_new_i64();
7465

    
7466
            gen_load_fpr64(ctx, fp0, fs);
7467
            gen_load_fpr64(ctx, fp1, fd);
7468
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7469
            tcg_temp_free_i64(fp1);
7470
            gen_store_fpr64(ctx, fp0, fd);
7471
            tcg_temp_free_i64(fp0);
7472
        }
7473
        opn = "recip2.ps";
7474
        break;
7475
    case OPC_RECIP1_PS:
7476
        check_cp1_64bitmode(ctx);
7477
        {
7478
            TCGv_i64 fp0 = tcg_temp_new_i64();
7479

    
7480
            gen_load_fpr64(ctx, fp0, fs);
7481
            gen_helper_float_recip1_ps(fp0, fp0);
7482
            gen_store_fpr64(ctx, fp0, fd);
7483
            tcg_temp_free_i64(fp0);
7484
        }
7485
        opn = "recip1.ps";
7486
        break;
7487
    case OPC_RSQRT1_PS:
7488
        check_cp1_64bitmode(ctx);
7489
        {
7490
            TCGv_i64 fp0 = tcg_temp_new_i64();
7491

    
7492
            gen_load_fpr64(ctx, fp0, fs);
7493
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7494
            gen_store_fpr64(ctx, fp0, fd);
7495
            tcg_temp_free_i64(fp0);
7496
        }
7497
        opn = "rsqrt1.ps";
7498
        break;
7499
    case OPC_RSQRT2_PS:
7500
        check_cp1_64bitmode(ctx);
7501
        {
7502
            TCGv_i64 fp0 = tcg_temp_new_i64();
7503
            TCGv_i64 fp1 = tcg_temp_new_i64();
7504

    
7505
            gen_load_fpr64(ctx, fp0, fs);
7506
            gen_load_fpr64(ctx, fp1, ft);
7507
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7508
            tcg_temp_free_i64(fp1);
7509
            gen_store_fpr64(ctx, fp0, fd);
7510
            tcg_temp_free_i64(fp0);
7511
        }
7512
        opn = "rsqrt2.ps";
7513
        break;
7514
    case OPC_CVT_S_PU:
7515
        check_cp1_64bitmode(ctx);
7516
        {
7517
            TCGv_i32 fp0 = tcg_temp_new_i32();
7518

    
7519
            gen_load_fpr32h(fp0, fs);
7520
            gen_helper_float_cvts_pu(fp0, fp0);
7521
            gen_store_fpr32(fp0, fd);
7522
            tcg_temp_free_i32(fp0);
7523
        }
7524
        opn = "cvt.s.pu";
7525
        break;
7526
    case OPC_CVT_PW_PS:
7527
        check_cp1_64bitmode(ctx);
7528
        {
7529
            TCGv_i64 fp0 = tcg_temp_new_i64();
7530

    
7531
            gen_load_fpr64(ctx, fp0, fs);
7532
            gen_helper_float_cvtpw_ps(fp0, fp0);
7533
            gen_store_fpr64(ctx, fp0, fd);
7534
            tcg_temp_free_i64(fp0);
7535
        }
7536
        opn = "cvt.pw.ps";
7537
        break;
7538
    case OPC_CVT_S_PL:
7539
        check_cp1_64bitmode(ctx);
7540
        {
7541
            TCGv_i32 fp0 = tcg_temp_new_i32();
7542

    
7543
            gen_load_fpr32(fp0, fs);
7544
            gen_helper_float_cvts_pl(fp0, fp0);
7545
            gen_store_fpr32(fp0, fd);
7546
            tcg_temp_free_i32(fp0);
7547
        }
7548
        opn = "cvt.s.pl";
7549
        break;
7550
    case OPC_PLL_PS:
7551
        check_cp1_64bitmode(ctx);
7552
        {
7553
            TCGv_i32 fp0 = tcg_temp_new_i32();
7554
            TCGv_i32 fp1 = tcg_temp_new_i32();
7555

    
7556
            gen_load_fpr32(fp0, fs);
7557
            gen_load_fpr32(fp1, ft);
7558
            gen_store_fpr32h(fp0, fd);
7559
            gen_store_fpr32(fp1, fd);
7560
            tcg_temp_free_i32(fp0);
7561
            tcg_temp_free_i32(fp1);
7562
        }
7563
        opn = "pll.ps";
7564
        break;
7565
    case OPC_PLU_PS:
7566
        check_cp1_64bitmode(ctx);
7567
        {
7568
            TCGv_i32 fp0 = tcg_temp_new_i32();
7569
            TCGv_i32 fp1 = tcg_temp_new_i32();
7570

    
7571
            gen_load_fpr32(fp0, fs);
7572
            gen_load_fpr32h(fp1, ft);
7573
            gen_store_fpr32(fp1, fd);
7574
            gen_store_fpr32h(fp0, fd);
7575
            tcg_temp_free_i32(fp0);
7576
            tcg_temp_free_i32(fp1);
7577
        }
7578
        opn = "plu.ps";
7579
        break;
7580
    case OPC_PUL_PS:
7581
        check_cp1_64bitmode(ctx);
7582
        {
7583
            TCGv_i32 fp0 = tcg_temp_new_i32();
7584
            TCGv_i32 fp1 = tcg_temp_new_i32();
7585

    
7586
            gen_load_fpr32h(fp0, fs);
7587
            gen_load_fpr32(fp1, ft);
7588
            gen_store_fpr32(fp1, fd);
7589
            gen_store_fpr32h(fp0, fd);
7590
            tcg_temp_free_i32(fp0);
7591
            tcg_temp_free_i32(fp1);
7592
        }
7593
        opn = "pul.ps";
7594
        break;
7595
    case OPC_PUU_PS:
7596
        check_cp1_64bitmode(ctx);
7597
        {
7598
            TCGv_i32 fp0 = tcg_temp_new_i32();
7599
            TCGv_i32 fp1 = tcg_temp_new_i32();
7600

    
7601
            gen_load_fpr32h(fp0, fs);
7602
            gen_load_fpr32h(fp1, ft);
7603
            gen_store_fpr32(fp1, fd);
7604
            gen_store_fpr32h(fp0, fd);
7605
            tcg_temp_free_i32(fp0);
7606
            tcg_temp_free_i32(fp1);
7607
        }
7608
        opn = "puu.ps";
7609
        break;
7610
    case OPC_CMP_F_PS:
7611
    case OPC_CMP_UN_PS:
7612
    case OPC_CMP_EQ_PS:
7613
    case OPC_CMP_UEQ_PS:
7614
    case OPC_CMP_OLT_PS:
7615
    case OPC_CMP_ULT_PS:
7616
    case OPC_CMP_OLE_PS:
7617
    case OPC_CMP_ULE_PS:
7618
    case OPC_CMP_SF_PS:
7619
    case OPC_CMP_NGLE_PS:
7620
    case OPC_CMP_SEQ_PS:
7621
    case OPC_CMP_NGL_PS:
7622
    case OPC_CMP_LT_PS:
7623
    case OPC_CMP_NGE_PS:
7624
    case OPC_CMP_LE_PS:
7625
    case OPC_CMP_NGT_PS:
7626
        if (ctx->opcode & (1 << 6)) {
7627
            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7628
            opn = condnames_abs[func-48];
7629
        } else {
7630
            gen_cmp_ps(ctx, func-48, ft, fs, cc);
7631
            opn = condnames[func-48];
7632
        }
7633
        break;
7634
    default:
7635
        MIPS_INVAL(opn);
7636
        generate_exception (ctx, EXCP_RI);
7637
        return;
7638
    }
7639
    (void)opn; /* avoid a compiler warning */
7640
    switch (optype) {
7641
    case BINOP:
7642
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7643
        break;
7644
    case CMPOP:
7645
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7646
        break;
7647
    default:
7648
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7649
        break;
7650
    }
7651
}
7652

    
7653
/* Coprocessor 3 (FPU) */
7654
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7655
                           int fd, int fs, int base, int index)
7656
{
7657
    const char *opn = "extended float load/store";
7658
    int store = 0;
7659
    TCGv t0 = tcg_temp_new();
7660

    
7661
    if (base == 0) {
7662
        gen_load_gpr(t0, index);
7663
    } else if (index == 0) {
7664
        gen_load_gpr(t0, base);
7665
    } else {
7666
        gen_load_gpr(t0, index);
7667
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7668
    }
7669
    /* Don't do NOP if destination is zero: we must perform the actual
7670
       memory access. */
7671
    save_cpu_state(ctx, 0);
7672
    switch (opc) {
7673
    case OPC_LWXC1:
7674
        check_cop1x(ctx);
7675
        {
7676
            TCGv_i32 fp0 = tcg_temp_new_i32();
7677

    
7678
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7679
            tcg_gen_trunc_tl_i32(fp0, t0);
7680
            gen_store_fpr32(fp0, fd);
7681
            tcg_temp_free_i32(fp0);
7682
        }
7683
        opn = "lwxc1";
7684
        break;
7685
    case OPC_LDXC1:
7686
        check_cop1x(ctx);
7687
        check_cp1_registers(ctx, fd);
7688
        {
7689
            TCGv_i64 fp0 = tcg_temp_new_i64();
7690

    
7691
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7692
            gen_store_fpr64(ctx, fp0, fd);
7693
            tcg_temp_free_i64(fp0);
7694
        }
7695
        opn = "ldxc1";
7696
        break;
7697
    case OPC_LUXC1:
7698
        check_cp1_64bitmode(ctx);
7699
        tcg_gen_andi_tl(t0, t0, ~0x7);
7700
        {
7701
            TCGv_i64 fp0 = tcg_temp_new_i64();
7702

    
7703
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7704
            gen_store_fpr64(ctx, fp0, fd);
7705
            tcg_temp_free_i64(fp0);
7706
        }
7707
        opn = "luxc1";
7708
        break;
7709
    case OPC_SWXC1:
7710
        check_cop1x(ctx);
7711
        {
7712
            TCGv_i32 fp0 = tcg_temp_new_i32();
7713
            TCGv t1 = tcg_temp_new();
7714

    
7715
            gen_load_fpr32(fp0, fs);
7716
            tcg_gen_extu_i32_tl(t1, fp0);
7717
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7718
            tcg_temp_free_i32(fp0);
7719
            tcg_temp_free(t1);
7720
        }
7721
        opn = "swxc1";
7722
        store = 1;
7723
        break;
7724
    case OPC_SDXC1:
7725
        check_cop1x(ctx);
7726
        check_cp1_registers(ctx, fs);
7727
        {
7728
            TCGv_i64 fp0 = tcg_temp_new_i64();
7729

    
7730
            gen_load_fpr64(ctx, fp0, fs);
7731
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7732
            tcg_temp_free_i64(fp0);
7733
        }
7734
        opn = "sdxc1";
7735
        store = 1;
7736
        break;
7737
    case OPC_SUXC1:
7738
        check_cp1_64bitmode(ctx);
7739
        tcg_gen_andi_tl(t0, t0, ~0x7);
7740
        {
7741
            TCGv_i64 fp0 = tcg_temp_new_i64();
7742

    
7743
            gen_load_fpr64(ctx, fp0, fs);
7744
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7745
            tcg_temp_free_i64(fp0);
7746
        }
7747
        opn = "suxc1";
7748
        store = 1;
7749
        break;
7750
    }
7751
    tcg_temp_free(t0);
7752
    (void)opn; (void)store; /* avoid compiler warnings */
7753
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7754
               regnames[index], regnames[base]);
7755
}
7756

    
7757
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7758
                            int fd, int fr, int fs, int ft)
7759
{
7760
    const char *opn = "flt3_arith";
7761

    
7762
    switch (opc) {
7763
    case OPC_ALNV_PS:
7764
        check_cp1_64bitmode(ctx);
7765
        {
7766
            TCGv t0 = tcg_temp_local_new();
7767
            TCGv_i32 fp = tcg_temp_new_i32();
7768
            TCGv_i32 fph = tcg_temp_new_i32();
7769
            int l1 = gen_new_label();
7770
            int l2 = gen_new_label();
7771

    
7772
            gen_load_gpr(t0, fr);
7773
            tcg_gen_andi_tl(t0, t0, 0x7);
7774

    
7775
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7776
            gen_load_fpr32(fp, fs);
7777
            gen_load_fpr32h(fph, fs);
7778
            gen_store_fpr32(fp, fd);
7779
            gen_store_fpr32h(fph, fd);
7780
            tcg_gen_br(l2);
7781
            gen_set_label(l1);
7782
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7783
            tcg_temp_free(t0);
7784
#ifdef TARGET_WORDS_BIGENDIAN
7785
            gen_load_fpr32(fp, fs);
7786
            gen_load_fpr32h(fph, ft);
7787
            gen_store_fpr32h(fp, fd);
7788
            gen_store_fpr32(fph, fd);
7789
#else
7790
            gen_load_fpr32h(fph, fs);
7791
            gen_load_fpr32(fp, ft);
7792
            gen_store_fpr32(fph, fd);
7793
            gen_store_fpr32h(fp, fd);
7794
#endif
7795
            gen_set_label(l2);
7796
            tcg_temp_free_i32(fp);
7797
            tcg_temp_free_i32(fph);
7798
        }
7799
        opn = "alnv.ps";
7800
        break;
7801
    case OPC_MADD_S:
7802
        check_cop1x(ctx);
7803
        {
7804
            TCGv_i32 fp0 = tcg_temp_new_i32();
7805
            TCGv_i32 fp1 = tcg_temp_new_i32();
7806
            TCGv_i32 fp2 = tcg_temp_new_i32();
7807

    
7808
            gen_load_fpr32(fp0, fs);
7809
            gen_load_fpr32(fp1, ft);
7810
            gen_load_fpr32(fp2, fr);
7811
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7812
            tcg_temp_free_i32(fp0);
7813
            tcg_temp_free_i32(fp1);
7814
            gen_store_fpr32(fp2, fd);
7815
            tcg_temp_free_i32(fp2);
7816
        }
7817
        opn = "madd.s";
7818
        break;
7819
    case OPC_MADD_D:
7820
        check_cop1x(ctx);
7821
        check_cp1_registers(ctx, fd | fs | ft | fr);
7822
        {
7823
            TCGv_i64 fp0 = tcg_temp_new_i64();
7824
            TCGv_i64 fp1 = tcg_temp_new_i64();
7825
            TCGv_i64 fp2 = tcg_temp_new_i64();
7826

    
7827
            gen_load_fpr64(ctx, fp0, fs);
7828
            gen_load_fpr64(ctx, fp1, ft);
7829
            gen_load_fpr64(ctx, fp2, fr);
7830
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7831
            tcg_temp_free_i64(fp0);
7832
            tcg_temp_free_i64(fp1);
7833
            gen_store_fpr64(ctx, fp2, fd);
7834
            tcg_temp_free_i64(fp2);
7835
        }
7836
        opn = "madd.d";
7837
        break;
7838
    case OPC_MADD_PS:
7839
        check_cp1_64bitmode(ctx);
7840
        {
7841
            TCGv_i64 fp0 = tcg_temp_new_i64();
7842
            TCGv_i64 fp1 = tcg_temp_new_i64();
7843
            TCGv_i64 fp2 = tcg_temp_new_i64();
7844

    
7845
            gen_load_fpr64(ctx, fp0, fs);
7846
            gen_load_fpr64(ctx, fp1, ft);
7847
            gen_load_fpr64(ctx, fp2, fr);
7848
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7849
            tcg_temp_free_i64(fp0);
7850
            tcg_temp_free_i64(fp1);
7851
            gen_store_fpr64(ctx, fp2, fd);
7852
            tcg_temp_free_i64(fp2);
7853
        }
7854
        opn = "madd.ps";
7855
        break;
7856
    case OPC_MSUB_S:
7857
        check_cop1x(ctx);
7858
        {
7859
            TCGv_i32 fp0 = tcg_temp_new_i32();
7860
            TCGv_i32 fp1 = tcg_temp_new_i32();
7861
            TCGv_i32 fp2 = tcg_temp_new_i32();
7862

    
7863
            gen_load_fpr32(fp0, fs);
7864
            gen_load_fpr32(fp1, ft);
7865
            gen_load_fpr32(fp2, fr);
7866
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7867
            tcg_temp_free_i32(fp0);
7868
            tcg_temp_free_i32(fp1);
7869
            gen_store_fpr32(fp2, fd);
7870
            tcg_temp_free_i32(fp2);
7871
        }
7872
        opn = "msub.s";
7873
        break;
7874
    case OPC_MSUB_D:
7875
        check_cop1x(ctx);
7876
        check_cp1_registers(ctx, fd | fs | ft | fr);
7877
        {
7878
            TCGv_i64 fp0 = tcg_temp_new_i64();
7879
            TCGv_i64 fp1 = tcg_temp_new_i64();
7880
            TCGv_i64 fp2 = tcg_temp_new_i64();
7881

    
7882
            gen_load_fpr64(ctx, fp0, fs);
7883
            gen_load_fpr64(ctx, fp1, ft);
7884
            gen_load_fpr64(ctx, fp2, fr);
7885
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7886
            tcg_temp_free_i64(fp0);
7887
            tcg_temp_free_i64(fp1);
7888
            gen_store_fpr64(ctx, fp2, fd);
7889
            tcg_temp_free_i64(fp2);
7890
        }
7891
        opn = "msub.d";
7892
        break;
7893
    case OPC_MSUB_PS:
7894
        check_cp1_64bitmode(ctx);
7895
        {
7896
            TCGv_i64 fp0 = tcg_temp_new_i64();
7897
            TCGv_i64 fp1 = tcg_temp_new_i64();
7898
            TCGv_i64 fp2 = tcg_temp_new_i64();
7899

    
7900
            gen_load_fpr64(ctx, fp0, fs);
7901
            gen_load_fpr64(ctx, fp1, ft);
7902
            gen_load_fpr64(ctx, fp2, fr);
7903
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7904
            tcg_temp_free_i64(fp0);
7905
            tcg_temp_free_i64(fp1);
7906
            gen_store_fpr64(ctx, fp2, fd);
7907
            tcg_temp_free_i64(fp2);
7908
        }
7909
        opn = "msub.ps";
7910
        break;
7911
    case OPC_NMADD_S:
7912
        check_cop1x(ctx);
7913
        {
7914
            TCGv_i32 fp0 = tcg_temp_new_i32();
7915
            TCGv_i32 fp1 = tcg_temp_new_i32();
7916
            TCGv_i32 fp2 = tcg_temp_new_i32();
7917

    
7918
            gen_load_fpr32(fp0, fs);
7919
            gen_load_fpr32(fp1, ft);
7920
            gen_load_fpr32(fp2, fr);
7921
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7922
            tcg_temp_free_i32(fp0);
7923
            tcg_temp_free_i32(fp1);
7924
            gen_store_fpr32(fp2, fd);
7925
            tcg_temp_free_i32(fp2);
7926
        }
7927
        opn = "nmadd.s";
7928
        break;
7929
    case OPC_NMADD_D:
7930
        check_cop1x(ctx);
7931
        check_cp1_registers(ctx, fd | fs | ft | fr);
7932
        {
7933
            TCGv_i64 fp0 = tcg_temp_new_i64();
7934
            TCGv_i64 fp1 = tcg_temp_new_i64();
7935
            TCGv_i64 fp2 = tcg_temp_new_i64();
7936

    
7937
            gen_load_fpr64(ctx, fp0, fs);
7938
            gen_load_fpr64(ctx, fp1, ft);
7939
            gen_load_fpr64(ctx, fp2, fr);
7940
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7941
            tcg_temp_free_i64(fp0);
7942
            tcg_temp_free_i64(fp1);
7943
            gen_store_fpr64(ctx, fp2, fd);
7944
            tcg_temp_free_i64(fp2);
7945
        }
7946
        opn = "nmadd.d";
7947
        break;
7948
    case OPC_NMADD_PS:
7949
        check_cp1_64bitmode(ctx);
7950
        {
7951
            TCGv_i64 fp0 = tcg_temp_new_i64();
7952
            TCGv_i64 fp1 = tcg_temp_new_i64();
7953
            TCGv_i64 fp2 = tcg_temp_new_i64();
7954

    
7955
            gen_load_fpr64(ctx, fp0, fs);
7956
            gen_load_fpr64(ctx, fp1, ft);
7957
            gen_load_fpr64(ctx, fp2, fr);
7958
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7959
            tcg_temp_free_i64(fp0);
7960
            tcg_temp_free_i64(fp1);
7961
            gen_store_fpr64(ctx, fp2, fd);
7962
            tcg_temp_free_i64(fp2);
7963
        }
7964
        opn = "nmadd.ps";
7965
        break;
7966
    case OPC_NMSUB_S:
7967
        check_cop1x(ctx);
7968
        {
7969
            TCGv_i32 fp0 = tcg_temp_new_i32();
7970
            TCGv_i32 fp1 = tcg_temp_new_i32();
7971
            TCGv_i32 fp2 = tcg_temp_new_i32();
7972

    
7973
            gen_load_fpr32(fp0, fs);
7974
            gen_load_fpr32(fp1, ft);
7975
            gen_load_fpr32(fp2, fr);
7976
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7977
            tcg_temp_free_i32(fp0);
7978
            tcg_temp_free_i32(fp1);
7979
            gen_store_fpr32(fp2, fd);
7980
            tcg_temp_free_i32(fp2);
7981
        }
7982
        opn = "nmsub.s";
7983
        break;
7984
    case OPC_NMSUB_D:
7985
        check_cop1x(ctx);
7986
        check_cp1_registers(ctx, fd | fs | ft | fr);
7987
        {
7988
            TCGv_i64 fp0 = tcg_temp_new_i64();
7989
            TCGv_i64 fp1 = tcg_temp_new_i64();
7990
            TCGv_i64 fp2 = tcg_temp_new_i64();
7991

    
7992
            gen_load_fpr64(ctx, fp0, fs);
7993
            gen_load_fpr64(ctx, fp1, ft);
7994
            gen_load_fpr64(ctx, fp2, fr);
7995
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7996
            tcg_temp_free_i64(fp0);
7997
            tcg_temp_free_i64(fp1);
7998
            gen_store_fpr64(ctx, fp2, fd);
7999
            tcg_temp_free_i64(fp2);
8000
        }
8001
        opn = "nmsub.d";
8002
        break;
8003
    case OPC_NMSUB_PS:
8004
        check_cp1_64bitmode(ctx);
8005
        {
8006
            TCGv_i64 fp0 = tcg_temp_new_i64();
8007
            TCGv_i64 fp1 = tcg_temp_new_i64();
8008
            TCGv_i64 fp2 = tcg_temp_new_i64();
8009

    
8010
            gen_load_fpr64(ctx, fp0, fs);
8011
            gen_load_fpr64(ctx, fp1, ft);
8012
            gen_load_fpr64(ctx, fp2, fr);
8013
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8014
            tcg_temp_free_i64(fp0);
8015
            tcg_temp_free_i64(fp1);
8016
            gen_store_fpr64(ctx, fp2, fd);
8017
            tcg_temp_free_i64(fp2);
8018
        }
8019
        opn = "nmsub.ps";
8020
        break;
8021
    default:
8022
        MIPS_INVAL(opn);
8023
        generate_exception (ctx, EXCP_RI);
8024
        return;
8025
    }
8026
    (void)opn; /* avoid a compiler warning */
8027
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8028
               fregnames[fs], fregnames[ft]);
8029
}
8030

    
8031
static void
8032
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8033
{
8034
    TCGv t0;
8035

    
8036
    check_insn(env, ctx, ISA_MIPS32R2);
8037
    t0 = tcg_temp_new();
8038

    
8039
    switch (rd) {
8040
    case 0:
8041
        save_cpu_state(ctx, 1);
8042
        gen_helper_rdhwr_cpunum(t0);
8043
        gen_store_gpr(t0, rt);
8044
        break;
8045
    case 1:
8046
        save_cpu_state(ctx, 1);
8047
        gen_helper_rdhwr_synci_step(t0);
8048
        gen_store_gpr(t0, rt);
8049
        break;
8050
    case 2:
8051
        save_cpu_state(ctx, 1);
8052
        gen_helper_rdhwr_cc(t0);
8053
        gen_store_gpr(t0, rt);
8054
        break;
8055
    case 3:
8056
        save_cpu_state(ctx, 1);
8057
        gen_helper_rdhwr_ccres(t0);
8058
        gen_store_gpr(t0, rt);
8059
        break;
8060
    case 29:
8061
#if defined(CONFIG_USER_ONLY)
8062
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8063
        gen_store_gpr(t0, rt);
8064
        break;
8065
#else
8066
        /* XXX: Some CPUs implement this in hardware.
8067
           Not supported yet. */
8068
#endif
8069
    default:            /* Invalid */
8070
        MIPS_INVAL("rdhwr");
8071
        generate_exception(ctx, EXCP_RI);
8072
        break;
8073
    }
8074
    tcg_temp_free(t0);
8075
}
8076

    
8077
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
8078
                               int insn_bytes)
8079
{
8080
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8081
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8082
        /* Branches completion */
8083
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8084
        ctx->bstate = BS_BRANCH;
8085
        save_cpu_state(ctx, 0);
8086
        /* FIXME: Need to clear can_do_io.  */
8087
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8088
        case MIPS_HFLAG_B:
8089
            /* unconditional branch */
8090
            MIPS_DEBUG("unconditional branch");
8091
            if (proc_hflags & MIPS_HFLAG_BX) {
8092
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8093
            }
8094
            gen_goto_tb(ctx, 0, ctx->btarget);
8095
            break;
8096
        case MIPS_HFLAG_BL:
8097
            /* blikely taken case */
8098
            MIPS_DEBUG("blikely branch taken");
8099
            gen_goto_tb(ctx, 0, ctx->btarget);
8100
            break;
8101
        case MIPS_HFLAG_BC:
8102
            /* Conditional branch */
8103
            MIPS_DEBUG("conditional branch");
8104
            {
8105
                int l1 = gen_new_label();
8106

    
8107
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8108
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8109
                gen_set_label(l1);
8110
                gen_goto_tb(ctx, 0, ctx->btarget);
8111
            }
8112
            break;
8113
        case MIPS_HFLAG_BR:
8114
            /* unconditional branch to register */
8115
            MIPS_DEBUG("branch to register");
8116
            if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8117
                TCGv t0 = tcg_temp_new();
8118
                TCGv_i32 t1 = tcg_temp_new_i32();
8119

    
8120
                tcg_gen_andi_tl(t0, btarget, 0x1);
8121
                tcg_gen_trunc_tl_i32(t1, t0);
8122
                tcg_temp_free(t0);
8123
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8124
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8125
                tcg_gen_or_i32(hflags, hflags, t1);
8126
                tcg_temp_free_i32(t1);
8127

    
8128
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8129
            } else {
8130
                tcg_gen_mov_tl(cpu_PC, btarget);
8131
            }
8132
            if (ctx->singlestep_enabled) {
8133
                save_cpu_state(ctx, 0);
8134
                gen_helper_0i(raise_exception, EXCP_DEBUG);
8135
            }
8136
            tcg_gen_exit_tb(0);
8137
            break;
8138
        default:
8139
            MIPS_DEBUG("unknown branch");
8140
            break;
8141
        }
8142
    }
8143
}
8144

    
8145
/* ISA extensions (ASEs) */
8146
/* MIPS16 extension to MIPS32 */
8147

    
8148
/* MIPS16 major opcodes */
8149
enum {
8150
  M16_OPC_ADDIUSP = 0x00,
8151
  M16_OPC_ADDIUPC = 0x01,
8152
  M16_OPC_B = 0x02,
8153
  M16_OPC_JAL = 0x03,
8154
  M16_OPC_BEQZ = 0x04,
8155
  M16_OPC_BNEQZ = 0x05,
8156
  M16_OPC_SHIFT = 0x06,
8157
  M16_OPC_LD = 0x07,
8158
  M16_OPC_RRIA = 0x08,
8159
  M16_OPC_ADDIU8 = 0x09,
8160
  M16_OPC_SLTI = 0x0a,
8161
  M16_OPC_SLTIU = 0x0b,
8162
  M16_OPC_I8 = 0x0c,
8163
  M16_OPC_LI = 0x0d,
8164
  M16_OPC_CMPI = 0x0e,
8165
  M16_OPC_SD = 0x0f,
8166
  M16_OPC_LB = 0x10,
8167
  M16_OPC_LH = 0x11,
8168
  M16_OPC_LWSP = 0x12,
8169
  M16_OPC_LW = 0x13,
8170
  M16_OPC_LBU = 0x14,
8171
  M16_OPC_LHU = 0x15,
8172
  M16_OPC_LWPC = 0x16,
8173
  M16_OPC_LWU = 0x17,
8174
  M16_OPC_SB = 0x18,
8175
  M16_OPC_SH = 0x19,
8176
  M16_OPC_SWSP = 0x1a,
8177
  M16_OPC_SW = 0x1b,
8178
  M16_OPC_RRR = 0x1c,
8179
  M16_OPC_RR = 0x1d,
8180
  M16_OPC_EXTEND = 0x1e,
8181
  M16_OPC_I64 = 0x1f
8182
};
8183

    
8184
/* I8 funct field */
8185
enum {
8186
  I8_BTEQZ = 0x0,
8187
  I8_BTNEZ = 0x1,
8188
  I8_SWRASP = 0x2,
8189
  I8_ADJSP = 0x3,
8190
  I8_SVRS = 0x4,
8191
  I8_MOV32R = 0x5,
8192
  I8_MOVR32 = 0x7
8193
};
8194

    
8195
/* RRR f field */
8196
enum {
8197
  RRR_DADDU = 0x0,
8198
  RRR_ADDU = 0x1,
8199
  RRR_DSUBU = 0x2,
8200
  RRR_SUBU = 0x3
8201
};
8202

    
8203
/* RR funct field */
8204
enum {
8205
  RR_JR = 0x00,
8206
  RR_SDBBP = 0x01,
8207
  RR_SLT = 0x02,
8208
  RR_SLTU = 0x03,
8209
  RR_SLLV = 0x04,
8210
  RR_BREAK = 0x05,
8211
  RR_SRLV = 0x06,
8212
  RR_SRAV = 0x07,
8213
  RR_DSRL = 0x08,
8214
  RR_CMP = 0x0a,
8215
  RR_NEG = 0x0b,
8216
  RR_AND = 0x0c,
8217
  RR_OR = 0x0d,
8218
  RR_XOR = 0x0e,
8219
  RR_NOT = 0x0f,
8220
  RR_MFHI = 0x10,
8221
  RR_CNVT = 0x11,
8222
  RR_MFLO = 0x12,
8223
  RR_DSRA = 0x13,
8224
  RR_DSLLV = 0x14,
8225
  RR_DSRLV = 0x16,
8226
  RR_DSRAV = 0x17,
8227
  RR_MULT = 0x18,
8228
  RR_MULTU = 0x19,
8229
  RR_DIV = 0x1a,
8230
  RR_DIVU = 0x1b,
8231
  RR_DMULT = 0x1c,
8232
  RR_DMULTU = 0x1d,
8233
  RR_DDIV = 0x1e,
8234
  RR_DDIVU = 0x1f
8235
};
8236

    
8237
/* I64 funct field */
8238
enum {
8239
  I64_LDSP = 0x0,
8240
  I64_SDSP = 0x1,
8241
  I64_SDRASP = 0x2,
8242
  I64_DADJSP = 0x3,
8243
  I64_LDPC = 0x4,
8244
  I64_DADDIU5 = 0x5,
8245
  I64_DADDIUPC = 0x6,
8246
  I64_DADDIUSP = 0x7
8247
};
8248

    
8249
/* RR ry field for CNVT */
8250
enum {
8251
  RR_RY_CNVT_ZEB = 0x0,
8252
  RR_RY_CNVT_ZEH = 0x1,
8253
  RR_RY_CNVT_ZEW = 0x2,
8254
  RR_RY_CNVT_SEB = 0x4,
8255
  RR_RY_CNVT_SEH = 0x5,
8256
  RR_RY_CNVT_SEW = 0x6,
8257
};
8258

    
8259
static int xlat (int r)
8260
{
8261
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8262

    
8263
  return map[r];
8264
}
8265

    
8266
static void gen_mips16_save (DisasContext *ctx,
8267
                             int xsregs, int aregs,
8268
                             int do_ra, int do_s0, int do_s1,
8269
                             int framesize)
8270
{
8271
    TCGv t0 = tcg_temp_new();
8272
    TCGv t1 = tcg_temp_new();
8273
    int args, astatic;
8274

    
8275
    switch (aregs) {
8276
    case 0:
8277
    case 1:
8278
    case 2:
8279
    case 3:
8280
    case 11:
8281
        args = 0;
8282
        break;
8283
    case 4:
8284
    case 5:
8285
    case 6:
8286
    case 7:
8287
        args = 1;
8288
        break;
8289
    case 8:
8290
    case 9:
8291
    case 10:
8292
        args = 2;
8293
        break;
8294
    case 12:
8295
    case 13:
8296
        args = 3;
8297
        break;
8298
    case 14:
8299
        args = 4;
8300
        break;
8301
    default:
8302
        generate_exception(ctx, EXCP_RI);
8303
        return;
8304
    }
8305

    
8306
    switch (args) {
8307
    case 4:
8308
        gen_base_offset_addr(ctx, t0, 29, 12);
8309
        gen_load_gpr(t1, 7);
8310
        op_st_sw(t1, t0, ctx);
8311
        /* Fall through */
8312
    case 3:
8313
        gen_base_offset_addr(ctx, t0, 29, 8);
8314
        gen_load_gpr(t1, 6);
8315
        op_st_sw(t1, t0, ctx);
8316
        /* Fall through */
8317
    case 2:
8318
        gen_base_offset_addr(ctx, t0, 29, 4);
8319
        gen_load_gpr(t1, 5);
8320
        op_st_sw(t1, t0, ctx);
8321
        /* Fall through */
8322
    case 1:
8323
        gen_base_offset_addr(ctx, t0, 29, 0);
8324
        gen_load_gpr(t1, 4);
8325
        op_st_sw(t1, t0, ctx);
8326
    }
8327

    
8328
    gen_load_gpr(t0, 29);
8329

    
8330
#define DECR_AND_STORE(reg) do {                \
8331
        tcg_gen_subi_tl(t0, t0, 4);             \
8332
        gen_load_gpr(t1, reg);                  \
8333
        op_st_sw(t1, t0, ctx);                  \
8334
    } while (0)
8335

    
8336
    if (do_ra) {
8337
        DECR_AND_STORE(31);
8338
    }
8339

    
8340
    switch (xsregs) {
8341
    case 7:
8342
        DECR_AND_STORE(30);
8343
        /* Fall through */
8344
    case 6:
8345
        DECR_AND_STORE(23);
8346
        /* Fall through */
8347
    case 5:
8348
        DECR_AND_STORE(22);
8349
        /* Fall through */
8350
    case 4:
8351
        DECR_AND_STORE(21);
8352
        /* Fall through */
8353
    case 3:
8354
        DECR_AND_STORE(20);
8355
        /* Fall through */
8356
    case 2:
8357
        DECR_AND_STORE(19);
8358
        /* Fall through */
8359
    case 1:
8360
        DECR_AND_STORE(18);
8361
    }
8362

    
8363
    if (do_s1) {
8364
        DECR_AND_STORE(17);
8365
    }
8366
    if (do_s0) {
8367
        DECR_AND_STORE(16);
8368
    }
8369

    
8370
    switch (aregs) {
8371
    case 0:
8372
    case 4:
8373
    case 8:
8374
    case 12:
8375
    case 14:
8376
        astatic = 0;
8377
        break;
8378
    case 1:
8379
    case 5:
8380
    case 9:
8381
    case 13:
8382
        astatic = 1;
8383
        break;
8384
    case 2:
8385
    case 6:
8386
    case 10:
8387
        astatic = 2;
8388
        break;
8389
    case 3:
8390
    case 7:
8391
        astatic = 3;
8392
        break;
8393
    case 11:
8394
        astatic = 4;
8395
        break;
8396
    default:
8397
        generate_exception(ctx, EXCP_RI);
8398
        return;
8399
    }
8400

    
8401
    if (astatic > 0) {
8402
        DECR_AND_STORE(7);
8403
        if (astatic > 1) {
8404
            DECR_AND_STORE(6);
8405
            if (astatic > 2) {
8406
                DECR_AND_STORE(5);
8407
                if (astatic > 3) {
8408
                    DECR_AND_STORE(4);
8409
                }
8410
            }
8411
        }
8412
    }
8413
#undef DECR_AND_STORE
8414

    
8415
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8416
    tcg_temp_free(t0);
8417
    tcg_temp_free(t1);
8418
}
8419

    
8420
static void gen_mips16_restore (DisasContext *ctx,
8421
                                int xsregs, int aregs,
8422
                                int do_ra, int do_s0, int do_s1,
8423
                                int framesize)
8424
{
8425
    int astatic;
8426
    TCGv t0 = tcg_temp_new();
8427
    TCGv t1 = tcg_temp_new();
8428

    
8429
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8430

    
8431
#define DECR_AND_LOAD(reg) do {                 \
8432
        tcg_gen_subi_tl(t0, t0, 4);             \
8433
        op_ld_lw(t1, t0, ctx);                  \
8434
        gen_store_gpr(t1, reg);                 \
8435
    } while (0)
8436

    
8437
    if (do_ra) {
8438
        DECR_AND_LOAD(31);
8439
    }
8440

    
8441
    switch (xsregs) {
8442
    case 7:
8443
        DECR_AND_LOAD(30);
8444
        /* Fall through */
8445
    case 6:
8446
        DECR_AND_LOAD(23);
8447
        /* Fall through */
8448
    case 5:
8449
        DECR_AND_LOAD(22);
8450
        /* Fall through */
8451
    case 4:
8452
        DECR_AND_LOAD(21);
8453
        /* Fall through */
8454
    case 3:
8455
        DECR_AND_LOAD(20);
8456
        /* Fall through */
8457
    case 2:
8458
        DECR_AND_LOAD(19);
8459
        /* Fall through */
8460
    case 1:
8461
        DECR_AND_LOAD(18);
8462
    }
8463

    
8464
    if (do_s1) {
8465
        DECR_AND_LOAD(17);
8466
    }
8467
    if (do_s0) {
8468
        DECR_AND_LOAD(16);
8469
    }
8470

    
8471
    switch (aregs) {
8472
    case 0:
8473
    case 4:
8474
    case 8:
8475
    case 12:
8476
    case 14:
8477
        astatic = 0;
8478
        break;
8479
    case 1:
8480
    case 5:
8481
    case 9:
8482
    case 13:
8483
        astatic = 1;
8484
        break;
8485
    case 2:
8486
    case 6:
8487
    case 10:
8488
        astatic = 2;
8489
        break;
8490
    case 3:
8491
    case 7:
8492
        astatic = 3;
8493
        break;
8494
    case 11:
8495
        astatic = 4;
8496
        break;
8497
    default:
8498
        generate_exception(ctx, EXCP_RI);
8499
        return;
8500
    }
8501

    
8502
    if (astatic > 0) {
8503
        DECR_AND_LOAD(7);
8504
        if (astatic > 1) {
8505
            DECR_AND_LOAD(6);
8506
            if (astatic > 2) {
8507
                DECR_AND_LOAD(5);
8508
                if (astatic > 3) {
8509
                    DECR_AND_LOAD(4);
8510
                }
8511
            }
8512
        }
8513
    }
8514
#undef DECR_AND_LOAD
8515

    
8516
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8517
    tcg_temp_free(t0);
8518
    tcg_temp_free(t1);
8519
}
8520

    
8521
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8522
                         int is_64_bit, int extended)
8523
{
8524
    TCGv t0;
8525

    
8526
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8527
        generate_exception(ctx, EXCP_RI);
8528
        return;
8529
    }
8530

    
8531
    t0 = tcg_temp_new();
8532

    
8533
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8534
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8535
    if (!is_64_bit) {
8536
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8537
    }
8538

    
8539
    tcg_temp_free(t0);
8540
}
8541

    
8542
#if defined(TARGET_MIPS64)
8543
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8544
                               int ry, int funct, int16_t offset,
8545
                               int extended)
8546
{
8547
    switch (funct) {
8548
    case I64_LDSP:
8549
        check_mips_64(ctx);
8550
        offset = extended ? offset : offset << 3;
8551
        gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8552
        break;
8553
    case I64_SDSP:
8554
        check_mips_64(ctx);
8555
        offset = extended ? offset : offset << 3;
8556
        gen_st(ctx, OPC_SD, ry, 29, offset);
8557
        break;
8558
    case I64_SDRASP:
8559
        check_mips_64(ctx);
8560
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8561
        gen_st(ctx, OPC_SD, 31, 29, offset);
8562
        break;
8563
    case I64_DADJSP:
8564
        check_mips_64(ctx);
8565
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8566
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8567
        break;
8568
    case I64_LDPC:
8569
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8570
            generate_exception(ctx, EXCP_RI);
8571
        } else {
8572
            offset = extended ? offset : offset << 3;
8573
            gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8574
        }
8575
        break;
8576
    case I64_DADDIU5:
8577
        check_mips_64(ctx);
8578
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8579
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8580
        break;
8581
    case I64_DADDIUPC:
8582
        check_mips_64(ctx);
8583
        offset = extended ? offset : offset << 2;
8584
        gen_addiupc(ctx, ry, offset, 1, extended);
8585
        break;
8586
    case I64_DADDIUSP:
8587
        check_mips_64(ctx);
8588
        offset = extended ? offset : offset << 2;
8589
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8590
        break;
8591
    }
8592
}
8593
#endif
8594

    
8595
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8596
                                       int *is_branch)
8597
{
8598
    int extend = lduw_code(ctx->pc + 2);
8599
    int op, rx, ry, funct, sa;
8600
    int16_t imm, offset;
8601

    
8602
    ctx->opcode = (ctx->opcode << 16) | extend;
8603
    op = (ctx->opcode >> 11) & 0x1f;
8604
    sa = (ctx->opcode >> 22) & 0x1f;
8605
    funct = (ctx->opcode >> 8) & 0x7;
8606
    rx = xlat((ctx->opcode >> 8) & 0x7);
8607
    ry = xlat((ctx->opcode >> 5) & 0x7);
8608
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8609
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8610
                              | (ctx->opcode & 0x1f));
8611

    
8612
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8613
       counterparts.  */
8614
    switch (op) {
8615
    case M16_OPC_ADDIUSP:
8616
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8617
        break;
8618
    case M16_OPC_ADDIUPC:
8619
        gen_addiupc(ctx, rx, imm, 0, 1);
8620
        break;
8621
    case M16_OPC_B:
8622
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8623
        /* No delay slot, so just process as a normal instruction */
8624
        break;
8625
    case M16_OPC_BEQZ:
8626
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8627
        /* No delay slot, so just process as a normal instruction */
8628
        break;
8629
    case M16_OPC_BNEQZ:
8630
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8631
        /* No delay slot, so just process as a normal instruction */
8632
        break;
8633
    case M16_OPC_SHIFT:
8634
        switch (ctx->opcode & 0x3) {
8635
        case 0x0:
8636
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8637
            break;
8638
        case 0x1:
8639
#if defined(TARGET_MIPS64)
8640
            check_mips_64(ctx);
8641
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8642
#else
8643
            generate_exception(ctx, EXCP_RI);
8644
#endif
8645
            break;
8646
        case 0x2:
8647
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8648
            break;
8649
        case 0x3:
8650
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8651
            break;
8652
        }
8653
        break;
8654
#if defined(TARGET_MIPS64)
8655
    case M16_OPC_LD:
8656
            check_mips_64(ctx);
8657
        gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8658
        break;
8659
#endif
8660
    case M16_OPC_RRIA:
8661
        imm = ctx->opcode & 0xf;
8662
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8663
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8664
        imm = (int16_t) (imm << 1) >> 1;
8665
        if ((ctx->opcode >> 4) & 0x1) {
8666
#if defined(TARGET_MIPS64)
8667
            check_mips_64(ctx);
8668
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8669
#else
8670
            generate_exception(ctx, EXCP_RI);
8671
#endif
8672
        } else {
8673
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8674
        }
8675
        break;
8676
    case M16_OPC_ADDIU8:
8677
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8678
        break;
8679
    case M16_OPC_SLTI:
8680
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8681
        break;
8682
    case M16_OPC_SLTIU:
8683
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8684
        break;
8685
    case M16_OPC_I8:
8686
        switch (funct) {
8687
        case I8_BTEQZ:
8688
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8689
            break;
8690
        case I8_BTNEZ:
8691
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8692
            break;
8693
        case I8_SWRASP:
8694
            gen_st(ctx, OPC_SW, 31, 29, imm);
8695
            break;
8696
        case I8_ADJSP:
8697
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8698
            break;
8699
        case I8_SVRS:
8700
            {
8701
                int xsregs = (ctx->opcode >> 24) & 0x7;
8702
                int aregs = (ctx->opcode >> 16) & 0xf;
8703
                int do_ra = (ctx->opcode >> 6) & 0x1;
8704
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8705
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8706
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8707
                                 | (ctx->opcode & 0xf)) << 3;
8708

    
8709
                if (ctx->opcode & (1 << 7)) {
8710
                    gen_mips16_save(ctx, xsregs, aregs,
8711
                                    do_ra, do_s0, do_s1,
8712
                                    framesize);
8713
                } else {
8714
                    gen_mips16_restore(ctx, xsregs, aregs,
8715
                                       do_ra, do_s0, do_s1,
8716
                                       framesize);
8717
                }
8718
            }
8719
            break;
8720
        default:
8721
            generate_exception(ctx, EXCP_RI);
8722
            break;
8723
        }
8724
        break;
8725
    case M16_OPC_LI:
8726
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8727
        break;
8728
    case M16_OPC_CMPI:
8729
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8730
        break;
8731
#if defined(TARGET_MIPS64)
8732
    case M16_OPC_SD:
8733
        gen_st(ctx, OPC_SD, ry, rx, offset);
8734
        break;
8735
#endif
8736
    case M16_OPC_LB:
8737
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8738
        break;
8739
    case M16_OPC_LH:
8740
        gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8741
        break;
8742
    case M16_OPC_LWSP:
8743
        gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8744
        break;
8745
    case M16_OPC_LW:
8746
        gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8747
        break;
8748
    case M16_OPC_LBU:
8749
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8750
        break;
8751
    case M16_OPC_LHU:
8752
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8753
        break;
8754
    case M16_OPC_LWPC:
8755
        gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8756
        break;
8757
#if defined(TARGET_MIPS64)
8758
    case M16_OPC_LWU:
8759
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8760
        break;
8761
#endif
8762
    case M16_OPC_SB:
8763
        gen_st(ctx, OPC_SB, ry, rx, offset);
8764
        break;
8765
    case M16_OPC_SH:
8766
        gen_st(ctx, OPC_SH, ry, rx, offset);
8767
        break;
8768
    case M16_OPC_SWSP:
8769
        gen_st(ctx, OPC_SW, rx, 29, offset);
8770
        break;
8771
    case M16_OPC_SW:
8772
        gen_st(ctx, OPC_SW, ry, rx, offset);
8773
        break;
8774
#if defined(TARGET_MIPS64)
8775
    case M16_OPC_I64:
8776
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8777
        break;
8778
#endif
8779
    default:
8780
        generate_exception(ctx, EXCP_RI);
8781
        break;
8782
    }
8783

    
8784
    return 4;
8785
}
8786

    
8787
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8788
                              int *is_branch)
8789
{
8790
    int rx, ry;
8791
    int sa;
8792
    int op, cnvt_op, op1, offset;
8793
    int funct;
8794
    int n_bytes;
8795

    
8796
    op = (ctx->opcode >> 11) & 0x1f;
8797
    sa = (ctx->opcode >> 2) & 0x7;
8798
    sa = sa == 0 ? 8 : sa;
8799
    rx = xlat((ctx->opcode >> 8) & 0x7);
8800
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8801
    ry = xlat((ctx->opcode >> 5) & 0x7);
8802
    op1 = offset = ctx->opcode & 0x1f;
8803

    
8804
    n_bytes = 2;
8805

    
8806
    switch (op) {
8807
    case M16_OPC_ADDIUSP:
8808
        {
8809
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8810

    
8811
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8812
        }
8813
        break;
8814
    case M16_OPC_ADDIUPC:
8815
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8816
        break;
8817
    case M16_OPC_B:
8818
        offset = (ctx->opcode & 0x7ff) << 1;
8819
        offset = (int16_t)(offset << 4) >> 4;
8820
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8821
        /* No delay slot, so just process as a normal instruction */
8822
        break;
8823
    case M16_OPC_JAL:
8824
        offset = lduw_code(ctx->pc + 2);
8825
        offset = (((ctx->opcode & 0x1f) << 21)
8826
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8827
                  | offset) << 2;
8828
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8829
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8830
        n_bytes = 4;
8831
        *is_branch = 1;
8832
        break;
8833
    case M16_OPC_BEQZ:
8834
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8835
        /* No delay slot, so just process as a normal instruction */
8836
        break;
8837
    case M16_OPC_BNEQZ:
8838
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8839
        /* No delay slot, so just process as a normal instruction */
8840
        break;
8841
    case M16_OPC_SHIFT:
8842
        switch (ctx->opcode & 0x3) {
8843
        case 0x0:
8844
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8845
            break;
8846
        case 0x1:
8847
#if defined(TARGET_MIPS64)
8848
            check_mips_64(ctx);
8849
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8850
#else
8851
            generate_exception(ctx, EXCP_RI);
8852
#endif
8853
            break;
8854
        case 0x2:
8855
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8856
            break;
8857
        case 0x3:
8858
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8859
            break;
8860
        }
8861
        break;
8862
#if defined(TARGET_MIPS64)
8863
    case M16_OPC_LD:
8864
        check_mips_64(ctx);
8865
        gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8866
        break;
8867
#endif
8868
    case M16_OPC_RRIA:
8869
        {
8870
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8871

    
8872
            if ((ctx->opcode >> 4) & 1) {
8873
#if defined(TARGET_MIPS64)
8874
                check_mips_64(ctx);
8875
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8876
#else
8877
                generate_exception(ctx, EXCP_RI);
8878
#endif
8879
            } else {
8880
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8881
            }
8882
        }
8883
        break;
8884
    case M16_OPC_ADDIU8:
8885
        {
8886
            int16_t imm = (int8_t) ctx->opcode;
8887

    
8888
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8889
        }
8890
        break;
8891
    case M16_OPC_SLTI:
8892
        {
8893
            int16_t imm = (uint8_t) ctx->opcode;
8894

    
8895
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8896
        }
8897
        break;
8898
    case M16_OPC_SLTIU:
8899
        {
8900
            int16_t imm = (uint8_t) ctx->opcode;
8901

    
8902
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8903
        }
8904
        break;
8905
    case M16_OPC_I8:
8906
        {
8907
            int reg32;
8908

    
8909
            funct = (ctx->opcode >> 8) & 0x7;
8910
            switch (funct) {
8911
            case I8_BTEQZ:
8912
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8913
                                   ((int8_t)ctx->opcode) << 1);
8914
                break;
8915
            case I8_BTNEZ:
8916
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8917
                                   ((int8_t)ctx->opcode) << 1);
8918
                break;
8919
            case I8_SWRASP:
8920
                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8921
                break;
8922
            case I8_ADJSP:
8923
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8924
                              ((int8_t)ctx->opcode) << 3);
8925
                break;
8926
            case I8_SVRS:
8927
                {
8928
                    int do_ra = ctx->opcode & (1 << 6);
8929
                    int do_s0 = ctx->opcode & (1 << 5);
8930
                    int do_s1 = ctx->opcode & (1 << 4);
8931
                    int framesize = ctx->opcode & 0xf;
8932

    
8933
                    if (framesize == 0) {
8934
                        framesize = 128;
8935
                    } else {
8936
                        framesize = framesize << 3;
8937
                    }
8938

    
8939
                    if (ctx->opcode & (1 << 7)) {
8940
                        gen_mips16_save(ctx, 0, 0,
8941
                                        do_ra, do_s0, do_s1, framesize);
8942
                    } else {
8943
                        gen_mips16_restore(ctx, 0, 0,
8944
                                           do_ra, do_s0, do_s1, framesize);
8945
                    }
8946
                }
8947
                break;
8948
            case I8_MOV32R:
8949
                {
8950
                    int rz = xlat(ctx->opcode & 0x7);
8951

    
8952
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8953
                        ((ctx->opcode >> 5) & 0x7);
8954
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8955
                }
8956
                break;
8957
            case I8_MOVR32:
8958
                reg32 = ctx->opcode & 0x1f;
8959
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8960
                break;
8961
            default:
8962
                generate_exception(ctx, EXCP_RI);
8963
                break;
8964
            }
8965
        }
8966
        break;
8967
    case M16_OPC_LI:
8968
        {
8969
            int16_t imm = (uint8_t) ctx->opcode;
8970

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

    
8978
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8979
        }
8980
        break;
8981
#if defined(TARGET_MIPS64)
8982
    case M16_OPC_SD:
8983
        check_mips_64(ctx);
8984
        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
8985
        break;
8986
#endif
8987
    case M16_OPC_LB:
8988
        gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8989
        break;
8990
    case M16_OPC_LH:
8991
        gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
8992
        break;
8993
    case M16_OPC_LWSP:
8994
        gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8995
        break;
8996
    case M16_OPC_LW:
8997
        gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
8998
        break;
8999
    case M16_OPC_LBU:
9000
        gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9001
        break;
9002
    case M16_OPC_LHU:
9003
        gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9004
        break;
9005
    case M16_OPC_LWPC:
9006
        gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9007
        break;
9008
#if defined (TARGET_MIPS64)
9009
    case M16_OPC_LWU:
9010
        check_mips_64(ctx);
9011
        gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9012
        break;
9013
#endif
9014
    case M16_OPC_SB:
9015
        gen_st(ctx, OPC_SB, ry, rx, offset);
9016
        break;
9017
    case M16_OPC_SH:
9018
        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9019
        break;
9020
    case M16_OPC_SWSP:
9021
        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9022
        break;
9023
    case M16_OPC_SW:
9024
        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9025
        break;
9026
    case M16_OPC_RRR:
9027
        {
9028
            int rz = xlat((ctx->opcode >> 2) & 0x7);
9029
            int mips32_op;
9030

    
9031
            switch (ctx->opcode & 0x3) {
9032
            case RRR_ADDU:
9033
                mips32_op = OPC_ADDU;
9034
                break;
9035
            case RRR_SUBU:
9036
                mips32_op = OPC_SUBU;
9037
                break;
9038
#if defined(TARGET_MIPS64)
9039
            case RRR_DADDU:
9040
                mips32_op = OPC_DADDU;
9041
                check_mips_64(ctx);
9042
                break;
9043
            case RRR_DSUBU:
9044
                mips32_op = OPC_DSUBU;
9045
                check_mips_64(ctx);
9046
                break;
9047
#endif
9048
            default:
9049
                generate_exception(ctx, EXCP_RI);
9050
                goto done;
9051
            }
9052

    
9053
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
9054
        done:
9055
            ;
9056
        }
9057
        break;
9058
    case M16_OPC_RR:
9059
        switch (op1) {
9060
        case RR_JR:
9061
            {
9062
                int nd = (ctx->opcode >> 7) & 0x1;
9063
                int link = (ctx->opcode >> 6) & 0x1;
9064
                int ra = (ctx->opcode >> 5) & 0x1;
9065

    
9066
                if (link) {
9067
                    op = nd ? OPC_JALRC : OPC_JALRS;
9068
                } else {
9069
                    op = OPC_JR;
9070
                }
9071

    
9072
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9073
                if (!nd) {
9074
                    *is_branch = 1;
9075
                }
9076
            }
9077
            break;
9078
        case RR_SDBBP:
9079
            /* XXX: not clear which exception should be raised
9080
             *      when in debug mode...
9081
             */
9082
            check_insn(env, ctx, ISA_MIPS32);
9083
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9084
                generate_exception(ctx, EXCP_DBp);
9085
            } else {
9086
                generate_exception(ctx, EXCP_DBp);
9087
            }
9088
            break;
9089
        case RR_SLT:
9090
            gen_slt(env, OPC_SLT, 24, rx, ry);
9091
            break;
9092
        case RR_SLTU:
9093
            gen_slt(env, OPC_SLTU, 24, rx, ry);
9094
            break;
9095
        case RR_BREAK:
9096
            generate_exception(ctx, EXCP_BREAK);
9097
            break;
9098
        case RR_SLLV:
9099
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9100
            break;
9101
        case RR_SRLV:
9102
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9103
            break;
9104
        case RR_SRAV:
9105
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9106
            break;
9107
#if defined (TARGET_MIPS64)
9108
        case RR_DSRL:
9109
            check_mips_64(ctx);
9110
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9111
            break;
9112
#endif
9113
        case RR_CMP:
9114
            gen_logic(env, OPC_XOR, 24, rx, ry);
9115
            break;
9116
        case RR_NEG:
9117
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9118
            break;
9119
        case RR_AND:
9120
            gen_logic(env, OPC_AND, rx, rx, ry);
9121
            break;
9122
        case RR_OR:
9123
            gen_logic(env, OPC_OR, rx, rx, ry);
9124
            break;
9125
        case RR_XOR:
9126
            gen_logic(env, OPC_XOR, rx, rx, ry);
9127
            break;
9128
        case RR_NOT:
9129
            gen_logic(env, OPC_NOR, rx, ry, 0);
9130
            break;
9131
        case RR_MFHI:
9132
            gen_HILO(ctx, OPC_MFHI, rx);
9133
            break;
9134
        case RR_CNVT:
9135
            switch (cnvt_op) {
9136
            case RR_RY_CNVT_ZEB:
9137
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9138
                break;
9139
            case RR_RY_CNVT_ZEH:
9140
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9141
                break;
9142
            case RR_RY_CNVT_SEB:
9143
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9144
                break;
9145
            case RR_RY_CNVT_SEH:
9146
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9147
                break;
9148
#if defined (TARGET_MIPS64)
9149
            case RR_RY_CNVT_ZEW:
9150
                check_mips_64(ctx);
9151
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9152
                break;
9153
            case RR_RY_CNVT_SEW:
9154
                check_mips_64(ctx);
9155
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9156
                break;
9157
#endif
9158
            default:
9159
                generate_exception(ctx, EXCP_RI);
9160
                break;
9161
            }
9162
            break;
9163
        case RR_MFLO:
9164
            gen_HILO(ctx, OPC_MFLO, rx);
9165
            break;
9166
#if defined (TARGET_MIPS64)
9167
        case RR_DSRA:
9168
            check_mips_64(ctx);
9169
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9170
            break;
9171
        case RR_DSLLV:
9172
            check_mips_64(ctx);
9173
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9174
            break;
9175
        case RR_DSRLV:
9176
            check_mips_64(ctx);
9177
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9178
            break;
9179
        case RR_DSRAV:
9180
            check_mips_64(ctx);
9181
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9182
            break;
9183
#endif
9184
        case RR_MULT:
9185
            gen_muldiv(ctx, OPC_MULT, rx, ry);
9186
            break;
9187
        case RR_MULTU:
9188
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
9189
            break;
9190
        case RR_DIV:
9191
            gen_muldiv(ctx, OPC_DIV, rx, ry);
9192
            break;
9193
        case RR_DIVU:
9194
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
9195
            break;
9196
#if defined (TARGET_MIPS64)
9197
        case RR_DMULT:
9198
            check_mips_64(ctx);
9199
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
9200
            break;
9201
        case RR_DMULTU:
9202
            check_mips_64(ctx);
9203
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9204
            break;
9205
        case RR_DDIV:
9206
            check_mips_64(ctx);
9207
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
9208
            break;
9209
        case RR_DDIVU:
9210
            check_mips_64(ctx);
9211
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9212
            break;
9213
#endif
9214
        default:
9215
            generate_exception(ctx, EXCP_RI);
9216
            break;
9217
        }
9218
        break;
9219
    case M16_OPC_EXTEND:
9220
        decode_extended_mips16_opc(env, ctx, is_branch);
9221
        n_bytes = 4;
9222
        break;
9223
#if defined(TARGET_MIPS64)
9224
    case M16_OPC_I64:
9225
        funct = (ctx->opcode >> 8) & 0x7;
9226
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9227
        break;
9228
#endif
9229
    default:
9230
        generate_exception(ctx, EXCP_RI);
9231
        break;
9232
    }
9233

    
9234
    return n_bytes;
9235
}
9236

    
9237
/* microMIPS extension to MIPS32 */
9238

    
9239
/* microMIPS32 major opcodes */
9240

    
9241
enum {
9242
    POOL32A = 0x00,
9243
    POOL16A = 0x01,
9244
    LBU16 = 0x02,
9245
    MOVE16 = 0x03,
9246
    ADDI32 = 0x04,
9247
    LBU32 = 0x05,
9248
    SB32 = 0x06,
9249
    LB32 = 0x07,
9250

    
9251
    POOL32B = 0x08,
9252
    POOL16B = 0x09,
9253
    LHU16 = 0x0a,
9254
    ANDI16 = 0x0b,
9255
    ADDIU32 = 0x0c,
9256
    LHU32 = 0x0d,
9257
    SH32 = 0x0e,
9258
    LH32 = 0x0f,
9259

    
9260
    POOL32I = 0x10,
9261
    POOL16C = 0x11,
9262
    LWSP16 = 0x12,
9263
    POOL16D = 0x13,
9264
    ORI32 = 0x14,
9265
    POOL32F = 0x15,
9266
    POOL32S = 0x16,
9267
    DADDIU32 = 0x17,
9268

    
9269
    POOL32C = 0x18,
9270
    LWGP16 = 0x19,
9271
    LW16 = 0x1a,
9272
    POOL16E = 0x1b,
9273
    XORI32 = 0x1c,
9274
    JALS32 = 0x1d,
9275
    ADDIUPC = 0x1e,
9276
    POOL48A = 0x1f,
9277

    
9278
    /* 0x20 is reserved */
9279
    RES_20 = 0x20,
9280
    POOL16F = 0x21,
9281
    SB16 = 0x22,
9282
    BEQZ16 = 0x23,
9283
    SLTI32 = 0x24,
9284
    BEQ32 = 0x25,
9285
    SWC132 = 0x26,
9286
    LWC132 = 0x27,
9287

    
9288
    /* 0x28 and 0x29 are reserved */
9289
    RES_28 = 0x28,
9290
    RES_29 = 0x29,
9291
    SH16 = 0x2a,
9292
    BNEZ16 = 0x2b,
9293
    SLTIU32 = 0x2c,
9294
    BNE32 = 0x2d,
9295
    SDC132 = 0x2e,
9296
    LDC132 = 0x2f,
9297

    
9298
    /* 0x30 and 0x31 are reserved */
9299
    RES_30 = 0x30,
9300
    RES_31 = 0x31,
9301
    SWSP16 = 0x32,
9302
    B16 = 0x33,
9303
    ANDI32 = 0x34,
9304
    J32 = 0x35,
9305
    SD32 = 0x36,
9306
    LD32 = 0x37,
9307

    
9308
    /* 0x38 and 0x39 are reserved */
9309
    RES_38 = 0x38,
9310
    RES_39 = 0x39,
9311
    SW16 = 0x3a,
9312
    LI16 = 0x3b,
9313
    JALX32 = 0x3c,
9314
    JAL32 = 0x3d,
9315
    SW32 = 0x3e,
9316
    LW32 = 0x3f
9317
};
9318

    
9319
/* POOL32A encoding of minor opcode field */
9320

    
9321
enum {
9322
    /* These opcodes are distinguished only by bits 9..6; those bits are
9323
     * what are recorded below. */
9324
    SLL32 = 0x0,
9325
    SRL32 = 0x1,
9326
    SRA = 0x2,
9327
    ROTR = 0x3,
9328

    
9329
    SLLV = 0x0,
9330
    SRLV = 0x1,
9331
    SRAV = 0x2,
9332
    ROTRV = 0x3,
9333
    ADD = 0x4,
9334
    ADDU32 = 0x5,
9335
    SUB = 0x6,
9336
    SUBU32 = 0x7,
9337
    MUL = 0x8,
9338
    AND = 0x9,
9339
    OR32 = 0xa,
9340
    NOR = 0xb,
9341
    XOR32 = 0xc,
9342
    SLT = 0xd,
9343
    SLTU = 0xe,
9344

    
9345
    MOVN = 0x0,
9346
    MOVZ = 0x1,
9347
    LWXS = 0x4,
9348

    
9349
    /* The following can be distinguished by their lower 6 bits. */
9350
    INS = 0x0c,
9351
    EXT = 0x2c,
9352
    POOL32AXF = 0x3c
9353
};
9354

    
9355
/* POOL32AXF encoding of minor opcode field extension */
9356

    
9357
enum {
9358
    /* bits 11..6 */
9359
    TEQ = 0x00,
9360
    TGE = 0x08,
9361
    TGEU = 0x10,
9362
    TLT = 0x20,
9363
    TLTU = 0x28,
9364
    TNE = 0x30,
9365

    
9366
    MFC0 = 0x03,
9367
    MTC0 = 0x0b,
9368

    
9369
    /* bits 13..12 for 0x01 */
9370
    MFHI_ACC = 0x0,
9371
    MFLO_ACC = 0x1,
9372
    MTHI_ACC = 0x2,
9373
    MTLO_ACC = 0x3,
9374

    
9375
    /* bits 13..12 for 0x2a */
9376
    MADD_ACC = 0x0,
9377
    MADDU_ACC = 0x1,
9378
    MSUB_ACC = 0x2,
9379
    MSUBU_ACC = 0x3,
9380

    
9381
    /* bits 13..12 for 0x32 */
9382
    MULT_ACC = 0x0,
9383
    MULTU_ACC = 0x0,
9384

    
9385
    /* bits 15..12 for 0x2c */
9386
    SEB = 0x2,
9387
    SEH = 0x3,
9388
    CLO = 0x4,
9389
    CLZ = 0x5,
9390
    RDHWR = 0x6,
9391
    WSBH = 0x7,
9392
    MULT = 0x8,
9393
    MULTU = 0x9,
9394
    DIV = 0xa,
9395
    DIVU = 0xb,
9396
    MADD = 0xc,
9397
    MADDU = 0xd,
9398
    MSUB = 0xe,
9399
    MSUBU = 0xf,
9400

    
9401
    /* bits 15..12 for 0x34 */
9402
    MFC2 = 0x4,
9403
    MTC2 = 0x5,
9404
    MFHC2 = 0x8,
9405
    MTHC2 = 0x9,
9406
    CFC2 = 0xc,
9407
    CTC2 = 0xd,
9408

    
9409
    /* bits 15..12 for 0x3c */
9410
    JALR = 0x0,
9411
    JR = 0x0,                   /* alias */
9412
    JALR_HB = 0x1,
9413
    JALRS = 0x4,
9414
    JALRS_HB = 0x5,
9415

    
9416
    /* bits 15..12 for 0x05 */
9417
    RDPGPR = 0xe,
9418
    WRPGPR = 0xf,
9419

    
9420
    /* bits 15..12 for 0x0d */
9421
    TLBP = 0x0,
9422
    TLBR = 0x1,
9423
    TLBWI = 0x2,
9424
    TLBWR = 0x3,
9425
    WAIT = 0x9,
9426
    IRET = 0xd,
9427
    DERET = 0xe,
9428
    ERET = 0xf,
9429

    
9430
    /* bits 15..12 for 0x15 */
9431
    DMT = 0x0,
9432
    DVPE = 0x1,
9433
    EMT = 0x2,
9434
    EVPE = 0x3,
9435

    
9436
    /* bits 15..12 for 0x1d */
9437
    DI = 0x4,
9438
    EI = 0x5,
9439

    
9440
    /* bits 15..12 for 0x2d */
9441
    SYNC = 0x6,
9442
    SYSCALL = 0x8,
9443
    SDBBP = 0xd,
9444

    
9445
    /* bits 15..12 for 0x35 */
9446
    MFHI32 = 0x0,
9447
    MFLO32 = 0x1,
9448
    MTHI32 = 0x2,
9449
    MTLO32 = 0x3,
9450
};
9451

    
9452
/* POOL32B encoding of minor opcode field (bits 15..12) */
9453

    
9454
enum {
9455
    LWC2 = 0x0,
9456
    LWP = 0x1,
9457
    LDP = 0x4,
9458
    LWM32 = 0x5,
9459
    CACHE = 0x6,
9460
    LDM = 0x7,
9461
    SWC2 = 0x8,
9462
    SWP = 0x9,
9463
    SDP = 0xc,
9464
    SWM32 = 0xd,
9465
    SDM = 0xf
9466
};
9467

    
9468
/* POOL32C encoding of minor opcode field (bits 15..12) */
9469

    
9470
enum {
9471
    LWL = 0x0,
9472
    SWL = 0x8,
9473
    LWR = 0x1,
9474
    SWR = 0x9,
9475
    PREF = 0x2,
9476
    /* 0xa is reserved */
9477
    LL = 0x3,
9478
    SC = 0xb,
9479
    LDL = 0x4,
9480
    SDL = 0xc,
9481
    LDR = 0x5,
9482
    SDR = 0xd,
9483
    /* 0x6 is reserved */
9484
    LWU = 0xe,
9485
    LLD = 0x7,
9486
    SCD = 0xf
9487
};
9488

    
9489
/* POOL32F encoding of minor opcode field (bits 5..0) */
9490

    
9491
enum {
9492
    /* These are the bit 7..6 values */
9493
    ADD_FMT = 0x0,
9494
    MOVN_FMT = 0x0,
9495

    
9496
    SUB_FMT = 0x1,
9497
    MOVZ_FMT = 0x1,
9498

    
9499
    MUL_FMT = 0x2,
9500

    
9501
    DIV_FMT = 0x3,
9502

    
9503
    /* These are the bit 8..6 values */
9504
    RSQRT2_FMT = 0x0,
9505
    MOVF_FMT = 0x0,
9506

    
9507
    LWXC1 = 0x1,
9508
    MOVT_FMT = 0x1,
9509

    
9510
    PLL_PS = 0x2,
9511
    SWXC1 = 0x2,
9512

    
9513
    PLU_PS = 0x3,
9514
    LDXC1 = 0x3,
9515

    
9516
    PUL_PS = 0x4,
9517
    SDXC1 = 0x4,
9518
    RECIP2_FMT = 0x4,
9519

    
9520
    PUU_PS = 0x5,
9521
    LUXC1 = 0x5,
9522

    
9523
    CVT_PS_S = 0x6,
9524
    SUXC1 = 0x6,
9525
    ADDR_PS = 0x6,
9526
    PREFX = 0x6,
9527

    
9528
    MULR_PS = 0x7,
9529

    
9530
    MADD_S = 0x01,
9531
    MADD_D = 0x09,
9532
    MADD_PS = 0x11,
9533
    ALNV_PS = 0x19,
9534
    MSUB_S = 0x21,
9535
    MSUB_D = 0x29,
9536
    MSUB_PS = 0x31,
9537

    
9538
    NMADD_S = 0x02,
9539
    NMADD_D = 0x0a,
9540
    NMADD_PS = 0x12,
9541
    NMSUB_S = 0x22,
9542
    NMSUB_D = 0x2a,
9543
    NMSUB_PS = 0x32,
9544

    
9545
    POOL32FXF = 0x3b,
9546

    
9547
    CABS_COND_FMT = 0x1c,              /* MIPS3D */
9548
    C_COND_FMT = 0x3c
9549
};
9550

    
9551
/* POOL32Fxf encoding of minor opcode extension field */
9552

    
9553
enum {
9554
    CVT_L = 0x04,
9555
    RSQRT_FMT = 0x08,
9556
    FLOOR_L = 0x0c,
9557
    CVT_PW_PS = 0x1c,
9558
    CVT_W = 0x24,
9559
    SQRT_FMT = 0x28,
9560
    FLOOR_W = 0x2c,
9561
    CVT_PS_PW = 0x3c,
9562
    CFC1 = 0x40,
9563
    RECIP_FMT = 0x48,
9564
    CEIL_L = 0x4c,
9565
    CTC1 = 0x60,
9566
    CEIL_W = 0x6c,
9567
    MFC1 = 0x80,
9568
    CVT_S_PL = 0x84,
9569
    TRUNC_L = 0x8c,
9570
    MTC1 = 0xa0,
9571
    CVT_S_PU = 0xa4,
9572
    TRUNC_W = 0xac,
9573
    MFHC1 = 0xc0,
9574
    ROUND_L = 0xcc,
9575
    MTHC1 = 0xe0,
9576
    ROUND_W = 0xec,
9577

    
9578
    MOV_FMT = 0x01,
9579
    MOVF = 0x05,
9580
    ABS_FMT = 0x0d,
9581
    RSQRT1_FMT = 0x1d,
9582
    MOVT = 0x25,
9583
    NEG_FMT = 0x2d,
9584
    CVT_D = 0x4d,
9585
    RECIP1_FMT = 0x5d,
9586
    CVT_S = 0x6d
9587
};
9588

    
9589
/* POOL32I encoding of minor opcode field (bits 25..21) */
9590

    
9591
enum {
9592
    BLTZ = 0x00,
9593
    BLTZAL = 0x01,
9594
    BGEZ = 0x02,
9595
    BGEZAL = 0x03,
9596
    BLEZ = 0x04,
9597
    BNEZC = 0x05,
9598
    BGTZ = 0x06,
9599
    BEQZC = 0x07,
9600
    TLTI = 0x08,
9601
    TGEI = 0x09,
9602
    TLTIU = 0x0a,
9603
    TGEIU = 0x0b,
9604
    TNEI = 0x0c,
9605
    LUI = 0x0d,
9606
    TEQI = 0x0e,
9607
    SYNCI = 0x10,
9608
    BLTZALS = 0x11,
9609
    BGEZALS = 0x13,
9610
    BC2F = 0x14,
9611
    BC2T = 0x15,
9612
    BPOSGE64 = 0x1a,
9613
    BPOSGE32 = 0x1b,
9614
    /* These overlap and are distinguished by bit16 of the instruction */
9615
    BC1F = 0x1c,
9616
    BC1T = 0x1d,
9617
    BC1ANY2F = 0x1c,
9618
    BC1ANY2T = 0x1d,
9619
    BC1ANY4F = 0x1e,
9620
    BC1ANY4T = 0x1f
9621
};
9622

    
9623
/* POOL16A encoding of minor opcode field */
9624

    
9625
enum {
9626
    ADDU16 = 0x0,
9627
    SUBU16 = 0x1
9628
};
9629

    
9630
/* POOL16B encoding of minor opcode field */
9631

    
9632
enum {
9633
    SLL16 = 0x0,
9634
    SRL16 = 0x1
9635
};
9636

    
9637
/* POOL16C encoding of minor opcode field */
9638

    
9639
enum {
9640
    NOT16 = 0x00,
9641
    XOR16 = 0x04,
9642
    AND16 = 0x08,
9643
    OR16 = 0x0c,
9644
    LWM16 = 0x10,
9645
    SWM16 = 0x14,
9646
    JR16 = 0x18,
9647
    JRC16 = 0x1a,
9648
    JALR16 = 0x1c,
9649
    JALR16S = 0x1e,
9650
    MFHI16 = 0x20,
9651
    MFLO16 = 0x24,
9652
    BREAK16 = 0x28,
9653
    SDBBP16 = 0x2c,
9654
    JRADDIUSP = 0x30
9655
};
9656

    
9657
/* POOL16D encoding of minor opcode field */
9658

    
9659
enum {
9660
    ADDIUS5 = 0x0,
9661
    ADDIUSP = 0x1
9662
};
9663

    
9664
/* POOL16E encoding of minor opcode field */
9665

    
9666
enum {
9667
    ADDIUR2 = 0x0,
9668
    ADDIUR1SP = 0x1
9669
};
9670

    
9671
static int mmreg (int r)
9672
{
9673
    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9674

    
9675
    return map[r];
9676
}
9677

    
9678
/* Used for 16-bit store instructions.  */
9679
static int mmreg2 (int r)
9680
{
9681
    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9682

    
9683
    return map[r];
9684
}
9685

    
9686
#define uMIPS_RD(op) ((op >> 7) & 0x7)
9687
#define uMIPS_RS(op) ((op >> 4) & 0x7)
9688
#define uMIPS_RS2(op) uMIPS_RS(op)
9689
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
9690
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9691
#define uMIPS_RS5(op) (op & 0x1f)
9692

    
9693
/* Signed immediate */
9694
#define SIMM(op, start, width)                                          \
9695
    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
9696
               << (32-width))                                           \
9697
     >> (32-width))
9698
/* Zero-extended immediate */
9699
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9700

    
9701
static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9702
{
9703
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9704

    
9705
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9706
}
9707

    
9708
static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9709
{
9710
    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9711
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9712
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9713

    
9714
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9715
}
9716

    
9717
static void gen_addiusp (CPUState *env, DisasContext *ctx)
9718
{
9719
    int encoded = ZIMM(ctx->opcode, 1, 9);
9720
    int decoded;
9721

    
9722
    if (encoded <= 1) {
9723
        decoded = 256 + encoded;
9724
    } else if (encoded <= 255) {
9725
        decoded = encoded;
9726
    } else if (encoded <= 509) {
9727
        decoded = encoded - 512;
9728
    } else {
9729
        decoded = encoded - 768;
9730
    }
9731

    
9732
    gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9733
}
9734

    
9735
static void gen_addius5 (CPUState *env, DisasContext *ctx)
9736
{
9737
    int imm = SIMM(ctx->opcode, 1, 4);
9738
    int rd = (ctx->opcode >> 5) & 0x1f;
9739

    
9740
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9741
}
9742

    
9743
static void gen_andi16 (CPUState *env, DisasContext *ctx)
9744
{
9745
    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9746
                                 31, 32, 63, 64, 255, 32768, 65535 };
9747
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9748
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9749
    int encoded = ZIMM(ctx->opcode, 0, 4);
9750

    
9751
    gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9752
}
9753

    
9754
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9755
                               int base, int16_t offset)
9756
{
9757
    TCGv t0, t1;
9758
    TCGv_i32 t2;
9759

    
9760
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9761
        generate_exception(ctx, EXCP_RI);
9762
        return;
9763
    }
9764

    
9765
    t0 = tcg_temp_new();
9766

    
9767
    gen_base_offset_addr(ctx, t0, base, offset);
9768

    
9769
    t1 = tcg_const_tl(reglist);
9770
    t2 = tcg_const_i32(ctx->mem_idx);
9771

    
9772
    save_cpu_state(ctx, 1);
9773
    switch (opc) {
9774
    case LWM32:
9775
        gen_helper_lwm(t0, t1, t2);
9776
        break;
9777
    case SWM32:
9778
        gen_helper_swm(t0, t1, t2);
9779
        break;
9780
#ifdef TARGET_MIPS64
9781
    case LDM:
9782
        gen_helper_ldm(t0, t1, t2);
9783
        break;
9784
    case SDM:
9785
        gen_helper_sdm(t0, t1, t2);
9786
        break;
9787
#endif
9788
    }
9789
    MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9790
    tcg_temp_free(t0);
9791
    tcg_temp_free(t1);
9792
    tcg_temp_free_i32(t2);
9793
}
9794

    
9795

    
9796
static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9797
{
9798
    int rd = mmreg((ctx->opcode >> 3) & 0x7);
9799
    int rs = mmreg(ctx->opcode & 0x7);
9800
    int opc;
9801

    
9802
    switch (((ctx->opcode) >> 4) & 0x3f) {
9803
    case NOT16 + 0:
9804
    case NOT16 + 1:
9805
    case NOT16 + 2:
9806
    case NOT16 + 3:
9807
        gen_logic(env, OPC_NOR, rd, rs, 0);
9808
        break;
9809
    case XOR16 + 0:
9810
    case XOR16 + 1:
9811
    case XOR16 + 2:
9812
    case XOR16 + 3:
9813
        gen_logic(env, OPC_XOR, rd, rd, rs);
9814
        break;
9815
    case AND16 + 0:
9816
    case AND16 + 1:
9817
    case AND16 + 2:
9818
    case AND16 + 3:
9819
        gen_logic(env, OPC_AND, rd, rd, rs);
9820
        break;
9821
    case OR16 + 0:
9822
    case OR16 + 1:
9823
    case OR16 + 2:
9824
    case OR16 + 3:
9825
        gen_logic(env, OPC_OR, rd, rd, rs);
9826
        break;
9827
    case LWM16 + 0:
9828
    case LWM16 + 1:
9829
    case LWM16 + 2:
9830
    case LWM16 + 3:
9831
        {
9832
            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9833
            int offset = ZIMM(ctx->opcode, 0, 4);
9834

    
9835
            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9836
                              29, offset << 2);
9837
        }
9838
        break;
9839
    case SWM16 + 0:
9840
    case SWM16 + 1:
9841
    case SWM16 + 2:
9842
    case SWM16 + 3:
9843
        {
9844
            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9845
            int offset = ZIMM(ctx->opcode, 0, 4);
9846

    
9847
            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9848
                              29, offset << 2);
9849
        }
9850
        break;
9851
    case JR16 + 0:
9852
    case JR16 + 1:
9853
        {
9854
            int reg = ctx->opcode & 0x1f;
9855

    
9856
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9857
        }
9858
        *is_branch = 1;
9859
        break;
9860
    case JRC16 + 0:
9861
    case JRC16 + 1:
9862
        {
9863
            int reg = ctx->opcode & 0x1f;
9864

    
9865
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9866
            /* Let normal delay slot handling in our caller take us
9867
               to the branch target.  */
9868
        }
9869
        break;
9870
    case JALR16 + 0:
9871
    case JALR16 + 1:
9872
        opc = OPC_JALR;
9873
        goto do_jalr;
9874
    case JALR16S + 0:
9875
    case JALR16S + 1:
9876
        opc = OPC_JALRS;
9877
    do_jalr:
9878
        {
9879
            int reg = ctx->opcode & 0x1f;
9880

    
9881
            gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9882
        }
9883
        *is_branch = 1;
9884
        break;
9885
    case MFHI16 + 0:
9886
    case MFHI16 + 1:
9887
        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9888
        break;
9889
    case MFLO16 + 0:
9890
    case MFLO16 + 1:
9891
        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9892
        break;
9893
    case BREAK16:
9894
        generate_exception(ctx, EXCP_BREAK);
9895
        break;
9896
    case SDBBP16:
9897
        /* XXX: not clear which exception should be raised
9898
         *      when in debug mode...
9899
         */
9900
        check_insn(env, ctx, ISA_MIPS32);
9901
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9902
            generate_exception(ctx, EXCP_DBp);
9903
        } else {
9904
            generate_exception(ctx, EXCP_DBp);
9905
        }
9906
        break;
9907
    case JRADDIUSP + 0:
9908
    case JRADDIUSP + 1:
9909
        {
9910
            int imm = ZIMM(ctx->opcode, 0, 5);
9911

    
9912
            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9913
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9914
            /* Let normal delay slot handling in our caller take us
9915
               to the branch target.  */
9916
        }
9917
        break;
9918
    default:
9919
        generate_exception(ctx, EXCP_RI);
9920
        break;
9921
    }
9922
}
9923

    
9924
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
9925
{
9926
    TCGv t0 = tcg_temp_new();
9927
    TCGv t1 = tcg_temp_new();
9928

    
9929
    gen_load_gpr(t0, base);
9930

    
9931
    if (index != 0) {
9932
        gen_load_gpr(t1, index);
9933
        tcg_gen_shli_tl(t1, t1, 2);
9934
        gen_op_addr_add(ctx, t0, t1, t0);
9935
    }
9936

    
9937
    save_cpu_state(ctx, 0);
9938
    op_ld_lw(t1, t0, ctx);
9939
    gen_store_gpr(t1, rd);
9940

    
9941
    tcg_temp_free(t0);
9942
    tcg_temp_free(t1);
9943
}
9944

    
9945
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
9946
                           int base, int16_t offset)
9947
{
9948
    const char *opn = "ldst_pair";
9949
    TCGv t0, t1;
9950

    
9951
    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
9952
        generate_exception(ctx, EXCP_RI);
9953
        return;
9954
    }
9955

    
9956
    t0 = tcg_temp_new();
9957
    t1 = tcg_temp_new();
9958

    
9959
    gen_base_offset_addr(ctx, t0, base, offset);
9960

    
9961
    switch (opc) {
9962
    case LWP:
9963
        save_cpu_state(ctx, 0);
9964
        op_ld_lw(t1, t0, ctx);
9965
        gen_store_gpr(t1, rd);
9966
        tcg_gen_movi_tl(t1, 4);
9967
        gen_op_addr_add(ctx, t0, t0, t1);
9968
        op_ld_lw(t1, t0, ctx);
9969
        gen_store_gpr(t1, rd+1);
9970
        opn = "lwp";
9971
        break;
9972
    case SWP:
9973
        save_cpu_state(ctx, 0);
9974
        gen_load_gpr(t1, rd);
9975
        op_st_sw(t1, t0, ctx);
9976
        tcg_gen_movi_tl(t1, 4);
9977
        gen_op_addr_add(ctx, t0, t0, t1);
9978
        gen_load_gpr(t1, rd+1);
9979
        op_st_sw(t1, t0, ctx);
9980
        opn = "swp";
9981
        break;
9982
#ifdef TARGET_MIPS64
9983
    case LDP:
9984
        save_cpu_state(ctx, 0);
9985
        op_ld_ld(t1, t0, ctx);
9986
        gen_store_gpr(t1, rd);
9987
        tcg_gen_movi_tl(t1, 8);
9988
        gen_op_addr_add(ctx, t0, t0, t1);
9989
        op_ld_ld(t1, t0, ctx);
9990
        gen_store_gpr(t1, rd+1);
9991
        opn = "ldp";
9992
        break;
9993
    case SDP:
9994
        save_cpu_state(ctx, 0);
9995
        gen_load_gpr(t1, rd);
9996
        op_st_sd(t1, t0, ctx);
9997
        tcg_gen_movi_tl(t1, 8);
9998
        gen_op_addr_add(ctx, t0, t0, t1);
9999
        gen_load_gpr(t1, rd+1);
10000
        op_st_sd(t1, t0, ctx);
10001
        opn = "sdp";
10002
        break;
10003
#endif
10004
    }
10005
    (void)opn; /* avoid a compiler warning */
10006
    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10007
    tcg_temp_free(t0);
10008
    tcg_temp_free(t1);
10009
}
10010

    
10011
static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
10012
                           int *is_branch)
10013
{
10014
    int extension = (ctx->opcode >> 6) & 0x3f;
10015
    int minor = (ctx->opcode >> 12) & 0xf;
10016
    uint32_t mips32_op;
10017

    
10018
    switch (extension) {
10019
    case TEQ:
10020
        mips32_op = OPC_TEQ;
10021
        goto do_trap;
10022
    case TGE:
10023
        mips32_op = OPC_TGE;
10024
        goto do_trap;
10025
    case TGEU:
10026
        mips32_op = OPC_TGEU;
10027
        goto do_trap;
10028
    case TLT:
10029
        mips32_op = OPC_TLT;
10030
        goto do_trap;
10031
    case TLTU:
10032
        mips32_op = OPC_TLTU;
10033
        goto do_trap;
10034
    case TNE:
10035
        mips32_op = OPC_TNE;
10036
    do_trap:
10037
        gen_trap(ctx, mips32_op, rs, rt, -1);
10038
        break;
10039
#ifndef CONFIG_USER_ONLY
10040
    case MFC0:
10041
    case MFC0 + 32:
10042
        if (rt == 0) {
10043
            /* Treat as NOP. */
10044
            break;
10045
        }
10046
        gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10047
        break;
10048
    case MTC0:
10049
    case MTC0 + 32:
10050
        {
10051
            TCGv t0 = tcg_temp_new();
10052

    
10053
            gen_load_gpr(t0, rt);
10054
            gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10055
            tcg_temp_free(t0);
10056
        }
10057
        break;
10058
#endif
10059
    case 0x2c:
10060
        switch (minor) {
10061
        case SEB:
10062
            gen_bshfl(ctx, OPC_SEB, rs, rt);
10063
            break;
10064
        case SEH:
10065
            gen_bshfl(ctx, OPC_SEH, rs, rt);
10066
            break;
10067
        case CLO:
10068
            mips32_op = OPC_CLO;
10069
            goto do_cl;
10070
        case CLZ:
10071
            mips32_op = OPC_CLZ;
10072
        do_cl:
10073
            check_insn(env, ctx, ISA_MIPS32);
10074
            gen_cl(ctx, mips32_op, rt, rs);
10075
            break;
10076
        case RDHWR:
10077
            gen_rdhwr(env, ctx, rt, rs);
10078
            break;
10079
        case WSBH:
10080
            gen_bshfl(ctx, OPC_WSBH, rs, rt);
10081
            break;
10082
        case MULT:
10083
            mips32_op = OPC_MULT;
10084
            goto do_muldiv;
10085
        case MULTU:
10086
            mips32_op = OPC_MULTU;
10087
            goto do_muldiv;
10088
        case DIV:
10089
            mips32_op = OPC_DIV;
10090
            goto do_muldiv;
10091
        case DIVU:
10092
            mips32_op = OPC_DIVU;
10093
            goto do_muldiv;
10094
        case MADD:
10095
            mips32_op = OPC_MADD;
10096
            goto do_muldiv;
10097
        case MADDU:
10098
            mips32_op = OPC_MADDU;
10099
            goto do_muldiv;
10100
        case MSUB:
10101
            mips32_op = OPC_MSUB;
10102
            goto do_muldiv;
10103
        case MSUBU:
10104
            mips32_op = OPC_MSUBU;
10105
        do_muldiv:
10106
            check_insn(env, ctx, ISA_MIPS32);
10107
            gen_muldiv(ctx, mips32_op, rs, rt);
10108
            break;
10109
        default:
10110
            goto pool32axf_invalid;
10111
        }
10112
        break;
10113
    case 0x34:
10114
        switch (minor) {
10115
        case MFC2:
10116
        case MTC2:
10117
        case MFHC2:
10118
        case MTHC2:
10119
        case CFC2:
10120
        case CTC2:
10121
            generate_exception_err(ctx, EXCP_CpU, 2);
10122
            break;
10123
        default:
10124
            goto pool32axf_invalid;
10125
        }
10126
        break;
10127
    case 0x3c:
10128
        switch (minor) {
10129
        case JALR:
10130
        case JALR_HB:
10131
            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10132
            *is_branch = 1;
10133
            break;
10134
        case JALRS:
10135
        case JALRS_HB:
10136
            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10137
            *is_branch = 1;
10138
            break;
10139
        default:
10140
            goto pool32axf_invalid;
10141
        }
10142
        break;
10143
    case 0x05:
10144
        switch (minor) {
10145
        case RDPGPR:
10146
            check_insn(env, ctx, ISA_MIPS32R2);
10147
            gen_load_srsgpr(rt, rs);
10148
            break;
10149
        case WRPGPR:
10150
            check_insn(env, ctx, ISA_MIPS32R2);
10151
            gen_store_srsgpr(rt, rs);
10152
            break;
10153
        default:
10154
            goto pool32axf_invalid;
10155
        }
10156
        break;
10157
#ifndef CONFIG_USER_ONLY
10158
    case 0x0d:
10159
        switch (minor) {
10160
        case TLBP:
10161
            mips32_op = OPC_TLBP;
10162
            goto do_cp0;
10163
        case TLBR:
10164
            mips32_op = OPC_TLBR;
10165
            goto do_cp0;
10166
        case TLBWI:
10167
            mips32_op = OPC_TLBWI;
10168
            goto do_cp0;
10169
        case TLBWR:
10170
            mips32_op = OPC_TLBWR;
10171
            goto do_cp0;
10172
        case WAIT:
10173
            mips32_op = OPC_WAIT;
10174
            goto do_cp0;
10175
        case DERET:
10176
            mips32_op = OPC_DERET;
10177
            goto do_cp0;
10178
        case ERET:
10179
            mips32_op = OPC_ERET;
10180
        do_cp0:
10181
            gen_cp0(env, ctx, mips32_op, rt, rs);
10182
            break;
10183
        default:
10184
            goto pool32axf_invalid;
10185
        }
10186
        break;
10187
    case 0x1d:
10188
        switch (minor) {
10189
        case DI:
10190
            {
10191
                TCGv t0 = tcg_temp_new();
10192

    
10193
                save_cpu_state(ctx, 1);
10194
                gen_helper_di(t0);
10195
                gen_store_gpr(t0, rs);
10196
                /* Stop translation as we may have switched the execution mode */
10197
                ctx->bstate = BS_STOP;
10198
                tcg_temp_free(t0);
10199
            }
10200
            break;
10201
        case EI:
10202
            {
10203
                TCGv t0 = tcg_temp_new();
10204

    
10205
                save_cpu_state(ctx, 1);
10206
                gen_helper_ei(t0);
10207
                gen_store_gpr(t0, rs);
10208
                /* Stop translation as we may have switched the execution mode */
10209
                ctx->bstate = BS_STOP;
10210
                tcg_temp_free(t0);
10211
            }
10212
            break;
10213
        default:
10214
            goto pool32axf_invalid;
10215
        }
10216
        break;
10217
#endif
10218
    case 0x2d:
10219
        switch (minor) {
10220
        case SYNC:
10221
            /* NOP */
10222
            break;
10223
        case SYSCALL:
10224
            generate_exception(ctx, EXCP_SYSCALL);
10225
            ctx->bstate = BS_STOP;
10226
            break;
10227
        case SDBBP:
10228
            check_insn(env, ctx, ISA_MIPS32);
10229
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10230
                generate_exception(ctx, EXCP_DBp);
10231
            } else {
10232
                generate_exception(ctx, EXCP_DBp);
10233
            }
10234
            break;
10235
        default:
10236
            goto pool32axf_invalid;
10237
        }
10238
        break;
10239
    case 0x35:
10240
        switch (minor) {
10241
        case MFHI32:
10242
            gen_HILO(ctx, OPC_MFHI, rs);
10243
            break;
10244
        case MFLO32:
10245
            gen_HILO(ctx, OPC_MFLO, rs);
10246
            break;
10247
        case MTHI32:
10248
            gen_HILO(ctx, OPC_MTHI, rs);
10249
            break;
10250
        case MTLO32:
10251
            gen_HILO(ctx, OPC_MTLO, rs);
10252
            break;
10253
        default:
10254
            goto pool32axf_invalid;
10255
        }
10256
        break;
10257
    default:
10258
    pool32axf_invalid:
10259
        MIPS_INVAL("pool32axf");
10260
        generate_exception(ctx, EXCP_RI);
10261
        break;
10262
    }
10263
}
10264

    
10265
/* Values for microMIPS fmt field.  Variable-width, depending on which
10266
   formats the instruction supports.  */
10267

    
10268
enum {
10269
    FMT_SD_S = 0,
10270
    FMT_SD_D = 1,
10271

    
10272
    FMT_SDPS_S = 0,
10273
    FMT_SDPS_D = 1,
10274
    FMT_SDPS_PS = 2,
10275

    
10276
    FMT_SWL_S = 0,
10277
    FMT_SWL_W = 1,
10278
    FMT_SWL_L = 2,
10279

    
10280
    FMT_DWL_D = 0,
10281
    FMT_DWL_W = 1,
10282
    FMT_DWL_L = 2
10283
};
10284

    
10285
static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10286
{
10287
    int extension = (ctx->opcode >> 6) & 0x3ff;
10288
    uint32_t mips32_op;
10289

    
10290
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10291
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10292
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10293

    
10294
    switch (extension) {
10295
    case FLOAT_1BIT_FMT(CFC1, 0):
10296
        mips32_op = OPC_CFC1;
10297
        goto do_cp1;
10298
    case FLOAT_1BIT_FMT(CTC1, 0):
10299
        mips32_op = OPC_CTC1;
10300
        goto do_cp1;
10301
    case FLOAT_1BIT_FMT(MFC1, 0):
10302
        mips32_op = OPC_MFC1;
10303
        goto do_cp1;
10304
    case FLOAT_1BIT_FMT(MTC1, 0):
10305
        mips32_op = OPC_MTC1;
10306
        goto do_cp1;
10307
    case FLOAT_1BIT_FMT(MFHC1, 0):
10308
        mips32_op = OPC_MFHC1;
10309
        goto do_cp1;
10310
    case FLOAT_1BIT_FMT(MTHC1, 0):
10311
        mips32_op = OPC_MTHC1;
10312
    do_cp1:
10313
        gen_cp1(ctx, mips32_op, rt, rs);
10314
        break;
10315

    
10316
        /* Reciprocal square root */
10317
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10318
        mips32_op = OPC_RSQRT_S;
10319
        goto do_unaryfp;
10320
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10321
        mips32_op = OPC_RSQRT_D;
10322
        goto do_unaryfp;
10323

    
10324
        /* Square root */
10325
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10326
        mips32_op = OPC_SQRT_S;
10327
        goto do_unaryfp;
10328
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10329
        mips32_op = OPC_SQRT_D;
10330
        goto do_unaryfp;
10331

    
10332
        /* Reciprocal */
10333
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10334
        mips32_op = OPC_RECIP_S;
10335
        goto do_unaryfp;
10336
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10337
        mips32_op = OPC_RECIP_D;
10338
        goto do_unaryfp;
10339

    
10340
        /* Floor */
10341
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10342
        mips32_op = OPC_FLOOR_L_S;
10343
        goto do_unaryfp;
10344
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10345
        mips32_op = OPC_FLOOR_L_D;
10346
        goto do_unaryfp;
10347
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10348
        mips32_op = OPC_FLOOR_W_S;
10349
        goto do_unaryfp;
10350
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10351
        mips32_op = OPC_FLOOR_W_D;
10352
        goto do_unaryfp;
10353

    
10354
        /* Ceiling */
10355
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10356
        mips32_op = OPC_CEIL_L_S;
10357
        goto do_unaryfp;
10358
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10359
        mips32_op = OPC_CEIL_L_D;
10360
        goto do_unaryfp;
10361
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10362
        mips32_op = OPC_CEIL_W_S;
10363
        goto do_unaryfp;
10364
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10365
        mips32_op = OPC_CEIL_W_D;
10366
        goto do_unaryfp;
10367

    
10368
        /* Truncation */
10369
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10370
        mips32_op = OPC_TRUNC_L_S;
10371
        goto do_unaryfp;
10372
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10373
        mips32_op = OPC_TRUNC_L_D;
10374
        goto do_unaryfp;
10375
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10376
        mips32_op = OPC_TRUNC_W_S;
10377
        goto do_unaryfp;
10378
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10379
        mips32_op = OPC_TRUNC_W_D;
10380
        goto do_unaryfp;
10381

    
10382
        /* Round */
10383
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10384
        mips32_op = OPC_ROUND_L_S;
10385
        goto do_unaryfp;
10386
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10387
        mips32_op = OPC_ROUND_L_D;
10388
        goto do_unaryfp;
10389
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10390
        mips32_op = OPC_ROUND_W_S;
10391
        goto do_unaryfp;
10392
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10393
        mips32_op = OPC_ROUND_W_D;
10394
        goto do_unaryfp;
10395

    
10396
        /* Integer to floating-point conversion */
10397
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10398
        mips32_op = OPC_CVT_L_S;
10399
        goto do_unaryfp;
10400
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10401
        mips32_op = OPC_CVT_L_D;
10402
        goto do_unaryfp;
10403
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10404
        mips32_op = OPC_CVT_W_S;
10405
        goto do_unaryfp;
10406
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10407
        mips32_op = OPC_CVT_W_D;
10408
        goto do_unaryfp;
10409

    
10410
        /* Paired-foo conversions */
10411
    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10412
        mips32_op = OPC_CVT_S_PL;
10413
        goto do_unaryfp;
10414
    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10415
        mips32_op = OPC_CVT_S_PU;
10416
        goto do_unaryfp;
10417
    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10418
        mips32_op = OPC_CVT_PW_PS;
10419
        goto do_unaryfp;
10420
    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10421
        mips32_op = OPC_CVT_PS_PW;
10422
        goto do_unaryfp;
10423

    
10424
        /* Floating-point moves */
10425
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10426
        mips32_op = OPC_MOV_S;
10427
        goto do_unaryfp;
10428
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10429
        mips32_op = OPC_MOV_D;
10430
        goto do_unaryfp;
10431
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10432
        mips32_op = OPC_MOV_PS;
10433
        goto do_unaryfp;
10434

    
10435
        /* Absolute value */
10436
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10437
        mips32_op = OPC_ABS_S;
10438
        goto do_unaryfp;
10439
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10440
        mips32_op = OPC_ABS_D;
10441
        goto do_unaryfp;
10442
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10443
        mips32_op = OPC_ABS_PS;
10444
        goto do_unaryfp;
10445

    
10446
        /* Negation */
10447
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10448
        mips32_op = OPC_NEG_S;
10449
        goto do_unaryfp;
10450
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10451
        mips32_op = OPC_NEG_D;
10452
        goto do_unaryfp;
10453
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10454
        mips32_op = OPC_NEG_PS;
10455
        goto do_unaryfp;
10456

    
10457
        /* Reciprocal square root step */
10458
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10459
        mips32_op = OPC_RSQRT1_S;
10460
        goto do_unaryfp;
10461
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10462
        mips32_op = OPC_RSQRT1_D;
10463
        goto do_unaryfp;
10464
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10465
        mips32_op = OPC_RSQRT1_PS;
10466
        goto do_unaryfp;
10467

    
10468
        /* Reciprocal step */
10469
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10470
        mips32_op = OPC_RECIP1_S;
10471
        goto do_unaryfp;
10472
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10473
        mips32_op = OPC_RECIP1_S;
10474
        goto do_unaryfp;
10475
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10476
        mips32_op = OPC_RECIP1_PS;
10477
        goto do_unaryfp;
10478

    
10479
        /* Conversions from double */
10480
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10481
        mips32_op = OPC_CVT_D_S;
10482
        goto do_unaryfp;
10483
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10484
        mips32_op = OPC_CVT_D_W;
10485
        goto do_unaryfp;
10486
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10487
        mips32_op = OPC_CVT_D_L;
10488
        goto do_unaryfp;
10489

    
10490
        /* Conversions from single */
10491
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10492
        mips32_op = OPC_CVT_S_D;
10493
        goto do_unaryfp;
10494
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10495
        mips32_op = OPC_CVT_S_W;
10496
        goto do_unaryfp;
10497
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10498
        mips32_op = OPC_CVT_S_L;
10499
    do_unaryfp:
10500
        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10501
        break;
10502

    
10503
        /* Conditional moves on floating-point codes */
10504
    case COND_FLOAT_MOV(MOVT, 0):
10505
    case COND_FLOAT_MOV(MOVT, 1):
10506
    case COND_FLOAT_MOV(MOVT, 2):
10507
    case COND_FLOAT_MOV(MOVT, 3):
10508
    case COND_FLOAT_MOV(MOVT, 4):
10509
    case COND_FLOAT_MOV(MOVT, 5):
10510
    case COND_FLOAT_MOV(MOVT, 6):
10511
    case COND_FLOAT_MOV(MOVT, 7):
10512
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10513
        break;
10514
    case COND_FLOAT_MOV(MOVF, 0):
10515
    case COND_FLOAT_MOV(MOVF, 1):
10516
    case COND_FLOAT_MOV(MOVF, 2):
10517
    case COND_FLOAT_MOV(MOVF, 3):
10518
    case COND_FLOAT_MOV(MOVF, 4):
10519
    case COND_FLOAT_MOV(MOVF, 5):
10520
    case COND_FLOAT_MOV(MOVF, 6):
10521
    case COND_FLOAT_MOV(MOVF, 7):
10522
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10523
        break;
10524
    default:
10525
        MIPS_INVAL("pool32fxf");
10526
        generate_exception(ctx, EXCP_RI);
10527
        break;
10528
    }
10529
}
10530

    
10531
static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10532
                                    uint16_t insn_hw1, int *is_branch)
10533
{
10534
    int32_t offset;
10535
    uint16_t insn;
10536
    int rt, rs, rd, rr;
10537
    int16_t imm;
10538
    uint32_t op, minor, mips32_op;
10539
    uint32_t cond, fmt, cc;
10540

    
10541
    insn = lduw_code(ctx->pc + 2);
10542
    ctx->opcode = (ctx->opcode << 16) | insn;
10543

    
10544
    rt = (ctx->opcode >> 21) & 0x1f;
10545
    rs = (ctx->opcode >> 16) & 0x1f;
10546
    rd = (ctx->opcode >> 11) & 0x1f;
10547
    rr = (ctx->opcode >> 6) & 0x1f;
10548
    imm = (int16_t) ctx->opcode;
10549

    
10550
    op = (ctx->opcode >> 26) & 0x3f;
10551
    switch (op) {
10552
    case POOL32A:
10553
        minor = ctx->opcode & 0x3f;
10554
        switch (minor) {
10555
        case 0x00:
10556
            minor = (ctx->opcode >> 6) & 0xf;
10557
            switch (minor) {
10558
            case SLL32:
10559
                mips32_op = OPC_SLL;
10560
                goto do_shifti;
10561
            case SRA:
10562
                mips32_op = OPC_SRA;
10563
                goto do_shifti;
10564
            case SRL32:
10565
                mips32_op = OPC_SRL;
10566
                goto do_shifti;
10567
            case ROTR:
10568
                mips32_op = OPC_ROTR;
10569
            do_shifti:
10570
                gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10571
                break;
10572
            default:
10573
                goto pool32a_invalid;
10574
            }
10575
            break;
10576
        case 0x10:
10577
            minor = (ctx->opcode >> 6) & 0xf;
10578
            switch (minor) {
10579
                /* Arithmetic */
10580
            case ADD:
10581
                mips32_op = OPC_ADD;
10582
                goto do_arith;
10583
            case ADDU32:
10584
                mips32_op = OPC_ADDU;
10585
                goto do_arith;
10586
            case SUB:
10587
                mips32_op = OPC_SUB;
10588
                goto do_arith;
10589
            case SUBU32:
10590
                mips32_op = OPC_SUBU;
10591
                goto do_arith;
10592
            case MUL:
10593
                mips32_op = OPC_MUL;
10594
            do_arith:
10595
                gen_arith(env, ctx, mips32_op, rd, rs, rt);
10596
                break;
10597
                /* Shifts */
10598
            case SLLV:
10599
                mips32_op = OPC_SLLV;
10600
                goto do_shift;
10601
            case SRLV:
10602
                mips32_op = OPC_SRLV;
10603
                goto do_shift;
10604
            case SRAV:
10605
                mips32_op = OPC_SRAV;
10606
                goto do_shift;
10607
            case ROTRV:
10608
                mips32_op = OPC_ROTRV;
10609
            do_shift:
10610
                gen_shift(env, ctx, mips32_op, rd, rs, rt);
10611
                break;
10612
                /* Logical operations */
10613
            case AND:
10614
                mips32_op = OPC_AND;
10615
                goto do_logic;
10616
            case OR32:
10617
                mips32_op = OPC_OR;
10618
                goto do_logic;
10619
            case NOR:
10620
                mips32_op = OPC_NOR;
10621
                goto do_logic;
10622
            case XOR32:
10623
                mips32_op = OPC_XOR;
10624
            do_logic:
10625
                gen_logic(env, mips32_op, rd, rs, rt);
10626
                break;
10627
                /* Set less than */
10628
            case SLT:
10629
                mips32_op = OPC_SLT;
10630
                goto do_slt;
10631
            case SLTU:
10632
                mips32_op = OPC_SLTU;
10633
            do_slt:
10634
                gen_slt(env, mips32_op, rd, rs, rt);
10635
                break;
10636
            default:
10637
                goto pool32a_invalid;
10638
            }
10639
            break;
10640
        case 0x18:
10641
            minor = (ctx->opcode >> 6) & 0xf;
10642
            switch (minor) {
10643
                /* Conditional moves */
10644
            case MOVN:
10645
                mips32_op = OPC_MOVN;
10646
                goto do_cmov;
10647
            case MOVZ:
10648
                mips32_op = OPC_MOVZ;
10649
            do_cmov:
10650
                gen_cond_move(env, mips32_op, rd, rs, rt);
10651
                break;
10652
            case LWXS:
10653
                gen_ldxs(ctx, rs, rt, rd);
10654
                break;
10655
            default:
10656
                goto pool32a_invalid;
10657
            }
10658
            break;
10659
        case INS:
10660
            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10661
            return;
10662
        case EXT:
10663
            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10664
            return;
10665
        case POOL32AXF:
10666
            gen_pool32axf(env, ctx, rt, rs, is_branch);
10667
            break;
10668
        case 0x07:
10669
            generate_exception(ctx, EXCP_BREAK);
10670
            break;
10671
        default:
10672
        pool32a_invalid:
10673
                MIPS_INVAL("pool32a");
10674
                generate_exception(ctx, EXCP_RI);
10675
                break;
10676
        }
10677
        break;
10678
    case POOL32B:
10679
        minor = (ctx->opcode >> 12) & 0xf;
10680
        switch (minor) {
10681
        case CACHE:
10682
            /* Treat as no-op. */
10683
            break;
10684
        case LWC2:
10685
        case SWC2:
10686
            /* COP2: Not implemented. */
10687
            generate_exception_err(ctx, EXCP_CpU, 2);
10688
            break;
10689
        case LWP:
10690
        case SWP:
10691
#ifdef TARGET_MIPS64
10692
        case LDP:
10693
        case SDP:
10694
#endif
10695
            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10696
            break;
10697
        case LWM32:
10698
        case SWM32:
10699
#ifdef TARGET_MIPS64
10700
        case LDM:
10701
        case SDM:
10702
#endif
10703
            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10704
            break;
10705
        default:
10706
            MIPS_INVAL("pool32b");
10707
            generate_exception(ctx, EXCP_RI);
10708
            break;
10709
        }
10710
        break;
10711
    case POOL32F:
10712
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10713
            minor = ctx->opcode & 0x3f;
10714
            check_cp1_enabled(ctx);
10715
            switch (minor) {
10716
            case ALNV_PS:
10717
                mips32_op = OPC_ALNV_PS;
10718
                goto do_madd;
10719
            case MADD_S:
10720
                mips32_op = OPC_MADD_S;
10721
                goto do_madd;
10722
            case MADD_D:
10723
                mips32_op = OPC_MADD_D;
10724
                goto do_madd;
10725
            case MADD_PS:
10726
                mips32_op = OPC_MADD_PS;
10727
                goto do_madd;
10728
            case MSUB_S:
10729
                mips32_op = OPC_MSUB_S;
10730
                goto do_madd;
10731
            case MSUB_D:
10732
                mips32_op = OPC_MSUB_D;
10733
                goto do_madd;
10734
            case MSUB_PS:
10735
                mips32_op = OPC_MSUB_PS;
10736
                goto do_madd;
10737
            case NMADD_S:
10738
                mips32_op = OPC_NMADD_S;
10739
                goto do_madd;
10740
            case NMADD_D:
10741
                mips32_op = OPC_NMADD_D;
10742
                goto do_madd;
10743
            case NMADD_PS:
10744
                mips32_op = OPC_NMADD_PS;
10745
                goto do_madd;
10746
            case NMSUB_S:
10747
                mips32_op = OPC_NMSUB_S;
10748
                goto do_madd;
10749
            case NMSUB_D:
10750
                mips32_op = OPC_NMSUB_D;
10751
                goto do_madd;
10752
            case NMSUB_PS:
10753
                mips32_op = OPC_NMSUB_PS;
10754
            do_madd:
10755
                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10756
                break;
10757
            case CABS_COND_FMT:
10758
                cond = (ctx->opcode >> 6) & 0xf;
10759
                cc = (ctx->opcode >> 13) & 0x7;
10760
                fmt = (ctx->opcode >> 10) & 0x3;
10761
                switch (fmt) {
10762
                case 0x0:
10763
                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
10764
                    break;
10765
                case 0x1:
10766
                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
10767
                    break;
10768
                case 0x2:
10769
                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10770
                    break;
10771
                default:
10772
                    goto pool32f_invalid;
10773
                }
10774
                break;
10775
            case C_COND_FMT:
10776
                cond = (ctx->opcode >> 6) & 0xf;
10777
                cc = (ctx->opcode >> 13) & 0x7;
10778
                fmt = (ctx->opcode >> 10) & 0x3;
10779
                switch (fmt) {
10780
                case 0x0:
10781
                    gen_cmp_s(ctx, cond, rt, rs, cc);
10782
                    break;
10783
                case 0x1:
10784
                    gen_cmp_d(ctx, cond, rt, rs, cc);
10785
                    break;
10786
                case 0x2:
10787
                    gen_cmp_ps(ctx, cond, rt, rs, cc);
10788
                    break;
10789
                default:
10790
                    goto pool32f_invalid;
10791
                }
10792
                break;
10793
            case POOL32FXF:
10794
                gen_pool32fxf(env, ctx, rt, rs);
10795
                break;
10796
            case 0x00:
10797
                /* PLL foo */
10798
                switch ((ctx->opcode >> 6) & 0x7) {
10799
                case PLL_PS:
10800
                    mips32_op = OPC_PLL_PS;
10801
                    goto do_ps;
10802
                case PLU_PS:
10803
                    mips32_op = OPC_PLU_PS;
10804
                    goto do_ps;
10805
                case PUL_PS:
10806
                    mips32_op = OPC_PUL_PS;
10807
                    goto do_ps;
10808
                case PUU_PS:
10809
                    mips32_op = OPC_PUU_PS;
10810
                    goto do_ps;
10811
                case CVT_PS_S:
10812
                    mips32_op = OPC_CVT_PS_S;
10813
                do_ps:
10814
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10815
                    break;
10816
                default:
10817
                    goto pool32f_invalid;
10818
                }
10819
                break;
10820
            case 0x08:
10821
                /* [LS][WDU]XC1 */
10822
                switch ((ctx->opcode >> 6) & 0x7) {
10823
                case LWXC1:
10824
                    mips32_op = OPC_LWXC1;
10825
                    goto do_ldst_cp1;
10826
                case SWXC1:
10827
                    mips32_op = OPC_SWXC1;
10828
                    goto do_ldst_cp1;
10829
                case LDXC1:
10830
                    mips32_op = OPC_LDXC1;
10831
                    goto do_ldst_cp1;
10832
                case SDXC1:
10833
                    mips32_op = OPC_SDXC1;
10834
                    goto do_ldst_cp1;
10835
                case LUXC1:
10836
                    mips32_op = OPC_LUXC1;
10837
                    goto do_ldst_cp1;
10838
                case SUXC1:
10839
                    mips32_op = OPC_SUXC1;
10840
                do_ldst_cp1:
10841
                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10842
                    break;
10843
                default:
10844
                    goto pool32f_invalid;
10845
                }
10846
                break;
10847
            case 0x18:
10848
                /* 3D insns */
10849
                fmt = (ctx->opcode >> 9) & 0x3;
10850
                switch ((ctx->opcode >> 6) & 0x7) {
10851
                case RSQRT2_FMT:
10852
                    switch (fmt) {
10853
                    case FMT_SDPS_S:
10854
                        mips32_op = OPC_RSQRT2_S;
10855
                        goto do_3d;
10856
                    case FMT_SDPS_D:
10857
                        mips32_op = OPC_RSQRT2_D;
10858
                        goto do_3d;
10859
                    case FMT_SDPS_PS:
10860
                        mips32_op = OPC_RSQRT2_PS;
10861
                        goto do_3d;
10862
                    default:
10863
                        goto pool32f_invalid;
10864
                    }
10865
                    break;
10866
                case RECIP2_FMT:
10867
                    switch (fmt) {
10868
                    case FMT_SDPS_S:
10869
                        mips32_op = OPC_RECIP2_S;
10870
                        goto do_3d;
10871
                    case FMT_SDPS_D:
10872
                        mips32_op = OPC_RECIP2_D;
10873
                        goto do_3d;
10874
                    case FMT_SDPS_PS:
10875
                        mips32_op = OPC_RECIP2_PS;
10876
                        goto do_3d;
10877
                    default:
10878
                        goto pool32f_invalid;
10879
                    }
10880
                    break;
10881
                case ADDR_PS:
10882
                    mips32_op = OPC_ADDR_PS;
10883
                    goto do_3d;
10884
                case MULR_PS:
10885
                    mips32_op = OPC_MULR_PS;
10886
                do_3d:
10887
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10888
                    break;
10889
                default:
10890
                    goto pool32f_invalid;
10891
                }
10892
                break;
10893
            case 0x20:
10894
                /* MOV[FT].fmt and PREFX */
10895
                cc = (ctx->opcode >> 13) & 0x7;
10896
                fmt = (ctx->opcode >> 9) & 0x3;
10897
                switch ((ctx->opcode >> 6) & 0x7) {
10898
                case MOVF_FMT:
10899
                    switch (fmt) {
10900
                    case FMT_SDPS_S:
10901
                        gen_movcf_s(rs, rt, cc, 0);
10902
                        break;
10903
                    case FMT_SDPS_D:
10904
                        gen_movcf_d(ctx, rs, rt, cc, 0);
10905
                        break;
10906
                    case FMT_SDPS_PS:
10907
                        gen_movcf_ps(rs, rt, cc, 0);
10908
                        break;
10909
                    default:
10910
                        goto pool32f_invalid;
10911
                    }
10912
                    break;
10913
                case MOVT_FMT:
10914
                    switch (fmt) {
10915
                    case FMT_SDPS_S:
10916
                        gen_movcf_s(rs, rt, cc, 1);
10917
                        break;
10918
                    case FMT_SDPS_D:
10919
                        gen_movcf_d(ctx, rs, rt, cc, 1);
10920
                        break;
10921
                    case FMT_SDPS_PS:
10922
                        gen_movcf_ps(rs, rt, cc, 1);
10923
                        break;
10924
                    default:
10925
                        goto pool32f_invalid;
10926
                    }
10927
                    break;
10928
                case PREFX:
10929
                    break;
10930
                default:
10931
                    goto pool32f_invalid;
10932
                }
10933
                break;
10934
#define FINSN_3ARG_SDPS(prfx)                           \
10935
                switch ((ctx->opcode >> 8) & 0x3) {     \
10936
                case FMT_SDPS_S:                        \
10937
                    mips32_op = OPC_##prfx##_S;         \
10938
                    goto do_fpop;                       \
10939
                case FMT_SDPS_D:                        \
10940
                    mips32_op = OPC_##prfx##_D;         \
10941
                    goto do_fpop;                       \
10942
                case FMT_SDPS_PS:                       \
10943
                    mips32_op = OPC_##prfx##_PS;        \
10944
                    goto do_fpop;                       \
10945
                default:                                \
10946
                    goto pool32f_invalid;               \
10947
                }
10948
            case 0x30:
10949
                /* regular FP ops */
10950
                switch ((ctx->opcode >> 6) & 0x3) {
10951
                case ADD_FMT:
10952
                    FINSN_3ARG_SDPS(ADD);
10953
                    break;
10954
                case SUB_FMT:
10955
                    FINSN_3ARG_SDPS(SUB);
10956
                    break;
10957
                case MUL_FMT:
10958
                    FINSN_3ARG_SDPS(MUL);
10959
                    break;
10960
                case DIV_FMT:
10961
                    fmt = (ctx->opcode >> 8) & 0x3;
10962
                    if (fmt == 1) {
10963
                        mips32_op = OPC_DIV_D;
10964
                    } else if (fmt == 0) {
10965
                        mips32_op = OPC_DIV_S;
10966
                    } else {
10967
                        goto pool32f_invalid;
10968
                    }
10969
                    goto do_fpop;
10970
                default:
10971
                    goto pool32f_invalid;
10972
                }
10973
                break;
10974
            case 0x38:
10975
                /* cmovs */
10976
                switch ((ctx->opcode >> 6) & 0x3) {
10977
                case MOVN_FMT:
10978
                    FINSN_3ARG_SDPS(MOVN);
10979
                    break;
10980
                case MOVZ_FMT:
10981
                    FINSN_3ARG_SDPS(MOVZ);
10982
                    break;
10983
                default:
10984
                    goto pool32f_invalid;
10985
                }
10986
                break;
10987
            do_fpop:
10988
                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10989
                break;
10990
            default:
10991
            pool32f_invalid:
10992
                MIPS_INVAL("pool32f");
10993
                generate_exception(ctx, EXCP_RI);
10994
                break;
10995
            }
10996
        } else {
10997
            generate_exception_err(ctx, EXCP_CpU, 1);
10998
        }
10999
        break;
11000
    case POOL32I:
11001
        minor = (ctx->opcode >> 21) & 0x1f;
11002
        switch (minor) {
11003
        case BLTZ:
11004
            mips32_op = OPC_BLTZ;
11005
            goto do_branch;
11006
        case BLTZAL:
11007
            mips32_op = OPC_BLTZAL;
11008
            goto do_branch;
11009
        case BLTZALS:
11010
            mips32_op = OPC_BLTZALS;
11011
            goto do_branch;
11012
        case BGEZ:
11013
            mips32_op = OPC_BGEZ;
11014
            goto do_branch;
11015
        case BGEZAL:
11016
            mips32_op = OPC_BGEZAL;
11017
            goto do_branch;
11018
        case BGEZALS:
11019
            mips32_op = OPC_BGEZALS;
11020
            goto do_branch;
11021
        case BLEZ:
11022
            mips32_op = OPC_BLEZ;
11023
            goto do_branch;
11024
        case BGTZ:
11025
            mips32_op = OPC_BGTZ;
11026
        do_branch:
11027
            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11028
            *is_branch = 1;
11029
            break;
11030

    
11031
            /* Traps */
11032
        case TLTI:
11033
            mips32_op = OPC_TLTI;
11034
            goto do_trapi;
11035
        case TGEI:
11036
            mips32_op = OPC_TGEI;
11037
            goto do_trapi;
11038
        case TLTIU:
11039
            mips32_op = OPC_TLTIU;
11040
            goto do_trapi;
11041
        case TGEIU:
11042
            mips32_op = OPC_TGEIU;
11043
            goto do_trapi;
11044
        case TNEI:
11045
            mips32_op = OPC_TNEI;
11046
            goto do_trapi;
11047
        case TEQI:
11048
            mips32_op = OPC_TEQI;
11049
        do_trapi:
11050
            gen_trap(ctx, mips32_op, rs, -1, imm);
11051
            break;
11052

    
11053
        case BNEZC:
11054
        case BEQZC:
11055
            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11056
                               4, rs, 0, imm << 1);
11057
            /* Compact branches don't have a delay slot, so just let
11058
               the normal delay slot handling take us to the branch
11059
               target. */
11060
            break;
11061
        case LUI:
11062
            gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11063
            break;
11064
        case SYNCI:
11065
            break;
11066
        case BC2F:
11067
        case BC2T:
11068
            /* COP2: Not implemented. */
11069
            generate_exception_err(ctx, EXCP_CpU, 2);
11070
            break;
11071
        case BC1F:
11072
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11073
            goto do_cp1branch;
11074
        case BC1T:
11075
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11076
            goto do_cp1branch;
11077
        case BC1ANY4F:
11078
            mips32_op = OPC_BC1FANY4;
11079
            goto do_cp1mips3d;
11080
        case BC1ANY4T:
11081
            mips32_op = OPC_BC1TANY4;
11082
        do_cp1mips3d:
11083
            check_cop1x(ctx);
11084
            check_insn(env, ctx, ASE_MIPS3D);
11085
            /* Fall through */
11086
        do_cp1branch:
11087
            gen_compute_branch1(env, ctx, mips32_op,
11088
                                (ctx->opcode >> 18) & 0x7, imm << 1);
11089
            *is_branch = 1;
11090
            break;
11091
        case BPOSGE64:
11092
        case BPOSGE32:
11093
            /* MIPS DSP: not implemented */
11094
            /* Fall through */
11095
        default:
11096
            MIPS_INVAL("pool32i");
11097
            generate_exception(ctx, EXCP_RI);
11098
            break;
11099
        }
11100
        break;
11101
    case POOL32C:
11102
        minor = (ctx->opcode >> 12) & 0xf;
11103
        switch (minor) {
11104
        case LWL:
11105
            mips32_op = OPC_LWL;
11106
            goto do_ld_lr;
11107
        case SWL:
11108
            mips32_op = OPC_SWL;
11109
            goto do_st_lr;
11110
        case LWR:
11111
            mips32_op = OPC_LWR;
11112
            goto do_ld_lr;
11113
        case SWR:
11114
            mips32_op = OPC_SWR;
11115
            goto do_st_lr;
11116
#if defined(TARGET_MIPS64)
11117
        case LDL:
11118
            mips32_op = OPC_LDL;
11119
            goto do_ld_lr;
11120
        case SDL:
11121
            mips32_op = OPC_SDL;
11122
            goto do_st_lr;
11123
        case LDR:
11124
            mips32_op = OPC_LDR;
11125
            goto do_ld_lr;
11126
        case SDR:
11127
            mips32_op = OPC_SDR;
11128
            goto do_st_lr;
11129
        case LWU:
11130
            mips32_op = OPC_LWU;
11131
            goto do_ld_lr;
11132
        case LLD:
11133
            mips32_op = OPC_LLD;
11134
            goto do_ld_lr;
11135
#endif
11136
        case LL:
11137
            mips32_op = OPC_LL;
11138
            goto do_ld_lr;
11139
        do_ld_lr:
11140
            gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11141
            break;
11142
        do_st_lr:
11143
            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11144
            break;
11145
        case SC:
11146
            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11147
            break;
11148
#if defined(TARGET_MIPS64)
11149
        case SCD:
11150
            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11151
            break;
11152
#endif
11153
        case PREF:
11154
            /* Treat as no-op */
11155
            break;
11156
        default:
11157
            MIPS_INVAL("pool32c");
11158
            generate_exception(ctx, EXCP_RI);
11159
            break;
11160
        }
11161
        break;
11162
    case ADDI32:
11163
        mips32_op = OPC_ADDI;
11164
        goto do_addi;
11165
    case ADDIU32:
11166
        mips32_op = OPC_ADDIU;
11167
    do_addi:
11168
        gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11169
        break;
11170

    
11171
        /* Logical operations */
11172
    case ORI32:
11173
        mips32_op = OPC_ORI;
11174
        goto do_logici;
11175
    case XORI32:
11176
        mips32_op = OPC_XORI;
11177
        goto do_logici;
11178
    case ANDI32:
11179
        mips32_op = OPC_ANDI;
11180
    do_logici:
11181
        gen_logic_imm(env, mips32_op, rt, rs, imm);
11182
        break;
11183

    
11184
        /* Set less than immediate */
11185
    case SLTI32:
11186
        mips32_op = OPC_SLTI;
11187
        goto do_slti;
11188
    case SLTIU32:
11189
        mips32_op = OPC_SLTIU;
11190
    do_slti:
11191
        gen_slt_imm(env, mips32_op, rt, rs, imm);
11192
        break;
11193
    case JALX32:
11194
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11195
        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11196
        *is_branch = 1;
11197
        break;
11198
    case JALS32:
11199
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11200
        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11201
        *is_branch = 1;
11202
        break;
11203
    case BEQ32:
11204
        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11205
        *is_branch = 1;
11206
        break;
11207
    case BNE32:
11208
        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11209
        *is_branch = 1;
11210
        break;
11211
    case J32:
11212
        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11213
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11214
        *is_branch = 1;
11215
        break;
11216
    case JAL32:
11217
        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11218
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11219
        *is_branch = 1;
11220
        break;
11221
        /* Floating point (COP1) */
11222
    case LWC132:
11223
        mips32_op = OPC_LWC1;
11224
        goto do_cop1;
11225
    case LDC132:
11226
        mips32_op = OPC_LDC1;
11227
        goto do_cop1;
11228
    case SWC132:
11229
        mips32_op = OPC_SWC1;
11230
        goto do_cop1;
11231
    case SDC132:
11232
        mips32_op = OPC_SDC1;
11233
    do_cop1:
11234
        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11235
        break;
11236
    case ADDIUPC:
11237
        {
11238
            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11239
            int offset = SIMM(ctx->opcode, 0, 23) << 2;
11240

    
11241
            gen_addiupc(ctx, reg, offset, 0, 0);
11242
        }
11243
        break;
11244
        /* Loads and stores */
11245
    case LB32:
11246
        mips32_op = OPC_LB;
11247
        goto do_ld;
11248
    case LBU32:
11249
        mips32_op = OPC_LBU;
11250
        goto do_ld;
11251
    case LH32:
11252
        mips32_op = OPC_LH;
11253
        goto do_ld;
11254
    case LHU32:
11255
        mips32_op = OPC_LHU;
11256
        goto do_ld;
11257
    case LW32:
11258
        mips32_op = OPC_LW;
11259
        goto do_ld;
11260
#ifdef TARGET_MIPS64
11261
    case LD32:
11262
        mips32_op = OPC_LD;
11263
        goto do_ld;
11264
    case SD32:
11265
        mips32_op = OPC_SD;
11266
        goto do_st;
11267
#endif
11268
    case SB32:
11269
        mips32_op = OPC_SB;
11270
        goto do_st;
11271
    case SH32:
11272
        mips32_op = OPC_SH;
11273
        goto do_st;
11274
    case SW32:
11275
        mips32_op = OPC_SW;
11276
        goto do_st;
11277
    do_ld:
11278
        gen_ld(env, ctx, mips32_op, rt, rs, imm);
11279
        break;
11280
    do_st:
11281
        gen_st(ctx, mips32_op, rt, rs, imm);
11282
        break;
11283
    default:
11284
        generate_exception(ctx, EXCP_RI);
11285
        break;
11286
    }
11287
}
11288

    
11289
static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11290
{
11291
    uint32_t op;
11292

    
11293
    /* make sure instructions are on a halfword boundary */
11294
    if (ctx->pc & 0x1) {
11295
        env->CP0_BadVAddr = ctx->pc;
11296
        generate_exception(ctx, EXCP_AdEL);
11297
        ctx->bstate = BS_STOP;
11298
        return 2;
11299
    }
11300

    
11301
    op = (ctx->opcode >> 10) & 0x3f;
11302
    /* Enforce properly-sized instructions in a delay slot */
11303
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11304
        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11305

    
11306
        switch (op) {
11307
        case POOL32A:
11308
        case POOL32B:
11309
        case POOL32I:
11310
        case POOL32C:
11311
        case ADDI32:
11312
        case ADDIU32:
11313
        case ORI32:
11314
        case XORI32:
11315
        case SLTI32:
11316
        case SLTIU32:
11317
        case ANDI32:
11318
        case JALX32:
11319
        case LBU32:
11320
        case LHU32:
11321
        case POOL32F:
11322
        case JALS32:
11323
        case BEQ32:
11324
        case BNE32:
11325
        case J32:
11326
        case JAL32:
11327
        case SB32:
11328
        case SH32:
11329
        case POOL32S:
11330
        case ADDIUPC:
11331
        case SWC132:
11332
        case SDC132:
11333
        case SD32:
11334
        case SW32:
11335
        case LB32:
11336
        case LH32:
11337
        case DADDIU32:
11338
        case POOL48A:           /* ??? */
11339
        case LWC132:
11340
        case LDC132:
11341
        case LD32:
11342
        case LW32:
11343
            if (bits & MIPS_HFLAG_BDS16) {
11344
                generate_exception(ctx, EXCP_RI);
11345
                /* Just stop translation; the user is confused.  */
11346
                ctx->bstate = BS_STOP;
11347
                return 2;
11348
            }
11349
            break;
11350
        case POOL16A:
11351
        case POOL16B:
11352
        case POOL16C:
11353
        case LWGP16:
11354
        case POOL16F:
11355
        case LBU16:
11356
        case LHU16:
11357
        case LWSP16:
11358
        case LW16:
11359
        case SB16:
11360
        case SH16:
11361
        case SWSP16:
11362
        case SW16:
11363
        case MOVE16:
11364
        case ANDI16:
11365
        case POOL16D:
11366
        case POOL16E:
11367
        case BEQZ16:
11368
        case BNEZ16:
11369
        case B16:
11370
        case LI16:
11371
            if (bits & MIPS_HFLAG_BDS32) {
11372
                generate_exception(ctx, EXCP_RI);
11373
                /* Just stop translation; the user is confused.  */
11374
                ctx->bstate = BS_STOP;
11375
                return 2;
11376
            }
11377
            break;
11378
        default:
11379
            break;
11380
        }
11381
    }
11382
    switch (op) {
11383
    case POOL16A:
11384
        {
11385
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11386
            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11387
            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11388
            uint32_t opc = 0;
11389

    
11390
            switch (ctx->opcode & 0x1) {
11391
            case ADDU16:
11392
                opc = OPC_ADDU;
11393
                break;
11394
            case SUBU16:
11395
                opc = OPC_SUBU;
11396
                break;
11397
            }
11398

    
11399
            gen_arith(env, ctx, opc, rd, rs1, rs2);
11400
        }
11401
        break;
11402
    case POOL16B:
11403
        {
11404
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11405
            int rs = mmreg(uMIPS_RS(ctx->opcode));
11406
            int amount = (ctx->opcode >> 1) & 0x7;
11407
            uint32_t opc = 0;
11408
            amount = amount == 0 ? 8 : amount;
11409

    
11410
            switch (ctx->opcode & 0x1) {
11411
            case SLL16:
11412
                opc = OPC_SLL;
11413
                break;
11414
            case SRL16:
11415
                opc = OPC_SRL;
11416
                break;
11417
            }
11418

    
11419
            gen_shift_imm(env, ctx, opc, rd, rs, amount);
11420
        }
11421
        break;
11422
    case POOL16C:
11423
        gen_pool16c_insn(env, ctx, is_branch);
11424
        break;
11425
    case LWGP16:
11426
        {
11427
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11428
            int rb = 28;            /* GP */
11429
            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11430

    
11431
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11432
        }
11433
        break;
11434
    case POOL16F:
11435
        if (ctx->opcode & 1) {
11436
            generate_exception(ctx, EXCP_RI);
11437
        } else {
11438
            /* MOVEP */
11439
            int enc_dest = uMIPS_RD(ctx->opcode);
11440
            int enc_rt = uMIPS_RS2(ctx->opcode);
11441
            int enc_rs = uMIPS_RS1(ctx->opcode);
11442
            int rd, rs, re, rt;
11443
            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11444
            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11445
            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11446

    
11447
            rd = rd_enc[enc_dest];
11448
            re = re_enc[enc_dest];
11449
            rs = rs_rt_enc[enc_rs];
11450
            rt = rs_rt_enc[enc_rt];
11451

    
11452
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11453
            gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11454
        }
11455
        break;
11456
    case LBU16:
11457
        {
11458
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11459
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11460
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11461
            offset = (offset == 0xf ? -1 : offset);
11462

    
11463
            gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11464
        }
11465
        break;
11466
    case LHU16:
11467
        {
11468
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11469
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11470
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11471

    
11472
            gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11473
        }
11474
        break;
11475
    case LWSP16:
11476
        {
11477
            int rd = (ctx->opcode >> 5) & 0x1f;
11478
            int rb = 29;            /* SP */
11479
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11480

    
11481
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11482
        }
11483
        break;
11484
    case LW16:
11485
        {
11486
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11487
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11488
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11489

    
11490
            gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11491
        }
11492
        break;
11493
    case SB16:
11494
        {
11495
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11496
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11497
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11498

    
11499
            gen_st(ctx, OPC_SB, rd, rb, offset);
11500
        }
11501
        break;
11502
    case SH16:
11503
        {
11504
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11505
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11506
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11507

    
11508
            gen_st(ctx, OPC_SH, rd, rb, offset);
11509
        }
11510
        break;
11511
    case SWSP16:
11512
        {
11513
            int rd = (ctx->opcode >> 5) & 0x1f;
11514
            int rb = 29;            /* SP */
11515
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11516

    
11517
            gen_st(ctx, OPC_SW, rd, rb, offset);
11518
        }
11519
        break;
11520
    case SW16:
11521
        {
11522
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11523
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11524
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11525

    
11526
            gen_st(ctx, OPC_SW, rd, rb, offset);
11527
        }
11528
        break;
11529
    case MOVE16:
11530
        {
11531
            int rd = uMIPS_RD5(ctx->opcode);
11532
            int rs = uMIPS_RS5(ctx->opcode);
11533

    
11534
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11535
        }
11536
        break;
11537
    case ANDI16:
11538
        gen_andi16(env, ctx);
11539
        break;
11540
    case POOL16D:
11541
        switch (ctx->opcode & 0x1) {
11542
        case ADDIUS5:
11543
            gen_addius5(env, ctx);
11544
            break;
11545
        case ADDIUSP:
11546
            gen_addiusp(env, ctx);
11547
            break;
11548
        }
11549
        break;
11550
    case POOL16E:
11551
        switch (ctx->opcode & 0x1) {
11552
        case ADDIUR2:
11553
            gen_addiur2(env, ctx);
11554
            break;
11555
        case ADDIUR1SP:
11556
            gen_addiur1sp(env, ctx);
11557
            break;
11558
        }
11559
        break;
11560
    case B16:
11561
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11562
                           SIMM(ctx->opcode, 0, 10) << 1);
11563
        *is_branch = 1;
11564
        break;
11565
    case BNEZ16:
11566
    case BEQZ16:
11567
        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11568
                           mmreg(uMIPS_RD(ctx->opcode)),
11569
                           0, SIMM(ctx->opcode, 0, 7) << 1);
11570
        *is_branch = 1;
11571
        break;
11572
    case LI16:
11573
        {
11574
            int reg = mmreg(uMIPS_RD(ctx->opcode));
11575
            int imm = ZIMM(ctx->opcode, 0, 7);
11576

    
11577
            imm = (imm == 0x7f ? -1 : imm);
11578
            tcg_gen_movi_tl(cpu_gpr[reg], imm);
11579
        }
11580
        break;
11581
    case RES_20:
11582
    case RES_28:
11583
    case RES_29:
11584
    case RES_30:
11585
    case RES_31:
11586
    case RES_38:
11587
    case RES_39:
11588
        generate_exception(ctx, EXCP_RI);
11589
        break;
11590
    default:
11591
        decode_micromips32_opc (env, ctx, op, is_branch);
11592
        return 4;
11593
    }
11594

    
11595
    return 2;
11596
}
11597

    
11598
/* SmartMIPS extension to MIPS32 */
11599

    
11600
#if defined(TARGET_MIPS64)
11601

    
11602
/* MDMX extension to MIPS64 */
11603

    
11604
#endif
11605

    
11606
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11607
{
11608
    int32_t offset;
11609
    int rs, rt, rd, sa;
11610
    uint32_t op, op1, op2;
11611
    int16_t imm;
11612

    
11613
    /* make sure instructions are on a word boundary */
11614
    if (ctx->pc & 0x3) {
11615
        env->CP0_BadVAddr = ctx->pc;
11616
        generate_exception(ctx, EXCP_AdEL);
11617
        return;
11618
    }
11619

    
11620
    /* Handle blikely not taken case */
11621
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11622
        int l1 = gen_new_label();
11623

    
11624
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11625
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11626
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11627
        gen_goto_tb(ctx, 1, ctx->pc + 4);
11628
        gen_set_label(l1);
11629
    }
11630

    
11631
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11632
        tcg_gen_debug_insn_start(ctx->pc);
11633

    
11634
    op = MASK_OP_MAJOR(ctx->opcode);
11635
    rs = (ctx->opcode >> 21) & 0x1f;
11636
    rt = (ctx->opcode >> 16) & 0x1f;
11637
    rd = (ctx->opcode >> 11) & 0x1f;
11638
    sa = (ctx->opcode >> 6) & 0x1f;
11639
    imm = (int16_t)ctx->opcode;
11640
    switch (op) {
11641
    case OPC_SPECIAL:
11642
        op1 = MASK_SPECIAL(ctx->opcode);
11643
        switch (op1) {
11644
        case OPC_SLL:          /* Shift with immediate */
11645
        case OPC_SRA:
11646
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11647
            break;
11648
        case OPC_SRL:
11649
            switch ((ctx->opcode >> 21) & 0x1f) {
11650
            case 1:
11651
                /* rotr is decoded as srl on non-R2 CPUs */
11652
                if (env->insn_flags & ISA_MIPS32R2) {
11653
                    op1 = OPC_ROTR;
11654
                }
11655
                /* Fallthrough */
11656
            case 0:
11657
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11658
                break;
11659
            default:
11660
                generate_exception(ctx, EXCP_RI);
11661
                break;
11662
            }
11663
            break;
11664
        case OPC_MOVN:         /* Conditional move */
11665
        case OPC_MOVZ:
11666
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11667
                                 INSN_LOONGSON2E | INSN_LOONGSON2F);
11668
            gen_cond_move(env, op1, rd, rs, rt);
11669
            break;
11670
        case OPC_ADD ... OPC_SUBU:
11671
            gen_arith(env, ctx, op1, rd, rs, rt);
11672
            break;
11673
        case OPC_SLLV:         /* Shifts */
11674
        case OPC_SRAV:
11675
            gen_shift(env, ctx, op1, rd, rs, rt);
11676
            break;
11677
        case OPC_SRLV:
11678
            switch ((ctx->opcode >> 6) & 0x1f) {
11679
            case 1:
11680
                /* rotrv is decoded as srlv on non-R2 CPUs */
11681
                if (env->insn_flags & ISA_MIPS32R2) {
11682
                    op1 = OPC_ROTRV;
11683
                }
11684
                /* Fallthrough */
11685
            case 0:
11686
                gen_shift(env, ctx, op1, rd, rs, rt);
11687
                break;
11688
            default:
11689
                generate_exception(ctx, EXCP_RI);
11690
                break;
11691
            }
11692
            break;
11693
        case OPC_SLT:          /* Set on less than */
11694
        case OPC_SLTU:
11695
            gen_slt(env, op1, rd, rs, rt);
11696
            break;
11697
        case OPC_AND:          /* Logic*/
11698
        case OPC_OR:
11699
        case OPC_NOR:
11700
        case OPC_XOR:
11701
            gen_logic(env, op1, rd, rs, rt);
11702
            break;
11703
        case OPC_MULT ... OPC_DIVU:
11704
            if (sa) {
11705
                check_insn(env, ctx, INSN_VR54XX);
11706
                op1 = MASK_MUL_VR54XX(ctx->opcode);
11707
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11708
            } else
11709
                gen_muldiv(ctx, op1, rs, rt);
11710
            break;
11711
        case OPC_JR ... OPC_JALR:
11712
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11713
            *is_branch = 1;
11714
            break;
11715
        case OPC_TGE ... OPC_TEQ: /* Traps */
11716
        case OPC_TNE:
11717
            gen_trap(ctx, op1, rs, rt, -1);
11718
            break;
11719
        case OPC_MFHI:          /* Move from HI/LO */
11720
        case OPC_MFLO:
11721
            gen_HILO(ctx, op1, rd);
11722
            break;
11723
        case OPC_MTHI:
11724
        case OPC_MTLO:          /* Move to HI/LO */
11725
            gen_HILO(ctx, op1, rs);
11726
            break;
11727
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
11728
#ifdef MIPS_STRICT_STANDARD
11729
            MIPS_INVAL("PMON / selsl");
11730
            generate_exception(ctx, EXCP_RI);
11731
#else
11732
            gen_helper_0i(pmon, sa);
11733
#endif
11734
            break;
11735
        case OPC_SYSCALL:
11736
            generate_exception(ctx, EXCP_SYSCALL);
11737
            ctx->bstate = BS_STOP;
11738
            break;
11739
        case OPC_BREAK:
11740
            generate_exception(ctx, EXCP_BREAK);
11741
            break;
11742
        case OPC_SPIM:
11743
#ifdef MIPS_STRICT_STANDARD
11744
            MIPS_INVAL("SPIM");
11745
            generate_exception(ctx, EXCP_RI);
11746
#else
11747
           /* Implemented as RI exception for now. */
11748
            MIPS_INVAL("spim (unofficial)");
11749
            generate_exception(ctx, EXCP_RI);
11750
#endif
11751
            break;
11752
        case OPC_SYNC:
11753
            /* Treat as NOP. */
11754
            break;
11755

    
11756
        case OPC_MOVCI:
11757
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11758
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11759
                check_cp1_enabled(ctx);
11760
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11761
                          (ctx->opcode >> 16) & 1);
11762
            } else {
11763
                generate_exception_err(ctx, EXCP_CpU, 1);
11764
            }
11765
            break;
11766

    
11767
#if defined(TARGET_MIPS64)
11768
       /* MIPS64 specific opcodes */
11769
        case OPC_DSLL:
11770
        case OPC_DSRA:
11771
        case OPC_DSLL32:
11772
        case OPC_DSRA32:
11773
            check_insn(env, ctx, ISA_MIPS3);
11774
            check_mips_64(ctx);
11775
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11776
            break;
11777
        case OPC_DSRL:
11778
            switch ((ctx->opcode >> 21) & 0x1f) {
11779
            case 1:
11780
                /* drotr is decoded as dsrl on non-R2 CPUs */
11781
                if (env->insn_flags & ISA_MIPS32R2) {
11782
                    op1 = OPC_DROTR;
11783
                }
11784
                /* Fallthrough */
11785
            case 0:
11786
                check_insn(env, ctx, ISA_MIPS3);
11787
                check_mips_64(ctx);
11788
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11789
                break;
11790
            default:
11791
                generate_exception(ctx, EXCP_RI);
11792
                break;
11793
            }
11794
            break;
11795
        case OPC_DSRL32:
11796
            switch ((ctx->opcode >> 21) & 0x1f) {
11797
            case 1:
11798
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11799
                if (env->insn_flags & ISA_MIPS32R2) {
11800
                    op1 = OPC_DROTR32;
11801
                }
11802
                /* Fallthrough */
11803
            case 0:
11804
                check_insn(env, ctx, ISA_MIPS3);
11805
                check_mips_64(ctx);
11806
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11807
                break;
11808
            default:
11809
                generate_exception(ctx, EXCP_RI);
11810
                break;
11811
            }
11812
            break;
11813
        case OPC_DADD ... OPC_DSUBU:
11814
            check_insn(env, ctx, ISA_MIPS3);
11815
            check_mips_64(ctx);
11816
            gen_arith(env, ctx, op1, rd, rs, rt);
11817
            break;
11818
        case OPC_DSLLV:
11819
        case OPC_DSRAV:
11820
            check_insn(env, ctx, ISA_MIPS3);
11821
            check_mips_64(ctx);
11822
            gen_shift(env, ctx, op1, rd, rs, rt);
11823
            break;
11824
        case OPC_DSRLV:
11825
            switch ((ctx->opcode >> 6) & 0x1f) {
11826
            case 1:
11827
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
11828
                if (env->insn_flags & ISA_MIPS32R2) {
11829
                    op1 = OPC_DROTRV;
11830
                }
11831
                /* Fallthrough */
11832
            case 0:
11833
                check_insn(env, ctx, ISA_MIPS3);
11834
                check_mips_64(ctx);
11835
                gen_shift(env, ctx, op1, rd, rs, rt);
11836
                break;
11837
            default:
11838
                generate_exception(ctx, EXCP_RI);
11839
                break;
11840
            }
11841
            break;
11842
        case OPC_DMULT ... OPC_DDIVU:
11843
            check_insn(env, ctx, ISA_MIPS3);
11844
            check_mips_64(ctx);
11845
            gen_muldiv(ctx, op1, rs, rt);
11846
            break;
11847
#endif
11848
        default:            /* Invalid */
11849
            MIPS_INVAL("special");
11850
            generate_exception(ctx, EXCP_RI);
11851
            break;
11852
        }
11853
        break;
11854
    case OPC_SPECIAL2:
11855
        op1 = MASK_SPECIAL2(ctx->opcode);
11856
        switch (op1) {
11857
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11858
        case OPC_MSUB ... OPC_MSUBU:
11859
            check_insn(env, ctx, ISA_MIPS32);
11860
            gen_muldiv(ctx, op1, rs, rt);
11861
            break;
11862
        case OPC_MUL:
11863
            gen_arith(env, ctx, op1, rd, rs, rt);
11864
            break;
11865
        case OPC_CLO:
11866
        case OPC_CLZ:
11867
            check_insn(env, ctx, ISA_MIPS32);
11868
            gen_cl(ctx, op1, rd, rs);
11869
            break;
11870
        case OPC_SDBBP:
11871
            /* XXX: not clear which exception should be raised
11872
             *      when in debug mode...
11873
             */
11874
            check_insn(env, ctx, ISA_MIPS32);
11875
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11876
                generate_exception(ctx, EXCP_DBp);
11877
            } else {
11878
                generate_exception(ctx, EXCP_DBp);
11879
            }
11880
            /* Treat as NOP. */
11881
            break;
11882
        case OPC_DIV_G_2F:
11883
        case OPC_DIVU_G_2F:
11884
        case OPC_MULT_G_2F:
11885
        case OPC_MULTU_G_2F:
11886
        case OPC_MOD_G_2F:
11887
        case OPC_MODU_G_2F:
11888
            check_insn(env, ctx, INSN_LOONGSON2F);
11889
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11890
            break;
11891
#if defined(TARGET_MIPS64)
11892
        case OPC_DCLO:
11893
        case OPC_DCLZ:
11894
            check_insn(env, ctx, ISA_MIPS64);
11895
            check_mips_64(ctx);
11896
            gen_cl(ctx, op1, rd, rs);
11897
            break;
11898
        case OPC_DMULT_G_2F:
11899
        case OPC_DMULTU_G_2F:
11900
        case OPC_DDIV_G_2F:
11901
        case OPC_DDIVU_G_2F:
11902
        case OPC_DMOD_G_2F:
11903
        case OPC_DMODU_G_2F:
11904
            check_insn(env, ctx, INSN_LOONGSON2F);
11905
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11906
            break;
11907
#endif
11908
        default:            /* Invalid */
11909
            MIPS_INVAL("special2");
11910
            generate_exception(ctx, EXCP_RI);
11911
            break;
11912
        }
11913
        break;
11914
    case OPC_SPECIAL3:
11915
        op1 = MASK_SPECIAL3(ctx->opcode);
11916
        switch (op1) {
11917
        case OPC_EXT:
11918
        case OPC_INS:
11919
            check_insn(env, ctx, ISA_MIPS32R2);
11920
            gen_bitops(ctx, op1, rt, rs, sa, rd);
11921
            break;
11922
        case OPC_BSHFL:
11923
            check_insn(env, ctx, ISA_MIPS32R2);
11924
            op2 = MASK_BSHFL(ctx->opcode);
11925
            gen_bshfl(ctx, op2, rt, rd);
11926
            break;
11927
        case OPC_RDHWR:
11928
            gen_rdhwr(env, ctx, rt, rd);
11929
            break;
11930
        case OPC_FORK:
11931
            check_insn(env, ctx, ASE_MT);
11932
            {
11933
                TCGv t0 = tcg_temp_new();
11934
                TCGv t1 = tcg_temp_new();
11935

    
11936
                gen_load_gpr(t0, rt);
11937
                gen_load_gpr(t1, rs);
11938
                gen_helper_fork(t0, t1);
11939
                tcg_temp_free(t0);
11940
                tcg_temp_free(t1);
11941
            }
11942
            break;
11943
        case OPC_YIELD:
11944
            check_insn(env, ctx, ASE_MT);
11945
            {
11946
                TCGv t0 = tcg_temp_new();
11947

    
11948
                save_cpu_state(ctx, 1);
11949
                gen_load_gpr(t0, rs);
11950
                gen_helper_yield(t0, t0);
11951
                gen_store_gpr(t0, rd);
11952
                tcg_temp_free(t0);
11953
            }
11954
            break;
11955
        case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
11956
        case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
11957
        case OPC_MOD_G_2E ... OPC_MODU_G_2E:
11958
            check_insn(env, ctx, INSN_LOONGSON2E);
11959
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11960
            break;
11961
#if defined(TARGET_MIPS64)
11962
        case OPC_DEXTM ... OPC_DEXT:
11963
        case OPC_DINSM ... OPC_DINS:
11964
            check_insn(env, ctx, ISA_MIPS64R2);
11965
            check_mips_64(ctx);
11966
            gen_bitops(ctx, op1, rt, rs, sa, rd);
11967
            break;
11968
        case OPC_DBSHFL:
11969
            check_insn(env, ctx, ISA_MIPS64R2);
11970
            check_mips_64(ctx);
11971
            op2 = MASK_DBSHFL(ctx->opcode);
11972
            gen_bshfl(ctx, op2, rt, rd);
11973
            break;
11974
        case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
11975
        case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
11976
        case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
11977
            check_insn(env, ctx, INSN_LOONGSON2E);
11978
            gen_loongson_integer(ctx, op1, rd, rs, rt);
11979
            break;
11980
#endif
11981
        default:            /* Invalid */
11982
            MIPS_INVAL("special3");
11983
            generate_exception(ctx, EXCP_RI);
11984
            break;
11985
        }
11986
        break;
11987
    case OPC_REGIMM:
11988
        op1 = MASK_REGIMM(ctx->opcode);
11989
        switch (op1) {
11990
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
11991
        case OPC_BLTZAL ... OPC_BGEZALL:
11992
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
11993
            *is_branch = 1;
11994
            break;
11995
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
11996
        case OPC_TNEI:
11997
            gen_trap(ctx, op1, rs, -1, imm);
11998
            break;
11999
        case OPC_SYNCI:
12000
            check_insn(env, ctx, ISA_MIPS32R2);
12001
            /* Treat as NOP. */
12002
            break;
12003
        default:            /* Invalid */
12004
            MIPS_INVAL("regimm");
12005
            generate_exception(ctx, EXCP_RI);
12006
            break;
12007
        }
12008
        break;
12009
    case OPC_CP0:
12010
        check_cp0_enabled(ctx);
12011
        op1 = MASK_CP0(ctx->opcode);
12012
        switch (op1) {
12013
        case OPC_MFC0:
12014
        case OPC_MTC0:
12015
        case OPC_MFTR:
12016
        case OPC_MTTR:
12017
#if defined(TARGET_MIPS64)
12018
        case OPC_DMFC0:
12019
        case OPC_DMTC0:
12020
#endif
12021
#ifndef CONFIG_USER_ONLY
12022
            gen_cp0(env, ctx, op1, rt, rd);
12023
#endif /* !CONFIG_USER_ONLY */
12024
            break;
12025
        case OPC_C0_FIRST ... OPC_C0_LAST:
12026
#ifndef CONFIG_USER_ONLY
12027
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12028
#endif /* !CONFIG_USER_ONLY */
12029
            break;
12030
        case OPC_MFMC0:
12031
#ifndef CONFIG_USER_ONLY
12032
            {
12033
                TCGv t0 = tcg_temp_new();
12034

    
12035
                op2 = MASK_MFMC0(ctx->opcode);
12036
                switch (op2) {
12037
                case OPC_DMT:
12038
                    check_insn(env, ctx, ASE_MT);
12039
                    gen_helper_dmt(t0);
12040
                    gen_store_gpr(t0, rt);
12041
                    break;
12042
                case OPC_EMT:
12043
                    check_insn(env, ctx, ASE_MT);
12044
                    gen_helper_emt(t0);
12045
                    gen_store_gpr(t0, rt);
12046
                    break;
12047
                case OPC_DVPE:
12048
                    check_insn(env, ctx, ASE_MT);
12049
                    gen_helper_dvpe(t0);
12050
                    gen_store_gpr(t0, rt);
12051
                    break;
12052
                case OPC_EVPE:
12053
                    check_insn(env, ctx, ASE_MT);
12054
                    gen_helper_evpe(t0);
12055
                    gen_store_gpr(t0, rt);
12056
                    break;
12057
                case OPC_DI:
12058
                    check_insn(env, ctx, ISA_MIPS32R2);
12059
                    save_cpu_state(ctx, 1);
12060
                    gen_helper_di(t0);
12061
                    gen_store_gpr(t0, rt);
12062
                    /* Stop translation as we may have switched the execution mode */
12063
                    ctx->bstate = BS_STOP;
12064
                    break;
12065
                case OPC_EI:
12066
                    check_insn(env, ctx, ISA_MIPS32R2);
12067
                    save_cpu_state(ctx, 1);
12068
                    gen_helper_ei(t0);
12069
                    gen_store_gpr(t0, rt);
12070
                    /* Stop translation as we may have switched the execution mode */
12071
                    ctx->bstate = BS_STOP;
12072
                    break;
12073
                default:            /* Invalid */
12074
                    MIPS_INVAL("mfmc0");
12075
                    generate_exception(ctx, EXCP_RI);
12076
                    break;
12077
                }
12078
                tcg_temp_free(t0);
12079
            }
12080
#endif /* !CONFIG_USER_ONLY */
12081
            break;
12082
        case OPC_RDPGPR:
12083
            check_insn(env, ctx, ISA_MIPS32R2);
12084
            gen_load_srsgpr(rt, rd);
12085
            break;
12086
        case OPC_WRPGPR:
12087
            check_insn(env, ctx, ISA_MIPS32R2);
12088
            gen_store_srsgpr(rt, rd);
12089
            break;
12090
        default:
12091
            MIPS_INVAL("cp0");
12092
            generate_exception(ctx, EXCP_RI);
12093
            break;
12094
        }
12095
        break;
12096
    case OPC_ADDI: /* Arithmetic with immediate opcode */
12097
    case OPC_ADDIU:
12098
         gen_arith_imm(env, ctx, op, rt, rs, imm);
12099
         break;
12100
    case OPC_SLTI: /* Set on less than with immediate opcode */
12101
    case OPC_SLTIU:
12102
         gen_slt_imm(env, op, rt, rs, imm);
12103
         break;
12104
    case OPC_ANDI: /* Arithmetic with immediate opcode */
12105
    case OPC_LUI:
12106
    case OPC_ORI:
12107
    case OPC_XORI:
12108
         gen_logic_imm(env, op, rt, rs, imm);
12109
         break;
12110
    case OPC_J ... OPC_JAL: /* Jump */
12111
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12112
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
12113
         *is_branch = 1;
12114
         break;
12115
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
12116
    case OPC_BEQL ... OPC_BGTZL:
12117
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12118
         *is_branch = 1;
12119
         break;
12120
    case OPC_LB ... OPC_LWR: /* Load and stores */
12121
    case OPC_LL:
12122
         gen_ld(env, ctx, op, rt, rs, imm);
12123
         break;
12124
    case OPC_SB ... OPC_SW:
12125
    case OPC_SWR:
12126
         gen_st(ctx, op, rt, rs, imm);
12127
         break;
12128
    case OPC_SC:
12129
         gen_st_cond(ctx, op, rt, rs, imm);
12130
         break;
12131
    case OPC_CACHE:
12132
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12133
        /* Treat as NOP. */
12134
        break;
12135
    case OPC_PREF:
12136
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12137
        /* Treat as NOP. */
12138
        break;
12139

    
12140
    /* Floating point (COP1). */
12141
    case OPC_LWC1:
12142
    case OPC_LDC1:
12143
    case OPC_SWC1:
12144
    case OPC_SDC1:
12145
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12146
        break;
12147

    
12148
    case OPC_CP1:
12149
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12150
            check_cp1_enabled(ctx);
12151
            op1 = MASK_CP1(ctx->opcode);
12152
            switch (op1) {
12153
            case OPC_MFHC1:
12154
            case OPC_MTHC1:
12155
                check_insn(env, ctx, ISA_MIPS32R2);
12156
            case OPC_MFC1:
12157
            case OPC_CFC1:
12158
            case OPC_MTC1:
12159
            case OPC_CTC1:
12160
                gen_cp1(ctx, op1, rt, rd);
12161
                break;
12162
#if defined(TARGET_MIPS64)
12163
            case OPC_DMFC1:
12164
            case OPC_DMTC1:
12165
                check_insn(env, ctx, ISA_MIPS3);
12166
                gen_cp1(ctx, op1, rt, rd);
12167
                break;
12168
#endif
12169
            case OPC_BC1ANY2:
12170
            case OPC_BC1ANY4:
12171
                check_cop1x(ctx);
12172
                check_insn(env, ctx, ASE_MIPS3D);
12173
                /* fall through */
12174
            case OPC_BC1:
12175
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12176
                                    (rt >> 2) & 0x7, imm << 2);
12177
                *is_branch = 1;
12178
                break;
12179
            case OPC_S_FMT:
12180
            case OPC_D_FMT:
12181
            case OPC_W_FMT:
12182
            case OPC_L_FMT:
12183
            case OPC_PS_FMT:
12184
                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12185
                           (imm >> 8) & 0x7);
12186
                break;
12187
            default:
12188
                MIPS_INVAL("cp1");
12189
                generate_exception (ctx, EXCP_RI);
12190
                break;
12191
            }
12192
        } else {
12193
            generate_exception_err(ctx, EXCP_CpU, 1);
12194
        }
12195
        break;
12196

    
12197
    /* COP2.  */
12198
    case OPC_LWC2:
12199
    case OPC_LDC2:
12200
    case OPC_SWC2:
12201
    case OPC_SDC2:
12202
    case OPC_CP2:
12203
        /* COP2: Not implemented. */
12204
        generate_exception_err(ctx, EXCP_CpU, 2);
12205
        break;
12206

    
12207
    case OPC_CP3:
12208
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12209
            check_cp1_enabled(ctx);
12210
            op1 = MASK_CP3(ctx->opcode);
12211
            switch (op1) {
12212
            case OPC_LWXC1:
12213
            case OPC_LDXC1:
12214
            case OPC_LUXC1:
12215
            case OPC_SWXC1:
12216
            case OPC_SDXC1:
12217
            case OPC_SUXC1:
12218
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12219
                break;
12220
            case OPC_PREFX:
12221
                /* Treat as NOP. */
12222
                break;
12223
            case OPC_ALNV_PS:
12224
            case OPC_MADD_S:
12225
            case OPC_MADD_D:
12226
            case OPC_MADD_PS:
12227
            case OPC_MSUB_S:
12228
            case OPC_MSUB_D:
12229
            case OPC_MSUB_PS:
12230
            case OPC_NMADD_S:
12231
            case OPC_NMADD_D:
12232
            case OPC_NMADD_PS:
12233
            case OPC_NMSUB_S:
12234
            case OPC_NMSUB_D:
12235
            case OPC_NMSUB_PS:
12236
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12237
                break;
12238
            default:
12239
                MIPS_INVAL("cp3");
12240
                generate_exception (ctx, EXCP_RI);
12241
                break;
12242
            }
12243
        } else {
12244
            generate_exception_err(ctx, EXCP_CpU, 1);
12245
        }
12246
        break;
12247

    
12248
#if defined(TARGET_MIPS64)
12249
    /* MIPS64 opcodes */
12250
    case OPC_LWU:
12251
    case OPC_LDL ... OPC_LDR:
12252
    case OPC_LLD:
12253
    case OPC_LD:
12254
        check_insn(env, ctx, ISA_MIPS3);
12255
        check_mips_64(ctx);
12256
        gen_ld(env, ctx, op, rt, rs, imm);
12257
        break;
12258
    case OPC_SDL ... OPC_SDR:
12259
    case OPC_SD:
12260
        check_insn(env, ctx, ISA_MIPS3);
12261
        check_mips_64(ctx);
12262
        gen_st(ctx, op, rt, rs, imm);
12263
        break;
12264
    case OPC_SCD:
12265
        check_insn(env, ctx, ISA_MIPS3);
12266
        check_mips_64(ctx);
12267
        gen_st_cond(ctx, op, rt, rs, imm);
12268
        break;
12269
    case OPC_DADDI:
12270
    case OPC_DADDIU:
12271
        check_insn(env, ctx, ISA_MIPS3);
12272
        check_mips_64(ctx);
12273
        gen_arith_imm(env, ctx, op, rt, rs, imm);
12274
        break;
12275
#endif
12276
    case OPC_JALX:
12277
        check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12278
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12279
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
12280
        *is_branch = 1;
12281
        break;
12282
    case OPC_MDMX:
12283
        check_insn(env, ctx, ASE_MDMX);
12284
        /* MDMX: Not implemented. */
12285
    default:            /* Invalid */
12286
        MIPS_INVAL("major opcode");
12287
        generate_exception(ctx, EXCP_RI);
12288
        break;
12289
    }
12290
}
12291

    
12292
static inline void
12293
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12294
                                int search_pc)
12295
{
12296
    DisasContext ctx;
12297
    target_ulong pc_start;
12298
    uint16_t *gen_opc_end;
12299
    CPUBreakpoint *bp;
12300
    int j, lj = -1;
12301
    int num_insns;
12302
    int max_insns;
12303
    int insn_bytes;
12304
    int is_branch;
12305

    
12306
    if (search_pc)
12307
        qemu_log("search pc %d\n", search_pc);
12308

    
12309
    pc_start = tb->pc;
12310
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12311
    ctx.pc = pc_start;
12312
    ctx.saved_pc = -1;
12313
    ctx.singlestep_enabled = env->singlestep_enabled;
12314
    ctx.tb = tb;
12315
    ctx.bstate = BS_NONE;
12316
    /* Restore delay slot state from the tb context.  */
12317
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12318
    restore_cpu_state(env, &ctx);
12319
#ifdef CONFIG_USER_ONLY
12320
        ctx.mem_idx = MIPS_HFLAG_UM;
12321
#else
12322
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12323
#endif
12324
    num_insns = 0;
12325
    max_insns = tb->cflags & CF_COUNT_MASK;
12326
    if (max_insns == 0)
12327
        max_insns = CF_COUNT_MASK;
12328
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12329
    gen_icount_start();
12330
    while (ctx.bstate == BS_NONE) {
12331
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12332
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12333
                if (bp->pc == ctx.pc) {
12334
                    save_cpu_state(&ctx, 1);
12335
                    ctx.bstate = BS_BRANCH;
12336
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
12337
                    /* Include the breakpoint location or the tb won't
12338
                     * be flushed when it must be.  */
12339
                    ctx.pc += 4;
12340
                    goto done_generating;
12341
                }
12342
            }
12343
        }
12344

    
12345
        if (search_pc) {
12346
            j = gen_opc_ptr - gen_opc_buf;
12347
            if (lj < j) {
12348
                lj++;
12349
                while (lj < j)
12350
                    gen_opc_instr_start[lj++] = 0;
12351
            }
12352
            gen_opc_pc[lj] = ctx.pc;
12353
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12354
            gen_opc_instr_start[lj] = 1;
12355
            gen_opc_icount[lj] = num_insns;
12356
        }
12357
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12358
            gen_io_start();
12359

    
12360
        is_branch = 0;
12361
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12362
            ctx.opcode = ldl_code(ctx.pc);
12363
            insn_bytes = 4;
12364
            decode_opc(env, &ctx, &is_branch);
12365
        } else if (env->insn_flags & ASE_MICROMIPS) {
12366
            ctx.opcode = lduw_code(ctx.pc);
12367
            insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12368
        } else if (env->insn_flags & ASE_MIPS16) {
12369
            ctx.opcode = lduw_code(ctx.pc);
12370
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12371
        } else {
12372
            generate_exception(&ctx, EXCP_RI);
12373
            ctx.bstate = BS_STOP;
12374
            break;
12375
        }
12376
        if (!is_branch) {
12377
            handle_delay_slot(env, &ctx, insn_bytes);
12378
        }
12379
        ctx.pc += insn_bytes;
12380

    
12381
        num_insns++;
12382

    
12383
        /* Execute a branch and its delay slot as a single instruction.
12384
           This is what GDB expects and is consistent with what the
12385
           hardware does (e.g. if a delay slot instruction faults, the
12386
           reported PC is the PC of the branch).  */
12387
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12388
            break;
12389

    
12390
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12391
            break;
12392

    
12393
        if (gen_opc_ptr >= gen_opc_end)
12394
            break;
12395

    
12396
        if (num_insns >= max_insns)
12397
            break;
12398

    
12399
        if (singlestep)
12400
            break;
12401
    }
12402
    if (tb->cflags & CF_LAST_IO)
12403
        gen_io_end();
12404
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12405
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12406
        gen_helper_0i(raise_exception, EXCP_DEBUG);
12407
    } else {
12408
        switch (ctx.bstate) {
12409
        case BS_STOP:
12410
            gen_goto_tb(&ctx, 0, ctx.pc);
12411
            break;
12412
        case BS_NONE:
12413
            save_cpu_state(&ctx, 0);
12414
            gen_goto_tb(&ctx, 0, ctx.pc);
12415
            break;
12416
        case BS_EXCP:
12417
            tcg_gen_exit_tb(0);
12418
            break;
12419
        case BS_BRANCH:
12420
        default:
12421
            break;
12422
        }
12423
    }
12424
done_generating:
12425
    gen_icount_end(tb, num_insns);
12426
    *gen_opc_ptr = INDEX_op_end;
12427
    if (search_pc) {
12428
        j = gen_opc_ptr - gen_opc_buf;
12429
        lj++;
12430
        while (lj <= j)
12431
            gen_opc_instr_start[lj++] = 0;
12432
    } else {
12433
        tb->size = ctx.pc - pc_start;
12434
        tb->icount = num_insns;
12435
    }
12436
#ifdef DEBUG_DISAS
12437
    LOG_DISAS("\n");
12438
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12439
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
12440
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
12441
        qemu_log("\n");
12442
    }
12443
#endif
12444
}
12445

    
12446
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12447
{
12448
    gen_intermediate_code_internal(env, tb, 0);
12449
}
12450

    
12451
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12452
{
12453
    gen_intermediate_code_internal(env, tb, 1);
12454
}
12455

    
12456
static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
12457
                           int flags)
12458
{
12459
    int i;
12460
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12461

    
12462
#define printfpr(fp)                                                    \
12463
    do {                                                                \
12464
        if (is_fpu64)                                                   \
12465
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12466
                        " fd:%13g fs:%13g psu: %13g\n",                 \
12467
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
12468
                        (double)(fp)->fd,                               \
12469
                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
12470
                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
12471
        else {                                                          \
12472
            fpr_t tmp;                                                  \
12473
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
12474
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
12475
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12476
                        " fd:%13g fs:%13g psu:%13g\n",                  \
12477
                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
12478
                        (double)tmp.fd,                                 \
12479
                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
12480
                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
12481
        }                                                               \
12482
    } while(0)
12483

    
12484

    
12485
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
12486
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12487
                get_float_exception_flags(&env->active_fpu.fp_status));
12488
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12489
        fpu_fprintf(f, "%3s: ", fregnames[i]);
12490
        printfpr(&env->active_fpu.fpr[i]);
12491
    }
12492

    
12493
#undef printfpr
12494
}
12495

    
12496
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12497
/* Debug help: The architecture requires 32bit code to maintain proper
12498
   sign-extended values on 64bit machines.  */
12499

    
12500
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12501

    
12502
static void
12503
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12504
                                fprintf_function cpu_fprintf,
12505
                                int flags)
12506
{
12507
    int i;
12508

    
12509
    if (!SIGN_EXT_P(env->active_tc.PC))
12510
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12511
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
12512
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12513
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
12514
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12515
    if (!SIGN_EXT_P(env->btarget))
12516
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12517

    
12518
    for (i = 0; i < 32; i++) {
12519
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12520
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12521
    }
12522

    
12523
    if (!SIGN_EXT_P(env->CP0_EPC))
12524
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12525
    if (!SIGN_EXT_P(env->lladdr))
12526
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12527
}
12528
#endif
12529

    
12530
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
12531
                     int flags)
12532
{
12533
    int i;
12534

    
12535
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12536
                " LO=0x" TARGET_FMT_lx " ds %04x "
12537
                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12538
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12539
                env->hflags, env->btarget, env->bcond);
12540
    for (i = 0; i < 32; i++) {
12541
        if ((i & 3) == 0)
12542
            cpu_fprintf(f, "GPR%02d:", i);
12543
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12544
        if ((i & 3) == 3)
12545
            cpu_fprintf(f, "\n");
12546
    }
12547

    
12548
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
12549
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12550
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12551
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
12552
    if (env->hflags & MIPS_HFLAG_FPU)
12553
        fpu_dump_state(env, f, cpu_fprintf, flags);
12554
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12555
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12556
#endif
12557
}
12558

    
12559
static void mips_tcg_init(void)
12560
{
12561
    int i;
12562
    static int inited;
12563

    
12564
    /* Initialize various static tables. */
12565
    if (inited)
12566
        return;
12567

    
12568
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12569
    TCGV_UNUSED(cpu_gpr[0]);
12570
    for (i = 1; i < 32; i++)
12571
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12572
                                        offsetof(CPUState, active_tc.gpr[i]),
12573
                                        regnames[i]);
12574
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
12575
                                offsetof(CPUState, active_tc.PC), "PC");
12576
    for (i = 0; i < MIPS_DSP_ACC; i++) {
12577
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12578
                                       offsetof(CPUState, active_tc.HI[i]),
12579
                                       regnames_HI[i]);
12580
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12581
                                       offsetof(CPUState, active_tc.LO[i]),
12582
                                       regnames_LO[i]);
12583
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12584
                                        offsetof(CPUState, active_tc.ACX[i]),
12585
                                        regnames_ACX[i]);
12586
    }
12587
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12588
                                     offsetof(CPUState, active_tc.DSPControl),
12589
                                     "DSPControl");
12590
    bcond = tcg_global_mem_new(TCG_AREG0,
12591
                               offsetof(CPUState, bcond), "bcond");
12592
    btarget = tcg_global_mem_new(TCG_AREG0,
12593
                                 offsetof(CPUState, btarget), "btarget");
12594
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
12595
                                    offsetof(CPUState, hflags), "hflags");
12596

    
12597
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12598
                                      offsetof(CPUState, active_fpu.fcr0),
12599
                                      "fcr0");
12600
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12601
                                       offsetof(CPUState, active_fpu.fcr31),
12602
                                       "fcr31");
12603

    
12604
    /* register helpers */
12605
#define GEN_HELPER 2
12606
#include "helper.h"
12607

    
12608
    inited = 1;
12609
}
12610

    
12611
#include "translate_init.c"
12612

    
12613
CPUMIPSState *cpu_mips_init (const char *cpu_model)
12614
{
12615
    CPUMIPSState *env;
12616
    const mips_def_t *def;
12617

    
12618
    def = cpu_mips_find_by_name(cpu_model);
12619
    if (!def)
12620
        return NULL;
12621
    env = g_malloc0(sizeof(CPUMIPSState));
12622
    env->cpu_model = def;
12623
    env->cpu_model_str = cpu_model;
12624

    
12625
    cpu_exec_init(env);
12626
#ifndef CONFIG_USER_ONLY
12627
    mmu_init(env, def);
12628
#endif
12629
    fpu_init(env, def);
12630
    mvp_init(env, def);
12631
    mips_tcg_init();
12632
    cpu_reset(env);
12633
    qemu_init_vcpu(env);
12634
    return env;
12635
}
12636

    
12637
void cpu_reset (CPUMIPSState *env)
12638
{
12639
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12640
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12641
        log_cpu_state(env, 0);
12642
    }
12643

    
12644
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12645
    tlb_flush(env, 1);
12646

    
12647
    /* Reset registers to their default values */
12648
    env->CP0_PRid = env->cpu_model->CP0_PRid;
12649
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
12650
#ifdef TARGET_WORDS_BIGENDIAN
12651
    env->CP0_Config0 |= (1 << CP0C0_BE);
12652
#endif
12653
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
12654
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
12655
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
12656
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
12657
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
12658
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12659
                                 << env->cpu_model->CP0_LLAddr_shift;
12660
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12661
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12662
    env->CCRes = env->cpu_model->CCRes;
12663
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12664
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12665
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12666
    env->current_tc = 0;
12667
    env->SEGBITS = env->cpu_model->SEGBITS;
12668
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12669
#if defined(TARGET_MIPS64)
12670
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12671
        env->SEGMask |= 3ULL << 62;
12672
    }
12673
#endif
12674
    env->PABITS = env->cpu_model->PABITS;
12675
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12676
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12677
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12678
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12679
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12680
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12681
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12682
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12683
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12684
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12685
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12686
    env->insn_flags = env->cpu_model->insn_flags;
12687

    
12688
#if defined(CONFIG_USER_ONLY)
12689
    env->hflags = MIPS_HFLAG_UM;
12690
    /* Enable access to the SYNCI_Step register.  */
12691
    env->CP0_HWREna |= (1 << 1);
12692
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12693
        env->hflags |= MIPS_HFLAG_FPU;
12694
    }
12695
#ifdef TARGET_MIPS64
12696
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12697
        env->hflags |= MIPS_HFLAG_F64;
12698
    }
12699
#endif
12700
#else
12701
    if (env->hflags & MIPS_HFLAG_BMASK) {
12702
        /* If the exception was raised from a delay slot,
12703
           come back to the jump.  */
12704
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
12705
    } else {
12706
        env->CP0_ErrorEPC = env->active_tc.PC;
12707
    }
12708
    env->active_tc.PC = (int32_t)0xBFC00000;
12709
    env->CP0_Random = env->tlb->nb_tlb - 1;
12710
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
12711
    env->CP0_Wired = 0;
12712
    env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12713
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12714
    /* vectored interrupts not implemented, timer on int 7,
12715
       no performance counters. */
12716
    env->CP0_IntCtl = 0xe0000000;
12717
    {
12718
        int i;
12719

    
12720
        for (i = 0; i < 7; i++) {
12721
            env->CP0_WatchLo[i] = 0;
12722
            env->CP0_WatchHi[i] = 0x80000000;
12723
        }
12724
        env->CP0_WatchLo[7] = 0;
12725
        env->CP0_WatchHi[7] = 0;
12726
    }
12727
    /* Count register increments in debug mode, EJTAG version 1 */
12728
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12729
    env->hflags = MIPS_HFLAG_CP0;
12730
#endif
12731
#if defined(TARGET_MIPS64)
12732
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12733
        env->hflags |= MIPS_HFLAG_64;
12734
    }
12735
#endif
12736
    env->exception_index = EXCP_NONE;
12737
}
12738

    
12739
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
12740
{
12741
    env->active_tc.PC = gen_opc_pc[pc_pos];
12742
    env->hflags &= ~MIPS_HFLAG_BMASK;
12743
    env->hflags |= gen_opc_hflags[pc_pos];
12744
}