Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 9e56e756

History | View | Annotate | Download (364 kB)

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

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

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

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

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

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

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

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

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

    
198
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
199

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
489
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
490

    
491
#include "gen-icount.h"
492

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1027
        pc -= branch_bytes;
1028
    }
1029

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

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

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

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

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

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

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

    
1221

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

    
1229
    t0 = tcg_temp_local_new();
1230

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3768
    if (use_icount)
3769
        gen_io_start();
3770

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

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

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

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

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

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

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

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

    
4934
    if (use_icount)
4935
        gen_io_start();
4936

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

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

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

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

    
5709
            gen_load_fpr32(fp0, rt);
5710
            tcg_gen_ext_i32_tl(t0, fp0);
5711
            tcg_temp_free_i32(fp0);
5712
        } else {
5713
            TCGv_i32 fp0 = tcg_temp_new_i32();
5714

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

    
5736
die:
5737
    tcg_temp_free(t0);
5738
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5739
    generate_exception(ctx, EXCP_RI);
5740
}
5741

    
5742
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5743
                     int u, int sel, int h)
5744
{
5745
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5746
    TCGv t0 = tcg_temp_local_new();
5747

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

    
5907
            tcg_gen_trunc_tl_i32(fp0, t0);
5908
            gen_store_fpr32(fp0, rd);
5909
            tcg_temp_free_i32(fp0);
5910
        } else {
5911
            TCGv_i32 fp0 = tcg_temp_new_i32();
5912

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

    
5933
die:
5934
    tcg_temp_free(t0);
5935
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5936
    generate_exception(ctx, EXCP_RI);
5937
}
5938

    
5939
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5940
{
5941
    const char *opn = "ldst";
5942

    
5943
    switch (opc) {
5944
    case OPC_MFC0:
5945
        if (rt == 0) {
5946
            /* Treat as NOP. */
5947
            return;
5948
        }
5949
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5950
        opn = "mfc0";
5951
        break;
5952
    case OPC_MTC0:
5953
        {
5954
            TCGv t0 = tcg_temp_new();
5955

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

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

    
6062
/* CP1 Branches (before delay slot) */
6063
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
6064
                                 int32_t cc, int32_t offset)
6065
{
6066
    target_ulong btarget;
6067
    const char *opn = "cp1 cond branch";
6068
    TCGv_i32 t0 = tcg_temp_new_i32();
6069

    
6070
    if (cc != 0)
6071
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6072

    
6073
    btarget = ctx->pc + 4 + offset;
6074

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

    
6172
 out:
6173
    tcg_temp_free_i32(t0);
6174
}
6175

    
6176
/* Coprocessor 1 (FPU) */
6177

    
6178
#define FOP(func, fmt) (((fmt) << 21) | (func))
6179

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

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

    
6272
    OPC_CVT_S_W = FOP(32, FMT_W),
6273
    OPC_CVT_D_W = FOP(33, FMT_W),
6274
    OPC_CVT_S_L = FOP(32, FMT_L),
6275
    OPC_CVT_D_L = FOP(33, FMT_L),
6276
    OPC_CVT_PS_PW = FOP(38, FMT_W),
6277

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

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

    
6320
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6321
{
6322
    const char *opn = "cp1 move";
6323
    TCGv t0 = tcg_temp_new();
6324

    
6325
    switch (opc) {
6326
    case OPC_MFC1:
6327
        {
6328
            TCGv_i32 fp0 = tcg_temp_new_i32();
6329

    
6330
            gen_load_fpr32(fp0, fs);
6331
            tcg_gen_ext_i32_tl(t0, fp0);
6332
            tcg_temp_free_i32(fp0);
6333
        }
6334
        gen_store_gpr(t0, rt);
6335
        opn = "mfc1";
6336
        break;
6337
    case OPC_MTC1:
6338
        gen_load_gpr(t0, rt);
6339
        {
6340
            TCGv_i32 fp0 = tcg_temp_new_i32();
6341

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

    
6374
            gen_load_fpr32h(fp0, fs);
6375
            tcg_gen_ext_i32_tl(t0, fp0);
6376
            tcg_temp_free_i32(fp0);
6377
        }
6378
        gen_store_gpr(t0, rt);
6379
        opn = "mfhc1";
6380
        break;
6381
    case OPC_MTHC1:
6382
        gen_load_gpr(t0, rt);
6383
        {
6384
            TCGv_i32 fp0 = tcg_temp_new_i32();
6385

    
6386
            tcg_gen_trunc_tl_i32(fp0, t0);
6387
            gen_store_fpr32h(fp0, fs);
6388
            tcg_temp_free_i32(fp0);
6389
        }
6390
        opn = "mthc1";
6391
        break;
6392
    default:
6393
        MIPS_INVAL(opn);
6394
        generate_exception (ctx, EXCP_RI);
6395
        goto out;
6396
    }
6397
    (void)opn; /* avoid a compiler warning */
6398
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6399

    
6400
 out:
6401
    tcg_temp_free(t0);
6402
}
6403

    
6404
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6405
{
6406
    int l1;
6407
    TCGCond cond;
6408
    TCGv_i32 t0;
6409

    
6410
    if (rd == 0) {
6411
        /* Treat as NOP. */
6412
        return;
6413
    }
6414

    
6415
    if (tf)
6416
        cond = TCG_COND_EQ;
6417
    else
6418
        cond = TCG_COND_NE;
6419

    
6420
    l1 = gen_new_label();
6421
    t0 = tcg_temp_new_i32();
6422
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6423
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6424
    tcg_temp_free_i32(t0);
6425
    if (rs == 0) {
6426
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
6427
    } else {
6428
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6429
    }
6430
    gen_set_label(l1);
6431
}
6432

    
6433
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6434
{
6435
    int cond;
6436
    TCGv_i32 t0 = tcg_temp_new_i32();
6437
    int l1 = gen_new_label();
6438

    
6439
    if (tf)
6440
        cond = TCG_COND_EQ;
6441
    else
6442
        cond = TCG_COND_NE;
6443

    
6444
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6445
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6446
    gen_load_fpr32(t0, fs);
6447
    gen_store_fpr32(t0, fd);
6448
    gen_set_label(l1);
6449
    tcg_temp_free_i32(t0);
6450
}
6451

    
6452
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6453
{
6454
    int cond;
6455
    TCGv_i32 t0 = tcg_temp_new_i32();
6456
    TCGv_i64 fp0;
6457
    int l1 = gen_new_label();
6458

    
6459
    if (tf)
6460
        cond = TCG_COND_EQ;
6461
    else
6462
        cond = TCG_COND_NE;
6463

    
6464
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6465
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6466
    tcg_temp_free_i32(t0);
6467
    fp0 = tcg_temp_new_i64();
6468
    gen_load_fpr64(ctx, fp0, fs);
6469
    gen_store_fpr64(ctx, fp0, fd);
6470
    tcg_temp_free_i64(fp0);
6471
    gen_set_label(l1);
6472
}
6473

    
6474
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6475
{
6476
    int cond;
6477
    TCGv_i32 t0 = tcg_temp_new_i32();
6478
    int l1 = gen_new_label();
6479
    int l2 = gen_new_label();
6480

    
6481
    if (tf)
6482
        cond = TCG_COND_EQ;
6483
    else
6484
        cond = TCG_COND_NE;
6485

    
6486
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6487
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6488
    gen_load_fpr32(t0, fs);
6489
    gen_store_fpr32(t0, fd);
6490
    gen_set_label(l1);
6491

    
6492
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6493
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
6494
    gen_load_fpr32h(t0, fs);
6495
    gen_store_fpr32h(t0, fd);
6496
    tcg_temp_free_i32(t0);
6497
    gen_set_label(l2);
6498
}
6499

    
6500

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

    
6544
    switch (op1) {
6545
    case OPC_ADD_S:
6546
        {
6547
            TCGv_i32 fp0 = tcg_temp_new_i32();
6548
            TCGv_i32 fp1 = tcg_temp_new_i32();
6549

    
6550
            gen_load_fpr32(fp0, fs);
6551
            gen_load_fpr32(fp1, ft);
6552
            gen_helper_float_add_s(fp0, fp0, fp1);
6553
            tcg_temp_free_i32(fp1);
6554
            gen_store_fpr32(fp0, fd);
6555
            tcg_temp_free_i32(fp0);
6556
        }
6557
        opn = "add.s";
6558
        optype = BINOP;
6559
        break;
6560
    case OPC_SUB_S:
6561
        {
6562
            TCGv_i32 fp0 = tcg_temp_new_i32();
6563
            TCGv_i32 fp1 = tcg_temp_new_i32();
6564

    
6565
            gen_load_fpr32(fp0, fs);
6566
            gen_load_fpr32(fp1, ft);
6567
            gen_helper_float_sub_s(fp0, fp0, fp1);
6568
            tcg_temp_free_i32(fp1);
6569
            gen_store_fpr32(fp0, fd);
6570
            tcg_temp_free_i32(fp0);
6571
        }
6572
        opn = "sub.s";
6573
        optype = BINOP;
6574
        break;
6575
    case OPC_MUL_S:
6576
        {
6577
            TCGv_i32 fp0 = tcg_temp_new_i32();
6578
            TCGv_i32 fp1 = tcg_temp_new_i32();
6579

    
6580
            gen_load_fpr32(fp0, fs);
6581
            gen_load_fpr32(fp1, ft);
6582
            gen_helper_float_mul_s(fp0, fp0, fp1);
6583
            tcg_temp_free_i32(fp1);
6584
            gen_store_fpr32(fp0, fd);
6585
            tcg_temp_free_i32(fp0);
6586
        }
6587
        opn = "mul.s";
6588
        optype = BINOP;
6589
        break;
6590
    case OPC_DIV_S:
6591
        {
6592
            TCGv_i32 fp0 = tcg_temp_new_i32();
6593
            TCGv_i32 fp1 = tcg_temp_new_i32();
6594

    
6595
            gen_load_fpr32(fp0, fs);
6596
            gen_load_fpr32(fp1, ft);
6597
            gen_helper_float_div_s(fp0, fp0, fp1);
6598
            tcg_temp_free_i32(fp1);
6599
            gen_store_fpr32(fp0, fd);
6600
            tcg_temp_free_i32(fp0);
6601
        }
6602
        opn = "div.s";
6603
        optype = BINOP;
6604
        break;
6605
    case OPC_SQRT_S:
6606
        {
6607
            TCGv_i32 fp0 = tcg_temp_new_i32();
6608

    
6609
            gen_load_fpr32(fp0, fs);
6610
            gen_helper_float_sqrt_s(fp0, fp0);
6611
            gen_store_fpr32(fp0, fd);
6612
            tcg_temp_free_i32(fp0);
6613
        }
6614
        opn = "sqrt.s";
6615
        break;
6616
    case OPC_ABS_S:
6617
        {
6618
            TCGv_i32 fp0 = tcg_temp_new_i32();
6619

    
6620
            gen_load_fpr32(fp0, fs);
6621
            gen_helper_float_abs_s(fp0, fp0);
6622
            gen_store_fpr32(fp0, fd);
6623
            tcg_temp_free_i32(fp0);
6624
        }
6625
        opn = "abs.s";
6626
        break;
6627
    case OPC_MOV_S:
6628
        {
6629
            TCGv_i32 fp0 = tcg_temp_new_i32();
6630

    
6631
            gen_load_fpr32(fp0, fs);
6632
            gen_store_fpr32(fp0, fd);
6633
            tcg_temp_free_i32(fp0);
6634
        }
6635
        opn = "mov.s";
6636
        break;
6637
    case OPC_NEG_S:
6638
        {
6639
            TCGv_i32 fp0 = tcg_temp_new_i32();
6640

    
6641
            gen_load_fpr32(fp0, fs);
6642
            gen_helper_float_chs_s(fp0, fp0);
6643
            gen_store_fpr32(fp0, fd);
6644
            tcg_temp_free_i32(fp0);
6645
        }
6646
        opn = "neg.s";
6647
        break;
6648
    case OPC_ROUND_L_S:
6649
        check_cp1_64bitmode(ctx);
6650
        {
6651
            TCGv_i32 fp32 = tcg_temp_new_i32();
6652
            TCGv_i64 fp64 = tcg_temp_new_i64();
6653

    
6654
            gen_load_fpr32(fp32, fs);
6655
            gen_helper_float_roundl_s(fp64, fp32);
6656
            tcg_temp_free_i32(fp32);
6657
            gen_store_fpr64(ctx, fp64, fd);
6658
            tcg_temp_free_i64(fp64);
6659
        }
6660
        opn = "round.l.s";
6661
        break;
6662
    case OPC_TRUNC_L_S:
6663
        check_cp1_64bitmode(ctx);
6664
        {
6665
            TCGv_i32 fp32 = tcg_temp_new_i32();
6666
            TCGv_i64 fp64 = tcg_temp_new_i64();
6667

    
6668
            gen_load_fpr32(fp32, fs);
6669
            gen_helper_float_truncl_s(fp64, fp32);
6670
            tcg_temp_free_i32(fp32);
6671
            gen_store_fpr64(ctx, fp64, fd);
6672
            tcg_temp_free_i64(fp64);
6673
        }
6674
        opn = "trunc.l.s";
6675
        break;
6676
    case OPC_CEIL_L_S:
6677
        check_cp1_64bitmode(ctx);
6678
        {
6679
            TCGv_i32 fp32 = tcg_temp_new_i32();
6680
            TCGv_i64 fp64 = tcg_temp_new_i64();
6681

    
6682
            gen_load_fpr32(fp32, fs);
6683
            gen_helper_float_ceill_s(fp64, fp32);
6684
            tcg_temp_free_i32(fp32);
6685
            gen_store_fpr64(ctx, fp64, fd);
6686
            tcg_temp_free_i64(fp64);
6687
        }
6688
        opn = "ceil.l.s";
6689
        break;
6690
    case OPC_FLOOR_L_S:
6691
        check_cp1_64bitmode(ctx);
6692
        {
6693
            TCGv_i32 fp32 = tcg_temp_new_i32();
6694
            TCGv_i64 fp64 = tcg_temp_new_i64();
6695

    
6696
            gen_load_fpr32(fp32, fs);
6697
            gen_helper_float_floorl_s(fp64, fp32);
6698
            tcg_temp_free_i32(fp32);
6699
            gen_store_fpr64(ctx, fp64, fd);
6700
            tcg_temp_free_i64(fp64);
6701
        }
6702
        opn = "floor.l.s";
6703
        break;
6704
    case OPC_ROUND_W_S:
6705
        {
6706
            TCGv_i32 fp0 = tcg_temp_new_i32();
6707

    
6708
            gen_load_fpr32(fp0, fs);
6709
            gen_helper_float_roundw_s(fp0, fp0);
6710
            gen_store_fpr32(fp0, fd);
6711
            tcg_temp_free_i32(fp0);
6712
        }
6713
        opn = "round.w.s";
6714
        break;
6715
    case OPC_TRUNC_W_S:
6716
        {
6717
            TCGv_i32 fp0 = tcg_temp_new_i32();
6718

    
6719
            gen_load_fpr32(fp0, fs);
6720
            gen_helper_float_truncw_s(fp0, fp0);
6721
            gen_store_fpr32(fp0, fd);
6722
            tcg_temp_free_i32(fp0);
6723
        }
6724
        opn = "trunc.w.s";
6725
        break;
6726
    case OPC_CEIL_W_S:
6727
        {
6728
            TCGv_i32 fp0 = tcg_temp_new_i32();
6729

    
6730
            gen_load_fpr32(fp0, fs);
6731
            gen_helper_float_ceilw_s(fp0, fp0);
6732
            gen_store_fpr32(fp0, fd);
6733
            tcg_temp_free_i32(fp0);
6734
        }
6735
        opn = "ceil.w.s";
6736
        break;
6737
    case OPC_FLOOR_W_S:
6738
        {
6739
            TCGv_i32 fp0 = tcg_temp_new_i32();
6740

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

    
6757
            if (ft != 0) {
6758
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6759
            }
6760
            fp0 = tcg_temp_new_i32();
6761
            gen_load_fpr32(fp0, fs);
6762
            gen_store_fpr32(fp0, fd);
6763
            tcg_temp_free_i32(fp0);
6764
            gen_set_label(l1);
6765
        }
6766
        opn = "movz.s";
6767
        break;
6768
    case OPC_MOVN_S:
6769
        {
6770
            int l1 = gen_new_label();
6771
            TCGv_i32 fp0;
6772

    
6773
            if (ft != 0) {
6774
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6775
                fp0 = tcg_temp_new_i32();
6776
                gen_load_fpr32(fp0, fs);
6777
                gen_store_fpr32(fp0, fd);
6778
                tcg_temp_free_i32(fp0);
6779
                gen_set_label(l1);
6780
            }
6781
        }
6782
        opn = "movn.s";
6783
        break;
6784
    case OPC_RECIP_S:
6785
        check_cop1x(ctx);
6786
        {
6787
            TCGv_i32 fp0 = tcg_temp_new_i32();
6788

    
6789
            gen_load_fpr32(fp0, fs);
6790
            gen_helper_float_recip_s(fp0, fp0);
6791
            gen_store_fpr32(fp0, fd);
6792
            tcg_temp_free_i32(fp0);
6793
        }
6794
        opn = "recip.s";
6795
        break;
6796
    case OPC_RSQRT_S:
6797
        check_cop1x(ctx);
6798
        {
6799
            TCGv_i32 fp0 = tcg_temp_new_i32();
6800

    
6801
            gen_load_fpr32(fp0, fs);
6802
            gen_helper_float_rsqrt_s(fp0, fp0);
6803
            gen_store_fpr32(fp0, fd);
6804
            tcg_temp_free_i32(fp0);
6805
        }
6806
        opn = "rsqrt.s";
6807
        break;
6808
    case OPC_RECIP2_S:
6809
        check_cp1_64bitmode(ctx);
6810
        {
6811
            TCGv_i32 fp0 = tcg_temp_new_i32();
6812
            TCGv_i32 fp1 = tcg_temp_new_i32();
6813

    
6814
            gen_load_fpr32(fp0, fs);
6815
            gen_load_fpr32(fp1, fd);
6816
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6817
            tcg_temp_free_i32(fp1);
6818
            gen_store_fpr32(fp0, fd);
6819
            tcg_temp_free_i32(fp0);
6820
        }
6821
        opn = "recip2.s";
6822
        break;
6823
    case OPC_RECIP1_S:
6824
        check_cp1_64bitmode(ctx);
6825
        {
6826
            TCGv_i32 fp0 = tcg_temp_new_i32();
6827

    
6828
            gen_load_fpr32(fp0, fs);
6829
            gen_helper_float_recip1_s(fp0, fp0);
6830
            gen_store_fpr32(fp0, fd);
6831
            tcg_temp_free_i32(fp0);
6832
        }
6833
        opn = "recip1.s";
6834
        break;
6835
    case OPC_RSQRT1_S:
6836
        check_cp1_64bitmode(ctx);
6837
        {
6838
            TCGv_i32 fp0 = tcg_temp_new_i32();
6839

    
6840
            gen_load_fpr32(fp0, fs);
6841
            gen_helper_float_rsqrt1_s(fp0, fp0);
6842
            gen_store_fpr32(fp0, fd);
6843
            tcg_temp_free_i32(fp0);
6844
        }
6845
        opn = "rsqrt1.s";
6846
        break;
6847
    case OPC_RSQRT2_S:
6848
        check_cp1_64bitmode(ctx);
6849
        {
6850
            TCGv_i32 fp0 = tcg_temp_new_i32();
6851
            TCGv_i32 fp1 = tcg_temp_new_i32();
6852

    
6853
            gen_load_fpr32(fp0, fs);
6854
            gen_load_fpr32(fp1, ft);
6855
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6856
            tcg_temp_free_i32(fp1);
6857
            gen_store_fpr32(fp0, fd);
6858
            tcg_temp_free_i32(fp0);
6859
        }
6860
        opn = "rsqrt2.s";
6861
        break;
6862
    case OPC_CVT_D_S:
6863
        check_cp1_registers(ctx, fd);
6864
        {
6865
            TCGv_i32 fp32 = tcg_temp_new_i32();
6866
            TCGv_i64 fp64 = tcg_temp_new_i64();
6867

    
6868
            gen_load_fpr32(fp32, fs);
6869
            gen_helper_float_cvtd_s(fp64, fp32);
6870
            tcg_temp_free_i32(fp32);
6871
            gen_store_fpr64(ctx, fp64, fd);
6872
            tcg_temp_free_i64(fp64);
6873
        }
6874
        opn = "cvt.d.s";
6875
        break;
6876
    case OPC_CVT_W_S:
6877
        {
6878
            TCGv_i32 fp0 = tcg_temp_new_i32();
6879

    
6880
            gen_load_fpr32(fp0, fs);
6881
            gen_helper_float_cvtw_s(fp0, fp0);
6882
            gen_store_fpr32(fp0, fd);
6883
            tcg_temp_free_i32(fp0);
6884
        }
6885
        opn = "cvt.w.s";
6886
        break;
6887
    case OPC_CVT_L_S:
6888
        check_cp1_64bitmode(ctx);
6889
        {
6890
            TCGv_i32 fp32 = tcg_temp_new_i32();
6891
            TCGv_i64 fp64 = tcg_temp_new_i64();
6892

    
6893
            gen_load_fpr32(fp32, fs);
6894
            gen_helper_float_cvtl_s(fp64, fp32);
6895
            tcg_temp_free_i32(fp32);
6896
            gen_store_fpr64(ctx, fp64, fd);
6897
            tcg_temp_free_i64(fp64);
6898
        }
6899
        opn = "cvt.l.s";
6900
        break;
6901
    case OPC_CVT_PS_S:
6902
        check_cp1_64bitmode(ctx);
6903
        {
6904
            TCGv_i64 fp64 = tcg_temp_new_i64();
6905
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6906
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6907

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

    
6948
            gen_load_fpr64(ctx, fp0, fs);
6949
            gen_load_fpr64(ctx, fp1, ft);
6950
            gen_helper_float_add_d(fp0, fp0, fp1);
6951
            tcg_temp_free_i64(fp1);
6952
            gen_store_fpr64(ctx, fp0, fd);
6953
            tcg_temp_free_i64(fp0);
6954
        }
6955
        opn = "add.d";
6956
        optype = BINOP;
6957
        break;
6958
    case OPC_SUB_D:
6959
        check_cp1_registers(ctx, fs | ft | fd);
6960
        {
6961
            TCGv_i64 fp0 = tcg_temp_new_i64();
6962
            TCGv_i64 fp1 = tcg_temp_new_i64();
6963

    
6964
            gen_load_fpr64(ctx, fp0, fs);
6965
            gen_load_fpr64(ctx, fp1, ft);
6966
            gen_helper_float_sub_d(fp0, fp0, fp1);
6967
            tcg_temp_free_i64(fp1);
6968
            gen_store_fpr64(ctx, fp0, fd);
6969
            tcg_temp_free_i64(fp0);
6970
        }
6971
        opn = "sub.d";
6972
        optype = BINOP;
6973
        break;
6974
    case OPC_MUL_D:
6975
        check_cp1_registers(ctx, fs | ft | fd);
6976
        {
6977
            TCGv_i64 fp0 = tcg_temp_new_i64();
6978
            TCGv_i64 fp1 = tcg_temp_new_i64();
6979

    
6980
            gen_load_fpr64(ctx, fp0, fs);
6981
            gen_load_fpr64(ctx, fp1, ft);
6982
            gen_helper_float_mul_d(fp0, fp0, fp1);
6983
            tcg_temp_free_i64(fp1);
6984
            gen_store_fpr64(ctx, fp0, fd);
6985
            tcg_temp_free_i64(fp0);
6986
        }
6987
        opn = "mul.d";
6988
        optype = BINOP;
6989
        break;
6990
    case OPC_DIV_D:
6991
        check_cp1_registers(ctx, fs | ft | fd);
6992
        {
6993
            TCGv_i64 fp0 = tcg_temp_new_i64();
6994
            TCGv_i64 fp1 = tcg_temp_new_i64();
6995

    
6996
            gen_load_fpr64(ctx, fp0, fs);
6997
            gen_load_fpr64(ctx, fp1, ft);
6998
            gen_helper_float_div_d(fp0, fp0, fp1);
6999
            tcg_temp_free_i64(fp1);
7000
            gen_store_fpr64(ctx, fp0, fd);
7001
            tcg_temp_free_i64(fp0);
7002
        }
7003
        opn = "div.d";
7004
        optype = BINOP;
7005
        break;
7006
    case OPC_SQRT_D:
7007
        check_cp1_registers(ctx, fs | fd);
7008
        {
7009
            TCGv_i64 fp0 = tcg_temp_new_i64();
7010

    
7011
            gen_load_fpr64(ctx, fp0, fs);
7012
            gen_helper_float_sqrt_d(fp0, fp0);
7013
            gen_store_fpr64(ctx, fp0, fd);
7014
            tcg_temp_free_i64(fp0);
7015
        }
7016
        opn = "sqrt.d";
7017
        break;
7018
    case OPC_ABS_D:
7019
        check_cp1_registers(ctx, fs | fd);
7020
        {
7021
            TCGv_i64 fp0 = tcg_temp_new_i64();
7022

    
7023
            gen_load_fpr64(ctx, fp0, fs);
7024
            gen_helper_float_abs_d(fp0, fp0);
7025
            gen_store_fpr64(ctx, fp0, fd);
7026
            tcg_temp_free_i64(fp0);
7027
        }
7028
        opn = "abs.d";
7029
        break;
7030
    case OPC_MOV_D:
7031
        check_cp1_registers(ctx, fs | fd);
7032
        {
7033
            TCGv_i64 fp0 = tcg_temp_new_i64();
7034

    
7035
            gen_load_fpr64(ctx, fp0, fs);
7036
            gen_store_fpr64(ctx, fp0, fd);
7037
            tcg_temp_free_i64(fp0);
7038
        }
7039
        opn = "mov.d";
7040
        break;
7041
    case OPC_NEG_D:
7042
        check_cp1_registers(ctx, fs | fd);
7043
        {
7044
            TCGv_i64 fp0 = tcg_temp_new_i64();
7045

    
7046
            gen_load_fpr64(ctx, fp0, fs);
7047
            gen_helper_float_chs_d(fp0, fp0);
7048
            gen_store_fpr64(ctx, fp0, fd);
7049
            tcg_temp_free_i64(fp0);
7050
        }
7051
        opn = "neg.d";
7052
        break;
7053
    case OPC_ROUND_L_D:
7054
        check_cp1_64bitmode(ctx);
7055
        {
7056
            TCGv_i64 fp0 = tcg_temp_new_i64();
7057

    
7058
            gen_load_fpr64(ctx, fp0, fs);
7059
            gen_helper_float_roundl_d(fp0, fp0);
7060
            gen_store_fpr64(ctx, fp0, fd);
7061
            tcg_temp_free_i64(fp0);
7062
        }
7063
        opn = "round.l.d";
7064
        break;
7065
    case OPC_TRUNC_L_D:
7066
        check_cp1_64bitmode(ctx);
7067
        {
7068
            TCGv_i64 fp0 = tcg_temp_new_i64();
7069

    
7070
            gen_load_fpr64(ctx, fp0, fs);
7071
            gen_helper_float_truncl_d(fp0, fp0);
7072
            gen_store_fpr64(ctx, fp0, fd);
7073
            tcg_temp_free_i64(fp0);
7074
        }
7075
        opn = "trunc.l.d";
7076
        break;
7077
    case OPC_CEIL_L_D:
7078
        check_cp1_64bitmode(ctx);
7079
        {
7080
            TCGv_i64 fp0 = tcg_temp_new_i64();
7081

    
7082
            gen_load_fpr64(ctx, fp0, fs);
7083
            gen_helper_float_ceill_d(fp0, fp0);
7084
            gen_store_fpr64(ctx, fp0, fd);
7085
            tcg_temp_free_i64(fp0);
7086
        }
7087
        opn = "ceil.l.d";
7088
        break;
7089
    case OPC_FLOOR_L_D:
7090
        check_cp1_64bitmode(ctx);
7091
        {
7092
            TCGv_i64 fp0 = tcg_temp_new_i64();
7093

    
7094
            gen_load_fpr64(ctx, fp0, fs);
7095
            gen_helper_float_floorl_d(fp0, fp0);
7096
            gen_store_fpr64(ctx, fp0, fd);
7097
            tcg_temp_free_i64(fp0);
7098
        }
7099
        opn = "floor.l.d";
7100
        break;
7101
    case OPC_ROUND_W_D:
7102
        check_cp1_registers(ctx, fs);
7103
        {
7104
            TCGv_i32 fp32 = tcg_temp_new_i32();
7105
            TCGv_i64 fp64 = tcg_temp_new_i64();
7106

    
7107
            gen_load_fpr64(ctx, fp64, fs);
7108
            gen_helper_float_roundw_d(fp32, fp64);
7109
            tcg_temp_free_i64(fp64);
7110
            gen_store_fpr32(fp32, fd);
7111
            tcg_temp_free_i32(fp32);
7112
        }
7113
        opn = "round.w.d";
7114
        break;
7115
    case OPC_TRUNC_W_D:
7116
        check_cp1_registers(ctx, fs);
7117
        {
7118
            TCGv_i32 fp32 = tcg_temp_new_i32();
7119
            TCGv_i64 fp64 = tcg_temp_new_i64();
7120

    
7121
            gen_load_fpr64(ctx, fp64, fs);
7122
            gen_helper_float_truncw_d(fp32, fp64);
7123
            tcg_temp_free_i64(fp64);
7124
            gen_store_fpr32(fp32, fd);
7125
            tcg_temp_free_i32(fp32);
7126
        }
7127
        opn = "trunc.w.d";
7128
        break;
7129
    case OPC_CEIL_W_D:
7130
        check_cp1_registers(ctx, fs);
7131
        {
7132
            TCGv_i32 fp32 = tcg_temp_new_i32();
7133
            TCGv_i64 fp64 = tcg_temp_new_i64();
7134

    
7135
            gen_load_fpr64(ctx, fp64, fs);
7136
            gen_helper_float_ceilw_d(fp32, fp64);
7137
            tcg_temp_free_i64(fp64);
7138
            gen_store_fpr32(fp32, fd);
7139
            tcg_temp_free_i32(fp32);
7140
        }
7141
        opn = "ceil.w.d";
7142
        break;
7143
    case OPC_FLOOR_W_D:
7144
        check_cp1_registers(ctx, fs);
7145
        {
7146
            TCGv_i32 fp32 = tcg_temp_new_i32();
7147
            TCGv_i64 fp64 = tcg_temp_new_i64();
7148

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

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

    
7182
            if (ft != 0) {
7183
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7184
                fp0 = tcg_temp_new_i64();
7185
                gen_load_fpr64(ctx, fp0, fs);
7186
                gen_store_fpr64(ctx, fp0, fd);
7187
                tcg_temp_free_i64(fp0);
7188
                gen_set_label(l1);
7189
            }
7190
        }
7191
        opn = "movn.d";
7192
        break;
7193
    case OPC_RECIP_D:
7194
        check_cp1_64bitmode(ctx);
7195
        {
7196
            TCGv_i64 fp0 = tcg_temp_new_i64();
7197

    
7198
            gen_load_fpr64(ctx, fp0, fs);
7199
            gen_helper_float_recip_d(fp0, fp0);
7200
            gen_store_fpr64(ctx, fp0, fd);
7201
            tcg_temp_free_i64(fp0);
7202
        }
7203
        opn = "recip.d";
7204
        break;
7205
    case OPC_RSQRT_D:
7206
        check_cp1_64bitmode(ctx);
7207
        {
7208
            TCGv_i64 fp0 = tcg_temp_new_i64();
7209

    
7210
            gen_load_fpr64(ctx, fp0, fs);
7211
            gen_helper_float_rsqrt_d(fp0, fp0);
7212
            gen_store_fpr64(ctx, fp0, fd);
7213
            tcg_temp_free_i64(fp0);
7214
        }
7215
        opn = "rsqrt.d";
7216
        break;
7217
    case OPC_RECIP2_D:
7218
        check_cp1_64bitmode(ctx);
7219
        {
7220
            TCGv_i64 fp0 = tcg_temp_new_i64();
7221
            TCGv_i64 fp1 = tcg_temp_new_i64();
7222

    
7223
            gen_load_fpr64(ctx, fp0, fs);
7224
            gen_load_fpr64(ctx, fp1, ft);
7225
            gen_helper_float_recip2_d(fp0, fp0, fp1);
7226
            tcg_temp_free_i64(fp1);
7227
            gen_store_fpr64(ctx, fp0, fd);
7228
            tcg_temp_free_i64(fp0);
7229
        }
7230
        opn = "recip2.d";
7231
        break;
7232
    case OPC_RECIP1_D:
7233
        check_cp1_64bitmode(ctx);
7234
        {
7235
            TCGv_i64 fp0 = tcg_temp_new_i64();
7236

    
7237
            gen_load_fpr64(ctx, fp0, fs);
7238
            gen_helper_float_recip1_d(fp0, fp0);
7239
            gen_store_fpr64(ctx, fp0, fd);
7240
            tcg_temp_free_i64(fp0);
7241
        }
7242
        opn = "recip1.d";
7243
        break;
7244
    case OPC_RSQRT1_D:
7245
        check_cp1_64bitmode(ctx);
7246
        {
7247
            TCGv_i64 fp0 = tcg_temp_new_i64();
7248

    
7249
            gen_load_fpr64(ctx, fp0, fs);
7250
            gen_helper_float_rsqrt1_d(fp0, fp0);
7251
            gen_store_fpr64(ctx, fp0, fd);
7252
            tcg_temp_free_i64(fp0);
7253
        }
7254
        opn = "rsqrt1.d";
7255
        break;
7256
    case OPC_RSQRT2_D:
7257
        check_cp1_64bitmode(ctx);
7258
        {
7259
            TCGv_i64 fp0 = tcg_temp_new_i64();
7260
            TCGv_i64 fp1 = tcg_temp_new_i64();
7261

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

    
7301
            gen_load_fpr64(ctx, fp64, fs);
7302
            gen_helper_float_cvts_d(fp32, fp64);
7303
            tcg_temp_free_i64(fp64);
7304
            gen_store_fpr32(fp32, fd);
7305
            tcg_temp_free_i32(fp32);
7306
        }
7307
        opn = "cvt.s.d";
7308
        break;
7309
    case OPC_CVT_W_D:
7310
        check_cp1_registers(ctx, fs);
7311
        {
7312
            TCGv_i32 fp32 = tcg_temp_new_i32();
7313
            TCGv_i64 fp64 = tcg_temp_new_i64();
7314

    
7315
            gen_load_fpr64(ctx, fp64, fs);
7316
            gen_helper_float_cvtw_d(fp32, fp64);
7317
            tcg_temp_free_i64(fp64);
7318
            gen_store_fpr32(fp32, fd);
7319
            tcg_temp_free_i32(fp32);
7320
        }
7321
        opn = "cvt.w.d";
7322
        break;
7323
    case OPC_CVT_L_D:
7324
        check_cp1_64bitmode(ctx);
7325
        {
7326
            TCGv_i64 fp0 = tcg_temp_new_i64();
7327

    
7328
            gen_load_fpr64(ctx, fp0, fs);
7329
            gen_helper_float_cvtl_d(fp0, fp0);
7330
            gen_store_fpr64(ctx, fp0, fd);
7331
            tcg_temp_free_i64(fp0);
7332
        }
7333
        opn = "cvt.l.d";
7334
        break;
7335
    case OPC_CVT_S_W:
7336
        {
7337
            TCGv_i32 fp0 = tcg_temp_new_i32();
7338

    
7339
            gen_load_fpr32(fp0, fs);
7340
            gen_helper_float_cvts_w(fp0, fp0);
7341
            gen_store_fpr32(fp0, fd);
7342
            tcg_temp_free_i32(fp0);
7343
        }
7344
        opn = "cvt.s.w";
7345
        break;
7346
    case OPC_CVT_D_W:
7347
        check_cp1_registers(ctx, fd);
7348
        {
7349
            TCGv_i32 fp32 = tcg_temp_new_i32();
7350
            TCGv_i64 fp64 = tcg_temp_new_i64();
7351

    
7352
            gen_load_fpr32(fp32, fs);
7353
            gen_helper_float_cvtd_w(fp64, fp32);
7354
            tcg_temp_free_i32(fp32);
7355
            gen_store_fpr64(ctx, fp64, fd);
7356
            tcg_temp_free_i64(fp64);
7357
        }
7358
        opn = "cvt.d.w";
7359
        break;
7360
    case OPC_CVT_S_L:
7361
        check_cp1_64bitmode(ctx);
7362
        {
7363
            TCGv_i32 fp32 = tcg_temp_new_i32();
7364
            TCGv_i64 fp64 = tcg_temp_new_i64();
7365

    
7366
            gen_load_fpr64(ctx, fp64, fs);
7367
            gen_helper_float_cvts_l(fp32, fp64);
7368
            tcg_temp_free_i64(fp64);
7369
            gen_store_fpr32(fp32, fd);
7370
            tcg_temp_free_i32(fp32);
7371
        }
7372
        opn = "cvt.s.l";
7373
        break;
7374
    case OPC_CVT_D_L:
7375
        check_cp1_64bitmode(ctx);
7376
        {
7377
            TCGv_i64 fp0 = tcg_temp_new_i64();
7378

    
7379
            gen_load_fpr64(ctx, fp0, fs);
7380
            gen_helper_float_cvtd_l(fp0, fp0);
7381
            gen_store_fpr64(ctx, fp0, fd);
7382
            tcg_temp_free_i64(fp0);
7383
        }
7384
        opn = "cvt.d.l";
7385
        break;
7386
    case OPC_CVT_PS_PW:
7387
        check_cp1_64bitmode(ctx);
7388
        {
7389
            TCGv_i64 fp0 = tcg_temp_new_i64();
7390

    
7391
            gen_load_fpr64(ctx, fp0, fs);
7392
            gen_helper_float_cvtps_pw(fp0, fp0);
7393
            gen_store_fpr64(ctx, fp0, fd);
7394
            tcg_temp_free_i64(fp0);
7395
        }
7396
        opn = "cvt.ps.pw";
7397
        break;
7398
    case OPC_ADD_PS:
7399
        check_cp1_64bitmode(ctx);
7400
        {
7401
            TCGv_i64 fp0 = tcg_temp_new_i64();
7402
            TCGv_i64 fp1 = tcg_temp_new_i64();
7403

    
7404
            gen_load_fpr64(ctx, fp0, fs);
7405
            gen_load_fpr64(ctx, fp1, ft);
7406
            gen_helper_float_add_ps(fp0, fp0, fp1);
7407
            tcg_temp_free_i64(fp1);
7408
            gen_store_fpr64(ctx, fp0, fd);
7409
            tcg_temp_free_i64(fp0);
7410
        }
7411
        opn = "add.ps";
7412
        break;
7413
    case OPC_SUB_PS:
7414
        check_cp1_64bitmode(ctx);
7415
        {
7416
            TCGv_i64 fp0 = tcg_temp_new_i64();
7417
            TCGv_i64 fp1 = tcg_temp_new_i64();
7418

    
7419
            gen_load_fpr64(ctx, fp0, fs);
7420
            gen_load_fpr64(ctx, fp1, ft);
7421
            gen_helper_float_sub_ps(fp0, fp0, fp1);
7422
            tcg_temp_free_i64(fp1);
7423
            gen_store_fpr64(ctx, fp0, fd);
7424
            tcg_temp_free_i64(fp0);
7425
        }
7426
        opn = "sub.ps";
7427
        break;
7428
    case OPC_MUL_PS:
7429
        check_cp1_64bitmode(ctx);
7430
        {
7431
            TCGv_i64 fp0 = tcg_temp_new_i64();
7432
            TCGv_i64 fp1 = tcg_temp_new_i64();
7433

    
7434
            gen_load_fpr64(ctx, fp0, fs);
7435
            gen_load_fpr64(ctx, fp1, ft);
7436
            gen_helper_float_mul_ps(fp0, fp0, fp1);
7437
            tcg_temp_free_i64(fp1);
7438
            gen_store_fpr64(ctx, fp0, fd);
7439
            tcg_temp_free_i64(fp0);
7440
        }
7441
        opn = "mul.ps";
7442
        break;
7443
    case OPC_ABS_PS:
7444
        check_cp1_64bitmode(ctx);
7445
        {
7446
            TCGv_i64 fp0 = tcg_temp_new_i64();
7447

    
7448
            gen_load_fpr64(ctx, fp0, fs);
7449
            gen_helper_float_abs_ps(fp0, fp0);
7450
            gen_store_fpr64(ctx, fp0, fd);
7451
            tcg_temp_free_i64(fp0);
7452
        }
7453
        opn = "abs.ps";
7454
        break;
7455
    case OPC_MOV_PS:
7456
        check_cp1_64bitmode(ctx);
7457
        {
7458
            TCGv_i64 fp0 = tcg_temp_new_i64();
7459

    
7460
            gen_load_fpr64(ctx, fp0, fs);
7461
            gen_store_fpr64(ctx, fp0, fd);
7462
            tcg_temp_free_i64(fp0);
7463
        }
7464
        opn = "mov.ps";
7465
        break;
7466
    case OPC_NEG_PS:
7467
        check_cp1_64bitmode(ctx);
7468
        {
7469
            TCGv_i64 fp0 = tcg_temp_new_i64();
7470

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

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

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

    
7522
            gen_load_fpr64(ctx, fp0, ft);
7523
            gen_load_fpr64(ctx, fp1, fs);
7524
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7525
            tcg_temp_free_i64(fp1);
7526
            gen_store_fpr64(ctx, fp0, fd);
7527
            tcg_temp_free_i64(fp0);
7528
        }
7529
        opn = "addr.ps";
7530
        break;
7531
    case OPC_MULR_PS:
7532
        check_cp1_64bitmode(ctx);
7533
        {
7534
            TCGv_i64 fp0 = tcg_temp_new_i64();
7535
            TCGv_i64 fp1 = tcg_temp_new_i64();
7536

    
7537
            gen_load_fpr64(ctx, fp0, ft);
7538
            gen_load_fpr64(ctx, fp1, fs);
7539
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7540
            tcg_temp_free_i64(fp1);
7541
            gen_store_fpr64(ctx, fp0, fd);
7542
            tcg_temp_free_i64(fp0);
7543
        }
7544
        opn = "mulr.ps";
7545
        break;
7546
    case OPC_RECIP2_PS:
7547
        check_cp1_64bitmode(ctx);
7548
        {
7549
            TCGv_i64 fp0 = tcg_temp_new_i64();
7550
            TCGv_i64 fp1 = tcg_temp_new_i64();
7551

    
7552
            gen_load_fpr64(ctx, fp0, fs);
7553
            gen_load_fpr64(ctx, fp1, fd);
7554
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7555
            tcg_temp_free_i64(fp1);
7556
            gen_store_fpr64(ctx, fp0, fd);
7557
            tcg_temp_free_i64(fp0);
7558
        }
7559
        opn = "recip2.ps";
7560
        break;
7561
    case OPC_RECIP1_PS:
7562
        check_cp1_64bitmode(ctx);
7563
        {
7564
            TCGv_i64 fp0 = tcg_temp_new_i64();
7565

    
7566
            gen_load_fpr64(ctx, fp0, fs);
7567
            gen_helper_float_recip1_ps(fp0, fp0);
7568
            gen_store_fpr64(ctx, fp0, fd);
7569
            tcg_temp_free_i64(fp0);
7570
        }
7571
        opn = "recip1.ps";
7572
        break;
7573
    case OPC_RSQRT1_PS:
7574
        check_cp1_64bitmode(ctx);
7575
        {
7576
            TCGv_i64 fp0 = tcg_temp_new_i64();
7577

    
7578
            gen_load_fpr64(ctx, fp0, fs);
7579
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7580
            gen_store_fpr64(ctx, fp0, fd);
7581
            tcg_temp_free_i64(fp0);
7582
        }
7583
        opn = "rsqrt1.ps";
7584
        break;
7585
    case OPC_RSQRT2_PS:
7586
        check_cp1_64bitmode(ctx);
7587
        {
7588
            TCGv_i64 fp0 = tcg_temp_new_i64();
7589
            TCGv_i64 fp1 = tcg_temp_new_i64();
7590

    
7591
            gen_load_fpr64(ctx, fp0, fs);
7592
            gen_load_fpr64(ctx, fp1, ft);
7593
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7594
            tcg_temp_free_i64(fp1);
7595
            gen_store_fpr64(ctx, fp0, fd);
7596
            tcg_temp_free_i64(fp0);
7597
        }
7598
        opn = "rsqrt2.ps";
7599
        break;
7600
    case OPC_CVT_S_PU:
7601
        check_cp1_64bitmode(ctx);
7602
        {
7603
            TCGv_i32 fp0 = tcg_temp_new_i32();
7604

    
7605
            gen_load_fpr32h(fp0, fs);
7606
            gen_helper_float_cvts_pu(fp0, fp0);
7607
            gen_store_fpr32(fp0, fd);
7608
            tcg_temp_free_i32(fp0);
7609
        }
7610
        opn = "cvt.s.pu";
7611
        break;
7612
    case OPC_CVT_PW_PS:
7613
        check_cp1_64bitmode(ctx);
7614
        {
7615
            TCGv_i64 fp0 = tcg_temp_new_i64();
7616

    
7617
            gen_load_fpr64(ctx, fp0, fs);
7618
            gen_helper_float_cvtpw_ps(fp0, fp0);
7619
            gen_store_fpr64(ctx, fp0, fd);
7620
            tcg_temp_free_i64(fp0);
7621
        }
7622
        opn = "cvt.pw.ps";
7623
        break;
7624
    case OPC_CVT_S_PL:
7625
        check_cp1_64bitmode(ctx);
7626
        {
7627
            TCGv_i32 fp0 = tcg_temp_new_i32();
7628

    
7629
            gen_load_fpr32(fp0, fs);
7630
            gen_helper_float_cvts_pl(fp0, fp0);
7631
            gen_store_fpr32(fp0, fd);
7632
            tcg_temp_free_i32(fp0);
7633
        }
7634
        opn = "cvt.s.pl";
7635
        break;
7636
    case OPC_PLL_PS:
7637
        check_cp1_64bitmode(ctx);
7638
        {
7639
            TCGv_i32 fp0 = tcg_temp_new_i32();
7640
            TCGv_i32 fp1 = tcg_temp_new_i32();
7641

    
7642
            gen_load_fpr32(fp0, fs);
7643
            gen_load_fpr32(fp1, ft);
7644
            gen_store_fpr32h(fp0, fd);
7645
            gen_store_fpr32(fp1, fd);
7646
            tcg_temp_free_i32(fp0);
7647
            tcg_temp_free_i32(fp1);
7648
        }
7649
        opn = "pll.ps";
7650
        break;
7651
    case OPC_PLU_PS:
7652
        check_cp1_64bitmode(ctx);
7653
        {
7654
            TCGv_i32 fp0 = tcg_temp_new_i32();
7655
            TCGv_i32 fp1 = tcg_temp_new_i32();
7656

    
7657
            gen_load_fpr32(fp0, fs);
7658
            gen_load_fpr32h(fp1, ft);
7659
            gen_store_fpr32(fp1, fd);
7660
            gen_store_fpr32h(fp0, fd);
7661
            tcg_temp_free_i32(fp0);
7662
            tcg_temp_free_i32(fp1);
7663
        }
7664
        opn = "plu.ps";
7665
        break;
7666
    case OPC_PUL_PS:
7667
        check_cp1_64bitmode(ctx);
7668
        {
7669
            TCGv_i32 fp0 = tcg_temp_new_i32();
7670
            TCGv_i32 fp1 = tcg_temp_new_i32();
7671

    
7672
            gen_load_fpr32h(fp0, fs);
7673
            gen_load_fpr32(fp1, ft);
7674
            gen_store_fpr32(fp1, fd);
7675
            gen_store_fpr32h(fp0, fd);
7676
            tcg_temp_free_i32(fp0);
7677
            tcg_temp_free_i32(fp1);
7678
        }
7679
        opn = "pul.ps";
7680
        break;
7681
    case OPC_PUU_PS:
7682
        check_cp1_64bitmode(ctx);
7683
        {
7684
            TCGv_i32 fp0 = tcg_temp_new_i32();
7685
            TCGv_i32 fp1 = tcg_temp_new_i32();
7686

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

    
7739
/* Coprocessor 3 (FPU) */
7740
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7741
                           int fd, int fs, int base, int index)
7742
{
7743
    const char *opn = "extended float load/store";
7744
    int store = 0;
7745
    TCGv t0 = tcg_temp_new();
7746

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

    
7764
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7765
            tcg_gen_trunc_tl_i32(fp0, t0);
7766
            gen_store_fpr32(fp0, fd);
7767
            tcg_temp_free_i32(fp0);
7768
        }
7769
        opn = "lwxc1";
7770
        break;
7771
    case OPC_LDXC1:
7772
        check_cop1x(ctx);
7773
        check_cp1_registers(ctx, fd);
7774
        {
7775
            TCGv_i64 fp0 = tcg_temp_new_i64();
7776

    
7777
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7778
            gen_store_fpr64(ctx, fp0, fd);
7779
            tcg_temp_free_i64(fp0);
7780
        }
7781
        opn = "ldxc1";
7782
        break;
7783
    case OPC_LUXC1:
7784
        check_cp1_64bitmode(ctx);
7785
        tcg_gen_andi_tl(t0, t0, ~0x7);
7786
        {
7787
            TCGv_i64 fp0 = tcg_temp_new_i64();
7788

    
7789
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7790
            gen_store_fpr64(ctx, fp0, fd);
7791
            tcg_temp_free_i64(fp0);
7792
        }
7793
        opn = "luxc1";
7794
        break;
7795
    case OPC_SWXC1:
7796
        check_cop1x(ctx);
7797
        {
7798
            TCGv_i32 fp0 = tcg_temp_new_i32();
7799
            TCGv t1 = tcg_temp_new();
7800

    
7801
            gen_load_fpr32(fp0, fs);
7802
            tcg_gen_extu_i32_tl(t1, fp0);
7803
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7804
            tcg_temp_free_i32(fp0);
7805
            tcg_temp_free(t1);
7806
        }
7807
        opn = "swxc1";
7808
        store = 1;
7809
        break;
7810
    case OPC_SDXC1:
7811
        check_cop1x(ctx);
7812
        check_cp1_registers(ctx, fs);
7813
        {
7814
            TCGv_i64 fp0 = tcg_temp_new_i64();
7815

    
7816
            gen_load_fpr64(ctx, fp0, fs);
7817
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7818
            tcg_temp_free_i64(fp0);
7819
        }
7820
        opn = "sdxc1";
7821
        store = 1;
7822
        break;
7823
    case OPC_SUXC1:
7824
        check_cp1_64bitmode(ctx);
7825
        tcg_gen_andi_tl(t0, t0, ~0x7);
7826
        {
7827
            TCGv_i64 fp0 = tcg_temp_new_i64();
7828

    
7829
            gen_load_fpr64(ctx, fp0, fs);
7830
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7831
            tcg_temp_free_i64(fp0);
7832
        }
7833
        opn = "suxc1";
7834
        store = 1;
7835
        break;
7836
    }
7837
    tcg_temp_free(t0);
7838
    (void)opn; (void)store; /* avoid compiler warnings */
7839
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7840
               regnames[index], regnames[base]);
7841
}
7842

    
7843
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7844
                            int fd, int fr, int fs, int ft)
7845
{
7846
    const char *opn = "flt3_arith";
7847

    
7848
    switch (opc) {
7849
    case OPC_ALNV_PS:
7850
        check_cp1_64bitmode(ctx);
7851
        {
7852
            TCGv t0 = tcg_temp_local_new();
7853
            TCGv_i32 fp = tcg_temp_new_i32();
7854
            TCGv_i32 fph = tcg_temp_new_i32();
7855
            int l1 = gen_new_label();
7856
            int l2 = gen_new_label();
7857

    
7858
            gen_load_gpr(t0, fr);
7859
            tcg_gen_andi_tl(t0, t0, 0x7);
7860

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

    
7894
            gen_load_fpr32(fp0, fs);
7895
            gen_load_fpr32(fp1, ft);
7896
            gen_load_fpr32(fp2, fr);
7897
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7898
            tcg_temp_free_i32(fp0);
7899
            tcg_temp_free_i32(fp1);
7900
            gen_store_fpr32(fp2, fd);
7901
            tcg_temp_free_i32(fp2);
7902
        }
7903
        opn = "madd.s";
7904
        break;
7905
    case OPC_MADD_D:
7906
        check_cop1x(ctx);
7907
        check_cp1_registers(ctx, fd | fs | ft | fr);
7908
        {
7909
            TCGv_i64 fp0 = tcg_temp_new_i64();
7910
            TCGv_i64 fp1 = tcg_temp_new_i64();
7911
            TCGv_i64 fp2 = tcg_temp_new_i64();
7912

    
7913
            gen_load_fpr64(ctx, fp0, fs);
7914
            gen_load_fpr64(ctx, fp1, ft);
7915
            gen_load_fpr64(ctx, fp2, fr);
7916
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7917
            tcg_temp_free_i64(fp0);
7918
            tcg_temp_free_i64(fp1);
7919
            gen_store_fpr64(ctx, fp2, fd);
7920
            tcg_temp_free_i64(fp2);
7921
        }
7922
        opn = "madd.d";
7923
        break;
7924
    case OPC_MADD_PS:
7925
        check_cp1_64bitmode(ctx);
7926
        {
7927
            TCGv_i64 fp0 = tcg_temp_new_i64();
7928
            TCGv_i64 fp1 = tcg_temp_new_i64();
7929
            TCGv_i64 fp2 = tcg_temp_new_i64();
7930

    
7931
            gen_load_fpr64(ctx, fp0, fs);
7932
            gen_load_fpr64(ctx, fp1, ft);
7933
            gen_load_fpr64(ctx, fp2, fr);
7934
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7935
            tcg_temp_free_i64(fp0);
7936
            tcg_temp_free_i64(fp1);
7937
            gen_store_fpr64(ctx, fp2, fd);
7938
            tcg_temp_free_i64(fp2);
7939
        }
7940
        opn = "madd.ps";
7941
        break;
7942
    case OPC_MSUB_S:
7943
        check_cop1x(ctx);
7944
        {
7945
            TCGv_i32 fp0 = tcg_temp_new_i32();
7946
            TCGv_i32 fp1 = tcg_temp_new_i32();
7947
            TCGv_i32 fp2 = tcg_temp_new_i32();
7948

    
7949
            gen_load_fpr32(fp0, fs);
7950
            gen_load_fpr32(fp1, ft);
7951
            gen_load_fpr32(fp2, fr);
7952
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7953
            tcg_temp_free_i32(fp0);
7954
            tcg_temp_free_i32(fp1);
7955
            gen_store_fpr32(fp2, fd);
7956
            tcg_temp_free_i32(fp2);
7957
        }
7958
        opn = "msub.s";
7959
        break;
7960
    case OPC_MSUB_D:
7961
        check_cop1x(ctx);
7962
        check_cp1_registers(ctx, fd | fs | ft | fr);
7963
        {
7964
            TCGv_i64 fp0 = tcg_temp_new_i64();
7965
            TCGv_i64 fp1 = tcg_temp_new_i64();
7966
            TCGv_i64 fp2 = tcg_temp_new_i64();
7967

    
7968
            gen_load_fpr64(ctx, fp0, fs);
7969
            gen_load_fpr64(ctx, fp1, ft);
7970
            gen_load_fpr64(ctx, fp2, fr);
7971
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7972
            tcg_temp_free_i64(fp0);
7973
            tcg_temp_free_i64(fp1);
7974
            gen_store_fpr64(ctx, fp2, fd);
7975
            tcg_temp_free_i64(fp2);
7976
        }
7977
        opn = "msub.d";
7978
        break;
7979
    case OPC_MSUB_PS:
7980
        check_cp1_64bitmode(ctx);
7981
        {
7982
            TCGv_i64 fp0 = tcg_temp_new_i64();
7983
            TCGv_i64 fp1 = tcg_temp_new_i64();
7984
            TCGv_i64 fp2 = tcg_temp_new_i64();
7985

    
7986
            gen_load_fpr64(ctx, fp0, fs);
7987
            gen_load_fpr64(ctx, fp1, ft);
7988
            gen_load_fpr64(ctx, fp2, fr);
7989
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7990
            tcg_temp_free_i64(fp0);
7991
            tcg_temp_free_i64(fp1);
7992
            gen_store_fpr64(ctx, fp2, fd);
7993
            tcg_temp_free_i64(fp2);
7994
        }
7995
        opn = "msub.ps";
7996
        break;
7997
    case OPC_NMADD_S:
7998
        check_cop1x(ctx);
7999
        {
8000
            TCGv_i32 fp0 = tcg_temp_new_i32();
8001
            TCGv_i32 fp1 = tcg_temp_new_i32();
8002
            TCGv_i32 fp2 = tcg_temp_new_i32();
8003

    
8004
            gen_load_fpr32(fp0, fs);
8005
            gen_load_fpr32(fp1, ft);
8006
            gen_load_fpr32(fp2, fr);
8007
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
8008
            tcg_temp_free_i32(fp0);
8009
            tcg_temp_free_i32(fp1);
8010
            gen_store_fpr32(fp2, fd);
8011
            tcg_temp_free_i32(fp2);
8012
        }
8013
        opn = "nmadd.s";
8014
        break;
8015
    case OPC_NMADD_D:
8016
        check_cop1x(ctx);
8017
        check_cp1_registers(ctx, fd | fs | ft | fr);
8018
        {
8019
            TCGv_i64 fp0 = tcg_temp_new_i64();
8020
            TCGv_i64 fp1 = tcg_temp_new_i64();
8021
            TCGv_i64 fp2 = tcg_temp_new_i64();
8022

    
8023
            gen_load_fpr64(ctx, fp0, fs);
8024
            gen_load_fpr64(ctx, fp1, ft);
8025
            gen_load_fpr64(ctx, fp2, fr);
8026
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
8027
            tcg_temp_free_i64(fp0);
8028
            tcg_temp_free_i64(fp1);
8029
            gen_store_fpr64(ctx, fp2, fd);
8030
            tcg_temp_free_i64(fp2);
8031
        }
8032
        opn = "nmadd.d";
8033
        break;
8034
    case OPC_NMADD_PS:
8035
        check_cp1_64bitmode(ctx);
8036
        {
8037
            TCGv_i64 fp0 = tcg_temp_new_i64();
8038
            TCGv_i64 fp1 = tcg_temp_new_i64();
8039
            TCGv_i64 fp2 = tcg_temp_new_i64();
8040

    
8041
            gen_load_fpr64(ctx, fp0, fs);
8042
            gen_load_fpr64(ctx, fp1, ft);
8043
            gen_load_fpr64(ctx, fp2, fr);
8044
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
8045
            tcg_temp_free_i64(fp0);
8046
            tcg_temp_free_i64(fp1);
8047
            gen_store_fpr64(ctx, fp2, fd);
8048
            tcg_temp_free_i64(fp2);
8049
        }
8050
        opn = "nmadd.ps";
8051
        break;
8052
    case OPC_NMSUB_S:
8053
        check_cop1x(ctx);
8054
        {
8055
            TCGv_i32 fp0 = tcg_temp_new_i32();
8056
            TCGv_i32 fp1 = tcg_temp_new_i32();
8057
            TCGv_i32 fp2 = tcg_temp_new_i32();
8058

    
8059
            gen_load_fpr32(fp0, fs);
8060
            gen_load_fpr32(fp1, ft);
8061
            gen_load_fpr32(fp2, fr);
8062
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
8063
            tcg_temp_free_i32(fp0);
8064
            tcg_temp_free_i32(fp1);
8065
            gen_store_fpr32(fp2, fd);
8066
            tcg_temp_free_i32(fp2);
8067
        }
8068
        opn = "nmsub.s";
8069
        break;
8070
    case OPC_NMSUB_D:
8071
        check_cop1x(ctx);
8072
        check_cp1_registers(ctx, fd | fs | ft | fr);
8073
        {
8074
            TCGv_i64 fp0 = tcg_temp_new_i64();
8075
            TCGv_i64 fp1 = tcg_temp_new_i64();
8076
            TCGv_i64 fp2 = tcg_temp_new_i64();
8077

    
8078
            gen_load_fpr64(ctx, fp0, fs);
8079
            gen_load_fpr64(ctx, fp1, ft);
8080
            gen_load_fpr64(ctx, fp2, fr);
8081
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
8082
            tcg_temp_free_i64(fp0);
8083
            tcg_temp_free_i64(fp1);
8084
            gen_store_fpr64(ctx, fp2, fd);
8085
            tcg_temp_free_i64(fp2);
8086
        }
8087
        opn = "nmsub.d";
8088
        break;
8089
    case OPC_NMSUB_PS:
8090
        check_cp1_64bitmode(ctx);
8091
        {
8092
            TCGv_i64 fp0 = tcg_temp_new_i64();
8093
            TCGv_i64 fp1 = tcg_temp_new_i64();
8094
            TCGv_i64 fp2 = tcg_temp_new_i64();
8095

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

    
8117
static void
8118
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8119
{
8120
    TCGv t0;
8121

    
8122
    check_insn(env, ctx, ISA_MIPS32R2);
8123
    t0 = tcg_temp_new();
8124

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

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

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

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

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

    
8231
/* ISA extensions (ASEs) */
8232
/* MIPS16 extension to MIPS32 */
8233

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

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

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

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

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

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

    
8345
static int xlat (int r)
8346
{
8347
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8348

    
8349
  return map[r];
8350
}
8351

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

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

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

    
8414
    gen_load_gpr(t0, 29);
8415

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

    
8422
    if (do_ra) {
8423
        DECR_AND_STORE(31);
8424
    }
8425

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

    
8449
    if (do_s1) {
8450
        DECR_AND_STORE(17);
8451
    }
8452
    if (do_s0) {
8453
        DECR_AND_STORE(16);
8454
    }
8455

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

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

    
8501
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8502
    tcg_temp_free(t0);
8503
    tcg_temp_free(t1);
8504
}
8505

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

    
8515
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8516

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

    
8523
    if (do_ra) {
8524
        DECR_AND_LOAD(31);
8525
    }
8526

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

    
8550
    if (do_s1) {
8551
        DECR_AND_LOAD(17);
8552
    }
8553
    if (do_s0) {
8554
        DECR_AND_LOAD(16);
8555
    }
8556

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

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

    
8602
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8603
    tcg_temp_free(t0);
8604
    tcg_temp_free(t1);
8605
}
8606

    
8607
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8608
                         int is_64_bit, int extended)
8609
{
8610
    TCGv t0;
8611

    
8612
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8613
        generate_exception(ctx, EXCP_RI);
8614
        return;
8615
    }
8616

    
8617
    t0 = tcg_temp_new();
8618

    
8619
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8620
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8621
    if (!is_64_bit) {
8622
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8623
    }
8624

    
8625
    tcg_temp_free(t0);
8626
}
8627

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

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

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

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

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

    
8870
    return 4;
8871
}
8872

    
8873
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8874
                              int *is_branch)
8875
{
8876
    int rx, ry;
8877
    int sa;
8878
    int op, cnvt_op, op1, offset;
8879
    int funct;
8880
    int n_bytes;
8881

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

    
8890
    n_bytes = 2;
8891

    
8892
    switch (op) {
8893
    case M16_OPC_ADDIUSP:
8894
        {
8895
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8896

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

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

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

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

    
8988
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8989
        }
8990
        break;
8991
    case M16_OPC_I8:
8992
        {
8993
            int reg32;
8994

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

    
9019
                    if (framesize == 0) {
9020
                        framesize = 128;
9021
                    } else {
9022
                        framesize = framesize << 3;
9023
                    }
9024

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

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

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

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

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

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

    
9152
                if (link) {
9153
                    op = nd ? OPC_JALRC : OPC_JALRS;
9154
                } else {
9155
                    op = OPC_JR;
9156
                }
9157

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

    
9320
    return n_bytes;
9321
}
9322

    
9323
/* microMIPS extension to MIPS32 */
9324

    
9325
/* microMIPS32 major opcodes */
9326

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

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

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

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

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

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

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

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

    
9405
/* POOL32A encoding of minor opcode field */
9406

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

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

    
9431
    MOVN = 0x0,
9432
    MOVZ = 0x1,
9433
    LWXS = 0x4,
9434

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

    
9441
/* POOL32AXF encoding of minor opcode field extension */
9442

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

    
9452
    MFC0 = 0x03,
9453
    MTC0 = 0x0b,
9454

    
9455
    /* bits 13..12 for 0x01 */
9456
    MFHI_ACC = 0x0,
9457
    MFLO_ACC = 0x1,
9458
    MTHI_ACC = 0x2,
9459
    MTLO_ACC = 0x3,
9460

    
9461
    /* bits 13..12 for 0x2a */
9462
    MADD_ACC = 0x0,
9463
    MADDU_ACC = 0x1,
9464
    MSUB_ACC = 0x2,
9465
    MSUBU_ACC = 0x3,
9466

    
9467
    /* bits 13..12 for 0x32 */
9468
    MULT_ACC = 0x0,
9469
    MULTU_ACC = 0x0,
9470

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

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

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

    
9502
    /* bits 15..12 for 0x05 */
9503
    RDPGPR = 0xe,
9504
    WRPGPR = 0xf,
9505

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

    
9516
    /* bits 15..12 for 0x15 */
9517
    DMT = 0x0,
9518
    DVPE = 0x1,
9519
    EMT = 0x2,
9520
    EVPE = 0x3,
9521

    
9522
    /* bits 15..12 for 0x1d */
9523
    DI = 0x4,
9524
    EI = 0x5,
9525

    
9526
    /* bits 15..12 for 0x2d */
9527
    SYNC = 0x6,
9528
    SYSCALL = 0x8,
9529
    SDBBP = 0xd,
9530

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

    
9538
/* POOL32B encoding of minor opcode field (bits 15..12) */
9539

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

    
9554
/* POOL32C encoding of minor opcode field (bits 15..12) */
9555

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

    
9575
/* POOL32F encoding of minor opcode field (bits 5..0) */
9576

    
9577
enum {
9578
    /* These are the bit 7..6 values */
9579
    ADD_FMT = 0x0,
9580
    MOVN_FMT = 0x0,
9581

    
9582
    SUB_FMT = 0x1,
9583
    MOVZ_FMT = 0x1,
9584

    
9585
    MUL_FMT = 0x2,
9586

    
9587
    DIV_FMT = 0x3,
9588

    
9589
    /* These are the bit 8..6 values */
9590
    RSQRT2_FMT = 0x0,
9591
    MOVF_FMT = 0x0,
9592

    
9593
    LWXC1 = 0x1,
9594
    MOVT_FMT = 0x1,
9595

    
9596
    PLL_PS = 0x2,
9597
    SWXC1 = 0x2,
9598

    
9599
    PLU_PS = 0x3,
9600
    LDXC1 = 0x3,
9601

    
9602
    PUL_PS = 0x4,
9603
    SDXC1 = 0x4,
9604
    RECIP2_FMT = 0x4,
9605

    
9606
    PUU_PS = 0x5,
9607
    LUXC1 = 0x5,
9608

    
9609
    CVT_PS_S = 0x6,
9610
    SUXC1 = 0x6,
9611
    ADDR_PS = 0x6,
9612
    PREFX = 0x6,
9613

    
9614
    MULR_PS = 0x7,
9615

    
9616
    MADD_S = 0x01,
9617
    MADD_D = 0x09,
9618
    MADD_PS = 0x11,
9619
    ALNV_PS = 0x19,
9620
    MSUB_S = 0x21,
9621
    MSUB_D = 0x29,
9622
    MSUB_PS = 0x31,
9623

    
9624
    NMADD_S = 0x02,
9625
    NMADD_D = 0x0a,
9626
    NMADD_PS = 0x12,
9627
    NMSUB_S = 0x22,
9628
    NMSUB_D = 0x2a,
9629
    NMSUB_PS = 0x32,
9630

    
9631
    POOL32FXF = 0x3b,
9632

    
9633
    CABS_COND_FMT = 0x1c,              /* MIPS3D */
9634
    C_COND_FMT = 0x3c
9635
};
9636

    
9637
/* POOL32Fxf encoding of minor opcode extension field */
9638

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

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

    
9675
/* POOL32I encoding of minor opcode field (bits 25..21) */
9676

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

    
9709
/* POOL16A encoding of minor opcode field */
9710

    
9711
enum {
9712
    ADDU16 = 0x0,
9713
    SUBU16 = 0x1
9714
};
9715

    
9716
/* POOL16B encoding of minor opcode field */
9717

    
9718
enum {
9719
    SLL16 = 0x0,
9720
    SRL16 = 0x1
9721
};
9722

    
9723
/* POOL16C encoding of minor opcode field */
9724

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

    
9743
/* POOL16D encoding of minor opcode field */
9744

    
9745
enum {
9746
    ADDIUS5 = 0x0,
9747
    ADDIUSP = 0x1
9748
};
9749

    
9750
/* POOL16E encoding of minor opcode field */
9751

    
9752
enum {
9753
    ADDIUR2 = 0x0,
9754
    ADDIUR1SP = 0x1
9755
};
9756

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

    
9761
    return map[r];
9762
}
9763

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

    
9769
    return map[r];
9770
}
9771

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

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

    
9787
static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9788
{
9789
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9790

    
9791
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9792
}
9793

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

    
9800
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9801
}
9802

    
9803
static void gen_addiusp (CPUState *env, DisasContext *ctx)
9804
{
9805
    int encoded = ZIMM(ctx->opcode, 1, 9);
9806
    int decoded;
9807

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

    
9818
    gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9819
}
9820

    
9821
static void gen_addius5 (CPUState *env, DisasContext *ctx)
9822
{
9823
    int imm = SIMM(ctx->opcode, 1, 4);
9824
    int rd = (ctx->opcode >> 5) & 0x1f;
9825

    
9826
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9827
}
9828

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

    
9837
    gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9838
}
9839

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

    
9846
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9847
        generate_exception(ctx, EXCP_RI);
9848
        return;
9849
    }
9850

    
9851
    t0 = tcg_temp_new();
9852

    
9853
    gen_base_offset_addr(ctx, t0, base, offset);
9854

    
9855
    t1 = tcg_const_tl(reglist);
9856
    t2 = tcg_const_i32(ctx->mem_idx);
9857

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

    
9881

    
9882
static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9883
{
9884
    int rd = mmreg((ctx->opcode >> 3) & 0x7);
9885
    int rs = mmreg(ctx->opcode & 0x7);
9886
    int opc;
9887

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

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

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

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

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

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

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

    
10010
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10011
{
10012
    TCGv t0 = tcg_temp_new();
10013
    TCGv t1 = tcg_temp_new();
10014

    
10015
    gen_load_gpr(t0, base);
10016

    
10017
    if (index != 0) {
10018
        gen_load_gpr(t1, index);
10019
        tcg_gen_shli_tl(t1, t1, 2);
10020
        gen_op_addr_add(ctx, t0, t1, t0);
10021
    }
10022

    
10023
    save_cpu_state(ctx, 0);
10024
    op_ld_lw(t1, t0, ctx);
10025
    gen_store_gpr(t1, rd);
10026

    
10027
    tcg_temp_free(t0);
10028
    tcg_temp_free(t1);
10029
}
10030

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

    
10037
    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
10038
        generate_exception(ctx, EXCP_RI);
10039
        return;
10040
    }
10041

    
10042
    t0 = tcg_temp_new();
10043
    t1 = tcg_temp_new();
10044

    
10045
    gen_base_offset_addr(ctx, t0, base, offset);
10046

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

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

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

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

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

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

    
10351
/* Values for microMIPS fmt field.  Variable-width, depending on which
10352
   formats the instruction supports.  */
10353

    
10354
enum {
10355
    FMT_SD_S = 0,
10356
    FMT_SD_D = 1,
10357

    
10358
    FMT_SDPS_S = 0,
10359
    FMT_SDPS_D = 1,
10360
    FMT_SDPS_PS = 2,
10361

    
10362
    FMT_SWL_S = 0,
10363
    FMT_SWL_W = 1,
10364
    FMT_SWL_L = 2,
10365

    
10366
    FMT_DWL_D = 0,
10367
    FMT_DWL_W = 1,
10368
    FMT_DWL_L = 2
10369
};
10370

    
10371
static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10372
{
10373
    int extension = (ctx->opcode >> 6) & 0x3ff;
10374
    uint32_t mips32_op;
10375

    
10376
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10377
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10378
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10379

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
10627
    insn = lduw_code(ctx->pc + 2);
10628
    ctx->opcode = (ctx->opcode << 16) | insn;
10629

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

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

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

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

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

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

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

    
11375
static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11376
{
11377
    uint32_t op;
11378

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

    
11387
    op = (ctx->opcode >> 10) & 0x3f;
11388
    /* Enforce properly-sized instructions in a delay slot */
11389
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11390
        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11391

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

    
11476
            switch (ctx->opcode & 0x1) {
11477
            case ADDU16:
11478
                opc = OPC_ADDU;
11479
                break;
11480
            case SUBU16:
11481
                opc = OPC_SUBU;
11482
                break;
11483
            }
11484

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

    
11496
            switch (ctx->opcode & 0x1) {
11497
            case SLL16:
11498
                opc = OPC_SLL;
11499
                break;
11500
            case SRL16:
11501
                opc = OPC_SRL;
11502
                break;
11503
            }
11504

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

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

    
11533
            rd = rd_enc[enc_dest];
11534
            re = re_enc[enc_dest];
11535
            rs = rs_rt_enc[enc_rs];
11536
            rt = rs_rt_enc[enc_rt];
11537

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

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

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

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

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

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

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

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

    
11612
            gen_st(ctx, OPC_SW, rd, rb, offset);
11613
        }
11614
        break;
11615
    case MOVE16:
11616
        {
11617
            int rd = uMIPS_RD5(ctx->opcode);
11618
            int rs = uMIPS_RS5(ctx->opcode);
11619

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

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

    
11681
    return 2;
11682
}
11683

    
11684
/* SmartMIPS extension to MIPS32 */
11685

    
11686
#if defined(TARGET_MIPS64)
11687

    
11688
/* MDMX extension to MIPS64 */
11689

    
11690
#endif
11691

    
11692
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11693
{
11694
    int32_t offset;
11695
    int rs, rt, rd, sa;
11696
    uint32_t op, op1, op2;
11697
    int16_t imm;
11698

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

    
11706
    /* Handle blikely not taken case */
11707
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11708
        int l1 = gen_new_label();
11709

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

    
11717
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11718
        tcg_gen_debug_insn_start(ctx->pc);
11719

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

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

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

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

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

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

    
12226
    /* Floating point (COP1). */
12227
    case OPC_LWC1:
12228
    case OPC_LDC1:
12229
    case OPC_SWC1:
12230
    case OPC_SDC1:
12231
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12232
        break;
12233

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

    
12283
    /* COP2.  */
12284
    case OPC_LWC2:
12285
    case OPC_LDC2:
12286
    case OPC_SWC2:
12287
    case OPC_SDC2:
12288
    case OPC_CP2:
12289
        /* COP2: Not implemented. */
12290
        generate_exception_err(ctx, EXCP_CpU, 2);
12291
        break;
12292

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

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

    
12378
static inline void
12379
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12380
                                int search_pc)
12381
{
12382
    DisasContext ctx;
12383
    target_ulong pc_start;
12384
    uint16_t *gen_opc_end;
12385
    CPUBreakpoint *bp;
12386
    int j, lj = -1;
12387
    int num_insns;
12388
    int max_insns;
12389
    int insn_bytes;
12390
    int is_branch;
12391

    
12392
    if (search_pc)
12393
        qemu_log("search pc %d\n", search_pc);
12394

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

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

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

    
12467
        num_insns++;
12468

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

    
12476
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12477
            break;
12478

    
12479
        if (gen_opc_ptr >= gen_opc_end)
12480
            break;
12481

    
12482
        if (num_insns >= max_insns)
12483
            break;
12484

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

    
12532
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12533
{
12534
    gen_intermediate_code_internal(env, tb, 0);
12535
}
12536

    
12537
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12538
{
12539
    gen_intermediate_code_internal(env, tb, 1);
12540
}
12541

    
12542
static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
12543
                           int flags)
12544
{
12545
    int i;
12546
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12547

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

    
12570

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

    
12579
#undef printfpr
12580
}
12581

    
12582
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12583
/* Debug help: The architecture requires 32bit code to maintain proper
12584
   sign-extended values on 64bit machines.  */
12585

    
12586
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12587

    
12588
static void
12589
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12590
                                fprintf_function cpu_fprintf,
12591
                                int flags)
12592
{
12593
    int i;
12594

    
12595
    if (!SIGN_EXT_P(env->active_tc.PC))
12596
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12597
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
12598
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12599
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
12600
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12601
    if (!SIGN_EXT_P(env->btarget))
12602
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12603

    
12604
    for (i = 0; i < 32; i++) {
12605
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12606
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12607
    }
12608

    
12609
    if (!SIGN_EXT_P(env->CP0_EPC))
12610
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12611
    if (!SIGN_EXT_P(env->lladdr))
12612
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12613
}
12614
#endif
12615

    
12616
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
12617
                     int flags)
12618
{
12619
    int i;
12620

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

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

    
12645
static void mips_tcg_init(void)
12646
{
12647
    int i;
12648
    static int inited;
12649

    
12650
    /* Initialize various static tables. */
12651
    if (inited)
12652
        return;
12653

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

    
12683
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12684
                                      offsetof(CPUState, active_fpu.fcr0),
12685
                                      "fcr0");
12686
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12687
                                       offsetof(CPUState, active_fpu.fcr31),
12688
                                       "fcr31");
12689

    
12690
    /* register helpers */
12691
#define GEN_HELPER 2
12692
#include "helper.h"
12693

    
12694
    inited = 1;
12695
}
12696

    
12697
#include "translate_init.c"
12698

    
12699
CPUMIPSState *cpu_mips_init (const char *cpu_model)
12700
{
12701
    CPUMIPSState *env;
12702
    const mips_def_t *def;
12703

    
12704
    def = cpu_mips_find_by_name(cpu_model);
12705
    if (!def)
12706
        return NULL;
12707
    env = g_malloc0(sizeof(CPUMIPSState));
12708
    env->cpu_model = def;
12709
    env->cpu_model_str = cpu_model;
12710

    
12711
    cpu_exec_init(env);
12712
#ifndef CONFIG_USER_ONLY
12713
    mmu_init(env, def);
12714
#endif
12715
    fpu_init(env, def);
12716
    mvp_init(env, def);
12717
    mips_tcg_init();
12718
    cpu_reset(env);
12719
    qemu_init_vcpu(env);
12720
    return env;
12721
}
12722

    
12723
void cpu_reset (CPUMIPSState *env)
12724
{
12725
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12726
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12727
        log_cpu_state(env, 0);
12728
    }
12729

    
12730
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12731
    tlb_flush(env, 1);
12732

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

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

    
12806
        for (i = 0; i < 7; i++) {
12807
            env->CP0_WatchLo[i] = 0;
12808
            env->CP0_WatchHi[i] = 0x80000000;
12809
        }
12810
        env->CP0_WatchLo[7] = 0;
12811
        env->CP0_WatchHi[7] = 0;
12812
    }
12813
    /* Count register increments in debug mode, EJTAG version 1 */
12814
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12815
    env->hflags = MIPS_HFLAG_CP0;
12816

    
12817
    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
12818
        int i;
12819

    
12820
        /* Only TC0 on VPE 0 starts as active.  */
12821
        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
12822
            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
12823
            env->tcs[i].CP0_TCHalt = 1;
12824
        }
12825
        env->active_tc.CP0_TCHalt = 1;
12826
        env->halted = 1;
12827

    
12828
        if (!env->cpu_index) {
12829
            /* VPE0 starts up enabled.  */
12830
            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
12831
            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
12832

    
12833
            /* TC0 starts up unhalted.  */
12834
            env->halted = 0;
12835
            env->active_tc.CP0_TCHalt = 0;
12836
            env->tcs[0].CP0_TCHalt = 0;
12837
            /* With thread 0 active.  */
12838
            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
12839
            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
12840
        }
12841
    }
12842
#endif
12843
#if defined(TARGET_MIPS64)
12844
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12845
        env->hflags |= MIPS_HFLAG_64;
12846
    }
12847
#endif
12848
    env->exception_index = EXCP_NONE;
12849
}
12850

    
12851
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
12852
{
12853
    env->active_tc.PC = gen_opc_pc[pc_pos];
12854
    env->hflags &= ~MIPS_HFLAG_BMASK;
12855
    env->hflags |= gen_opc_hflags[pc_pos];
12856
}