Statistics
| Branch: | Revision:

root / target-mips / translate.c @ a825aefb

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 "exec-all.h"
31
#include "disas.h"
32
#include "tcg-op.h"
33
#include "qemu-common.h"
34

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

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

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
490
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
491

    
492
#include "gen-icount.h"
493

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1028
        pc -= branch_bytes;
1029
    }
1030

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

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

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

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

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

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

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

    
1222

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

    
1230
    t0 = tcg_temp_local_new();
1231

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3769
    if (use_icount)
3770
        gen_io_start();
3771

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

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

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

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

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

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

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

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

    
4935
    if (use_icount)
4936
        gen_io_start();
4937

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6091
/* Coprocessor 1 (FPU) */
6092

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6415

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7375
            gen_load_fpr64(ctx, fp0, fs);
7376
            gen_store_fpr64(ctx, fp0, fd);
7377
            tcg_temp_free_i64(fp0);
7378
        }
7379
        opn = "mov.ps";
7380
        break;
7381
    case OPC_NEG_PS:
7382
        check_cp1_64bitmode(ctx);
7383
        {
7384
            TCGv_i64 fp0 = tcg_temp_new_i64();
7385

    
7386
            gen_load_fpr64(ctx, fp0, fs);
7387
            gen_helper_float_chs_ps(fp0, fp0);
7388
            gen_store_fpr64(ctx, fp0, fd);
7389
            tcg_temp_free_i64(fp0);
7390
        }
7391
        opn = "neg.ps";
7392
        break;
7393
    case OPC_MOVCF_PS:
7394
        check_cp1_64bitmode(ctx);
7395
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7396
        opn = "movcf.ps";
7397
        break;
7398
    case OPC_MOVZ_PS:
7399
        check_cp1_64bitmode(ctx);
7400
        {
7401
            int l1 = gen_new_label();
7402
            TCGv_i64 fp0;
7403

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8264
  return map[r];
8265
}
8266

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

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

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

    
8329
    gen_load_gpr(t0, 29);
8330

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8532
    t0 = tcg_temp_new();
8533

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

    
8540
    tcg_temp_free(t0);
8541
}
8542

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

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

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

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

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

    
8785
    return 4;
8786
}
8787

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

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

    
8805
    n_bytes = 2;
8806

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
9235
    return n_bytes;
9236
}
9237

    
9238
/* microMIPS extension to MIPS32 */
9239

    
9240
/* microMIPS32 major opcodes */
9241

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
9500
    MUL_FMT = 0x2,
9501

    
9502
    DIV_FMT = 0x3,
9503

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

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

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

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

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

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

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

    
9529
    MULR_PS = 0x7,
9530

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

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

    
9546
    POOL32FXF = 0x3b,
9547

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
9676
    return map[r];
9677
}
9678

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

    
9684
    return map[r];
9685
}
9686

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
9766
    t0 = tcg_temp_new();
9767

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

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

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

    
9796

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

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

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

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

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

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

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

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

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

    
9930
    gen_load_gpr(t0, base);
9931

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
11596
    return 2;
11597
}
11598

    
11599
/* SmartMIPS extension to MIPS32 */
11600

    
11601
#if defined(TARGET_MIPS64)
11602

    
11603
/* MDMX extension to MIPS64 */
11604

    
11605
#endif
11606

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
12382
        num_insns++;
12383

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

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

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

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

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

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

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

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

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

    
12485

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

    
12494
#undef printfpr
12495
}
12496

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
12609
    inited = 1;
12610
}
12611

    
12612
#include "translate_init.c"
12613

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

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

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

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

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

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

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

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

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