Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 6fbab869

History | View | Annotate | Download (350.2 kB)

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

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

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

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

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

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

    
279
/* Special3 opcodes */
280
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
281

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

    
298
/* BSHFL opcodes */
299
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
300

    
301
enum {
302
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
303
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
304
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
305
};
306

    
307
/* DBSHFL opcodes */
308
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
309

    
310
enum {
311
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
312
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
313
};
314

    
315
/* Coprocessor 0 (rs field) */
316
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
317

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

    
333
/* MFMC0 opcodes */
334
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
335

    
336
enum {
337
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
338
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
339
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
340
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
341
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
342
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
343
};
344

    
345
/* Coprocessor 0 (with rs == C0) */
346
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
347

    
348
enum {
349
    OPC_TLBR     = 0x01 | OPC_C0,
350
    OPC_TLBWI    = 0x02 | OPC_C0,
351
    OPC_TLBWR    = 0x06 | OPC_C0,
352
    OPC_TLBP     = 0x08 | OPC_C0,
353
    OPC_RFE      = 0x10 | OPC_C0,
354
    OPC_ERET     = 0x18 | OPC_C0,
355
    OPC_DERET    = 0x1F | OPC_C0,
356
    OPC_WAIT     = 0x20 | OPC_C0,
357
};
358

    
359
/* Coprocessor 1 (rs field) */
360
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
361

    
362
/* Values for the fmt field in FP instructions */
363
enum {
364
    /* 0 - 15 are reserved */
365
    FMT_S = 16,          /* single fp */
366
    FMT_D = 17,          /* double fp */
367
    FMT_E = 18,          /* extended fp */
368
    FMT_Q = 19,          /* quad fp */
369
    FMT_W = 20,          /* 32-bit fixed */
370
    FMT_L = 21,          /* 64-bit fixed */
371
    FMT_PS = 22,         /* paired single fp */
372
    /* 23 - 31 are reserved */
373
};
374

    
375
enum {
376
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
377
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
378
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
379
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
380
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
381
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
382
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
383
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
384
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
385
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
386
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
387
    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
388
    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
389
    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
390
    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
391
    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
392
    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
393
    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
394
};
395

    
396
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
397
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
398

    
399
enum {
400
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
401
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
402
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
403
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
404
};
405

    
406
enum {
407
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
408
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
409
};
410

    
411
enum {
412
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
413
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
414
};
415

    
416
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
417

    
418
enum {
419
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
420
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
421
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
422
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
423
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
424
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
425
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
426
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
427
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
428
};
429

    
430
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
431

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

    
455
/* global register indices */
456
static TCGv_ptr cpu_env;
457
static TCGv cpu_gpr[32], cpu_PC;
458
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
459
static TCGv cpu_dspctrl, btarget, bcond;
460
static TCGv_i32 hflags;
461
static TCGv_i32 fpu_fcr0, fpu_fcr31;
462

    
463
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
464

    
465
#include "gen-icount.h"
466

    
467
#define gen_helper_0i(name, arg) do {                             \
468
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
469
    gen_helper_##name(helper_tmp);                                \
470
    tcg_temp_free_i32(helper_tmp);                                \
471
    } while(0)
472

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

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

    
485
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
486
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
487
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
488
    tcg_temp_free_i32(helper_tmp);                                \
489
    } while(0)
490

    
491
typedef struct DisasContext {
492
    struct TranslationBlock *tb;
493
    target_ulong pc, saved_pc;
494
    uint32_t opcode;
495
    int singlestep_enabled;
496
    /* Routine used to access memory */
497
    int mem_idx;
498
    uint32_t hflags, saved_hflags;
499
    int bstate;
500
    target_ulong btarget;
501
} DisasContext;
502

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

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

    
517
static const char *regnames_HI[] =
518
    { "HI0", "HI1", "HI2", "HI3", };
519

    
520
static const char *regnames_LO[] =
521
    { "LO0", "LO1", "LO2", "LO3", };
522

    
523
static const char *regnames_ACX[] =
524
    { "ACX0", "ACX1", "ACX2", "ACX3", };
525

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

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

    
543
#define MIPS_INVAL(op)                                                        \
544
do {                                                                          \
545
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
546
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
547
} while (0)
548

    
549
/* General purpose registers moves. */
550
static inline void gen_load_gpr (TCGv t, int reg)
551
{
552
    if (reg == 0)
553
        tcg_gen_movi_tl(t, 0);
554
    else
555
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
556
}
557

    
558
static inline void gen_store_gpr (TCGv t, int reg)
559
{
560
    if (reg != 0)
561
        tcg_gen_mov_tl(cpu_gpr[reg], t);
562
}
563

    
564
/* Moves to/from ACX register.  */
565
static inline void gen_load_ACX (TCGv t, int reg)
566
{
567
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
568
}
569

    
570
static inline void gen_store_ACX (TCGv t, int reg)
571
{
572
    tcg_gen_mov_tl(cpu_ACX[reg], t);
573
}
574

    
575
/* Moves to/from shadow registers. */
576
static inline void gen_load_srsgpr (int from, int to)
577
{
578
    TCGv t0 = tcg_temp_new();
579

    
580
    if (from == 0)
581
        tcg_gen_movi_tl(t0, 0);
582
    else {
583
        TCGv_i32 t2 = tcg_temp_new_i32();
584
        TCGv_ptr addr = tcg_temp_new_ptr();
585

    
586
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
587
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
588
        tcg_gen_andi_i32(t2, t2, 0xf);
589
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
590
        tcg_gen_ext_i32_ptr(addr, t2);
591
        tcg_gen_add_ptr(addr, cpu_env, addr);
592

    
593
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
594
        tcg_temp_free_ptr(addr);
595
        tcg_temp_free_i32(t2);
596
    }
597
    gen_store_gpr(t0, to);
598
    tcg_temp_free(t0);
599
}
600

    
601
static inline void gen_store_srsgpr (int from, int to)
602
{
603
    if (to != 0) {
604
        TCGv t0 = tcg_temp_new();
605
        TCGv_i32 t2 = tcg_temp_new_i32();
606
        TCGv_ptr addr = tcg_temp_new_ptr();
607

    
608
        gen_load_gpr(t0, from);
609
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
610
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
611
        tcg_gen_andi_i32(t2, t2, 0xf);
612
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
613
        tcg_gen_ext_i32_ptr(addr, t2);
614
        tcg_gen_add_ptr(addr, cpu_env, addr);
615

    
616
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
617
        tcg_temp_free_ptr(addr);
618
        tcg_temp_free_i32(t2);
619
        tcg_temp_free(t0);
620
    }
621
}
622

    
623
/* Floating point register moves. */
624
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
625
{
626
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
627
}
628

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

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

    
639
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
640
{
641
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
642
}
643

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

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

    
676
static inline int get_fp_bit (int cc)
677
{
678
    if (cc)
679
        return 24 + cc;
680
    else
681
        return 23;
682
}
683

    
684
/* Tests */
685
static inline void gen_save_pc(target_ulong pc)
686
{
687
    tcg_gen_movi_tl(cpu_PC, pc);
688
}
689

    
690
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
691
{
692
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
693
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
694
        gen_save_pc(ctx->pc);
695
        ctx->saved_pc = ctx->pc;
696
    }
697
    if (ctx->hflags != ctx->saved_hflags) {
698
        tcg_gen_movi_i32(hflags, ctx->hflags);
699
        ctx->saved_hflags = ctx->hflags;
700
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
701
        case MIPS_HFLAG_BR:
702
            break;
703
        case MIPS_HFLAG_BC:
704
        case MIPS_HFLAG_BL:
705
        case MIPS_HFLAG_B:
706
            tcg_gen_movi_tl(btarget, ctx->btarget);
707
            break;
708
        }
709
    }
710
}
711

    
712
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
713
{
714
    ctx->saved_hflags = ctx->hflags;
715
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
716
    case MIPS_HFLAG_BR:
717
        break;
718
    case MIPS_HFLAG_BC:
719
    case MIPS_HFLAG_BL:
720
    case MIPS_HFLAG_B:
721
        ctx->btarget = env->btarget;
722
        break;
723
    }
724
}
725

    
726
static inline void
727
generate_exception_err (DisasContext *ctx, int excp, int err)
728
{
729
    TCGv_i32 texcp = tcg_const_i32(excp);
730
    TCGv_i32 terr = tcg_const_i32(err);
731
    save_cpu_state(ctx, 1);
732
    gen_helper_raise_exception_err(texcp, terr);
733
    tcg_temp_free_i32(terr);
734
    tcg_temp_free_i32(texcp);
735
}
736

    
737
static inline void
738
generate_exception (DisasContext *ctx, int excp)
739
{
740
    save_cpu_state(ctx, 1);
741
    gen_helper_0i(raise_exception, excp);
742
}
743

    
744
/* Addresses computation */
745
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
746
{
747
    tcg_gen_add_tl(ret, arg0, arg1);
748

    
749
#if defined(TARGET_MIPS64)
750
    /* For compatibility with 32-bit code, data reference in user mode
751
       with Status_UX = 0 should be casted to 32-bit and sign extended.
752
       See the MIPS64 PRA manual, section 4.10. */
753
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
754
        !(ctx->hflags & MIPS_HFLAG_UX)) {
755
        tcg_gen_ext32s_i64(ret, ret);
756
    }
757
#endif
758
}
759

    
760
static inline void check_cp0_enabled(DisasContext *ctx)
761
{
762
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
763
        generate_exception_err(ctx, EXCP_CpU, 0);
764
}
765

    
766
static inline void check_cp1_enabled(DisasContext *ctx)
767
{
768
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
769
        generate_exception_err(ctx, EXCP_CpU, 1);
770
}
771

    
772
/* Verify that the processor is running with COP1X instructions enabled.
773
   This is associated with the nabla symbol in the MIPS32 and MIPS64
774
   opcode tables.  */
775

    
776
static inline void check_cop1x(DisasContext *ctx)
777
{
778
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
779
        generate_exception(ctx, EXCP_RI);
780
}
781

    
782
/* Verify that the processor is running with 64-bit floating-point
783
   operations enabled.  */
784

    
785
static inline void check_cp1_64bitmode(DisasContext *ctx)
786
{
787
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
788
        generate_exception(ctx, EXCP_RI);
789
}
790

    
791
/*
792
 * Verify if floating point register is valid; an operation is not defined
793
 * if bit 0 of any register specification is set and the FR bit in the
794
 * Status register equals zero, since the register numbers specify an
795
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
796
 * in the Status register equals one, both even and odd register numbers
797
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
798
 *
799
 * Multiple 64 bit wide registers can be checked by calling
800
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
801
 */
802
static inline void check_cp1_registers(DisasContext *ctx, int regs)
803
{
804
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
805
        generate_exception(ctx, EXCP_RI);
806
}
807

    
808
/* This code generates a "reserved instruction" exception if the
809
   CPU does not support the instruction set corresponding to flags. */
810
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
811
{
812
    if (unlikely(!(env->insn_flags & flags)))
813
        generate_exception(ctx, EXCP_RI);
814
}
815

    
816
/* This code generates a "reserved instruction" exception if 64-bit
817
   instructions are not enabled. */
818
static inline void check_mips_64(DisasContext *ctx)
819
{
820
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
821
        generate_exception(ctx, EXCP_RI);
822
}
823

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

    
877
FOP_CONDS(, 0, d, FMT_D, 64)
878
FOP_CONDS(abs, 1, d, FMT_D, 64)
879
FOP_CONDS(, 0, s, FMT_S, 32)
880
FOP_CONDS(abs, 1, s, FMT_S, 32)
881
FOP_CONDS(, 0, ps, FMT_PS, 64)
882
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
883
#undef FOP_CONDS
884
#undef gen_ldcmp_fpr32
885
#undef gen_ldcmp_fpr64
886

    
887
/* load/store instructions. */
888
#define OP_LD(insn,fname)                                                 \
889
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
890
{                                                                         \
891
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
892
}
893
OP_LD(lb,ld8s);
894
OP_LD(lbu,ld8u);
895
OP_LD(lh,ld16s);
896
OP_LD(lhu,ld16u);
897
OP_LD(lw,ld32s);
898
#if defined(TARGET_MIPS64)
899
OP_LD(lwu,ld32u);
900
OP_LD(ld,ld64);
901
#endif
902
#undef OP_LD
903

    
904
#define OP_ST(insn,fname)                                                  \
905
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
906
{                                                                          \
907
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
908
}
909
OP_ST(sb,st8);
910
OP_ST(sh,st16);
911
OP_ST(sw,st32);
912
#if defined(TARGET_MIPS64)
913
OP_ST(sd,st64);
914
#endif
915
#undef OP_ST
916

    
917
#ifdef CONFIG_USER_ONLY
918
#define OP_LD_ATOMIC(insn,fname)                                           \
919
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
920
{                                                                          \
921
    TCGv t0 = tcg_temp_new();                                              \
922
    tcg_gen_mov_tl(t0, arg1);                                              \
923
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
924
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
925
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
926
    tcg_temp_free(t0);                                                     \
927
}
928
#else
929
#define OP_LD_ATOMIC(insn,fname)                                           \
930
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
931
{                                                                          \
932
    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
933
}
934
#endif
935
OP_LD_ATOMIC(ll,ld32s);
936
#if defined(TARGET_MIPS64)
937
OP_LD_ATOMIC(lld,ld64);
938
#endif
939
#undef OP_LD_ATOMIC
940

    
941
#ifdef CONFIG_USER_ONLY
942
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
943
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
944
{                                                                            \
945
    TCGv t0 = tcg_temp_new();                                                \
946
    int l1 = gen_new_label();                                                \
947
    int l2 = gen_new_label();                                                \
948
                                                                             \
949
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
950
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
951
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
952
    generate_exception(ctx, EXCP_AdES);                                      \
953
    gen_set_label(l1);                                                       \
954
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
955
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
956
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
957
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
958
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
959
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
960
    gen_set_label(l2);                                                       \
961
    tcg_gen_movi_tl(t0, 0);                                                  \
962
    gen_store_gpr(t0, rt);                                                   \
963
    tcg_temp_free(t0);                                                       \
964
}
965
#else
966
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
967
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
968
{                                                                            \
969
    TCGv t0 = tcg_temp_new();                                                \
970
    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
971
    gen_store_gpr(t0, rt);                                                   \
972
    tcg_temp_free(t0);                                                       \
973
}
974
#endif
975
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
976
#if defined(TARGET_MIPS64)
977
OP_ST_ATOMIC(scd,st64,ld64,0x7);
978
#endif
979
#undef OP_ST_ATOMIC
980

    
981
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
982
                                  int base, int16_t offset)
983
{
984
    if (base == 0) {
985
        tcg_gen_movi_tl(addr, offset);
986
    } else if (offset == 0) {
987
        gen_load_gpr(addr, base);
988
    } else {
989
        tcg_gen_movi_tl(addr, offset);
990
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
991
    }
992
}
993

    
994
static target_ulong pc_relative_pc (DisasContext *ctx)
995
{
996
    target_ulong pc = ctx->pc;
997

    
998
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
999
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1000

    
1001
        pc -= branch_bytes;
1002
    }
1003

    
1004
    pc &= ~(target_ulong)3;
1005
    return pc;
1006
}
1007

    
1008
/* Load and store */
1009
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1010
                      int base, int16_t offset)
1011
{
1012
    const char *opn = "ldst";
1013
    TCGv t0 = tcg_temp_new();
1014
    TCGv t1 = tcg_temp_new();
1015

    
1016
    gen_base_offset_addr(ctx, t0, base, offset);
1017
    /* Don't do NOP if destination is zero: we must perform the actual
1018
       memory access. */
1019
    switch (opc) {
1020
#if defined(TARGET_MIPS64)
1021
    case OPC_LWU:
1022
        save_cpu_state(ctx, 0);
1023
        op_ldst_lwu(t0, t0, ctx);
1024
        gen_store_gpr(t0, rt);
1025
        opn = "lwu";
1026
        break;
1027
    case OPC_LD:
1028
        save_cpu_state(ctx, 0);
1029
        op_ldst_ld(t0, t0, ctx);
1030
        gen_store_gpr(t0, rt);
1031
        opn = "ld";
1032
        break;
1033
    case OPC_LLD:
1034
        save_cpu_state(ctx, 0);
1035
        op_ldst_lld(t0, t0, ctx);
1036
        gen_store_gpr(t0, rt);
1037
        opn = "lld";
1038
        break;
1039
    case OPC_SD:
1040
        save_cpu_state(ctx, 0);
1041
        gen_load_gpr(t1, rt);
1042
        op_ldst_sd(t1, t0, ctx);
1043
        opn = "sd";
1044
        break;
1045
    case OPC_LDL:
1046
        save_cpu_state(ctx, 1);
1047
        gen_load_gpr(t1, rt);
1048
        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1049
        gen_store_gpr(t1, rt);
1050
        opn = "ldl";
1051
        break;
1052
    case OPC_SDL:
1053
        save_cpu_state(ctx, 1);
1054
        gen_load_gpr(t1, rt);
1055
        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1056
        opn = "sdl";
1057
        break;
1058
    case OPC_LDR:
1059
        save_cpu_state(ctx, 1);
1060
        gen_load_gpr(t1, rt);
1061
        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1062
        gen_store_gpr(t1, rt);
1063
        opn = "ldr";
1064
        break;
1065
    case OPC_SDR:
1066
        save_cpu_state(ctx, 1);
1067
        gen_load_gpr(t1, rt);
1068
        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1069
        opn = "sdr";
1070
        break;
1071
    case OPC_LDPC:
1072
        save_cpu_state(ctx, 1);
1073
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1074
        gen_op_addr_add(ctx, t0, t0, t1);
1075
        op_ldst_ld(t0, t0, ctx);
1076
        gen_store_gpr(t0, rt);
1077
        break;
1078
#endif
1079
    case OPC_LWPC:
1080
        save_cpu_state(ctx, 1);
1081
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1082
        gen_op_addr_add(ctx, t0, t0, t1);
1083
        op_ldst_lw(t0, t0, ctx);
1084
        gen_store_gpr(t0, rt);
1085
        break;
1086
    case OPC_LW:
1087
        save_cpu_state(ctx, 0);
1088
        op_ldst_lw(t0, t0, ctx);
1089
        gen_store_gpr(t0, rt);
1090
        opn = "lw";
1091
        break;
1092
    case OPC_SW:
1093
        save_cpu_state(ctx, 0);
1094
        gen_load_gpr(t1, rt);
1095
        op_ldst_sw(t1, t0, ctx);
1096
        opn = "sw";
1097
        break;
1098
    case OPC_LH:
1099
        save_cpu_state(ctx, 0);
1100
        op_ldst_lh(t0, t0, ctx);
1101
        gen_store_gpr(t0, rt);
1102
        opn = "lh";
1103
        break;
1104
    case OPC_SH:
1105
        save_cpu_state(ctx, 0);
1106
        gen_load_gpr(t1, rt);
1107
        op_ldst_sh(t1, t0, ctx);
1108
        opn = "sh";
1109
        break;
1110
    case OPC_LHU:
1111
        save_cpu_state(ctx, 0);
1112
        op_ldst_lhu(t0, t0, ctx);
1113
        gen_store_gpr(t0, rt);
1114
        opn = "lhu";
1115
        break;
1116
    case OPC_LB:
1117
        save_cpu_state(ctx, 0);
1118
        op_ldst_lb(t0, t0, ctx);
1119
        gen_store_gpr(t0, rt);
1120
        opn = "lb";
1121
        break;
1122
    case OPC_SB:
1123
        save_cpu_state(ctx, 0);
1124
        gen_load_gpr(t1, rt);
1125
        op_ldst_sb(t1, t0, ctx);
1126
        opn = "sb";
1127
        break;
1128
    case OPC_LBU:
1129
        save_cpu_state(ctx, 0);
1130
        op_ldst_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_SWL:
1142
        save_cpu_state(ctx, 1);
1143
        gen_load_gpr(t1, rt);
1144
        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1145
        opn = "swr";
1146
        break;
1147
    case OPC_LWR:
1148
        save_cpu_state(ctx, 1);
1149
        gen_load_gpr(t1, rt);
1150
        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1151
        gen_store_gpr(t1, rt);
1152
        opn = "lwr";
1153
        break;
1154
    case OPC_SWR:
1155
        save_cpu_state(ctx, 1);
1156
        gen_load_gpr(t1, rt);
1157
        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1158
        opn = "swr";
1159
        break;
1160
    case OPC_LL:
1161
        save_cpu_state(ctx, 1);
1162
        op_ldst_ll(t0, t0, ctx);
1163
        gen_store_gpr(t0, rt);
1164
        opn = "ll";
1165
        break;
1166
    }
1167
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1168
    tcg_temp_free(t0);
1169
    tcg_temp_free(t1);
1170
}
1171

    
1172
/* Store conditional */
1173
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1174
                         int base, int16_t offset)
1175
{
1176
    const char *opn = "st_cond";
1177
    TCGv t0, t1;
1178

    
1179
    t0 = tcg_temp_local_new();
1180

    
1181
    gen_base_offset_addr(ctx, t0, base, offset);
1182
    /* Don't do NOP if destination is zero: we must perform the actual
1183
       memory access. */
1184

    
1185
    t1 = tcg_temp_local_new();
1186
    gen_load_gpr(t1, rt);
1187
    switch (opc) {
1188
#if defined(TARGET_MIPS64)
1189
    case OPC_SCD:
1190
        save_cpu_state(ctx, 0);
1191
        op_ldst_scd(t1, t0, rt, ctx);
1192
        opn = "scd";
1193
        break;
1194
#endif
1195
    case OPC_SC:
1196
        save_cpu_state(ctx, 1);
1197
        op_ldst_sc(t1, t0, rt, ctx);
1198
        opn = "sc";
1199
        break;
1200
    }
1201
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1202
    tcg_temp_free(t1);
1203
    tcg_temp_free(t0);
1204
}
1205

    
1206
/* Load and store */
1207
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1208
                          int base, int16_t offset)
1209
{
1210
    const char *opn = "flt_ldst";
1211
    TCGv t0 = tcg_temp_new();
1212

    
1213
    gen_base_offset_addr(ctx, t0, base, offset);
1214
    /* Don't do NOP if destination is zero: we must perform the actual
1215
       memory access. */
1216
    switch (opc) {
1217
    case OPC_LWC1:
1218
        {
1219
            TCGv_i32 fp0 = tcg_temp_new_i32();
1220

    
1221
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1222
            tcg_gen_trunc_tl_i32(fp0, t0);
1223
            gen_store_fpr32(fp0, ft);
1224
            tcg_temp_free_i32(fp0);
1225
        }
1226
        opn = "lwc1";
1227
        break;
1228
    case OPC_SWC1:
1229
        {
1230
            TCGv_i32 fp0 = tcg_temp_new_i32();
1231
            TCGv t1 = tcg_temp_new();
1232

    
1233
            gen_load_fpr32(fp0, ft);
1234
            tcg_gen_extu_i32_tl(t1, fp0);
1235
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1236
            tcg_temp_free(t1);
1237
            tcg_temp_free_i32(fp0);
1238
        }
1239
        opn = "swc1";
1240
        break;
1241
    case OPC_LDC1:
1242
        {
1243
            TCGv_i64 fp0 = tcg_temp_new_i64();
1244

    
1245
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1246
            gen_store_fpr64(ctx, fp0, ft);
1247
            tcg_temp_free_i64(fp0);
1248
        }
1249
        opn = "ldc1";
1250
        break;
1251
    case OPC_SDC1:
1252
        {
1253
            TCGv_i64 fp0 = tcg_temp_new_i64();
1254

    
1255
            gen_load_fpr64(ctx, fp0, ft);
1256
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1257
            tcg_temp_free_i64(fp0);
1258
        }
1259
        opn = "sdc1";
1260
        break;
1261
    default:
1262
        MIPS_INVAL(opn);
1263
        generate_exception(ctx, EXCP_RI);
1264
        goto out;
1265
    }
1266
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1267
 out:
1268
    tcg_temp_free(t0);
1269
}
1270

    
1271
static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1272
                          uint32_t op, int rt, int rs, int16_t imm)
1273
{
1274
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1275
        check_cp1_enabled(ctx);
1276
        gen_flt_ldst(ctx, op, rt, rs, imm);
1277
    } else {
1278
        generate_exception_err(ctx, EXCP_CpU, 1);
1279
    }
1280
}
1281

    
1282
/* Arithmetic with immediate operand */
1283
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1284
                           int rt, int rs, int16_t imm)
1285
{
1286
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1287
    const char *opn = "imm arith";
1288

    
1289
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1290
        /* If no destination, treat it as a NOP.
1291
           For addi, we must generate the overflow exception when needed. */
1292
        MIPS_DEBUG("NOP");
1293
        return;
1294
    }
1295
    switch (opc) {
1296
    case OPC_ADDI:
1297
        {
1298
            TCGv t0 = tcg_temp_local_new();
1299
            TCGv t1 = tcg_temp_new();
1300
            TCGv t2 = tcg_temp_new();
1301
            int l1 = gen_new_label();
1302

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

    
1307
            tcg_gen_xori_tl(t1, t1, ~uimm);
1308
            tcg_gen_xori_tl(t2, t0, uimm);
1309
            tcg_gen_and_tl(t1, t1, t2);
1310
            tcg_temp_free(t2);
1311
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1312
            tcg_temp_free(t1);
1313
            /* operands of same sign, result different sign */
1314
            generate_exception(ctx, EXCP_OVERFLOW);
1315
            gen_set_label(l1);
1316
            tcg_gen_ext32s_tl(t0, t0);
1317
            gen_store_gpr(t0, rt);
1318
            tcg_temp_free(t0);
1319
        }
1320
        opn = "addi";
1321
        break;
1322
    case OPC_ADDIU:
1323
        if (rs != 0) {
1324
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1325
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1326
        } else {
1327
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1328
        }
1329
        opn = "addiu";
1330
        break;
1331
#if defined(TARGET_MIPS64)
1332
    case OPC_DADDI:
1333
        {
1334
            TCGv t0 = tcg_temp_local_new();
1335
            TCGv t1 = tcg_temp_new();
1336
            TCGv t2 = tcg_temp_new();
1337
            int l1 = gen_new_label();
1338

    
1339
            gen_load_gpr(t1, rs);
1340
            tcg_gen_addi_tl(t0, t1, uimm);
1341

    
1342
            tcg_gen_xori_tl(t1, t1, ~uimm);
1343
            tcg_gen_xori_tl(t2, t0, uimm);
1344
            tcg_gen_and_tl(t1, t1, t2);
1345
            tcg_temp_free(t2);
1346
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1347
            tcg_temp_free(t1);
1348
            /* operands of same sign, result different sign */
1349
            generate_exception(ctx, EXCP_OVERFLOW);
1350
            gen_set_label(l1);
1351
            gen_store_gpr(t0, rt);
1352
            tcg_temp_free(t0);
1353
        }
1354
        opn = "daddi";
1355
        break;
1356
    case OPC_DADDIU:
1357
        if (rs != 0) {
1358
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1359
        } else {
1360
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1361
        }
1362
        opn = "daddiu";
1363
        break;
1364
#endif
1365
    }
1366
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1367
}
1368

    
1369
/* Logic with immediate operand */
1370
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1371
{
1372
    target_ulong uimm;
1373
    const char *opn = "imm logic";
1374

    
1375
    if (rt == 0) {
1376
        /* If no destination, treat it as a NOP. */
1377
        MIPS_DEBUG("NOP");
1378
        return;
1379
    }
1380
    uimm = (uint16_t)imm;
1381
    switch (opc) {
1382
    case OPC_ANDI:
1383
        if (likely(rs != 0))
1384
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1385
        else
1386
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1387
        opn = "andi";
1388
        break;
1389
    case OPC_ORI:
1390
        if (rs != 0)
1391
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1392
        else
1393
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1394
        opn = "ori";
1395
        break;
1396
    case OPC_XORI:
1397
        if (likely(rs != 0))
1398
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1399
        else
1400
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1401
        opn = "xori";
1402
        break;
1403
    case OPC_LUI:
1404
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1405
        opn = "lui";
1406
        break;
1407
    }
1408
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1409
}
1410

    
1411
/* Set on less than with immediate operand */
1412
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1413
{
1414
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1415
    const char *opn = "imm arith";
1416
    TCGv t0;
1417

    
1418
    if (rt == 0) {
1419
        /* If no destination, treat it as a NOP. */
1420
        MIPS_DEBUG("NOP");
1421
        return;
1422
    }
1423
    t0 = tcg_temp_new();
1424
    gen_load_gpr(t0, rs);
1425
    switch (opc) {
1426
    case OPC_SLTI:
1427
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1428
        opn = "slti";
1429
        break;
1430
    case OPC_SLTIU:
1431
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1432
        opn = "sltiu";
1433
        break;
1434
    }
1435
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1436
    tcg_temp_free(t0);
1437
}
1438

    
1439
/* Shifts with immediate operand */
1440
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1441
                          int rt, int rs, int16_t imm)
1442
{
1443
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1444
    const char *opn = "imm shift";
1445
    TCGv t0;
1446

    
1447
    if (rt == 0) {
1448
        /* If no destination, treat it as a NOP. */
1449
        MIPS_DEBUG("NOP");
1450
        return;
1451
    }
1452

    
1453
    t0 = tcg_temp_new();
1454
    gen_load_gpr(t0, rs);
1455
    switch (opc) {
1456
    case OPC_SLL:
1457
        tcg_gen_shli_tl(t0, t0, uimm);
1458
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1459
        opn = "sll";
1460
        break;
1461
    case OPC_SRA:
1462
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1463
        opn = "sra";
1464
        break;
1465
    case OPC_SRL:
1466
        if (uimm != 0) {
1467
            tcg_gen_ext32u_tl(t0, t0);
1468
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1469
        } else {
1470
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1471
        }
1472
        opn = "srl";
1473
        break;
1474
    case OPC_ROTR:
1475
        if (uimm != 0) {
1476
            TCGv_i32 t1 = tcg_temp_new_i32();
1477

    
1478
            tcg_gen_trunc_tl_i32(t1, t0);
1479
            tcg_gen_rotri_i32(t1, t1, uimm);
1480
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1481
            tcg_temp_free_i32(t1);
1482
        } else {
1483
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1484
        }
1485
        opn = "rotr";
1486
        break;
1487
#if defined(TARGET_MIPS64)
1488
    case OPC_DSLL:
1489
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1490
        opn = "dsll";
1491
        break;
1492
    case OPC_DSRA:
1493
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1494
        opn = "dsra";
1495
        break;
1496
    case OPC_DSRL:
1497
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1498
        opn = "dsrl";
1499
        break;
1500
    case OPC_DROTR:
1501
        if (uimm != 0) {
1502
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1503
        } else {
1504
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
1505
        }
1506
        opn = "drotr";
1507
        break;
1508
    case OPC_DSLL32:
1509
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1510
        opn = "dsll32";
1511
        break;
1512
    case OPC_DSRA32:
1513
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1514
        opn = "dsra32";
1515
        break;
1516
    case OPC_DSRL32:
1517
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1518
        opn = "dsrl32";
1519
        break;
1520
    case OPC_DROTR32:
1521
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1522
        opn = "drotr32";
1523
        break;
1524
#endif
1525
    }
1526
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1527
    tcg_temp_free(t0);
1528
}
1529

    
1530
/* Arithmetic */
1531
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1532
                       int rd, int rs, int rt)
1533
{
1534
    const char *opn = "arith";
1535

    
1536
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1537
       && opc != OPC_DADD && opc != OPC_DSUB) {
1538
        /* If no destination, treat it as a NOP.
1539
           For add & sub, we must generate the overflow exception when needed. */
1540
        MIPS_DEBUG("NOP");
1541
        return;
1542
    }
1543

    
1544
    switch (opc) {
1545
    case OPC_ADD:
1546
        {
1547
            TCGv t0 = tcg_temp_local_new();
1548
            TCGv t1 = tcg_temp_new();
1549
            TCGv t2 = tcg_temp_new();
1550
            int l1 = gen_new_label();
1551

    
1552
            gen_load_gpr(t1, rs);
1553
            gen_load_gpr(t2, rt);
1554
            tcg_gen_add_tl(t0, t1, t2);
1555
            tcg_gen_ext32s_tl(t0, t0);
1556
            tcg_gen_xor_tl(t1, t1, t2);
1557
            tcg_gen_xor_tl(t2, t0, t2);
1558
            tcg_gen_andc_tl(t1, t2, t1);
1559
            tcg_temp_free(t2);
1560
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1561
            tcg_temp_free(t1);
1562
            /* operands of same sign, result different sign */
1563
            generate_exception(ctx, EXCP_OVERFLOW);
1564
            gen_set_label(l1);
1565
            gen_store_gpr(t0, rd);
1566
            tcg_temp_free(t0);
1567
        }
1568
        opn = "add";
1569
        break;
1570
    case OPC_ADDU:
1571
        if (rs != 0 && rt != 0) {
1572
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1573
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1574
        } else if (rs == 0 && rt != 0) {
1575
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1576
        } else if (rs != 0 && rt == 0) {
1577
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1578
        } else {
1579
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1580
        }
1581
        opn = "addu";
1582
        break;
1583
    case OPC_SUB:
1584
        {
1585
            TCGv t0 = tcg_temp_local_new();
1586
            TCGv t1 = tcg_temp_new();
1587
            TCGv t2 = tcg_temp_new();
1588
            int l1 = gen_new_label();
1589

    
1590
            gen_load_gpr(t1, rs);
1591
            gen_load_gpr(t2, rt);
1592
            tcg_gen_sub_tl(t0, t1, t2);
1593
            tcg_gen_ext32s_tl(t0, t0);
1594
            tcg_gen_xor_tl(t2, t1, t2);
1595
            tcg_gen_xor_tl(t1, t0, t1);
1596
            tcg_gen_and_tl(t1, t1, t2);
1597
            tcg_temp_free(t2);
1598
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1599
            tcg_temp_free(t1);
1600
            /* operands of different sign, first operand and result different sign */
1601
            generate_exception(ctx, EXCP_OVERFLOW);
1602
            gen_set_label(l1);
1603
            gen_store_gpr(t0, rd);
1604
            tcg_temp_free(t0);
1605
        }
1606
        opn = "sub";
1607
        break;
1608
    case OPC_SUBU:
1609
        if (rs != 0 && rt != 0) {
1610
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1611
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1612
        } else if (rs == 0 && rt != 0) {
1613
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1614
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1615
        } else if (rs != 0 && rt == 0) {
1616
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1617
        } else {
1618
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1619
        }
1620
        opn = "subu";
1621
        break;
1622
#if defined(TARGET_MIPS64)
1623
    case OPC_DADD:
1624
        {
1625
            TCGv t0 = tcg_temp_local_new();
1626
            TCGv t1 = tcg_temp_new();
1627
            TCGv t2 = tcg_temp_new();
1628
            int l1 = gen_new_label();
1629

    
1630
            gen_load_gpr(t1, rs);
1631
            gen_load_gpr(t2, rt);
1632
            tcg_gen_add_tl(t0, t1, t2);
1633
            tcg_gen_xor_tl(t1, t1, t2);
1634
            tcg_gen_xor_tl(t2, t0, t2);
1635
            tcg_gen_andc_tl(t1, t2, t1);
1636
            tcg_temp_free(t2);
1637
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1638
            tcg_temp_free(t1);
1639
            /* operands of same sign, result different sign */
1640
            generate_exception(ctx, EXCP_OVERFLOW);
1641
            gen_set_label(l1);
1642
            gen_store_gpr(t0, rd);
1643
            tcg_temp_free(t0);
1644
        }
1645
        opn = "dadd";
1646
        break;
1647
    case OPC_DADDU:
1648
        if (rs != 0 && rt != 0) {
1649
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1650
        } else if (rs == 0 && rt != 0) {
1651
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1652
        } else if (rs != 0 && rt == 0) {
1653
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1654
        } else {
1655
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1656
        }
1657
        opn = "daddu";
1658
        break;
1659
    case OPC_DSUB:
1660
        {
1661
            TCGv t0 = tcg_temp_local_new();
1662
            TCGv t1 = tcg_temp_new();
1663
            TCGv t2 = tcg_temp_new();
1664
            int l1 = gen_new_label();
1665

    
1666
            gen_load_gpr(t1, rs);
1667
            gen_load_gpr(t2, rt);
1668
            tcg_gen_sub_tl(t0, t1, t2);
1669
            tcg_gen_xor_tl(t2, t1, t2);
1670
            tcg_gen_xor_tl(t1, t0, t1);
1671
            tcg_gen_and_tl(t1, t1, t2);
1672
            tcg_temp_free(t2);
1673
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1674
            tcg_temp_free(t1);
1675
            /* operands of different sign, first operand and result different sign */
1676
            generate_exception(ctx, EXCP_OVERFLOW);
1677
            gen_set_label(l1);
1678
            gen_store_gpr(t0, rd);
1679
            tcg_temp_free(t0);
1680
        }
1681
        opn = "dsub";
1682
        break;
1683
    case OPC_DSUBU:
1684
        if (rs != 0 && rt != 0) {
1685
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1686
        } else if (rs == 0 && rt != 0) {
1687
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1688
        } else if (rs != 0 && rt == 0) {
1689
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1690
        } else {
1691
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1692
        }
1693
        opn = "dsubu";
1694
        break;
1695
#endif
1696
    case OPC_MUL:
1697
        if (likely(rs != 0 && rt != 0)) {
1698
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1699
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1700
        } else {
1701
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1702
        }
1703
        opn = "mul";
1704
        break;
1705
    }
1706
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1707
}
1708

    
1709
/* Conditional move */
1710
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1711
{
1712
    const char *opn = "cond move";
1713
    int l1;
1714

    
1715
    if (rd == 0) {
1716
        /* If no destination, treat it as a NOP.
1717
           For add & sub, we must generate the overflow exception when needed. */
1718
        MIPS_DEBUG("NOP");
1719
        return;
1720
    }
1721

    
1722
    l1 = gen_new_label();
1723
    switch (opc) {
1724
    case OPC_MOVN:
1725
        if (likely(rt != 0))
1726
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1727
        else
1728
            tcg_gen_br(l1);
1729
        opn = "movn";
1730
        break;
1731
    case OPC_MOVZ:
1732
        if (likely(rt != 0))
1733
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1734
        opn = "movz";
1735
        break;
1736
    }
1737
    if (rs != 0)
1738
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1739
    else
1740
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1741
    gen_set_label(l1);
1742

    
1743
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1744
}
1745

    
1746
/* Logic */
1747
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1748
{
1749
    const char *opn = "logic";
1750

    
1751
    if (rd == 0) {
1752
        /* If no destination, treat it as a NOP. */
1753
        MIPS_DEBUG("NOP");
1754
        return;
1755
    }
1756

    
1757
    switch (opc) {
1758
    case OPC_AND:
1759
        if (likely(rs != 0 && rt != 0)) {
1760
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1761
        } else {
1762
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1763
        }
1764
        opn = "and";
1765
        break;
1766
    case OPC_NOR:
1767
        if (rs != 0 && rt != 0) {
1768
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1769
        } else if (rs == 0 && rt != 0) {
1770
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1771
        } else if (rs != 0 && rt == 0) {
1772
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1773
        } else {
1774
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1775
        }
1776
        opn = "nor";
1777
        break;
1778
    case OPC_OR:
1779
        if (likely(rs != 0 && rt != 0)) {
1780
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1781
        } else if (rs == 0 && rt != 0) {
1782
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1783
        } else if (rs != 0 && rt == 0) {
1784
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1785
        } else {
1786
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1787
        }
1788
        opn = "or";
1789
        break;
1790
    case OPC_XOR:
1791
        if (likely(rs != 0 && rt != 0)) {
1792
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1793
        } else if (rs == 0 && rt != 0) {
1794
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1795
        } else if (rs != 0 && rt == 0) {
1796
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1797
        } else {
1798
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1799
        }
1800
        opn = "xor";
1801
        break;
1802
    }
1803
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1804
}
1805

    
1806
/* Set on lower than */
1807
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1808
{
1809
    const char *opn = "slt";
1810
    TCGv t0, t1;
1811

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

    
1818
    t0 = tcg_temp_new();
1819
    t1 = tcg_temp_new();
1820
    gen_load_gpr(t0, rs);
1821
    gen_load_gpr(t1, rt);
1822
    switch (opc) {
1823
    case OPC_SLT:
1824
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1825
        opn = "slt";
1826
        break;
1827
    case OPC_SLTU:
1828
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1829
        opn = "sltu";
1830
        break;
1831
    }
1832
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1833
    tcg_temp_free(t0);
1834
    tcg_temp_free(t1);
1835
}
1836

    
1837
/* Shifts */
1838
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1839
                       int rd, int rs, int rt)
1840
{
1841
    const char *opn = "shifts";
1842
    TCGv t0, t1;
1843

    
1844
    if (rd == 0) {
1845
        /* If no destination, treat it as a NOP.
1846
           For add & sub, we must generate the overflow exception when needed. */
1847
        MIPS_DEBUG("NOP");
1848
        return;
1849
    }
1850

    
1851
    t0 = tcg_temp_new();
1852
    t1 = tcg_temp_new();
1853
    gen_load_gpr(t0, rs);
1854
    gen_load_gpr(t1, rt);
1855
    switch (opc) {
1856
    case OPC_SLLV:
1857
        tcg_gen_andi_tl(t0, t0, 0x1f);
1858
        tcg_gen_shl_tl(t0, t1, t0);
1859
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1860
        opn = "sllv";
1861
        break;
1862
    case OPC_SRAV:
1863
        tcg_gen_andi_tl(t0, t0, 0x1f);
1864
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1865
        opn = "srav";
1866
        break;
1867
    case OPC_SRLV:
1868
        tcg_gen_ext32u_tl(t1, t1);
1869
        tcg_gen_andi_tl(t0, t0, 0x1f);
1870
        tcg_gen_shr_tl(t0, t1, t0);
1871
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1872
        opn = "srlv";
1873
        break;
1874
    case OPC_ROTRV:
1875
        {
1876
            TCGv_i32 t2 = tcg_temp_new_i32();
1877
            TCGv_i32 t3 = tcg_temp_new_i32();
1878

    
1879
            tcg_gen_trunc_tl_i32(t2, t0);
1880
            tcg_gen_trunc_tl_i32(t3, t1);
1881
            tcg_gen_andi_i32(t2, t2, 0x1f);
1882
            tcg_gen_rotr_i32(t2, t3, t2);
1883
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1884
            tcg_temp_free_i32(t2);
1885
            tcg_temp_free_i32(t3);
1886
            opn = "rotrv";
1887
        }
1888
        break;
1889
#if defined(TARGET_MIPS64)
1890
    case OPC_DSLLV:
1891
        tcg_gen_andi_tl(t0, t0, 0x3f);
1892
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1893
        opn = "dsllv";
1894
        break;
1895
    case OPC_DSRAV:
1896
        tcg_gen_andi_tl(t0, t0, 0x3f);
1897
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1898
        opn = "dsrav";
1899
        break;
1900
    case OPC_DSRLV:
1901
        tcg_gen_andi_tl(t0, t0, 0x3f);
1902
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1903
        opn = "dsrlv";
1904
        break;
1905
    case OPC_DROTRV:
1906
        tcg_gen_andi_tl(t0, t0, 0x3f);
1907
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1908
        opn = "drotrv";
1909
        break;
1910
#endif
1911
    }
1912
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1913
    tcg_temp_free(t0);
1914
    tcg_temp_free(t1);
1915
}
1916

    
1917
/* Arithmetic on HI/LO registers */
1918
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1919
{
1920
    const char *opn = "hilo";
1921

    
1922
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1923
        /* Treat as NOP. */
1924
        MIPS_DEBUG("NOP");
1925
        return;
1926
    }
1927
    switch (opc) {
1928
    case OPC_MFHI:
1929
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1930
        opn = "mfhi";
1931
        break;
1932
    case OPC_MFLO:
1933
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1934
        opn = "mflo";
1935
        break;
1936
    case OPC_MTHI:
1937
        if (reg != 0)
1938
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1939
        else
1940
            tcg_gen_movi_tl(cpu_HI[0], 0);
1941
        opn = "mthi";
1942
        break;
1943
    case OPC_MTLO:
1944
        if (reg != 0)
1945
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1946
        else
1947
            tcg_gen_movi_tl(cpu_LO[0], 0);
1948
        opn = "mtlo";
1949
        break;
1950
    }
1951
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1952
}
1953

    
1954
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1955
                        int rs, int rt)
1956
{
1957
    const char *opn = "mul/div";
1958
    TCGv t0, t1;
1959

    
1960
    switch (opc) {
1961
    case OPC_DIV:
1962
    case OPC_DIVU:
1963
#if defined(TARGET_MIPS64)
1964
    case OPC_DDIV:
1965
    case OPC_DDIVU:
1966
#endif
1967
        t0 = tcg_temp_local_new();
1968
        t1 = tcg_temp_local_new();
1969
        break;
1970
    default:
1971
        t0 = tcg_temp_new();
1972
        t1 = tcg_temp_new();
1973
        break;
1974
    }
1975

    
1976
    gen_load_gpr(t0, rs);
1977
    gen_load_gpr(t1, rt);
1978
    switch (opc) {
1979
    case OPC_DIV:
1980
        {
1981
            int l1 = gen_new_label();
1982
            int l2 = gen_new_label();
1983

    
1984
            tcg_gen_ext32s_tl(t0, t0);
1985
            tcg_gen_ext32s_tl(t1, t1);
1986
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1987
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1988
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1989

    
1990
            tcg_gen_mov_tl(cpu_LO[0], t0);
1991
            tcg_gen_movi_tl(cpu_HI[0], 0);
1992
            tcg_gen_br(l1);
1993
            gen_set_label(l2);
1994
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1995
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1996
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1997
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1998
            gen_set_label(l1);
1999
        }
2000
        opn = "div";
2001
        break;
2002
    case OPC_DIVU:
2003
        {
2004
            int l1 = gen_new_label();
2005

    
2006
            tcg_gen_ext32u_tl(t0, t0);
2007
            tcg_gen_ext32u_tl(t1, t1);
2008
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2009
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2010
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2011
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2012
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2013
            gen_set_label(l1);
2014
        }
2015
        opn = "divu";
2016
        break;
2017
    case OPC_MULT:
2018
        {
2019
            TCGv_i64 t2 = tcg_temp_new_i64();
2020
            TCGv_i64 t3 = tcg_temp_new_i64();
2021

    
2022
            tcg_gen_ext_tl_i64(t2, t0);
2023
            tcg_gen_ext_tl_i64(t3, t1);
2024
            tcg_gen_mul_i64(t2, t2, t3);
2025
            tcg_temp_free_i64(t3);
2026
            tcg_gen_trunc_i64_tl(t0, t2);
2027
            tcg_gen_shri_i64(t2, t2, 32);
2028
            tcg_gen_trunc_i64_tl(t1, t2);
2029
            tcg_temp_free_i64(t2);
2030
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2031
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2032
        }
2033
        opn = "mult";
2034
        break;
2035
    case OPC_MULTU:
2036
        {
2037
            TCGv_i64 t2 = tcg_temp_new_i64();
2038
            TCGv_i64 t3 = tcg_temp_new_i64();
2039

    
2040
            tcg_gen_ext32u_tl(t0, t0);
2041
            tcg_gen_ext32u_tl(t1, t1);
2042
            tcg_gen_extu_tl_i64(t2, t0);
2043
            tcg_gen_extu_tl_i64(t3, t1);
2044
            tcg_gen_mul_i64(t2, t2, t3);
2045
            tcg_temp_free_i64(t3);
2046
            tcg_gen_trunc_i64_tl(t0, t2);
2047
            tcg_gen_shri_i64(t2, t2, 32);
2048
            tcg_gen_trunc_i64_tl(t1, t2);
2049
            tcg_temp_free_i64(t2);
2050
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2051
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2052
        }
2053
        opn = "multu";
2054
        break;
2055
#if defined(TARGET_MIPS64)
2056
    case OPC_DDIV:
2057
        {
2058
            int l1 = gen_new_label();
2059
            int l2 = gen_new_label();
2060

    
2061
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2062
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2063
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2064
            tcg_gen_mov_tl(cpu_LO[0], t0);
2065
            tcg_gen_movi_tl(cpu_HI[0], 0);
2066
            tcg_gen_br(l1);
2067
            gen_set_label(l2);
2068
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2069
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2070
            gen_set_label(l1);
2071
        }
2072
        opn = "ddiv";
2073
        break;
2074
    case OPC_DDIVU:
2075
        {
2076
            int l1 = gen_new_label();
2077

    
2078
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2079
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2080
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2081
            gen_set_label(l1);
2082
        }
2083
        opn = "ddivu";
2084
        break;
2085
    case OPC_DMULT:
2086
        gen_helper_dmult(t0, t1);
2087
        opn = "dmult";
2088
        break;
2089
    case OPC_DMULTU:
2090
        gen_helper_dmultu(t0, t1);
2091
        opn = "dmultu";
2092
        break;
2093
#endif
2094
    case OPC_MADD:
2095
        {
2096
            TCGv_i64 t2 = tcg_temp_new_i64();
2097
            TCGv_i64 t3 = tcg_temp_new_i64();
2098

    
2099
            tcg_gen_ext_tl_i64(t2, t0);
2100
            tcg_gen_ext_tl_i64(t3, t1);
2101
            tcg_gen_mul_i64(t2, t2, t3);
2102
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2103
            tcg_gen_add_i64(t2, t2, t3);
2104
            tcg_temp_free_i64(t3);
2105
            tcg_gen_trunc_i64_tl(t0, t2);
2106
            tcg_gen_shri_i64(t2, t2, 32);
2107
            tcg_gen_trunc_i64_tl(t1, t2);
2108
            tcg_temp_free_i64(t2);
2109
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2110
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2111
        }
2112
        opn = "madd";
2113
        break;
2114
    case OPC_MADDU:
2115
       {
2116
            TCGv_i64 t2 = tcg_temp_new_i64();
2117
            TCGv_i64 t3 = tcg_temp_new_i64();
2118

    
2119
            tcg_gen_ext32u_tl(t0, t0);
2120
            tcg_gen_ext32u_tl(t1, t1);
2121
            tcg_gen_extu_tl_i64(t2, t0);
2122
            tcg_gen_extu_tl_i64(t3, t1);
2123
            tcg_gen_mul_i64(t2, t2, t3);
2124
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2125
            tcg_gen_add_i64(t2, t2, t3);
2126
            tcg_temp_free_i64(t3);
2127
            tcg_gen_trunc_i64_tl(t0, t2);
2128
            tcg_gen_shri_i64(t2, t2, 32);
2129
            tcg_gen_trunc_i64_tl(t1, t2);
2130
            tcg_temp_free_i64(t2);
2131
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2132
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2133
        }
2134
        opn = "maddu";
2135
        break;
2136
    case OPC_MSUB:
2137
        {
2138
            TCGv_i64 t2 = tcg_temp_new_i64();
2139
            TCGv_i64 t3 = tcg_temp_new_i64();
2140

    
2141
            tcg_gen_ext_tl_i64(t2, t0);
2142
            tcg_gen_ext_tl_i64(t3, t1);
2143
            tcg_gen_mul_i64(t2, t2, t3);
2144
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2145
            tcg_gen_sub_i64(t2, t3, t2);
2146
            tcg_temp_free_i64(t3);
2147
            tcg_gen_trunc_i64_tl(t0, t2);
2148
            tcg_gen_shri_i64(t2, t2, 32);
2149
            tcg_gen_trunc_i64_tl(t1, t2);
2150
            tcg_temp_free_i64(t2);
2151
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2152
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2153
        }
2154
        opn = "msub";
2155
        break;
2156
    case OPC_MSUBU:
2157
        {
2158
            TCGv_i64 t2 = tcg_temp_new_i64();
2159
            TCGv_i64 t3 = tcg_temp_new_i64();
2160

    
2161
            tcg_gen_ext32u_tl(t0, t0);
2162
            tcg_gen_ext32u_tl(t1, t1);
2163
            tcg_gen_extu_tl_i64(t2, t0);
2164
            tcg_gen_extu_tl_i64(t3, t1);
2165
            tcg_gen_mul_i64(t2, t2, t3);
2166
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2167
            tcg_gen_sub_i64(t2, t3, t2);
2168
            tcg_temp_free_i64(t3);
2169
            tcg_gen_trunc_i64_tl(t0, t2);
2170
            tcg_gen_shri_i64(t2, t2, 32);
2171
            tcg_gen_trunc_i64_tl(t1, t2);
2172
            tcg_temp_free_i64(t2);
2173
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2174
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2175
        }
2176
        opn = "msubu";
2177
        break;
2178
    default:
2179
        MIPS_INVAL(opn);
2180
        generate_exception(ctx, EXCP_RI);
2181
        goto out;
2182
    }
2183
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2184
 out:
2185
    tcg_temp_free(t0);
2186
    tcg_temp_free(t1);
2187
}
2188

    
2189
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2190
                            int rd, int rs, int rt)
2191
{
2192
    const char *opn = "mul vr54xx";
2193
    TCGv t0 = tcg_temp_new();
2194
    TCGv t1 = tcg_temp_new();
2195

    
2196
    gen_load_gpr(t0, rs);
2197
    gen_load_gpr(t1, rt);
2198

    
2199
    switch (opc) {
2200
    case OPC_VR54XX_MULS:
2201
        gen_helper_muls(t0, t0, t1);
2202
        opn = "muls";
2203
        break;
2204
    case OPC_VR54XX_MULSU:
2205
        gen_helper_mulsu(t0, t0, t1);
2206
        opn = "mulsu";
2207
        break;
2208
    case OPC_VR54XX_MACC:
2209
        gen_helper_macc(t0, t0, t1);
2210
        opn = "macc";
2211
        break;
2212
    case OPC_VR54XX_MACCU:
2213
        gen_helper_maccu(t0, t0, t1);
2214
        opn = "maccu";
2215
        break;
2216
    case OPC_VR54XX_MSAC:
2217
        gen_helper_msac(t0, t0, t1);
2218
        opn = "msac";
2219
        break;
2220
    case OPC_VR54XX_MSACU:
2221
        gen_helper_msacu(t0, t0, t1);
2222
        opn = "msacu";
2223
        break;
2224
    case OPC_VR54XX_MULHI:
2225
        gen_helper_mulhi(t0, t0, t1);
2226
        opn = "mulhi";
2227
        break;
2228
    case OPC_VR54XX_MULHIU:
2229
        gen_helper_mulhiu(t0, t0, t1);
2230
        opn = "mulhiu";
2231
        break;
2232
    case OPC_VR54XX_MULSHI:
2233
        gen_helper_mulshi(t0, t0, t1);
2234
        opn = "mulshi";
2235
        break;
2236
    case OPC_VR54XX_MULSHIU:
2237
        gen_helper_mulshiu(t0, t0, t1);
2238
        opn = "mulshiu";
2239
        break;
2240
    case OPC_VR54XX_MACCHI:
2241
        gen_helper_macchi(t0, t0, t1);
2242
        opn = "macchi";
2243
        break;
2244
    case OPC_VR54XX_MACCHIU:
2245
        gen_helper_macchiu(t0, t0, t1);
2246
        opn = "macchiu";
2247
        break;
2248
    case OPC_VR54XX_MSACHI:
2249
        gen_helper_msachi(t0, t0, t1);
2250
        opn = "msachi";
2251
        break;
2252
    case OPC_VR54XX_MSACHIU:
2253
        gen_helper_msachiu(t0, t0, t1);
2254
        opn = "msachiu";
2255
        break;
2256
    default:
2257
        MIPS_INVAL("mul vr54xx");
2258
        generate_exception(ctx, EXCP_RI);
2259
        goto out;
2260
    }
2261
    gen_store_gpr(t0, rd);
2262
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2263

    
2264
 out:
2265
    tcg_temp_free(t0);
2266
    tcg_temp_free(t1);
2267
}
2268

    
2269
static void gen_cl (DisasContext *ctx, uint32_t opc,
2270
                    int rd, int rs)
2271
{
2272
    const char *opn = "CLx";
2273
    TCGv t0;
2274

    
2275
    if (rd == 0) {
2276
        /* Treat as NOP. */
2277
        MIPS_DEBUG("NOP");
2278
        return;
2279
    }
2280
    t0 = tcg_temp_new();
2281
    gen_load_gpr(t0, rs);
2282
    switch (opc) {
2283
    case OPC_CLO:
2284
        gen_helper_clo(cpu_gpr[rd], t0);
2285
        opn = "clo";
2286
        break;
2287
    case OPC_CLZ:
2288
        gen_helper_clz(cpu_gpr[rd], t0);
2289
        opn = "clz";
2290
        break;
2291
#if defined(TARGET_MIPS64)
2292
    case OPC_DCLO:
2293
        gen_helper_dclo(cpu_gpr[rd], t0);
2294
        opn = "dclo";
2295
        break;
2296
    case OPC_DCLZ:
2297
        gen_helper_dclz(cpu_gpr[rd], t0);
2298
        opn = "dclz";
2299
        break;
2300
#endif
2301
    }
2302
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2303
    tcg_temp_free(t0);
2304
}
2305

    
2306
/* Traps */
2307
static void gen_trap (DisasContext *ctx, uint32_t opc,
2308
                      int rs, int rt, int16_t imm)
2309
{
2310
    int cond;
2311
    TCGv t0 = tcg_temp_new();
2312
    TCGv t1 = tcg_temp_new();
2313

    
2314
    cond = 0;
2315
    /* Load needed operands */
2316
    switch (opc) {
2317
    case OPC_TEQ:
2318
    case OPC_TGE:
2319
    case OPC_TGEU:
2320
    case OPC_TLT:
2321
    case OPC_TLTU:
2322
    case OPC_TNE:
2323
        /* Compare two registers */
2324
        if (rs != rt) {
2325
            gen_load_gpr(t0, rs);
2326
            gen_load_gpr(t1, rt);
2327
            cond = 1;
2328
        }
2329
        break;
2330
    case OPC_TEQI:
2331
    case OPC_TGEI:
2332
    case OPC_TGEIU:
2333
    case OPC_TLTI:
2334
    case OPC_TLTIU:
2335
    case OPC_TNEI:
2336
        /* Compare register to immediate */
2337
        if (rs != 0 || imm != 0) {
2338
            gen_load_gpr(t0, rs);
2339
            tcg_gen_movi_tl(t1, (int32_t)imm);
2340
            cond = 1;
2341
        }
2342
        break;
2343
    }
2344
    if (cond == 0) {
2345
        switch (opc) {
2346
        case OPC_TEQ:   /* rs == rs */
2347
        case OPC_TEQI:  /* r0 == 0  */
2348
        case OPC_TGE:   /* rs >= rs */
2349
        case OPC_TGEI:  /* r0 >= 0  */
2350
        case OPC_TGEU:  /* rs >= rs unsigned */
2351
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2352
            /* Always trap */
2353
            generate_exception(ctx, EXCP_TRAP);
2354
            break;
2355
        case OPC_TLT:   /* rs < rs           */
2356
        case OPC_TLTI:  /* r0 < 0            */
2357
        case OPC_TLTU:  /* rs < rs unsigned  */
2358
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2359
        case OPC_TNE:   /* rs != rs          */
2360
        case OPC_TNEI:  /* r0 != 0           */
2361
            /* Never trap: treat as NOP. */
2362
            break;
2363
        }
2364
    } else {
2365
        int l1 = gen_new_label();
2366

    
2367
        switch (opc) {
2368
        case OPC_TEQ:
2369
        case OPC_TEQI:
2370
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2371
            break;
2372
        case OPC_TGE:
2373
        case OPC_TGEI:
2374
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2375
            break;
2376
        case OPC_TGEU:
2377
        case OPC_TGEIU:
2378
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2379
            break;
2380
        case OPC_TLT:
2381
        case OPC_TLTI:
2382
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2383
            break;
2384
        case OPC_TLTU:
2385
        case OPC_TLTIU:
2386
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2387
            break;
2388
        case OPC_TNE:
2389
        case OPC_TNEI:
2390
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2391
            break;
2392
        }
2393
        generate_exception(ctx, EXCP_TRAP);
2394
        gen_set_label(l1);
2395
    }
2396
    tcg_temp_free(t0);
2397
    tcg_temp_free(t1);
2398
}
2399

    
2400
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2401
{
2402
    TranslationBlock *tb;
2403
    tb = ctx->tb;
2404
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2405
        likely(!ctx->singlestep_enabled)) {
2406
        tcg_gen_goto_tb(n);
2407
        gen_save_pc(dest);
2408
        tcg_gen_exit_tb((long)tb + n);
2409
    } else {
2410
        gen_save_pc(dest);
2411
        if (ctx->singlestep_enabled) {
2412
            save_cpu_state(ctx, 0);
2413
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2414
        }
2415
        tcg_gen_exit_tb(0);
2416
    }
2417
}
2418

    
2419
/* Branches (before delay slot) */
2420
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2421
                                int insn_bytes,
2422
                                int rs, int rt, int32_t offset)
2423
{
2424
    target_ulong btgt = -1;
2425
    int blink = 0;
2426
    int bcond_compute = 0;
2427
    TCGv t0 = tcg_temp_new();
2428
    TCGv t1 = tcg_temp_new();
2429

    
2430
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2431
#ifdef MIPS_DEBUG_DISAS
2432
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2433
#endif
2434
        generate_exception(ctx, EXCP_RI);
2435
        goto out;
2436
    }
2437

    
2438
    /* Load needed operands */
2439
    switch (opc) {
2440
    case OPC_BEQ:
2441
    case OPC_BEQL:
2442
    case OPC_BNE:
2443
    case OPC_BNEL:
2444
        /* Compare two registers */
2445
        if (rs != rt) {
2446
            gen_load_gpr(t0, rs);
2447
            gen_load_gpr(t1, rt);
2448
            bcond_compute = 1;
2449
        }
2450
        btgt = ctx->pc + insn_bytes + offset;
2451
        break;
2452
    case OPC_BGEZ:
2453
    case OPC_BGEZAL:
2454
    case OPC_BGEZALS:
2455
    case OPC_BGEZALL:
2456
    case OPC_BGEZL:
2457
    case OPC_BGTZ:
2458
    case OPC_BGTZL:
2459
    case OPC_BLEZ:
2460
    case OPC_BLEZL:
2461
    case OPC_BLTZ:
2462
    case OPC_BLTZAL:
2463
    case OPC_BLTZALS:
2464
    case OPC_BLTZALL:
2465
    case OPC_BLTZL:
2466
        /* Compare to zero */
2467
        if (rs != 0) {
2468
            gen_load_gpr(t0, rs);
2469
            bcond_compute = 1;
2470
        }
2471
        btgt = ctx->pc + insn_bytes + offset;
2472
        break;
2473
    case OPC_J:
2474
    case OPC_JAL:
2475
    case OPC_JALX:
2476
    case OPC_JALS:
2477
    case OPC_JALXS:
2478
        /* Jump to immediate */
2479
        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2480
        break;
2481
    case OPC_JR:
2482
    case OPC_JALR:
2483
    case OPC_JALRC:
2484
    case OPC_JALRS:
2485
        /* Jump to register */
2486
        if (offset != 0 && offset != 16) {
2487
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2488
               others are reserved. */
2489
            MIPS_INVAL("jump hint");
2490
            generate_exception(ctx, EXCP_RI);
2491
            goto out;
2492
        }
2493
        gen_load_gpr(btarget, rs);
2494
        break;
2495
    default:
2496
        MIPS_INVAL("branch/jump");
2497
        generate_exception(ctx, EXCP_RI);
2498
        goto out;
2499
    }
2500
    if (bcond_compute == 0) {
2501
        /* No condition to be computed */
2502
        switch (opc) {
2503
        case OPC_BEQ:     /* rx == rx        */
2504
        case OPC_BEQL:    /* rx == rx likely */
2505
        case OPC_BGEZ:    /* 0 >= 0          */
2506
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2507
        case OPC_BLEZ:    /* 0 <= 0          */
2508
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2509
            /* Always take */
2510
            ctx->hflags |= MIPS_HFLAG_B;
2511
            MIPS_DEBUG("balways");
2512
            break;
2513
        case OPC_BGEZALS:
2514
        case OPC_BGEZAL:  /* 0 >= 0          */
2515
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2516
            ctx->hflags |= (opc == OPC_BGEZALS
2517
                            ? MIPS_HFLAG_BDS16
2518
                            : MIPS_HFLAG_BDS32);
2519
            /* Always take and link */
2520
            blink = 31;
2521
            ctx->hflags |= MIPS_HFLAG_B;
2522
            MIPS_DEBUG("balways and link");
2523
            break;
2524
        case OPC_BNE:     /* rx != rx        */
2525
        case OPC_BGTZ:    /* 0 > 0           */
2526
        case OPC_BLTZ:    /* 0 < 0           */
2527
            /* Treat as NOP. */
2528
            MIPS_DEBUG("bnever (NOP)");
2529
            goto out;
2530
        case OPC_BLTZALS:
2531
        case OPC_BLTZAL:  /* 0 < 0           */
2532
            ctx->hflags |= (opc == OPC_BLTZALS
2533
                            ? MIPS_HFLAG_BDS16
2534
                            : MIPS_HFLAG_BDS32);
2535
            /* Handle as an unconditional branch to get correct delay
2536
               slot checking.  */
2537
            blink = 31;
2538
            btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2539
            ctx->hflags |= MIPS_HFLAG_B;
2540
            MIPS_DEBUG("bnever and link");
2541
            break;
2542
        case OPC_BLTZALL: /* 0 < 0 likely */
2543
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2544
            /* Skip the instruction in the delay slot */
2545
            MIPS_DEBUG("bnever, link and skip");
2546
            ctx->pc += 4;
2547
            goto out;
2548
        case OPC_BNEL:    /* rx != rx likely */
2549
        case OPC_BGTZL:   /* 0 > 0 likely */
2550
        case OPC_BLTZL:   /* 0 < 0 likely */
2551
            /* Skip the instruction in the delay slot */
2552
            MIPS_DEBUG("bnever and skip");
2553
            ctx->pc += 4;
2554
            goto out;
2555
        case OPC_J:
2556
            ctx->hflags |= MIPS_HFLAG_B;
2557
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2558
            break;
2559
        case OPC_JALXS:
2560
        case OPC_JALX:
2561
            ctx->hflags |= MIPS_HFLAG_BX;
2562
            /* Fallthrough */
2563
        case OPC_JALS:
2564
        case OPC_JAL:
2565
            blink = 31;
2566
            ctx->hflags |= MIPS_HFLAG_B;
2567
            ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2568
                            ? MIPS_HFLAG_BDS16
2569
                            : MIPS_HFLAG_BDS32);
2570
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2571
            break;
2572
        case OPC_JR:
2573
            ctx->hflags |= MIPS_HFLAG_BR;
2574
            if (insn_bytes == 4)
2575
                ctx->hflags |= MIPS_HFLAG_BDS32;
2576
            MIPS_DEBUG("jr %s", regnames[rs]);
2577
            break;
2578
        case OPC_JALRS:
2579
        case OPC_JALR:
2580
        case OPC_JALRC:
2581
            blink = rt;
2582
            ctx->hflags |= MIPS_HFLAG_BR;
2583
            ctx->hflags |= (opc == OPC_JALRS
2584
                            ? MIPS_HFLAG_BDS16
2585
                            : MIPS_HFLAG_BDS32);
2586
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2587
            break;
2588
        default:
2589
            MIPS_INVAL("branch/jump");
2590
            generate_exception(ctx, EXCP_RI);
2591
            goto out;
2592
        }
2593
    } else {
2594
        switch (opc) {
2595
        case OPC_BEQ:
2596
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2597
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2598
                       regnames[rs], regnames[rt], btgt);
2599
            goto not_likely;
2600
        case OPC_BEQL:
2601
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2602
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2603
                       regnames[rs], regnames[rt], btgt);
2604
            goto likely;
2605
        case OPC_BNE:
2606
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2607
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2608
                       regnames[rs], regnames[rt], btgt);
2609
            goto not_likely;
2610
        case OPC_BNEL:
2611
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2612
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2613
                       regnames[rs], regnames[rt], btgt);
2614
            goto likely;
2615
        case OPC_BGEZ:
2616
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2617
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2618
            goto not_likely;
2619
        case OPC_BGEZL:
2620
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2621
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2622
            goto likely;
2623
        case OPC_BGEZALS:
2624
        case OPC_BGEZAL:
2625
            ctx->hflags |= (opc == OPC_BGEZALS
2626
                            ? MIPS_HFLAG_BDS16
2627
                            : MIPS_HFLAG_BDS32);
2628
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2629
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2630
            blink = 31;
2631
            goto not_likely;
2632
        case OPC_BGEZALL:
2633
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2634
            blink = 31;
2635
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2636
            goto likely;
2637
        case OPC_BGTZ:
2638
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2639
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2640
            goto not_likely;
2641
        case OPC_BGTZL:
2642
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2643
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2644
            goto likely;
2645
        case OPC_BLEZ:
2646
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2647
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2648
            goto not_likely;
2649
        case OPC_BLEZL:
2650
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2651
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2652
            goto likely;
2653
        case OPC_BLTZ:
2654
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2655
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2656
            goto not_likely;
2657
        case OPC_BLTZL:
2658
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2659
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2660
            goto likely;
2661
        case OPC_BLTZALS:
2662
        case OPC_BLTZAL:
2663
            ctx->hflags |= (opc == OPC_BLTZALS
2664
                            ? MIPS_HFLAG_BDS16
2665
                            : MIPS_HFLAG_BDS32);
2666
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2667
            blink = 31;
2668
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2669
        not_likely:
2670
            ctx->hflags |= MIPS_HFLAG_BC;
2671
            break;
2672
        case OPC_BLTZALL:
2673
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2674
            blink = 31;
2675
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2676
        likely:
2677
            ctx->hflags |= MIPS_HFLAG_BL;
2678
            break;
2679
        default:
2680
            MIPS_INVAL("conditional branch/jump");
2681
            generate_exception(ctx, EXCP_RI);
2682
            goto out;
2683
        }
2684
    }
2685
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2686
               blink, ctx->hflags, btgt);
2687

    
2688
    ctx->btarget = btgt;
2689
    if (blink > 0) {
2690
        int post_delay = insn_bytes;
2691
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2692

    
2693
        if (opc != OPC_JALRC)
2694
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2695

    
2696
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2697
    }
2698

    
2699
 out:
2700
    if (insn_bytes == 2)
2701
        ctx->hflags |= MIPS_HFLAG_B16;
2702
    tcg_temp_free(t0);
2703
    tcg_temp_free(t1);
2704
}
2705

    
2706
/* special3 bitfield operations */
2707
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2708
                        int rs, int lsb, int msb)
2709
{
2710
    TCGv t0 = tcg_temp_new();
2711
    TCGv t1 = tcg_temp_new();
2712
    target_ulong mask;
2713

    
2714
    gen_load_gpr(t1, rs);
2715
    switch (opc) {
2716
    case OPC_EXT:
2717
        if (lsb + msb > 31)
2718
            goto fail;
2719
        tcg_gen_shri_tl(t0, t1, lsb);
2720
        if (msb != 31) {
2721
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2722
        } else {
2723
            tcg_gen_ext32s_tl(t0, t0);
2724
        }
2725
        break;
2726
#if defined(TARGET_MIPS64)
2727
    case OPC_DEXTM:
2728
        tcg_gen_shri_tl(t0, t1, lsb);
2729
        if (msb != 31) {
2730
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2731
        }
2732
        break;
2733
    case OPC_DEXTU:
2734
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2735
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2736
        break;
2737
    case OPC_DEXT:
2738
        tcg_gen_shri_tl(t0, t1, lsb);
2739
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2740
        break;
2741
#endif
2742
    case OPC_INS:
2743
        if (lsb > msb)
2744
            goto fail;
2745
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2746
        gen_load_gpr(t0, rt);
2747
        tcg_gen_andi_tl(t0, t0, ~mask);
2748
        tcg_gen_shli_tl(t1, t1, lsb);
2749
        tcg_gen_andi_tl(t1, t1, mask);
2750
        tcg_gen_or_tl(t0, t0, t1);
2751
        tcg_gen_ext32s_tl(t0, t0);
2752
        break;
2753
#if defined(TARGET_MIPS64)
2754
    case OPC_DINSM:
2755
        if (lsb > msb)
2756
            goto fail;
2757
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2758
        gen_load_gpr(t0, rt);
2759
        tcg_gen_andi_tl(t0, t0, ~mask);
2760
        tcg_gen_shli_tl(t1, t1, lsb);
2761
        tcg_gen_andi_tl(t1, t1, mask);
2762
        tcg_gen_or_tl(t0, t0, t1);
2763
        break;
2764
    case OPC_DINSU:
2765
        if (lsb > msb)
2766
            goto fail;
2767
        mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
2768
        gen_load_gpr(t0, rt);
2769
        tcg_gen_andi_tl(t0, t0, ~mask);
2770
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2771
        tcg_gen_andi_tl(t1, t1, mask);
2772
        tcg_gen_or_tl(t0, t0, t1);
2773
        break;
2774
    case OPC_DINS:
2775
        if (lsb > msb)
2776
            goto fail;
2777
        gen_load_gpr(t0, rt);
2778
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2779
        gen_load_gpr(t0, rt);
2780
        tcg_gen_andi_tl(t0, t0, ~mask);
2781
        tcg_gen_shli_tl(t1, t1, lsb);
2782
        tcg_gen_andi_tl(t1, t1, mask);
2783
        tcg_gen_or_tl(t0, t0, t1);
2784
        break;
2785
#endif
2786
    default:
2787
fail:
2788
        MIPS_INVAL("bitops");
2789
        generate_exception(ctx, EXCP_RI);
2790
        tcg_temp_free(t0);
2791
        tcg_temp_free(t1);
2792
        return;
2793
    }
2794
    gen_store_gpr(t0, rt);
2795
    tcg_temp_free(t0);
2796
    tcg_temp_free(t1);
2797
}
2798

    
2799
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2800
{
2801
    TCGv t0;
2802

    
2803
    if (rd == 0) {
2804
        /* If no destination, treat it as a NOP. */
2805
        MIPS_DEBUG("NOP");
2806
        return;
2807
    }
2808

    
2809
    t0 = tcg_temp_new();
2810
    gen_load_gpr(t0, rt);
2811
    switch (op2) {
2812
    case OPC_WSBH:
2813
        {
2814
            TCGv t1 = tcg_temp_new();
2815

    
2816
            tcg_gen_shri_tl(t1, t0, 8);
2817
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2818
            tcg_gen_shli_tl(t0, t0, 8);
2819
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2820
            tcg_gen_or_tl(t0, t0, t1);
2821
            tcg_temp_free(t1);
2822
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2823
        }
2824
        break;
2825
    case OPC_SEB:
2826
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2827
        break;
2828
    case OPC_SEH:
2829
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2830
        break;
2831
#if defined(TARGET_MIPS64)
2832
    case OPC_DSBH:
2833
        {
2834
            TCGv t1 = tcg_temp_new();
2835

    
2836
            tcg_gen_shri_tl(t1, t0, 8);
2837
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2838
            tcg_gen_shli_tl(t0, t0, 8);
2839
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2840
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2841
            tcg_temp_free(t1);
2842
        }
2843
        break;
2844
    case OPC_DSHD:
2845
        {
2846
            TCGv t1 = tcg_temp_new();
2847

    
2848
            tcg_gen_shri_tl(t1, t0, 16);
2849
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2850
            tcg_gen_shli_tl(t0, t0, 16);
2851
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2852
            tcg_gen_or_tl(t0, t0, t1);
2853
            tcg_gen_shri_tl(t1, t0, 32);
2854
            tcg_gen_shli_tl(t0, t0, 32);
2855
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2856
            tcg_temp_free(t1);
2857
        }
2858
        break;
2859
#endif
2860
    default:
2861
        MIPS_INVAL("bsfhl");
2862
        generate_exception(ctx, EXCP_RI);
2863
        tcg_temp_free(t0);
2864
        return;
2865
    }
2866
    tcg_temp_free(t0);
2867
}
2868

    
2869
#ifndef CONFIG_USER_ONLY
2870
/* CP0 (MMU and control) */
2871
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2872
{
2873
    TCGv_i32 t0 = tcg_temp_new_i32();
2874

    
2875
    tcg_gen_ld_i32(t0, cpu_env, off);
2876
    tcg_gen_ext_i32_tl(arg, t0);
2877
    tcg_temp_free_i32(t0);
2878
}
2879

    
2880
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2881
{
2882
    tcg_gen_ld_tl(arg, cpu_env, off);
2883
    tcg_gen_ext32s_tl(arg, arg);
2884
}
2885

    
2886
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2887
{
2888
    TCGv_i32 t0 = tcg_temp_new_i32();
2889

    
2890
    tcg_gen_trunc_tl_i32(t0, arg);
2891
    tcg_gen_st_i32(t0, cpu_env, off);
2892
    tcg_temp_free_i32(t0);
2893
}
2894

    
2895
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2896
{
2897
    tcg_gen_ext32s_tl(arg, arg);
2898
    tcg_gen_st_tl(arg, cpu_env, off);
2899
}
2900

    
2901
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2902
{
2903
    const char *rn = "invalid";
2904

    
2905
    if (sel != 0)
2906
        check_insn(env, ctx, ISA_MIPS32);
2907

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

    
3473
die:
3474
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3475
    generate_exception(ctx, EXCP_RI);
3476
}
3477

    
3478
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3479
{
3480
    const char *rn = "invalid";
3481

    
3482
    if (sel != 0)
3483
        check_insn(env, ctx, ISA_MIPS32);
3484

    
3485
    if (use_icount)
3486
        gen_io_start();
3487

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

    
4068
die:
4069
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4070
    generate_exception(ctx, EXCP_RI);
4071
}
4072

    
4073
#if defined(TARGET_MIPS64)
4074
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4075
{
4076
    const char *rn = "invalid";
4077

    
4078
    if (sel != 0)
4079
        check_insn(env, ctx, ISA_MIPS64);
4080

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

    
4635
die:
4636
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4637
    generate_exception(ctx, EXCP_RI);
4638
}
4639

    
4640
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4641
{
4642
    const char *rn = "invalid";
4643

    
4644
    if (sel != 0)
4645
        check_insn(env, ctx, ISA_MIPS64);
4646

    
4647
    if (use_icount)
4648
        gen_io_start();
4649

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

    
5221
die:
5222
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5223
    generate_exception(ctx, EXCP_RI);
5224
}
5225
#endif /* TARGET_MIPS64 */
5226

    
5227
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5228
                     int u, int sel, int h)
5229
{
5230
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5231
    TCGv t0 = tcg_temp_local_new();
5232

    
5233
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5234
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5235
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5236
        tcg_gen_movi_tl(t0, -1);
5237
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5238
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5239
        tcg_gen_movi_tl(t0, -1);
5240
    else if (u == 0) {
5241
        switch (rt) {
5242
        case 2:
5243
            switch (sel) {
5244
            case 1:
5245
                gen_helper_mftc0_tcstatus(t0);
5246
                break;
5247
            case 2:
5248
                gen_helper_mftc0_tcbind(t0);
5249
                break;
5250
            case 3:
5251
                gen_helper_mftc0_tcrestart(t0);
5252
                break;
5253
            case 4:
5254
                gen_helper_mftc0_tchalt(t0);
5255
                break;
5256
            case 5:
5257
                gen_helper_mftc0_tccontext(t0);
5258
                break;
5259
            case 6:
5260
                gen_helper_mftc0_tcschedule(t0);
5261
                break;
5262
            case 7:
5263
                gen_helper_mftc0_tcschefback(t0);
5264
                break;
5265
            default:
5266
                gen_mfc0(env, ctx, t0, rt, sel);
5267
                break;
5268
            }
5269
            break;
5270
        case 10:
5271
            switch (sel) {
5272
            case 0:
5273
                gen_helper_mftc0_entryhi(t0);
5274
                break;
5275
            default:
5276
                gen_mfc0(env, ctx, t0, rt, sel);
5277
                break;
5278
            }
5279
        case 12:
5280
            switch (sel) {
5281
            case 0:
5282
                gen_helper_mftc0_status(t0);
5283
                break;
5284
            default:
5285
                gen_mfc0(env, ctx, t0, rt, sel);
5286
                break;
5287
            }
5288
        case 23:
5289
            switch (sel) {
5290
            case 0:
5291
                gen_helper_mftc0_debug(t0);
5292
                break;
5293
            default:
5294
                gen_mfc0(env, ctx, t0, rt, sel);
5295
                break;
5296
            }
5297
            break;
5298
        default:
5299
            gen_mfc0(env, ctx, t0, rt, sel);
5300
        }
5301
    } else switch (sel) {
5302
    /* GPR registers. */
5303
    case 0:
5304
        gen_helper_1i(mftgpr, t0, rt);
5305
        break;
5306
    /* Auxiliary CPU registers */
5307
    case 1:
5308
        switch (rt) {
5309
        case 0:
5310
            gen_helper_1i(mftlo, t0, 0);
5311
            break;
5312
        case 1:
5313
            gen_helper_1i(mfthi, t0, 0);
5314
            break;
5315
        case 2:
5316
            gen_helper_1i(mftacx, t0, 0);
5317
            break;
5318
        case 4:
5319
            gen_helper_1i(mftlo, t0, 1);
5320
            break;
5321
        case 5:
5322
            gen_helper_1i(mfthi, t0, 1);
5323
            break;
5324
        case 6:
5325
            gen_helper_1i(mftacx, t0, 1);
5326
            break;
5327
        case 8:
5328
            gen_helper_1i(mftlo, t0, 2);
5329
            break;
5330
        case 9:
5331
            gen_helper_1i(mfthi, t0, 2);
5332
            break;
5333
        case 10:
5334
            gen_helper_1i(mftacx, t0, 2);
5335
            break;
5336
        case 12:
5337
            gen_helper_1i(mftlo, t0, 3);
5338
            break;
5339
        case 13:
5340
            gen_helper_1i(mfthi, t0, 3);
5341
            break;
5342
        case 14:
5343
            gen_helper_1i(mftacx, t0, 3);
5344
            break;
5345
        case 16:
5346
            gen_helper_mftdsp(t0);
5347
            break;
5348
        default:
5349
            goto die;
5350
        }
5351
        break;
5352
    /* Floating point (COP1). */
5353
    case 2:
5354
        /* XXX: For now we support only a single FPU context. */
5355
        if (h == 0) {
5356
            TCGv_i32 fp0 = tcg_temp_new_i32();
5357

    
5358
            gen_load_fpr32(fp0, rt);
5359
            tcg_gen_ext_i32_tl(t0, fp0);
5360
            tcg_temp_free_i32(fp0);
5361
        } else {
5362
            TCGv_i32 fp0 = tcg_temp_new_i32();
5363

    
5364
            gen_load_fpr32h(fp0, rt);
5365
            tcg_gen_ext_i32_tl(t0, fp0);
5366
            tcg_temp_free_i32(fp0);
5367
        }
5368
        break;
5369
    case 3:
5370
        /* XXX: For now we support only a single FPU context. */
5371
        gen_helper_1i(cfc1, t0, rt);
5372
        break;
5373
    /* COP2: Not implemented. */
5374
    case 4:
5375
    case 5:
5376
        /* fall through */
5377
    default:
5378
        goto die;
5379
    }
5380
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5381
    gen_store_gpr(t0, rd);
5382
    tcg_temp_free(t0);
5383
    return;
5384

    
5385
die:
5386
    tcg_temp_free(t0);
5387
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5388
    generate_exception(ctx, EXCP_RI);
5389
}
5390

    
5391
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5392
                     int u, int sel, int h)
5393
{
5394
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5395
    TCGv t0 = tcg_temp_local_new();
5396

    
5397
    gen_load_gpr(t0, rt);
5398
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5399
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5400
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5401
        /* NOP */ ;
5402
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5403
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5404
        /* NOP */ ;
5405
    else if (u == 0) {
5406
        switch (rd) {
5407
        case 2:
5408
            switch (sel) {
5409
            case 1:
5410
                gen_helper_mttc0_tcstatus(t0);
5411
                break;
5412
            case 2:
5413
                gen_helper_mttc0_tcbind(t0);
5414
                break;
5415
            case 3:
5416
                gen_helper_mttc0_tcrestart(t0);
5417
                break;
5418
            case 4:
5419
                gen_helper_mttc0_tchalt(t0);
5420
                break;
5421
            case 5:
5422
                gen_helper_mttc0_tccontext(t0);
5423
                break;
5424
            case 6:
5425
                gen_helper_mttc0_tcschedule(t0);
5426
                break;
5427
            case 7:
5428
                gen_helper_mttc0_tcschefback(t0);
5429
                break;
5430
            default:
5431
                gen_mtc0(env, ctx, t0, rd, sel);
5432
                break;
5433
            }
5434
            break;
5435
        case 10:
5436
            switch (sel) {
5437
            case 0:
5438
                gen_helper_mttc0_entryhi(t0);
5439
                break;
5440
            default:
5441
                gen_mtc0(env, ctx, t0, rd, sel);
5442
                break;
5443
            }
5444
        case 12:
5445
            switch (sel) {
5446
            case 0:
5447
                gen_helper_mttc0_status(t0);
5448
                break;
5449
            default:
5450
                gen_mtc0(env, ctx, t0, rd, sel);
5451
                break;
5452
            }
5453
        case 23:
5454
            switch (sel) {
5455
            case 0:
5456
                gen_helper_mttc0_debug(t0);
5457
                break;
5458
            default:
5459
                gen_mtc0(env, ctx, t0, rd, sel);
5460
                break;
5461
            }
5462
            break;
5463
        default:
5464
            gen_mtc0(env, ctx, t0, rd, sel);
5465
        }
5466
    } else switch (sel) {
5467
    /* GPR registers. */
5468
    case 0:
5469
        gen_helper_1i(mttgpr, t0, rd);
5470
        break;
5471
    /* Auxiliary CPU registers */
5472
    case 1:
5473
        switch (rd) {
5474
        case 0:
5475
            gen_helper_1i(mttlo, t0, 0);
5476
            break;
5477
        case 1:
5478
            gen_helper_1i(mtthi, t0, 0);
5479
            break;
5480
        case 2:
5481
            gen_helper_1i(mttacx, t0, 0);
5482
            break;
5483
        case 4:
5484
            gen_helper_1i(mttlo, t0, 1);
5485
            break;
5486
        case 5:
5487
            gen_helper_1i(mtthi, t0, 1);
5488
            break;
5489
        case 6:
5490
            gen_helper_1i(mttacx, t0, 1);
5491
            break;
5492
        case 8:
5493
            gen_helper_1i(mttlo, t0, 2);
5494
            break;
5495
        case 9:
5496
            gen_helper_1i(mtthi, t0, 2);
5497
            break;
5498
        case 10:
5499
            gen_helper_1i(mttacx, t0, 2);
5500
            break;
5501
        case 12:
5502
            gen_helper_1i(mttlo, t0, 3);
5503
            break;
5504
        case 13:
5505
            gen_helper_1i(mtthi, t0, 3);
5506
            break;
5507
        case 14:
5508
            gen_helper_1i(mttacx, t0, 3);
5509
            break;
5510
        case 16:
5511
            gen_helper_mttdsp(t0);
5512
            break;
5513
        default:
5514
            goto die;
5515
        }
5516
        break;
5517
    /* Floating point (COP1). */
5518
    case 2:
5519
        /* XXX: For now we support only a single FPU context. */
5520
        if (h == 0) {
5521
            TCGv_i32 fp0 = tcg_temp_new_i32();
5522

    
5523
            tcg_gen_trunc_tl_i32(fp0, t0);
5524
            gen_store_fpr32(fp0, rd);
5525
            tcg_temp_free_i32(fp0);
5526
        } else {
5527
            TCGv_i32 fp0 = tcg_temp_new_i32();
5528

    
5529
            tcg_gen_trunc_tl_i32(fp0, t0);
5530
            gen_store_fpr32h(fp0, rd);
5531
            tcg_temp_free_i32(fp0);
5532
        }
5533
        break;
5534
    case 3:
5535
        /* XXX: For now we support only a single FPU context. */
5536
        gen_helper_1i(ctc1, t0, rd);
5537
        break;
5538
    /* COP2: Not implemented. */
5539
    case 4:
5540
    case 5:
5541
        /* fall through */
5542
    default:
5543
        goto die;
5544
    }
5545
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5546
    tcg_temp_free(t0);
5547
    return;
5548

    
5549
die:
5550
    tcg_temp_free(t0);
5551
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5552
    generate_exception(ctx, EXCP_RI);
5553
}
5554

    
5555
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5556
{
5557
    const char *opn = "ldst";
5558

    
5559
    switch (opc) {
5560
    case OPC_MFC0:
5561
        if (rt == 0) {
5562
            /* Treat as NOP. */
5563
            return;
5564
        }
5565
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5566
        opn = "mfc0";
5567
        break;
5568
    case OPC_MTC0:
5569
        {
5570
            TCGv t0 = tcg_temp_new();
5571

    
5572
            gen_load_gpr(t0, rt);
5573
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5574
            tcg_temp_free(t0);
5575
        }
5576
        opn = "mtc0";
5577
        break;
5578
#if defined(TARGET_MIPS64)
5579
    case OPC_DMFC0:
5580
        check_insn(env, ctx, ISA_MIPS3);
5581
        if (rt == 0) {
5582
            /* Treat as NOP. */
5583
            return;
5584
        }
5585
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5586
        opn = "dmfc0";
5587
        break;
5588
    case OPC_DMTC0:
5589
        check_insn(env, ctx, ISA_MIPS3);
5590
        {
5591
            TCGv t0 = tcg_temp_new();
5592

    
5593
            gen_load_gpr(t0, rt);
5594
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5595
            tcg_temp_free(t0);
5596
        }
5597
        opn = "dmtc0";
5598
        break;
5599
#endif
5600
    case OPC_MFTR:
5601
        check_insn(env, ctx, ASE_MT);
5602
        if (rd == 0) {
5603
            /* Treat as NOP. */
5604
            return;
5605
        }
5606
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5607
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5608
        opn = "mftr";
5609
        break;
5610
    case OPC_MTTR:
5611
        check_insn(env, ctx, ASE_MT);
5612
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5613
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5614
        opn = "mttr";
5615
        break;
5616
    case OPC_TLBWI:
5617
        opn = "tlbwi";
5618
        if (!env->tlb->helper_tlbwi)
5619
            goto die;
5620
        gen_helper_tlbwi();
5621
        break;
5622
    case OPC_TLBWR:
5623
        opn = "tlbwr";
5624
        if (!env->tlb->helper_tlbwr)
5625
            goto die;
5626
        gen_helper_tlbwr();
5627
        break;
5628
    case OPC_TLBP:
5629
        opn = "tlbp";
5630
        if (!env->tlb->helper_tlbp)
5631
            goto die;
5632
        gen_helper_tlbp();
5633
        break;
5634
    case OPC_TLBR:
5635
        opn = "tlbr";
5636
        if (!env->tlb->helper_tlbr)
5637
            goto die;
5638
        gen_helper_tlbr();
5639
        break;
5640
    case OPC_ERET:
5641
        opn = "eret";
5642
        check_insn(env, ctx, ISA_MIPS2);
5643
        gen_helper_eret();
5644
        ctx->bstate = BS_EXCP;
5645
        break;
5646
    case OPC_DERET:
5647
        opn = "deret";
5648
        check_insn(env, ctx, ISA_MIPS32);
5649
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5650
            MIPS_INVAL(opn);
5651
            generate_exception(ctx, EXCP_RI);
5652
        } else {
5653
            gen_helper_deret();
5654
            ctx->bstate = BS_EXCP;
5655
        }
5656
        break;
5657
    case OPC_WAIT:
5658
        opn = "wait";
5659
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5660
        /* If we get an exception, we want to restart at next instruction */
5661
        ctx->pc += 4;
5662
        save_cpu_state(ctx, 1);
5663
        ctx->pc -= 4;
5664
        gen_helper_wait();
5665
        ctx->bstate = BS_EXCP;
5666
        break;
5667
    default:
5668
 die:
5669
        MIPS_INVAL(opn);
5670
        generate_exception(ctx, EXCP_RI);
5671
        return;
5672
    }
5673
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5674
}
5675
#endif /* !CONFIG_USER_ONLY */
5676

    
5677
/* CP1 Branches (before delay slot) */
5678
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5679
                                 int32_t cc, int32_t offset)
5680
{
5681
    target_ulong btarget;
5682
    const char *opn = "cp1 cond branch";
5683
    TCGv_i32 t0 = tcg_temp_new_i32();
5684

    
5685
    if (cc != 0)
5686
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5687

    
5688
    btarget = ctx->pc + 4 + offset;
5689

    
5690
    switch (op) {
5691
    case OPC_BC1F:
5692
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5693
        tcg_gen_not_i32(t0, t0);
5694
        tcg_gen_andi_i32(t0, t0, 1);
5695
        tcg_gen_extu_i32_tl(bcond, t0);
5696
        opn = "bc1f";
5697
        goto not_likely;
5698
    case OPC_BC1FL:
5699
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5700
        tcg_gen_not_i32(t0, t0);
5701
        tcg_gen_andi_i32(t0, t0, 1);
5702
        tcg_gen_extu_i32_tl(bcond, t0);
5703
        opn = "bc1fl";
5704
        goto likely;
5705
    case OPC_BC1T:
5706
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5707
        tcg_gen_andi_i32(t0, t0, 1);
5708
        tcg_gen_extu_i32_tl(bcond, t0);
5709
        opn = "bc1t";
5710
        goto not_likely;
5711
    case OPC_BC1TL:
5712
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5713
        tcg_gen_andi_i32(t0, t0, 1);
5714
        tcg_gen_extu_i32_tl(bcond, t0);
5715
        opn = "bc1tl";
5716
    likely:
5717
        ctx->hflags |= MIPS_HFLAG_BL;
5718
        break;
5719
    case OPC_BC1FANY2:
5720
        {
5721
            TCGv_i32 t1 = tcg_temp_new_i32();
5722
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5723
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5724
            tcg_gen_nor_i32(t0, t0, t1);
5725
            tcg_temp_free_i32(t1);
5726
            tcg_gen_andi_i32(t0, t0, 1);
5727
            tcg_gen_extu_i32_tl(bcond, t0);
5728
        }
5729
        opn = "bc1any2f";
5730
        goto not_likely;
5731
    case OPC_BC1TANY2:
5732
        {
5733
            TCGv_i32 t1 = tcg_temp_new_i32();
5734
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5735
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5736
            tcg_gen_or_i32(t0, t0, t1);
5737
            tcg_temp_free_i32(t1);
5738
            tcg_gen_andi_i32(t0, t0, 1);
5739
            tcg_gen_extu_i32_tl(bcond, t0);
5740
        }
5741
        opn = "bc1any2t";
5742
        goto not_likely;
5743
    case OPC_BC1FANY4:
5744
        {
5745
            TCGv_i32 t1 = tcg_temp_new_i32();
5746
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5747
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5748
            tcg_gen_or_i32(t0, t0, t1);
5749
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5750
            tcg_gen_or_i32(t0, t0, t1);
5751
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5752
            tcg_gen_nor_i32(t0, t0, t1);
5753
            tcg_temp_free_i32(t1);
5754
            tcg_gen_andi_i32(t0, t0, 1);
5755
            tcg_gen_extu_i32_tl(bcond, t0);
5756
        }
5757
        opn = "bc1any4f";
5758
        goto not_likely;
5759
    case OPC_BC1TANY4:
5760
        {
5761
            TCGv_i32 t1 = tcg_temp_new_i32();
5762
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5763
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5764
            tcg_gen_or_i32(t0, t0, t1);
5765
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5766
            tcg_gen_or_i32(t0, t0, t1);
5767
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5768
            tcg_gen_or_i32(t0, t0, t1);
5769
            tcg_temp_free_i32(t1);
5770
            tcg_gen_andi_i32(t0, t0, 1);
5771
            tcg_gen_extu_i32_tl(bcond, t0);
5772
        }
5773
        opn = "bc1any4t";
5774
    not_likely:
5775
        ctx->hflags |= MIPS_HFLAG_BC;
5776
        break;
5777
    default:
5778
        MIPS_INVAL(opn);
5779
        generate_exception (ctx, EXCP_RI);
5780
        goto out;
5781
    }
5782
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5783
               ctx->hflags, btarget);
5784
    ctx->btarget = btarget;
5785

    
5786
 out:
5787
    tcg_temp_free_i32(t0);
5788
}
5789

    
5790
/* Coprocessor 1 (FPU) */
5791

    
5792
#define FOP(func, fmt) (((fmt) << 21) | (func))
5793

    
5794
enum fopcode {
5795
    OPC_ADD_S = FOP(0, FMT_S),
5796
    OPC_SUB_S = FOP(1, FMT_S),
5797
    OPC_MUL_S = FOP(2, FMT_S),
5798
    OPC_DIV_S = FOP(3, FMT_S),
5799
    OPC_SQRT_S = FOP(4, FMT_S),
5800
    OPC_ABS_S = FOP(5, FMT_S),
5801
    OPC_MOV_S = FOP(6, FMT_S),
5802
    OPC_NEG_S = FOP(7, FMT_S),
5803
    OPC_ROUND_L_S = FOP(8, FMT_S),
5804
    OPC_TRUNC_L_S = FOP(9, FMT_S),
5805
    OPC_CEIL_L_S = FOP(10, FMT_S),
5806
    OPC_FLOOR_L_S = FOP(11, FMT_S),
5807
    OPC_ROUND_W_S = FOP(12, FMT_S),
5808
    OPC_TRUNC_W_S = FOP(13, FMT_S),
5809
    OPC_CEIL_W_S = FOP(14, FMT_S),
5810
    OPC_FLOOR_W_S = FOP(15, FMT_S),
5811
    OPC_MOVCF_S = FOP(17, FMT_S),
5812
    OPC_MOVZ_S = FOP(18, FMT_S),
5813
    OPC_MOVN_S = FOP(19, FMT_S),
5814
    OPC_RECIP_S = FOP(21, FMT_S),
5815
    OPC_RSQRT_S = FOP(22, FMT_S),
5816
    OPC_RECIP2_S = FOP(28, FMT_S),
5817
    OPC_RECIP1_S = FOP(29, FMT_S),
5818
    OPC_RSQRT1_S = FOP(30, FMT_S),
5819
    OPC_RSQRT2_S = FOP(31, FMT_S),
5820
    OPC_CVT_D_S = FOP(33, FMT_S),
5821
    OPC_CVT_W_S = FOP(36, FMT_S),
5822
    OPC_CVT_L_S = FOP(37, FMT_S),
5823
    OPC_CVT_PS_S = FOP(38, FMT_S),
5824
    OPC_CMP_F_S = FOP (48, FMT_S),
5825
    OPC_CMP_UN_S = FOP (49, FMT_S),
5826
    OPC_CMP_EQ_S = FOP (50, FMT_S),
5827
    OPC_CMP_UEQ_S = FOP (51, FMT_S),
5828
    OPC_CMP_OLT_S = FOP (52, FMT_S),
5829
    OPC_CMP_ULT_S = FOP (53, FMT_S),
5830
    OPC_CMP_OLE_S = FOP (54, FMT_S),
5831
    OPC_CMP_ULE_S = FOP (55, FMT_S),
5832
    OPC_CMP_SF_S = FOP (56, FMT_S),
5833
    OPC_CMP_NGLE_S = FOP (57, FMT_S),
5834
    OPC_CMP_SEQ_S = FOP (58, FMT_S),
5835
    OPC_CMP_NGL_S = FOP (59, FMT_S),
5836
    OPC_CMP_LT_S = FOP (60, FMT_S),
5837
    OPC_CMP_NGE_S = FOP (61, FMT_S),
5838
    OPC_CMP_LE_S = FOP (62, FMT_S),
5839
    OPC_CMP_NGT_S = FOP (63, FMT_S),
5840

    
5841
    OPC_ADD_D = FOP(0, FMT_D),
5842
    OPC_SUB_D = FOP(1, FMT_D),
5843
    OPC_MUL_D = FOP(2, FMT_D),
5844
    OPC_DIV_D = FOP(3, FMT_D),
5845
    OPC_SQRT_D = FOP(4, FMT_D),
5846
    OPC_ABS_D = FOP(5, FMT_D),
5847
    OPC_MOV_D = FOP(6, FMT_D),
5848
    OPC_NEG_D = FOP(7, FMT_D),
5849
    OPC_ROUND_L_D = FOP(8, FMT_D),
5850
    OPC_TRUNC_L_D = FOP(9, FMT_D),
5851
    OPC_CEIL_L_D = FOP(10, FMT_D),
5852
    OPC_FLOOR_L_D = FOP(11, FMT_D),
5853
    OPC_ROUND_W_D = FOP(12, FMT_D),
5854
    OPC_TRUNC_W_D = FOP(13, FMT_D),
5855
    OPC_CEIL_W_D = FOP(14, FMT_D),
5856
    OPC_FLOOR_W_D = FOP(15, FMT_D),
5857
    OPC_MOVCF_D = FOP(17, FMT_D),
5858
    OPC_MOVZ_D = FOP(18, FMT_D),
5859
    OPC_MOVN_D = FOP(19, FMT_D),
5860
    OPC_RECIP_D = FOP(21, FMT_D),
5861
    OPC_RSQRT_D = FOP(22, FMT_D),
5862
    OPC_RECIP2_D = FOP(28, FMT_D),
5863
    OPC_RECIP1_D = FOP(29, FMT_D),
5864
    OPC_RSQRT1_D = FOP(30, FMT_D),
5865
    OPC_RSQRT2_D = FOP(31, FMT_D),
5866
    OPC_CVT_S_D = FOP(32, FMT_D),
5867
    OPC_CVT_W_D = FOP(36, FMT_D),
5868
    OPC_CVT_L_D = FOP(37, FMT_D),
5869
    OPC_CMP_F_D = FOP (48, FMT_D),
5870
    OPC_CMP_UN_D = FOP (49, FMT_D),
5871
    OPC_CMP_EQ_D = FOP (50, FMT_D),
5872
    OPC_CMP_UEQ_D = FOP (51, FMT_D),
5873
    OPC_CMP_OLT_D = FOP (52, FMT_D),
5874
    OPC_CMP_ULT_D = FOP (53, FMT_D),
5875
    OPC_CMP_OLE_D = FOP (54, FMT_D),
5876
    OPC_CMP_ULE_D = FOP (55, FMT_D),
5877
    OPC_CMP_SF_D = FOP (56, FMT_D),
5878
    OPC_CMP_NGLE_D = FOP (57, FMT_D),
5879
    OPC_CMP_SEQ_D = FOP (58, FMT_D),
5880
    OPC_CMP_NGL_D = FOP (59, FMT_D),
5881
    OPC_CMP_LT_D = FOP (60, FMT_D),
5882
    OPC_CMP_NGE_D = FOP (61, FMT_D),
5883
    OPC_CMP_LE_D = FOP (62, FMT_D),
5884
    OPC_CMP_NGT_D = FOP (63, FMT_D),
5885

    
5886
    OPC_CVT_S_W = FOP(32, FMT_W),
5887
    OPC_CVT_D_W = FOP(33, FMT_W),
5888
    OPC_CVT_S_L = FOP(32, FMT_L),
5889
    OPC_CVT_D_L = FOP(33, FMT_L),
5890
    OPC_CVT_PS_PW = FOP(38, FMT_W),
5891

    
5892
    OPC_ADD_PS = FOP(0, FMT_PS),
5893
    OPC_SUB_PS = FOP(1, FMT_PS),
5894
    OPC_MUL_PS = FOP(2, FMT_PS),
5895
    OPC_DIV_PS = FOP(3, FMT_PS),
5896
    OPC_ABS_PS = FOP(5, FMT_PS),
5897
    OPC_MOV_PS = FOP(6, FMT_PS),
5898
    OPC_NEG_PS = FOP(7, FMT_PS),
5899
    OPC_MOVCF_PS = FOP(17, FMT_PS),
5900
    OPC_MOVZ_PS = FOP(18, FMT_PS),
5901
    OPC_MOVN_PS = FOP(19, FMT_PS),
5902
    OPC_ADDR_PS = FOP(24, FMT_PS),
5903
    OPC_MULR_PS = FOP(26, FMT_PS),
5904
    OPC_RECIP2_PS = FOP(28, FMT_PS),
5905
    OPC_RECIP1_PS = FOP(29, FMT_PS),
5906
    OPC_RSQRT1_PS = FOP(30, FMT_PS),
5907
    OPC_RSQRT2_PS = FOP(31, FMT_PS),
5908

    
5909
    OPC_CVT_S_PU = FOP(32, FMT_PS),
5910
    OPC_CVT_PW_PS = FOP(36, FMT_PS),
5911
    OPC_CVT_S_PL = FOP(40, FMT_PS),
5912
    OPC_PLL_PS = FOP(44, FMT_PS),
5913
    OPC_PLU_PS = FOP(45, FMT_PS),
5914
    OPC_PUL_PS = FOP(46, FMT_PS),
5915
    OPC_PUU_PS = FOP(47, FMT_PS),
5916
    OPC_CMP_F_PS = FOP (48, FMT_PS),
5917
    OPC_CMP_UN_PS = FOP (49, FMT_PS),
5918
    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
5919
    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
5920
    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
5921
    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
5922
    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
5923
    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
5924
    OPC_CMP_SF_PS = FOP (56, FMT_PS),
5925
    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
5926
    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
5927
    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
5928
    OPC_CMP_LT_PS = FOP (60, FMT_PS),
5929
    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
5930
    OPC_CMP_LE_PS = FOP (62, FMT_PS),
5931
    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
5932
};
5933

    
5934
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5935
{
5936
    const char *opn = "cp1 move";
5937
    TCGv t0 = tcg_temp_new();
5938

    
5939
    switch (opc) {
5940
    case OPC_MFC1:
5941
        {
5942
            TCGv_i32 fp0 = tcg_temp_new_i32();
5943

    
5944
            gen_load_fpr32(fp0, fs);
5945
            tcg_gen_ext_i32_tl(t0, fp0);
5946
            tcg_temp_free_i32(fp0);
5947
        }
5948
        gen_store_gpr(t0, rt);
5949
        opn = "mfc1";
5950
        break;
5951
    case OPC_MTC1:
5952
        gen_load_gpr(t0, rt);
5953
        {
5954
            TCGv_i32 fp0 = tcg_temp_new_i32();
5955

    
5956
            tcg_gen_trunc_tl_i32(fp0, t0);
5957
            gen_store_fpr32(fp0, fs);
5958
            tcg_temp_free_i32(fp0);
5959
        }
5960
        opn = "mtc1";
5961
        break;
5962
    case OPC_CFC1:
5963
        gen_helper_1i(cfc1, t0, fs);
5964
        gen_store_gpr(t0, rt);
5965
        opn = "cfc1";
5966
        break;
5967
    case OPC_CTC1:
5968
        gen_load_gpr(t0, rt);
5969
        gen_helper_1i(ctc1, t0, fs);
5970
        opn = "ctc1";
5971
        break;
5972
#if defined(TARGET_MIPS64)
5973
    case OPC_DMFC1:
5974
        gen_load_fpr64(ctx, t0, fs);
5975
        gen_store_gpr(t0, rt);
5976
        opn = "dmfc1";
5977
        break;
5978
    case OPC_DMTC1:
5979
        gen_load_gpr(t0, rt);
5980
        gen_store_fpr64(ctx, t0, fs);
5981
        opn = "dmtc1";
5982
        break;
5983
#endif
5984
    case OPC_MFHC1:
5985
        {
5986
            TCGv_i32 fp0 = tcg_temp_new_i32();
5987

    
5988
            gen_load_fpr32h(fp0, fs);
5989
            tcg_gen_ext_i32_tl(t0, fp0);
5990
            tcg_temp_free_i32(fp0);
5991
        }
5992
        gen_store_gpr(t0, rt);
5993
        opn = "mfhc1";
5994
        break;
5995
    case OPC_MTHC1:
5996
        gen_load_gpr(t0, rt);
5997
        {
5998
            TCGv_i32 fp0 = tcg_temp_new_i32();
5999

    
6000
            tcg_gen_trunc_tl_i32(fp0, t0);
6001
            gen_store_fpr32h(fp0, fs);
6002
            tcg_temp_free_i32(fp0);
6003
        }
6004
        opn = "mthc1";
6005
        break;
6006
    default:
6007
        MIPS_INVAL(opn);
6008
        generate_exception (ctx, EXCP_RI);
6009
        goto out;
6010
    }
6011
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6012

    
6013
 out:
6014
    tcg_temp_free(t0);
6015
}
6016

    
6017
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6018
{
6019
    int l1;
6020
    TCGCond cond;
6021
    TCGv_i32 t0;
6022

    
6023
    if (rd == 0) {
6024
        /* Treat as NOP. */
6025
        return;
6026
    }
6027

    
6028
    if (tf)
6029
        cond = TCG_COND_EQ;
6030
    else
6031
        cond = TCG_COND_NE;
6032

    
6033
    l1 = gen_new_label();
6034
    t0 = tcg_temp_new_i32();
6035
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6036
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6037
    tcg_temp_free_i32(t0);
6038
    if (rs == 0) {
6039
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
6040
    } else {
6041
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6042
    }
6043
    gen_set_label(l1);
6044
}
6045

    
6046
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6047
{
6048
    int cond;
6049
    TCGv_i32 t0 = tcg_temp_new_i32();
6050
    int l1 = gen_new_label();
6051

    
6052
    if (tf)
6053
        cond = TCG_COND_EQ;
6054
    else
6055
        cond = TCG_COND_NE;
6056

    
6057
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6058
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6059
    gen_load_fpr32(t0, fs);
6060
    gen_store_fpr32(t0, fd);
6061
    gen_set_label(l1);
6062
    tcg_temp_free_i32(t0);
6063
}
6064

    
6065
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6066
{
6067
    int cond;
6068
    TCGv_i32 t0 = tcg_temp_new_i32();
6069
    TCGv_i64 fp0;
6070
    int l1 = gen_new_label();
6071

    
6072
    if (tf)
6073
        cond = TCG_COND_EQ;
6074
    else
6075
        cond = TCG_COND_NE;
6076

    
6077
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6078
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6079
    tcg_temp_free_i32(t0);
6080
    fp0 = tcg_temp_new_i64();
6081
    gen_load_fpr64(ctx, fp0, fs);
6082
    gen_store_fpr64(ctx, fp0, fd);
6083
    tcg_temp_free_i64(fp0);
6084
    gen_set_label(l1);
6085
}
6086

    
6087
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6088
{
6089
    int cond;
6090
    TCGv_i32 t0 = tcg_temp_new_i32();
6091
    int l1 = gen_new_label();
6092
    int l2 = gen_new_label();
6093

    
6094
    if (tf)
6095
        cond = TCG_COND_EQ;
6096
    else
6097
        cond = TCG_COND_NE;
6098

    
6099
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6100
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
6101
    gen_load_fpr32(t0, fs);
6102
    gen_store_fpr32(t0, fd);
6103
    gen_set_label(l1);
6104

    
6105
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6106
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
6107
    gen_load_fpr32h(t0, fs);
6108
    gen_store_fpr32h(t0, fd);
6109
    tcg_temp_free_i32(t0);
6110
    gen_set_label(l2);
6111
}
6112

    
6113

    
6114
static void gen_farith (DisasContext *ctx, enum fopcode op1,
6115
                        int ft, int fs, int fd, int cc)
6116
{
6117
    const char *opn = "farith";
6118
    const char *condnames[] = {
6119
            "c.f",
6120
            "c.un",
6121
            "c.eq",
6122
            "c.ueq",
6123
            "c.olt",
6124
            "c.ult",
6125
            "c.ole",
6126
            "c.ule",
6127
            "c.sf",
6128
            "c.ngle",
6129
            "c.seq",
6130
            "c.ngl",
6131
            "c.lt",
6132
            "c.nge",
6133
            "c.le",
6134
            "c.ngt",
6135
    };
6136
    const char *condnames_abs[] = {
6137
            "cabs.f",
6138
            "cabs.un",
6139
            "cabs.eq",
6140
            "cabs.ueq",
6141
            "cabs.olt",
6142
            "cabs.ult",
6143
            "cabs.ole",
6144
            "cabs.ule",
6145
            "cabs.sf",
6146
            "cabs.ngle",
6147
            "cabs.seq",
6148
            "cabs.ngl",
6149
            "cabs.lt",
6150
            "cabs.nge",
6151
            "cabs.le",
6152
            "cabs.ngt",
6153
    };
6154
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6155
    uint32_t func = ctx->opcode & 0x3f;
6156

    
6157
    switch (op1) {
6158
    case OPC_ADD_S:
6159
        {
6160
            TCGv_i32 fp0 = tcg_temp_new_i32();
6161
            TCGv_i32 fp1 = tcg_temp_new_i32();
6162

    
6163
            gen_load_fpr32(fp0, fs);
6164
            gen_load_fpr32(fp1, ft);
6165
            gen_helper_float_add_s(fp0, fp0, fp1);
6166
            tcg_temp_free_i32(fp1);
6167
            gen_store_fpr32(fp0, fd);
6168
            tcg_temp_free_i32(fp0);
6169
        }
6170
        opn = "add.s";
6171
        optype = BINOP;
6172
        break;
6173
    case OPC_SUB_S:
6174
        {
6175
            TCGv_i32 fp0 = tcg_temp_new_i32();
6176
            TCGv_i32 fp1 = tcg_temp_new_i32();
6177

    
6178
            gen_load_fpr32(fp0, fs);
6179
            gen_load_fpr32(fp1, ft);
6180
            gen_helper_float_sub_s(fp0, fp0, fp1);
6181
            tcg_temp_free_i32(fp1);
6182
            gen_store_fpr32(fp0, fd);
6183
            tcg_temp_free_i32(fp0);
6184
        }
6185
        opn = "sub.s";
6186
        optype = BINOP;
6187
        break;
6188
    case OPC_MUL_S:
6189
        {
6190
            TCGv_i32 fp0 = tcg_temp_new_i32();
6191
            TCGv_i32 fp1 = tcg_temp_new_i32();
6192

    
6193
            gen_load_fpr32(fp0, fs);
6194
            gen_load_fpr32(fp1, ft);
6195
            gen_helper_float_mul_s(fp0, fp0, fp1);
6196
            tcg_temp_free_i32(fp1);
6197
            gen_store_fpr32(fp0, fd);
6198
            tcg_temp_free_i32(fp0);
6199
        }
6200
        opn = "mul.s";
6201
        optype = BINOP;
6202
        break;
6203
    case OPC_DIV_S:
6204
        {
6205
            TCGv_i32 fp0 = tcg_temp_new_i32();
6206
            TCGv_i32 fp1 = tcg_temp_new_i32();
6207

    
6208
            gen_load_fpr32(fp0, fs);
6209
            gen_load_fpr32(fp1, ft);
6210
            gen_helper_float_div_s(fp0, fp0, fp1);
6211
            tcg_temp_free_i32(fp1);
6212
            gen_store_fpr32(fp0, fd);
6213
            tcg_temp_free_i32(fp0);
6214
        }
6215
        opn = "div.s";
6216
        optype = BINOP;
6217
        break;
6218
    case OPC_SQRT_S:
6219
        {
6220
            TCGv_i32 fp0 = tcg_temp_new_i32();
6221

    
6222
            gen_load_fpr32(fp0, fs);
6223
            gen_helper_float_sqrt_s(fp0, fp0);
6224
            gen_store_fpr32(fp0, fd);
6225
            tcg_temp_free_i32(fp0);
6226
        }
6227
        opn = "sqrt.s";
6228
        break;
6229
    case OPC_ABS_S:
6230
        {
6231
            TCGv_i32 fp0 = tcg_temp_new_i32();
6232

    
6233
            gen_load_fpr32(fp0, fs);
6234
            gen_helper_float_abs_s(fp0, fp0);
6235
            gen_store_fpr32(fp0, fd);
6236
            tcg_temp_free_i32(fp0);
6237
        }
6238
        opn = "abs.s";
6239
        break;
6240
    case OPC_MOV_S:
6241
        {
6242
            TCGv_i32 fp0 = tcg_temp_new_i32();
6243

    
6244
            gen_load_fpr32(fp0, fs);
6245
            gen_store_fpr32(fp0, fd);
6246
            tcg_temp_free_i32(fp0);
6247
        }
6248
        opn = "mov.s";
6249
        break;
6250
    case OPC_NEG_S:
6251
        {
6252
            TCGv_i32 fp0 = tcg_temp_new_i32();
6253

    
6254
            gen_load_fpr32(fp0, fs);
6255
            gen_helper_float_chs_s(fp0, fp0);
6256
            gen_store_fpr32(fp0, fd);
6257
            tcg_temp_free_i32(fp0);
6258
        }
6259
        opn = "neg.s";
6260
        break;
6261
    case OPC_ROUND_L_S:
6262
        check_cp1_64bitmode(ctx);
6263
        {
6264
            TCGv_i32 fp32 = tcg_temp_new_i32();
6265
            TCGv_i64 fp64 = tcg_temp_new_i64();
6266

    
6267
            gen_load_fpr32(fp32, fs);
6268
            gen_helper_float_roundl_s(fp64, fp32);
6269
            tcg_temp_free_i32(fp32);
6270
            gen_store_fpr64(ctx, fp64, fd);
6271
            tcg_temp_free_i64(fp64);
6272
        }
6273
        opn = "round.l.s";
6274
        break;
6275
    case OPC_TRUNC_L_S:
6276
        check_cp1_64bitmode(ctx);
6277
        {
6278
            TCGv_i32 fp32 = tcg_temp_new_i32();
6279
            TCGv_i64 fp64 = tcg_temp_new_i64();
6280

    
6281
            gen_load_fpr32(fp32, fs);
6282
            gen_helper_float_truncl_s(fp64, fp32);
6283
            tcg_temp_free_i32(fp32);
6284
            gen_store_fpr64(ctx, fp64, fd);
6285
            tcg_temp_free_i64(fp64);
6286
        }
6287
        opn = "trunc.l.s";
6288
        break;
6289
    case OPC_CEIL_L_S:
6290
        check_cp1_64bitmode(ctx);
6291
        {
6292
            TCGv_i32 fp32 = tcg_temp_new_i32();
6293
            TCGv_i64 fp64 = tcg_temp_new_i64();
6294

    
6295
            gen_load_fpr32(fp32, fs);
6296
            gen_helper_float_ceill_s(fp64, fp32);
6297
            tcg_temp_free_i32(fp32);
6298
            gen_store_fpr64(ctx, fp64, fd);
6299
            tcg_temp_free_i64(fp64);
6300
        }
6301
        opn = "ceil.l.s";
6302
        break;
6303
    case OPC_FLOOR_L_S:
6304
        check_cp1_64bitmode(ctx);
6305
        {
6306
            TCGv_i32 fp32 = tcg_temp_new_i32();
6307
            TCGv_i64 fp64 = tcg_temp_new_i64();
6308

    
6309
            gen_load_fpr32(fp32, fs);
6310
            gen_helper_float_floorl_s(fp64, fp32);
6311
            tcg_temp_free_i32(fp32);
6312
            gen_store_fpr64(ctx, fp64, fd);
6313
            tcg_temp_free_i64(fp64);
6314
        }
6315
        opn = "floor.l.s";
6316
        break;
6317
    case OPC_ROUND_W_S:
6318
        {
6319
            TCGv_i32 fp0 = tcg_temp_new_i32();
6320

    
6321
            gen_load_fpr32(fp0, fs);
6322
            gen_helper_float_roundw_s(fp0, fp0);
6323
            gen_store_fpr32(fp0, fd);
6324
            tcg_temp_free_i32(fp0);
6325
        }
6326
        opn = "round.w.s";
6327
        break;
6328
    case OPC_TRUNC_W_S:
6329
        {
6330
            TCGv_i32 fp0 = tcg_temp_new_i32();
6331

    
6332
            gen_load_fpr32(fp0, fs);
6333
            gen_helper_float_truncw_s(fp0, fp0);
6334
            gen_store_fpr32(fp0, fd);
6335
            tcg_temp_free_i32(fp0);
6336
        }
6337
        opn = "trunc.w.s";
6338
        break;
6339
    case OPC_CEIL_W_S:
6340
        {
6341
            TCGv_i32 fp0 = tcg_temp_new_i32();
6342

    
6343
            gen_load_fpr32(fp0, fs);
6344
            gen_helper_float_ceilw_s(fp0, fp0);
6345
            gen_store_fpr32(fp0, fd);
6346
            tcg_temp_free_i32(fp0);
6347
        }
6348
        opn = "ceil.w.s";
6349
        break;
6350
    case OPC_FLOOR_W_S:
6351
        {
6352
            TCGv_i32 fp0 = tcg_temp_new_i32();
6353

    
6354
            gen_load_fpr32(fp0, fs);
6355
            gen_helper_float_floorw_s(fp0, fp0);
6356
            gen_store_fpr32(fp0, fd);
6357
            tcg_temp_free_i32(fp0);
6358
        }
6359
        opn = "floor.w.s";
6360
        break;
6361
    case OPC_MOVCF_S:
6362
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6363
        opn = "movcf.s";
6364
        break;
6365
    case OPC_MOVZ_S:
6366
        {
6367
            int l1 = gen_new_label();
6368
            TCGv_i32 fp0;
6369

    
6370
            if (ft != 0) {
6371
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6372
            }
6373
            fp0 = tcg_temp_new_i32();
6374
            gen_load_fpr32(fp0, fs);
6375
            gen_store_fpr32(fp0, fd);
6376
            tcg_temp_free_i32(fp0);
6377
            gen_set_label(l1);
6378
        }
6379
        opn = "movz.s";
6380
        break;
6381
    case OPC_MOVN_S:
6382
        {
6383
            int l1 = gen_new_label();
6384
            TCGv_i32 fp0;
6385

    
6386
            if (ft != 0) {
6387
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6388
                fp0 = tcg_temp_new_i32();
6389
                gen_load_fpr32(fp0, fs);
6390
                gen_store_fpr32(fp0, fd);
6391
                tcg_temp_free_i32(fp0);
6392
                gen_set_label(l1);
6393
            }
6394
        }
6395
        opn = "movn.s";
6396
        break;
6397
    case OPC_RECIP_S:
6398
        check_cop1x(ctx);
6399
        {
6400
            TCGv_i32 fp0 = tcg_temp_new_i32();
6401

    
6402
            gen_load_fpr32(fp0, fs);
6403
            gen_helper_float_recip_s(fp0, fp0);
6404
            gen_store_fpr32(fp0, fd);
6405
            tcg_temp_free_i32(fp0);
6406
        }
6407
        opn = "recip.s";
6408
        break;
6409
    case OPC_RSQRT_S:
6410
        check_cop1x(ctx);
6411
        {
6412
            TCGv_i32 fp0 = tcg_temp_new_i32();
6413

    
6414
            gen_load_fpr32(fp0, fs);
6415
            gen_helper_float_rsqrt_s(fp0, fp0);
6416
            gen_store_fpr32(fp0, fd);
6417
            tcg_temp_free_i32(fp0);
6418
        }
6419
        opn = "rsqrt.s";
6420
        break;
6421
    case OPC_RECIP2_S:
6422
        check_cp1_64bitmode(ctx);
6423
        {
6424
            TCGv_i32 fp0 = tcg_temp_new_i32();
6425
            TCGv_i32 fp1 = tcg_temp_new_i32();
6426

    
6427
            gen_load_fpr32(fp0, fs);
6428
            gen_load_fpr32(fp1, fd);
6429
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6430
            tcg_temp_free_i32(fp1);
6431
            gen_store_fpr32(fp0, fd);
6432
            tcg_temp_free_i32(fp0);
6433
        }
6434
        opn = "recip2.s";
6435
        break;
6436
    case OPC_RECIP1_S:
6437
        check_cp1_64bitmode(ctx);
6438
        {
6439
            TCGv_i32 fp0 = tcg_temp_new_i32();
6440

    
6441
            gen_load_fpr32(fp0, fs);
6442
            gen_helper_float_recip1_s(fp0, fp0);
6443
            gen_store_fpr32(fp0, fd);
6444
            tcg_temp_free_i32(fp0);
6445
        }
6446
        opn = "recip1.s";
6447
        break;
6448
    case OPC_RSQRT1_S:
6449
        check_cp1_64bitmode(ctx);
6450
        {
6451
            TCGv_i32 fp0 = tcg_temp_new_i32();
6452

    
6453
            gen_load_fpr32(fp0, fs);
6454
            gen_helper_float_rsqrt1_s(fp0, fp0);
6455
            gen_store_fpr32(fp0, fd);
6456
            tcg_temp_free_i32(fp0);
6457
        }
6458
        opn = "rsqrt1.s";
6459
        break;
6460
    case OPC_RSQRT2_S:
6461
        check_cp1_64bitmode(ctx);
6462
        {
6463
            TCGv_i32 fp0 = tcg_temp_new_i32();
6464
            TCGv_i32 fp1 = tcg_temp_new_i32();
6465

    
6466
            gen_load_fpr32(fp0, fs);
6467
            gen_load_fpr32(fp1, ft);
6468
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6469
            tcg_temp_free_i32(fp1);
6470
            gen_store_fpr32(fp0, fd);
6471
            tcg_temp_free_i32(fp0);
6472
        }
6473
        opn = "rsqrt2.s";
6474
        break;
6475
    case OPC_CVT_D_S:
6476
        check_cp1_registers(ctx, fd);
6477
        {
6478
            TCGv_i32 fp32 = tcg_temp_new_i32();
6479
            TCGv_i64 fp64 = tcg_temp_new_i64();
6480

    
6481
            gen_load_fpr32(fp32, fs);
6482
            gen_helper_float_cvtd_s(fp64, fp32);
6483
            tcg_temp_free_i32(fp32);
6484
            gen_store_fpr64(ctx, fp64, fd);
6485
            tcg_temp_free_i64(fp64);
6486
        }
6487
        opn = "cvt.d.s";
6488
        break;
6489
    case OPC_CVT_W_S:
6490
        {
6491
            TCGv_i32 fp0 = tcg_temp_new_i32();
6492

    
6493
            gen_load_fpr32(fp0, fs);
6494
            gen_helper_float_cvtw_s(fp0, fp0);
6495
            gen_store_fpr32(fp0, fd);
6496
            tcg_temp_free_i32(fp0);
6497
        }
6498
        opn = "cvt.w.s";
6499
        break;
6500
    case OPC_CVT_L_S:
6501
        check_cp1_64bitmode(ctx);
6502
        {
6503
            TCGv_i32 fp32 = tcg_temp_new_i32();
6504
            TCGv_i64 fp64 = tcg_temp_new_i64();
6505

    
6506
            gen_load_fpr32(fp32, fs);
6507
            gen_helper_float_cvtl_s(fp64, fp32);
6508
            tcg_temp_free_i32(fp32);
6509
            gen_store_fpr64(ctx, fp64, fd);
6510
            tcg_temp_free_i64(fp64);
6511
        }
6512
        opn = "cvt.l.s";
6513
        break;
6514
    case OPC_CVT_PS_S:
6515
        check_cp1_64bitmode(ctx);
6516
        {
6517
            TCGv_i64 fp64 = tcg_temp_new_i64();
6518
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6519
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6520

    
6521
            gen_load_fpr32(fp32_0, fs);
6522
            gen_load_fpr32(fp32_1, ft);
6523
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6524
            tcg_temp_free_i32(fp32_1);
6525
            tcg_temp_free_i32(fp32_0);
6526
            gen_store_fpr64(ctx, fp64, fd);
6527
            tcg_temp_free_i64(fp64);
6528
        }
6529
        opn = "cvt.ps.s";
6530
        break;
6531
    case OPC_CMP_F_S:
6532
    case OPC_CMP_UN_S:
6533
    case OPC_CMP_EQ_S:
6534
    case OPC_CMP_UEQ_S:
6535
    case OPC_CMP_OLT_S:
6536
    case OPC_CMP_ULT_S:
6537
    case OPC_CMP_OLE_S:
6538
    case OPC_CMP_ULE_S:
6539
    case OPC_CMP_SF_S:
6540
    case OPC_CMP_NGLE_S:
6541
    case OPC_CMP_SEQ_S:
6542
    case OPC_CMP_NGL_S:
6543
    case OPC_CMP_LT_S:
6544
    case OPC_CMP_NGE_S:
6545
    case OPC_CMP_LE_S:
6546
    case OPC_CMP_NGT_S:
6547
        if (ctx->opcode & (1 << 6)) {
6548
            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6549
            opn = condnames_abs[func-48];
6550
        } else {
6551
            gen_cmp_s(ctx, func-48, ft, fs, cc);
6552
            opn = condnames[func-48];
6553
        }
6554
        break;
6555
    case OPC_ADD_D:
6556
        check_cp1_registers(ctx, fs | ft | fd);
6557
        {
6558
            TCGv_i64 fp0 = tcg_temp_new_i64();
6559
            TCGv_i64 fp1 = tcg_temp_new_i64();
6560

    
6561
            gen_load_fpr64(ctx, fp0, fs);
6562
            gen_load_fpr64(ctx, fp1, ft);
6563
            gen_helper_float_add_d(fp0, fp0, fp1);
6564
            tcg_temp_free_i64(fp1);
6565
            gen_store_fpr64(ctx, fp0, fd);
6566
            tcg_temp_free_i64(fp0);
6567
        }
6568
        opn = "add.d";
6569
        optype = BINOP;
6570
        break;
6571
    case OPC_SUB_D:
6572
        check_cp1_registers(ctx, fs | ft | fd);
6573
        {
6574
            TCGv_i64 fp0 = tcg_temp_new_i64();
6575
            TCGv_i64 fp1 = tcg_temp_new_i64();
6576

    
6577
            gen_load_fpr64(ctx, fp0, fs);
6578
            gen_load_fpr64(ctx, fp1, ft);
6579
            gen_helper_float_sub_d(fp0, fp0, fp1);
6580
            tcg_temp_free_i64(fp1);
6581
            gen_store_fpr64(ctx, fp0, fd);
6582
            tcg_temp_free_i64(fp0);
6583
        }
6584
        opn = "sub.d";
6585
        optype = BINOP;
6586
        break;
6587
    case OPC_MUL_D:
6588
        check_cp1_registers(ctx, fs | ft | fd);
6589
        {
6590
            TCGv_i64 fp0 = tcg_temp_new_i64();
6591
            TCGv_i64 fp1 = tcg_temp_new_i64();
6592

    
6593
            gen_load_fpr64(ctx, fp0, fs);
6594
            gen_load_fpr64(ctx, fp1, ft);
6595
            gen_helper_float_mul_d(fp0, fp0, fp1);
6596
            tcg_temp_free_i64(fp1);
6597
            gen_store_fpr64(ctx, fp0, fd);
6598
            tcg_temp_free_i64(fp0);
6599
        }
6600
        opn = "mul.d";
6601
        optype = BINOP;
6602
        break;
6603
    case OPC_DIV_D:
6604
        check_cp1_registers(ctx, fs | ft | fd);
6605
        {
6606
            TCGv_i64 fp0 = tcg_temp_new_i64();
6607
            TCGv_i64 fp1 = tcg_temp_new_i64();
6608

    
6609
            gen_load_fpr64(ctx, fp0, fs);
6610
            gen_load_fpr64(ctx, fp1, ft);
6611
            gen_helper_float_div_d(fp0, fp0, fp1);
6612
            tcg_temp_free_i64(fp1);
6613
            gen_store_fpr64(ctx, fp0, fd);
6614
            tcg_temp_free_i64(fp0);
6615
        }
6616
        opn = "div.d";
6617
        optype = BINOP;
6618
        break;
6619
    case OPC_SQRT_D:
6620
        check_cp1_registers(ctx, fs | fd);
6621
        {
6622
            TCGv_i64 fp0 = tcg_temp_new_i64();
6623

    
6624
            gen_load_fpr64(ctx, fp0, fs);
6625
            gen_helper_float_sqrt_d(fp0, fp0);
6626
            gen_store_fpr64(ctx, fp0, fd);
6627
            tcg_temp_free_i64(fp0);
6628
        }
6629
        opn = "sqrt.d";
6630
        break;
6631
    case OPC_ABS_D:
6632
        check_cp1_registers(ctx, fs | fd);
6633
        {
6634
            TCGv_i64 fp0 = tcg_temp_new_i64();
6635

    
6636
            gen_load_fpr64(ctx, fp0, fs);
6637
            gen_helper_float_abs_d(fp0, fp0);
6638
            gen_store_fpr64(ctx, fp0, fd);
6639
            tcg_temp_free_i64(fp0);
6640
        }
6641
        opn = "abs.d";
6642
        break;
6643
    case OPC_MOV_D:
6644
        check_cp1_registers(ctx, fs | fd);
6645
        {
6646
            TCGv_i64 fp0 = tcg_temp_new_i64();
6647

    
6648
            gen_load_fpr64(ctx, fp0, fs);
6649
            gen_store_fpr64(ctx, fp0, fd);
6650
            tcg_temp_free_i64(fp0);
6651
        }
6652
        opn = "mov.d";
6653
        break;
6654
    case OPC_NEG_D:
6655
        check_cp1_registers(ctx, fs | fd);
6656
        {
6657
            TCGv_i64 fp0 = tcg_temp_new_i64();
6658

    
6659
            gen_load_fpr64(ctx, fp0, fs);
6660
            gen_helper_float_chs_d(fp0, fp0);
6661
            gen_store_fpr64(ctx, fp0, fd);
6662
            tcg_temp_free_i64(fp0);
6663
        }
6664
        opn = "neg.d";
6665
        break;
6666
    case OPC_ROUND_L_D:
6667
        check_cp1_64bitmode(ctx);
6668
        {
6669
            TCGv_i64 fp0 = tcg_temp_new_i64();
6670

    
6671
            gen_load_fpr64(ctx, fp0, fs);
6672
            gen_helper_float_roundl_d(fp0, fp0);
6673
            gen_store_fpr64(ctx, fp0, fd);
6674
            tcg_temp_free_i64(fp0);
6675
        }
6676
        opn = "round.l.d";
6677
        break;
6678
    case OPC_TRUNC_L_D:
6679
        check_cp1_64bitmode(ctx);
6680
        {
6681
            TCGv_i64 fp0 = tcg_temp_new_i64();
6682

    
6683
            gen_load_fpr64(ctx, fp0, fs);
6684
            gen_helper_float_truncl_d(fp0, fp0);
6685
            gen_store_fpr64(ctx, fp0, fd);
6686
            tcg_temp_free_i64(fp0);
6687
        }
6688
        opn = "trunc.l.d";
6689
        break;
6690
    case OPC_CEIL_L_D:
6691
        check_cp1_64bitmode(ctx);
6692
        {
6693
            TCGv_i64 fp0 = tcg_temp_new_i64();
6694

    
6695
            gen_load_fpr64(ctx, fp0, fs);
6696
            gen_helper_float_ceill_d(fp0, fp0);
6697
            gen_store_fpr64(ctx, fp0, fd);
6698
            tcg_temp_free_i64(fp0);
6699
        }
6700
        opn = "ceil.l.d";
6701
        break;
6702
    case OPC_FLOOR_L_D:
6703
        check_cp1_64bitmode(ctx);
6704
        {
6705
            TCGv_i64 fp0 = tcg_temp_new_i64();
6706

    
6707
            gen_load_fpr64(ctx, fp0, fs);
6708
            gen_helper_float_floorl_d(fp0, fp0);
6709
            gen_store_fpr64(ctx, fp0, fd);
6710
            tcg_temp_free_i64(fp0);
6711
        }
6712
        opn = "floor.l.d";
6713
        break;
6714
    case OPC_ROUND_W_D:
6715
        check_cp1_registers(ctx, fs);
6716
        {
6717
            TCGv_i32 fp32 = tcg_temp_new_i32();
6718
            TCGv_i64 fp64 = tcg_temp_new_i64();
6719

    
6720
            gen_load_fpr64(ctx, fp64, fs);
6721
            gen_helper_float_roundw_d(fp32, fp64);
6722
            tcg_temp_free_i64(fp64);
6723
            gen_store_fpr32(fp32, fd);
6724
            tcg_temp_free_i32(fp32);
6725
        }
6726
        opn = "round.w.d";
6727
        break;
6728
    case OPC_TRUNC_W_D:
6729
        check_cp1_registers(ctx, fs);
6730
        {
6731
            TCGv_i32 fp32 = tcg_temp_new_i32();
6732
            TCGv_i64 fp64 = tcg_temp_new_i64();
6733

    
6734
            gen_load_fpr64(ctx, fp64, fs);
6735
            gen_helper_float_truncw_d(fp32, fp64);
6736
            tcg_temp_free_i64(fp64);
6737
            gen_store_fpr32(fp32, fd);
6738
            tcg_temp_free_i32(fp32);
6739
        }
6740
        opn = "trunc.w.d";
6741
        break;
6742
    case OPC_CEIL_W_D:
6743
        check_cp1_registers(ctx, fs);
6744
        {
6745
            TCGv_i32 fp32 = tcg_temp_new_i32();
6746
            TCGv_i64 fp64 = tcg_temp_new_i64();
6747

    
6748
            gen_load_fpr64(ctx, fp64, fs);
6749
            gen_helper_float_ceilw_d(fp32, fp64);
6750
            tcg_temp_free_i64(fp64);
6751
            gen_store_fpr32(fp32, fd);
6752
            tcg_temp_free_i32(fp32);
6753
        }
6754
        opn = "ceil.w.d";
6755
        break;
6756
    case OPC_FLOOR_W_D:
6757
        check_cp1_registers(ctx, fs);
6758
        {
6759
            TCGv_i32 fp32 = tcg_temp_new_i32();
6760
            TCGv_i64 fp64 = tcg_temp_new_i64();
6761

    
6762
            gen_load_fpr64(ctx, fp64, fs);
6763
            gen_helper_float_floorw_d(fp32, fp64);
6764
            tcg_temp_free_i64(fp64);
6765
            gen_store_fpr32(fp32, fd);
6766
            tcg_temp_free_i32(fp32);
6767
        }
6768
        opn = "floor.w.d";
6769
        break;
6770
    case OPC_MOVCF_D:
6771
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6772
        opn = "movcf.d";
6773
        break;
6774
    case OPC_MOVZ_D:
6775
        {
6776
            int l1 = gen_new_label();
6777
            TCGv_i64 fp0;
6778

    
6779
            if (ft != 0) {
6780
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6781
            }
6782
            fp0 = tcg_temp_new_i64();
6783
            gen_load_fpr64(ctx, fp0, fs);
6784
            gen_store_fpr64(ctx, fp0, fd);
6785
            tcg_temp_free_i64(fp0);
6786
            gen_set_label(l1);
6787
        }
6788
        opn = "movz.d";
6789
        break;
6790
    case OPC_MOVN_D:
6791
        {
6792
            int l1 = gen_new_label();
6793
            TCGv_i64 fp0;
6794

    
6795
            if (ft != 0) {
6796
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6797
                fp0 = tcg_temp_new_i64();
6798
                gen_load_fpr64(ctx, fp0, fs);
6799
                gen_store_fpr64(ctx, fp0, fd);
6800
                tcg_temp_free_i64(fp0);
6801
                gen_set_label(l1);
6802
            }
6803
        }
6804
        opn = "movn.d";
6805
        break;
6806
    case OPC_RECIP_D:
6807
        check_cp1_64bitmode(ctx);
6808
        {
6809
            TCGv_i64 fp0 = tcg_temp_new_i64();
6810

    
6811
            gen_load_fpr64(ctx, fp0, fs);
6812
            gen_helper_float_recip_d(fp0, fp0);
6813
            gen_store_fpr64(ctx, fp0, fd);
6814
            tcg_temp_free_i64(fp0);
6815
        }
6816
        opn = "recip.d";
6817
        break;
6818
    case OPC_RSQRT_D:
6819
        check_cp1_64bitmode(ctx);
6820
        {
6821
            TCGv_i64 fp0 = tcg_temp_new_i64();
6822

    
6823
            gen_load_fpr64(ctx, fp0, fs);
6824
            gen_helper_float_rsqrt_d(fp0, fp0);
6825
            gen_store_fpr64(ctx, fp0, fd);
6826
            tcg_temp_free_i64(fp0);
6827
        }
6828
        opn = "rsqrt.d";
6829
        break;
6830
    case OPC_RECIP2_D:
6831
        check_cp1_64bitmode(ctx);
6832
        {
6833
            TCGv_i64 fp0 = tcg_temp_new_i64();
6834
            TCGv_i64 fp1 = tcg_temp_new_i64();
6835

    
6836
            gen_load_fpr64(ctx, fp0, fs);
6837
            gen_load_fpr64(ctx, fp1, ft);
6838
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6839
            tcg_temp_free_i64(fp1);
6840
            gen_store_fpr64(ctx, fp0, fd);
6841
            tcg_temp_free_i64(fp0);
6842
        }
6843
        opn = "recip2.d";
6844
        break;
6845
    case OPC_RECIP1_D:
6846
        check_cp1_64bitmode(ctx);
6847
        {
6848
            TCGv_i64 fp0 = tcg_temp_new_i64();
6849

    
6850
            gen_load_fpr64(ctx, fp0, fs);
6851
            gen_helper_float_recip1_d(fp0, fp0);
6852
            gen_store_fpr64(ctx, fp0, fd);
6853
            tcg_temp_free_i64(fp0);
6854
        }
6855
        opn = "recip1.d";
6856
        break;
6857
    case OPC_RSQRT1_D:
6858
        check_cp1_64bitmode(ctx);
6859
        {
6860
            TCGv_i64 fp0 = tcg_temp_new_i64();
6861

    
6862
            gen_load_fpr64(ctx, fp0, fs);
6863
            gen_helper_float_rsqrt1_d(fp0, fp0);
6864
            gen_store_fpr64(ctx, fp0, fd);
6865
            tcg_temp_free_i64(fp0);
6866
        }
6867
        opn = "rsqrt1.d";
6868
        break;
6869
    case OPC_RSQRT2_D:
6870
        check_cp1_64bitmode(ctx);
6871
        {
6872
            TCGv_i64 fp0 = tcg_temp_new_i64();
6873
            TCGv_i64 fp1 = tcg_temp_new_i64();
6874

    
6875
            gen_load_fpr64(ctx, fp0, fs);
6876
            gen_load_fpr64(ctx, fp1, ft);
6877
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6878
            tcg_temp_free_i64(fp1);
6879
            gen_store_fpr64(ctx, fp0, fd);
6880
            tcg_temp_free_i64(fp0);
6881
        }
6882
        opn = "rsqrt2.d";
6883
        break;
6884
    case OPC_CMP_F_D:
6885
    case OPC_CMP_UN_D:
6886
    case OPC_CMP_EQ_D:
6887
    case OPC_CMP_UEQ_D:
6888
    case OPC_CMP_OLT_D:
6889
    case OPC_CMP_ULT_D:
6890
    case OPC_CMP_OLE_D:
6891
    case OPC_CMP_ULE_D:
6892
    case OPC_CMP_SF_D:
6893
    case OPC_CMP_NGLE_D:
6894
    case OPC_CMP_SEQ_D:
6895
    case OPC_CMP_NGL_D:
6896
    case OPC_CMP_LT_D:
6897
    case OPC_CMP_NGE_D:
6898
    case OPC_CMP_LE_D:
6899
    case OPC_CMP_NGT_D:
6900
        if (ctx->opcode & (1 << 6)) {
6901
            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
6902
            opn = condnames_abs[func-48];
6903
        } else {
6904
            gen_cmp_d(ctx, func-48, ft, fs, cc);
6905
            opn = condnames[func-48];
6906
        }
6907
        break;
6908
    case OPC_CVT_S_D:
6909
        check_cp1_registers(ctx, fs);
6910
        {
6911
            TCGv_i32 fp32 = tcg_temp_new_i32();
6912
            TCGv_i64 fp64 = tcg_temp_new_i64();
6913

    
6914
            gen_load_fpr64(ctx, fp64, fs);
6915
            gen_helper_float_cvts_d(fp32, fp64);
6916
            tcg_temp_free_i64(fp64);
6917
            gen_store_fpr32(fp32, fd);
6918
            tcg_temp_free_i32(fp32);
6919
        }
6920
        opn = "cvt.s.d";
6921
        break;
6922
    case OPC_CVT_W_D:
6923
        check_cp1_registers(ctx, fs);
6924
        {
6925
            TCGv_i32 fp32 = tcg_temp_new_i32();
6926
            TCGv_i64 fp64 = tcg_temp_new_i64();
6927

    
6928
            gen_load_fpr64(ctx, fp64, fs);
6929
            gen_helper_float_cvtw_d(fp32, fp64);
6930
            tcg_temp_free_i64(fp64);
6931
            gen_store_fpr32(fp32, fd);
6932
            tcg_temp_free_i32(fp32);
6933
        }
6934
        opn = "cvt.w.d";
6935
        break;
6936
    case OPC_CVT_L_D:
6937
        check_cp1_64bitmode(ctx);
6938
        {
6939
            TCGv_i64 fp0 = tcg_temp_new_i64();
6940

    
6941
            gen_load_fpr64(ctx, fp0, fs);
6942
            gen_helper_float_cvtl_d(fp0, fp0);
6943
            gen_store_fpr64(ctx, fp0, fd);
6944
            tcg_temp_free_i64(fp0);
6945
        }
6946
        opn = "cvt.l.d";
6947
        break;
6948
    case OPC_CVT_S_W:
6949
        {
6950
            TCGv_i32 fp0 = tcg_temp_new_i32();
6951

    
6952
            gen_load_fpr32(fp0, fs);
6953
            gen_helper_float_cvts_w(fp0, fp0);
6954
            gen_store_fpr32(fp0, fd);
6955
            tcg_temp_free_i32(fp0);
6956
        }
6957
        opn = "cvt.s.w";
6958
        break;
6959
    case OPC_CVT_D_W:
6960
        check_cp1_registers(ctx, fd);
6961
        {
6962
            TCGv_i32 fp32 = tcg_temp_new_i32();
6963
            TCGv_i64 fp64 = tcg_temp_new_i64();
6964

    
6965
            gen_load_fpr32(fp32, fs);
6966
            gen_helper_float_cvtd_w(fp64, fp32);
6967
            tcg_temp_free_i32(fp32);
6968
            gen_store_fpr64(ctx, fp64, fd);
6969
            tcg_temp_free_i64(fp64);
6970
        }
6971
        opn = "cvt.d.w";
6972
        break;
6973
    case OPC_CVT_S_L:
6974
        check_cp1_64bitmode(ctx);
6975
        {
6976
            TCGv_i32 fp32 = tcg_temp_new_i32();
6977
            TCGv_i64 fp64 = tcg_temp_new_i64();
6978

    
6979
            gen_load_fpr64(ctx, fp64, fs);
6980
            gen_helper_float_cvts_l(fp32, fp64);
6981
            tcg_temp_free_i64(fp64);
6982
            gen_store_fpr32(fp32, fd);
6983
            tcg_temp_free_i32(fp32);
6984
        }
6985
        opn = "cvt.s.l";
6986
        break;
6987
    case OPC_CVT_D_L:
6988
        check_cp1_64bitmode(ctx);
6989
        {
6990
            TCGv_i64 fp0 = tcg_temp_new_i64();
6991

    
6992
            gen_load_fpr64(ctx, fp0, fs);
6993
            gen_helper_float_cvtd_l(fp0, fp0);
6994
            gen_store_fpr64(ctx, fp0, fd);
6995
            tcg_temp_free_i64(fp0);
6996
        }
6997
        opn = "cvt.d.l";
6998
        break;
6999
    case OPC_CVT_PS_PW:
7000
        check_cp1_64bitmode(ctx);
7001
        {
7002
            TCGv_i64 fp0 = tcg_temp_new_i64();
7003

    
7004
            gen_load_fpr64(ctx, fp0, fs);
7005
            gen_helper_float_cvtps_pw(fp0, fp0);
7006
            gen_store_fpr64(ctx, fp0, fd);
7007
            tcg_temp_free_i64(fp0);
7008
        }
7009
        opn = "cvt.ps.pw";
7010
        break;
7011
    case OPC_ADD_PS:
7012
        check_cp1_64bitmode(ctx);
7013
        {
7014
            TCGv_i64 fp0 = tcg_temp_new_i64();
7015
            TCGv_i64 fp1 = tcg_temp_new_i64();
7016

    
7017
            gen_load_fpr64(ctx, fp0, fs);
7018
            gen_load_fpr64(ctx, fp1, ft);
7019
            gen_helper_float_add_ps(fp0, fp0, fp1);
7020
            tcg_temp_free_i64(fp1);
7021
            gen_store_fpr64(ctx, fp0, fd);
7022
            tcg_temp_free_i64(fp0);
7023
        }
7024
        opn = "add.ps";
7025
        break;
7026
    case OPC_SUB_PS:
7027
        check_cp1_64bitmode(ctx);
7028
        {
7029
            TCGv_i64 fp0 = tcg_temp_new_i64();
7030
            TCGv_i64 fp1 = tcg_temp_new_i64();
7031

    
7032
            gen_load_fpr64(ctx, fp0, fs);
7033
            gen_load_fpr64(ctx, fp1, ft);
7034
            gen_helper_float_sub_ps(fp0, fp0, fp1);
7035
            tcg_temp_free_i64(fp1);
7036
            gen_store_fpr64(ctx, fp0, fd);
7037
            tcg_temp_free_i64(fp0);
7038
        }
7039
        opn = "sub.ps";
7040
        break;
7041
    case OPC_MUL_PS:
7042
        check_cp1_64bitmode(ctx);
7043
        {
7044
            TCGv_i64 fp0 = tcg_temp_new_i64();
7045
            TCGv_i64 fp1 = tcg_temp_new_i64();
7046

    
7047
            gen_load_fpr64(ctx, fp0, fs);
7048
            gen_load_fpr64(ctx, fp1, ft);
7049
            gen_helper_float_mul_ps(fp0, fp0, fp1);
7050
            tcg_temp_free_i64(fp1);
7051
            gen_store_fpr64(ctx, fp0, fd);
7052
            tcg_temp_free_i64(fp0);
7053
        }
7054
        opn = "mul.ps";
7055
        break;
7056
    case OPC_ABS_PS:
7057
        check_cp1_64bitmode(ctx);
7058
        {
7059
            TCGv_i64 fp0 = tcg_temp_new_i64();
7060

    
7061
            gen_load_fpr64(ctx, fp0, fs);
7062
            gen_helper_float_abs_ps(fp0, fp0);
7063
            gen_store_fpr64(ctx, fp0, fd);
7064
            tcg_temp_free_i64(fp0);
7065
        }
7066
        opn = "abs.ps";
7067
        break;
7068
    case OPC_MOV_PS:
7069
        check_cp1_64bitmode(ctx);
7070
        {
7071
            TCGv_i64 fp0 = tcg_temp_new_i64();
7072

    
7073
            gen_load_fpr64(ctx, fp0, fs);
7074
            gen_store_fpr64(ctx, fp0, fd);
7075
            tcg_temp_free_i64(fp0);
7076
        }
7077
        opn = "mov.ps";
7078
        break;
7079
    case OPC_NEG_PS:
7080
        check_cp1_64bitmode(ctx);
7081
        {
7082
            TCGv_i64 fp0 = tcg_temp_new_i64();
7083

    
7084
            gen_load_fpr64(ctx, fp0, fs);
7085
            gen_helper_float_chs_ps(fp0, fp0);
7086
            gen_store_fpr64(ctx, fp0, fd);
7087
            tcg_temp_free_i64(fp0);
7088
        }
7089
        opn = "neg.ps";
7090
        break;
7091
    case OPC_MOVCF_PS:
7092
        check_cp1_64bitmode(ctx);
7093
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7094
        opn = "movcf.ps";
7095
        break;
7096
    case OPC_MOVZ_PS:
7097
        check_cp1_64bitmode(ctx);
7098
        {
7099
            int l1 = gen_new_label();
7100
            TCGv_i64 fp0;
7101

    
7102
            if (ft != 0)
7103
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7104
            fp0 = tcg_temp_new_i64();
7105
            gen_load_fpr64(ctx, fp0, fs);
7106
            gen_store_fpr64(ctx, fp0, fd);
7107
            tcg_temp_free_i64(fp0);
7108
            gen_set_label(l1);
7109
        }
7110
        opn = "movz.ps";
7111
        break;
7112
    case OPC_MOVN_PS:
7113
        check_cp1_64bitmode(ctx);
7114
        {
7115
            int l1 = gen_new_label();
7116
            TCGv_i64 fp0;
7117

    
7118
            if (ft != 0) {
7119
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7120
                fp0 = tcg_temp_new_i64();
7121
                gen_load_fpr64(ctx, fp0, fs);
7122
                gen_store_fpr64(ctx, fp0, fd);
7123
                tcg_temp_free_i64(fp0);
7124
                gen_set_label(l1);
7125
            }
7126
        }
7127
        opn = "movn.ps";
7128
        break;
7129
    case OPC_ADDR_PS:
7130
        check_cp1_64bitmode(ctx);
7131
        {
7132
            TCGv_i64 fp0 = tcg_temp_new_i64();
7133
            TCGv_i64 fp1 = tcg_temp_new_i64();
7134

    
7135
            gen_load_fpr64(ctx, fp0, ft);
7136
            gen_load_fpr64(ctx, fp1, fs);
7137
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7138
            tcg_temp_free_i64(fp1);
7139
            gen_store_fpr64(ctx, fp0, fd);
7140
            tcg_temp_free_i64(fp0);
7141
        }
7142
        opn = "addr.ps";
7143
        break;
7144
    case OPC_MULR_PS:
7145
        check_cp1_64bitmode(ctx);
7146
        {
7147
            TCGv_i64 fp0 = tcg_temp_new_i64();
7148
            TCGv_i64 fp1 = tcg_temp_new_i64();
7149

    
7150
            gen_load_fpr64(ctx, fp0, ft);
7151
            gen_load_fpr64(ctx, fp1, fs);
7152
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7153
            tcg_temp_free_i64(fp1);
7154
            gen_store_fpr64(ctx, fp0, fd);
7155
            tcg_temp_free_i64(fp0);
7156
        }
7157
        opn = "mulr.ps";
7158
        break;
7159
    case OPC_RECIP2_PS:
7160
        check_cp1_64bitmode(ctx);
7161
        {
7162
            TCGv_i64 fp0 = tcg_temp_new_i64();
7163
            TCGv_i64 fp1 = tcg_temp_new_i64();
7164

    
7165
            gen_load_fpr64(ctx, fp0, fs);
7166
            gen_load_fpr64(ctx, fp1, fd);
7167
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7168
            tcg_temp_free_i64(fp1);
7169
            gen_store_fpr64(ctx, fp0, fd);
7170
            tcg_temp_free_i64(fp0);
7171
        }
7172
        opn = "recip2.ps";
7173
        break;
7174
    case OPC_RECIP1_PS:
7175
        check_cp1_64bitmode(ctx);
7176
        {
7177
            TCGv_i64 fp0 = tcg_temp_new_i64();
7178

    
7179
            gen_load_fpr64(ctx, fp0, fs);
7180
            gen_helper_float_recip1_ps(fp0, fp0);
7181
            gen_store_fpr64(ctx, fp0, fd);
7182
            tcg_temp_free_i64(fp0);
7183
        }
7184
        opn = "recip1.ps";
7185
        break;
7186
    case OPC_RSQRT1_PS:
7187
        check_cp1_64bitmode(ctx);
7188
        {
7189
            TCGv_i64 fp0 = tcg_temp_new_i64();
7190

    
7191
            gen_load_fpr64(ctx, fp0, fs);
7192
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7193
            gen_store_fpr64(ctx, fp0, fd);
7194
            tcg_temp_free_i64(fp0);
7195
        }
7196
        opn = "rsqrt1.ps";
7197
        break;
7198
    case OPC_RSQRT2_PS:
7199
        check_cp1_64bitmode(ctx);
7200
        {
7201
            TCGv_i64 fp0 = tcg_temp_new_i64();
7202
            TCGv_i64 fp1 = tcg_temp_new_i64();
7203

    
7204
            gen_load_fpr64(ctx, fp0, fs);
7205
            gen_load_fpr64(ctx, fp1, ft);
7206
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7207
            tcg_temp_free_i64(fp1);
7208
            gen_store_fpr64(ctx, fp0, fd);
7209
            tcg_temp_free_i64(fp0);
7210
        }
7211
        opn = "rsqrt2.ps";
7212
        break;
7213
    case OPC_CVT_S_PU:
7214
        check_cp1_64bitmode(ctx);
7215
        {
7216
            TCGv_i32 fp0 = tcg_temp_new_i32();
7217

    
7218
            gen_load_fpr32h(fp0, fs);
7219
            gen_helper_float_cvts_pu(fp0, fp0);
7220
            gen_store_fpr32(fp0, fd);
7221
            tcg_temp_free_i32(fp0);
7222
        }
7223
        opn = "cvt.s.pu";
7224
        break;
7225
    case OPC_CVT_PW_PS:
7226
        check_cp1_64bitmode(ctx);
7227
        {
7228
            TCGv_i64 fp0 = tcg_temp_new_i64();
7229

    
7230
            gen_load_fpr64(ctx, fp0, fs);
7231
            gen_helper_float_cvtpw_ps(fp0, fp0);
7232
            gen_store_fpr64(ctx, fp0, fd);
7233
            tcg_temp_free_i64(fp0);
7234
        }
7235
        opn = "cvt.pw.ps";
7236
        break;
7237
    case OPC_CVT_S_PL:
7238
        check_cp1_64bitmode(ctx);
7239
        {
7240
            TCGv_i32 fp0 = tcg_temp_new_i32();
7241

    
7242
            gen_load_fpr32(fp0, fs);
7243
            gen_helper_float_cvts_pl(fp0, fp0);
7244
            gen_store_fpr32(fp0, fd);
7245
            tcg_temp_free_i32(fp0);
7246
        }
7247
        opn = "cvt.s.pl";
7248
        break;
7249
    case OPC_PLL_PS:
7250
        check_cp1_64bitmode(ctx);
7251
        {
7252
            TCGv_i32 fp0 = tcg_temp_new_i32();
7253
            TCGv_i32 fp1 = tcg_temp_new_i32();
7254

    
7255
            gen_load_fpr32(fp0, fs);
7256
            gen_load_fpr32(fp1, ft);
7257
            gen_store_fpr32h(fp0, fd);
7258
            gen_store_fpr32(fp1, fd);
7259
            tcg_temp_free_i32(fp0);
7260
            tcg_temp_free_i32(fp1);
7261
        }
7262
        opn = "pll.ps";
7263
        break;
7264
    case OPC_PLU_PS:
7265
        check_cp1_64bitmode(ctx);
7266
        {
7267
            TCGv_i32 fp0 = tcg_temp_new_i32();
7268
            TCGv_i32 fp1 = tcg_temp_new_i32();
7269

    
7270
            gen_load_fpr32(fp0, fs);
7271
            gen_load_fpr32h(fp1, ft);
7272
            gen_store_fpr32(fp1, fd);
7273
            gen_store_fpr32h(fp0, fd);
7274
            tcg_temp_free_i32(fp0);
7275
            tcg_temp_free_i32(fp1);
7276
        }
7277
        opn = "plu.ps";
7278
        break;
7279
    case OPC_PUL_PS:
7280
        check_cp1_64bitmode(ctx);
7281
        {
7282
            TCGv_i32 fp0 = tcg_temp_new_i32();
7283
            TCGv_i32 fp1 = tcg_temp_new_i32();
7284

    
7285
            gen_load_fpr32h(fp0, fs);
7286
            gen_load_fpr32(fp1, ft);
7287
            gen_store_fpr32(fp1, fd);
7288
            gen_store_fpr32h(fp0, fd);
7289
            tcg_temp_free_i32(fp0);
7290
            tcg_temp_free_i32(fp1);
7291
        }
7292
        opn = "pul.ps";
7293
        break;
7294
    case OPC_PUU_PS:
7295
        check_cp1_64bitmode(ctx);
7296
        {
7297
            TCGv_i32 fp0 = tcg_temp_new_i32();
7298
            TCGv_i32 fp1 = tcg_temp_new_i32();
7299

    
7300
            gen_load_fpr32h(fp0, fs);
7301
            gen_load_fpr32h(fp1, ft);
7302
            gen_store_fpr32(fp1, fd);
7303
            gen_store_fpr32h(fp0, fd);
7304
            tcg_temp_free_i32(fp0);
7305
            tcg_temp_free_i32(fp1);
7306
        }
7307
        opn = "puu.ps";
7308
        break;
7309
    case OPC_CMP_F_PS:
7310
    case OPC_CMP_UN_PS:
7311
    case OPC_CMP_EQ_PS:
7312
    case OPC_CMP_UEQ_PS:
7313
    case OPC_CMP_OLT_PS:
7314
    case OPC_CMP_ULT_PS:
7315
    case OPC_CMP_OLE_PS:
7316
    case OPC_CMP_ULE_PS:
7317
    case OPC_CMP_SF_PS:
7318
    case OPC_CMP_NGLE_PS:
7319
    case OPC_CMP_SEQ_PS:
7320
    case OPC_CMP_NGL_PS:
7321
    case OPC_CMP_LT_PS:
7322
    case OPC_CMP_NGE_PS:
7323
    case OPC_CMP_LE_PS:
7324
    case OPC_CMP_NGT_PS:
7325
        if (ctx->opcode & (1 << 6)) {
7326
            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7327
            opn = condnames_abs[func-48];
7328
        } else {
7329
            gen_cmp_ps(ctx, func-48, ft, fs, cc);
7330
            opn = condnames[func-48];
7331
        }
7332
        break;
7333
    default:
7334
        MIPS_INVAL(opn);
7335
        generate_exception (ctx, EXCP_RI);
7336
        return;
7337
    }
7338
    switch (optype) {
7339
    case BINOP:
7340
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7341
        break;
7342
    case CMPOP:
7343
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7344
        break;
7345
    default:
7346
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7347
        break;
7348
    }
7349
}
7350

    
7351
/* Coprocessor 3 (FPU) */
7352
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7353
                           int fd, int fs, int base, int index)
7354
{
7355
    const char *opn = "extended float load/store";
7356
    int store = 0;
7357
    TCGv t0 = tcg_temp_new();
7358

    
7359
    if (base == 0) {
7360
        gen_load_gpr(t0, index);
7361
    } else if (index == 0) {
7362
        gen_load_gpr(t0, base);
7363
    } else {
7364
        gen_load_gpr(t0, index);
7365
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7366
    }
7367
    /* Don't do NOP if destination is zero: we must perform the actual
7368
       memory access. */
7369
    save_cpu_state(ctx, 0);
7370
    switch (opc) {
7371
    case OPC_LWXC1:
7372
        check_cop1x(ctx);
7373
        {
7374
            TCGv_i32 fp0 = tcg_temp_new_i32();
7375

    
7376
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7377
            tcg_gen_trunc_tl_i32(fp0, t0);
7378
            gen_store_fpr32(fp0, fd);
7379
            tcg_temp_free_i32(fp0);
7380
        }
7381
        opn = "lwxc1";
7382
        break;
7383
    case OPC_LDXC1:
7384
        check_cop1x(ctx);
7385
        check_cp1_registers(ctx, fd);
7386
        {
7387
            TCGv_i64 fp0 = tcg_temp_new_i64();
7388

    
7389
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7390
            gen_store_fpr64(ctx, fp0, fd);
7391
            tcg_temp_free_i64(fp0);
7392
        }
7393
        opn = "ldxc1";
7394
        break;
7395
    case OPC_LUXC1:
7396
        check_cp1_64bitmode(ctx);
7397
        tcg_gen_andi_tl(t0, t0, ~0x7);
7398
        {
7399
            TCGv_i64 fp0 = tcg_temp_new_i64();
7400

    
7401
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7402
            gen_store_fpr64(ctx, fp0, fd);
7403
            tcg_temp_free_i64(fp0);
7404
        }
7405
        opn = "luxc1";
7406
        break;
7407
    case OPC_SWXC1:
7408
        check_cop1x(ctx);
7409
        {
7410
            TCGv_i32 fp0 = tcg_temp_new_i32();
7411
            TCGv t1 = tcg_temp_new();
7412

    
7413
            gen_load_fpr32(fp0, fs);
7414
            tcg_gen_extu_i32_tl(t1, fp0);
7415
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7416
            tcg_temp_free_i32(fp0);
7417
            tcg_temp_free(t1);
7418
        }
7419
        opn = "swxc1";
7420
        store = 1;
7421
        break;
7422
    case OPC_SDXC1:
7423
        check_cop1x(ctx);
7424
        check_cp1_registers(ctx, fs);
7425
        {
7426
            TCGv_i64 fp0 = tcg_temp_new_i64();
7427

    
7428
            gen_load_fpr64(ctx, fp0, fs);
7429
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7430
            tcg_temp_free_i64(fp0);
7431
        }
7432
        opn = "sdxc1";
7433
        store = 1;
7434
        break;
7435
    case OPC_SUXC1:
7436
        check_cp1_64bitmode(ctx);
7437
        tcg_gen_andi_tl(t0, t0, ~0x7);
7438
        {
7439
            TCGv_i64 fp0 = tcg_temp_new_i64();
7440

    
7441
            gen_load_fpr64(ctx, fp0, fs);
7442
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7443
            tcg_temp_free_i64(fp0);
7444
        }
7445
        opn = "suxc1";
7446
        store = 1;
7447
        break;
7448
    }
7449
    tcg_temp_free(t0);
7450
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7451
               regnames[index], regnames[base]);
7452
}
7453

    
7454
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7455
                            int fd, int fr, int fs, int ft)
7456
{
7457
    const char *opn = "flt3_arith";
7458

    
7459
    switch (opc) {
7460
    case OPC_ALNV_PS:
7461
        check_cp1_64bitmode(ctx);
7462
        {
7463
            TCGv t0 = tcg_temp_local_new();
7464
            TCGv_i32 fp = tcg_temp_new_i32();
7465
            TCGv_i32 fph = tcg_temp_new_i32();
7466
            int l1 = gen_new_label();
7467
            int l2 = gen_new_label();
7468

    
7469
            gen_load_gpr(t0, fr);
7470
            tcg_gen_andi_tl(t0, t0, 0x7);
7471

    
7472
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7473
            gen_load_fpr32(fp, fs);
7474
            gen_load_fpr32h(fph, fs);
7475
            gen_store_fpr32(fp, fd);
7476
            gen_store_fpr32h(fph, fd);
7477
            tcg_gen_br(l2);
7478
            gen_set_label(l1);
7479
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7480
            tcg_temp_free(t0);
7481
#ifdef TARGET_WORDS_BIGENDIAN
7482
            gen_load_fpr32(fp, fs);
7483
            gen_load_fpr32h(fph, ft);
7484
            gen_store_fpr32h(fp, fd);
7485
            gen_store_fpr32(fph, fd);
7486
#else
7487
            gen_load_fpr32h(fph, fs);
7488
            gen_load_fpr32(fp, ft);
7489
            gen_store_fpr32(fph, fd);
7490
            gen_store_fpr32h(fp, fd);
7491
#endif
7492
            gen_set_label(l2);
7493
            tcg_temp_free_i32(fp);
7494
            tcg_temp_free_i32(fph);
7495
        }
7496
        opn = "alnv.ps";
7497
        break;
7498
    case OPC_MADD_S:
7499
        check_cop1x(ctx);
7500
        {
7501
            TCGv_i32 fp0 = tcg_temp_new_i32();
7502
            TCGv_i32 fp1 = tcg_temp_new_i32();
7503
            TCGv_i32 fp2 = tcg_temp_new_i32();
7504

    
7505
            gen_load_fpr32(fp0, fs);
7506
            gen_load_fpr32(fp1, ft);
7507
            gen_load_fpr32(fp2, fr);
7508
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7509
            tcg_temp_free_i32(fp0);
7510
            tcg_temp_free_i32(fp1);
7511
            gen_store_fpr32(fp2, fd);
7512
            tcg_temp_free_i32(fp2);
7513
        }
7514
        opn = "madd.s";
7515
        break;
7516
    case OPC_MADD_D:
7517
        check_cop1x(ctx);
7518
        check_cp1_registers(ctx, fd | fs | ft | fr);
7519
        {
7520
            TCGv_i64 fp0 = tcg_temp_new_i64();
7521
            TCGv_i64 fp1 = tcg_temp_new_i64();
7522
            TCGv_i64 fp2 = tcg_temp_new_i64();
7523

    
7524
            gen_load_fpr64(ctx, fp0, fs);
7525
            gen_load_fpr64(ctx, fp1, ft);
7526
            gen_load_fpr64(ctx, fp2, fr);
7527
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7528
            tcg_temp_free_i64(fp0);
7529
            tcg_temp_free_i64(fp1);
7530
            gen_store_fpr64(ctx, fp2, fd);
7531
            tcg_temp_free_i64(fp2);
7532
        }
7533
        opn = "madd.d";
7534
        break;
7535
    case OPC_MADD_PS:
7536
        check_cp1_64bitmode(ctx);
7537
        {
7538
            TCGv_i64 fp0 = tcg_temp_new_i64();
7539
            TCGv_i64 fp1 = tcg_temp_new_i64();
7540
            TCGv_i64 fp2 = tcg_temp_new_i64();
7541

    
7542
            gen_load_fpr64(ctx, fp0, fs);
7543
            gen_load_fpr64(ctx, fp1, ft);
7544
            gen_load_fpr64(ctx, fp2, fr);
7545
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7546
            tcg_temp_free_i64(fp0);
7547
            tcg_temp_free_i64(fp1);
7548
            gen_store_fpr64(ctx, fp2, fd);
7549
            tcg_temp_free_i64(fp2);
7550
        }
7551
        opn = "madd.ps";
7552
        break;
7553
    case OPC_MSUB_S:
7554
        check_cop1x(ctx);
7555
        {
7556
            TCGv_i32 fp0 = tcg_temp_new_i32();
7557
            TCGv_i32 fp1 = tcg_temp_new_i32();
7558
            TCGv_i32 fp2 = tcg_temp_new_i32();
7559

    
7560
            gen_load_fpr32(fp0, fs);
7561
            gen_load_fpr32(fp1, ft);
7562
            gen_load_fpr32(fp2, fr);
7563
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7564
            tcg_temp_free_i32(fp0);
7565
            tcg_temp_free_i32(fp1);
7566
            gen_store_fpr32(fp2, fd);
7567
            tcg_temp_free_i32(fp2);
7568
        }
7569
        opn = "msub.s";
7570
        break;
7571
    case OPC_MSUB_D:
7572
        check_cop1x(ctx);
7573
        check_cp1_registers(ctx, fd | fs | ft | fr);
7574
        {
7575
            TCGv_i64 fp0 = tcg_temp_new_i64();
7576
            TCGv_i64 fp1 = tcg_temp_new_i64();
7577
            TCGv_i64 fp2 = tcg_temp_new_i64();
7578

    
7579
            gen_load_fpr64(ctx, fp0, fs);
7580
            gen_load_fpr64(ctx, fp1, ft);
7581
            gen_load_fpr64(ctx, fp2, fr);
7582
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7583
            tcg_temp_free_i64(fp0);
7584
            tcg_temp_free_i64(fp1);
7585
            gen_store_fpr64(ctx, fp2, fd);
7586
            tcg_temp_free_i64(fp2);
7587
        }
7588
        opn = "msub.d";
7589
        break;
7590
    case OPC_MSUB_PS:
7591
        check_cp1_64bitmode(ctx);
7592
        {
7593
            TCGv_i64 fp0 = tcg_temp_new_i64();
7594
            TCGv_i64 fp1 = tcg_temp_new_i64();
7595
            TCGv_i64 fp2 = tcg_temp_new_i64();
7596

    
7597
            gen_load_fpr64(ctx, fp0, fs);
7598
            gen_load_fpr64(ctx, fp1, ft);
7599
            gen_load_fpr64(ctx, fp2, fr);
7600
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7601
            tcg_temp_free_i64(fp0);
7602
            tcg_temp_free_i64(fp1);
7603
            gen_store_fpr64(ctx, fp2, fd);
7604
            tcg_temp_free_i64(fp2);
7605
        }
7606
        opn = "msub.ps";
7607
        break;
7608
    case OPC_NMADD_S:
7609
        check_cop1x(ctx);
7610
        {
7611
            TCGv_i32 fp0 = tcg_temp_new_i32();
7612
            TCGv_i32 fp1 = tcg_temp_new_i32();
7613
            TCGv_i32 fp2 = tcg_temp_new_i32();
7614

    
7615
            gen_load_fpr32(fp0, fs);
7616
            gen_load_fpr32(fp1, ft);
7617
            gen_load_fpr32(fp2, fr);
7618
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7619
            tcg_temp_free_i32(fp0);
7620
            tcg_temp_free_i32(fp1);
7621
            gen_store_fpr32(fp2, fd);
7622
            tcg_temp_free_i32(fp2);
7623
        }
7624
        opn = "nmadd.s";
7625
        break;
7626
    case OPC_NMADD_D:
7627
        check_cop1x(ctx);
7628
        check_cp1_registers(ctx, fd | fs | ft | fr);
7629
        {
7630
            TCGv_i64 fp0 = tcg_temp_new_i64();
7631
            TCGv_i64 fp1 = tcg_temp_new_i64();
7632
            TCGv_i64 fp2 = tcg_temp_new_i64();
7633

    
7634
            gen_load_fpr64(ctx, fp0, fs);
7635
            gen_load_fpr64(ctx, fp1, ft);
7636
            gen_load_fpr64(ctx, fp2, fr);
7637
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7638
            tcg_temp_free_i64(fp0);
7639
            tcg_temp_free_i64(fp1);
7640
            gen_store_fpr64(ctx, fp2, fd);
7641
            tcg_temp_free_i64(fp2);
7642
        }
7643
        opn = "nmadd.d";
7644
        break;
7645
    case OPC_NMADD_PS:
7646
        check_cp1_64bitmode(ctx);
7647
        {
7648
            TCGv_i64 fp0 = tcg_temp_new_i64();
7649
            TCGv_i64 fp1 = tcg_temp_new_i64();
7650
            TCGv_i64 fp2 = tcg_temp_new_i64();
7651

    
7652
            gen_load_fpr64(ctx, fp0, fs);
7653
            gen_load_fpr64(ctx, fp1, ft);
7654
            gen_load_fpr64(ctx, fp2, fr);
7655
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7656
            tcg_temp_free_i64(fp0);
7657
            tcg_temp_free_i64(fp1);
7658
            gen_store_fpr64(ctx, fp2, fd);
7659
            tcg_temp_free_i64(fp2);
7660
        }
7661
        opn = "nmadd.ps";
7662
        break;
7663
    case OPC_NMSUB_S:
7664
        check_cop1x(ctx);
7665
        {
7666
            TCGv_i32 fp0 = tcg_temp_new_i32();
7667
            TCGv_i32 fp1 = tcg_temp_new_i32();
7668
            TCGv_i32 fp2 = tcg_temp_new_i32();
7669

    
7670
            gen_load_fpr32(fp0, fs);
7671
            gen_load_fpr32(fp1, ft);
7672
            gen_load_fpr32(fp2, fr);
7673
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7674
            tcg_temp_free_i32(fp0);
7675
            tcg_temp_free_i32(fp1);
7676
            gen_store_fpr32(fp2, fd);
7677
            tcg_temp_free_i32(fp2);
7678
        }
7679
        opn = "nmsub.s";
7680
        break;
7681
    case OPC_NMSUB_D:
7682
        check_cop1x(ctx);
7683
        check_cp1_registers(ctx, fd | fs | ft | fr);
7684
        {
7685
            TCGv_i64 fp0 = tcg_temp_new_i64();
7686
            TCGv_i64 fp1 = tcg_temp_new_i64();
7687
            TCGv_i64 fp2 = tcg_temp_new_i64();
7688

    
7689
            gen_load_fpr64(ctx, fp0, fs);
7690
            gen_load_fpr64(ctx, fp1, ft);
7691
            gen_load_fpr64(ctx, fp2, fr);
7692
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7693
            tcg_temp_free_i64(fp0);
7694
            tcg_temp_free_i64(fp1);
7695
            gen_store_fpr64(ctx, fp2, fd);
7696
            tcg_temp_free_i64(fp2);
7697
        }
7698
        opn = "nmsub.d";
7699
        break;
7700
    case OPC_NMSUB_PS:
7701
        check_cp1_64bitmode(ctx);
7702
        {
7703
            TCGv_i64 fp0 = tcg_temp_new_i64();
7704
            TCGv_i64 fp1 = tcg_temp_new_i64();
7705
            TCGv_i64 fp2 = tcg_temp_new_i64();
7706

    
7707
            gen_load_fpr64(ctx, fp0, fs);
7708
            gen_load_fpr64(ctx, fp1, ft);
7709
            gen_load_fpr64(ctx, fp2, fr);
7710
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7711
            tcg_temp_free_i64(fp0);
7712
            tcg_temp_free_i64(fp1);
7713
            gen_store_fpr64(ctx, fp2, fd);
7714
            tcg_temp_free_i64(fp2);
7715
        }
7716
        opn = "nmsub.ps";
7717
        break;
7718
    default:
7719
        MIPS_INVAL(opn);
7720
        generate_exception (ctx, EXCP_RI);
7721
        return;
7722
    }
7723
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7724
               fregnames[fs], fregnames[ft]);
7725
}
7726

    
7727
static void
7728
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
7729
{
7730
    TCGv t0;
7731

    
7732
    check_insn(env, ctx, ISA_MIPS32R2);
7733
    t0 = tcg_temp_new();
7734

    
7735
    switch (rd) {
7736
    case 0:
7737
        save_cpu_state(ctx, 1);
7738
        gen_helper_rdhwr_cpunum(t0);
7739
        gen_store_gpr(t0, rt);
7740
        break;
7741
    case 1:
7742
        save_cpu_state(ctx, 1);
7743
        gen_helper_rdhwr_synci_step(t0);
7744
        gen_store_gpr(t0, rt);
7745
        break;
7746
    case 2:
7747
        save_cpu_state(ctx, 1);
7748
        gen_helper_rdhwr_cc(t0);
7749
        gen_store_gpr(t0, rt);
7750
        break;
7751
    case 3:
7752
        save_cpu_state(ctx, 1);
7753
        gen_helper_rdhwr_ccres(t0);
7754
        gen_store_gpr(t0, rt);
7755
        break;
7756
    case 29:
7757
#if defined(CONFIG_USER_ONLY)
7758
        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7759
        gen_store_gpr(t0, rt);
7760
        break;
7761
#else
7762
        /* XXX: Some CPUs implement this in hardware.
7763
           Not supported yet. */
7764
#endif
7765
    default:            /* Invalid */
7766
        MIPS_INVAL("rdhwr");
7767
        generate_exception(ctx, EXCP_RI);
7768
        break;
7769
    }
7770
    tcg_temp_free(t0);
7771
}
7772

    
7773
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
7774
                               int insn_bytes)
7775
{
7776
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7777
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7778
        /* Branches completion */
7779
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7780
        ctx->bstate = BS_BRANCH;
7781
        save_cpu_state(ctx, 0);
7782
        /* FIXME: Need to clear can_do_io.  */
7783
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
7784
        case MIPS_HFLAG_B:
7785
            /* unconditional branch */
7786
            MIPS_DEBUG("unconditional branch");
7787
            if (proc_hflags & MIPS_HFLAG_BX) {
7788
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
7789
            }
7790
            gen_goto_tb(ctx, 0, ctx->btarget);
7791
            break;
7792
        case MIPS_HFLAG_BL:
7793
            /* blikely taken case */
7794
            MIPS_DEBUG("blikely branch taken");
7795
            gen_goto_tb(ctx, 0, ctx->btarget);
7796
            break;
7797
        case MIPS_HFLAG_BC:
7798
            /* Conditional branch */
7799
            MIPS_DEBUG("conditional branch");
7800
            {
7801
                int l1 = gen_new_label();
7802

    
7803
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7804
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
7805
                gen_set_label(l1);
7806
                gen_goto_tb(ctx, 0, ctx->btarget);
7807
            }
7808
            break;
7809
        case MIPS_HFLAG_BR:
7810
            /* unconditional branch to register */
7811
            MIPS_DEBUG("branch to register");
7812
            if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
7813
                TCGv t0 = tcg_temp_new();
7814
                TCGv_i32 t1 = tcg_temp_new_i32();
7815

    
7816
                tcg_gen_andi_tl(t0, btarget, 0x1);
7817
                tcg_gen_trunc_tl_i32(t1, t0);
7818
                tcg_temp_free(t0);
7819
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
7820
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
7821
                tcg_gen_or_i32(hflags, hflags, t1);
7822
                tcg_temp_free_i32(t1);
7823

    
7824
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
7825
            } else {
7826
                tcg_gen_mov_tl(cpu_PC, btarget);
7827
            }
7828
            if (ctx->singlestep_enabled) {
7829
                save_cpu_state(ctx, 0);
7830
                gen_helper_0i(raise_exception, EXCP_DEBUG);
7831
            }
7832
            tcg_gen_exit_tb(0);
7833
            break;
7834
        default:
7835
            MIPS_DEBUG("unknown branch");
7836
            break;
7837
        }
7838
    }
7839
}
7840

    
7841
/* ISA extensions (ASEs) */
7842
/* MIPS16 extension to MIPS32 */
7843

    
7844
/* MIPS16 major opcodes */
7845
enum {
7846
  M16_OPC_ADDIUSP = 0x00,
7847
  M16_OPC_ADDIUPC = 0x01,
7848
  M16_OPC_B = 0x02,
7849
  M16_OPC_JAL = 0x03,
7850
  M16_OPC_BEQZ = 0x04,
7851
  M16_OPC_BNEQZ = 0x05,
7852
  M16_OPC_SHIFT = 0x06,
7853
  M16_OPC_LD = 0x07,
7854
  M16_OPC_RRIA = 0x08,
7855
  M16_OPC_ADDIU8 = 0x09,
7856
  M16_OPC_SLTI = 0x0a,
7857
  M16_OPC_SLTIU = 0x0b,
7858
  M16_OPC_I8 = 0x0c,
7859
  M16_OPC_LI = 0x0d,
7860
  M16_OPC_CMPI = 0x0e,
7861
  M16_OPC_SD = 0x0f,
7862
  M16_OPC_LB = 0x10,
7863
  M16_OPC_LH = 0x11,
7864
  M16_OPC_LWSP = 0x12,
7865
  M16_OPC_LW = 0x13,
7866
  M16_OPC_LBU = 0x14,
7867
  M16_OPC_LHU = 0x15,
7868
  M16_OPC_LWPC = 0x16,
7869
  M16_OPC_LWU = 0x17,
7870
  M16_OPC_SB = 0x18,
7871
  M16_OPC_SH = 0x19,
7872
  M16_OPC_SWSP = 0x1a,
7873
  M16_OPC_SW = 0x1b,
7874
  M16_OPC_RRR = 0x1c,
7875
  M16_OPC_RR = 0x1d,
7876
  M16_OPC_EXTEND = 0x1e,
7877
  M16_OPC_I64 = 0x1f
7878
};
7879

    
7880
/* I8 funct field */
7881
enum {
7882
  I8_BTEQZ = 0x0,
7883
  I8_BTNEZ = 0x1,
7884
  I8_SWRASP = 0x2,
7885
  I8_ADJSP = 0x3,
7886
  I8_SVRS = 0x4,
7887
  I8_MOV32R = 0x5,
7888
  I8_MOVR32 = 0x7
7889
};
7890

    
7891
/* RRR f field */
7892
enum {
7893
  RRR_DADDU = 0x0,
7894
  RRR_ADDU = 0x1,
7895
  RRR_DSUBU = 0x2,
7896
  RRR_SUBU = 0x3
7897
};
7898

    
7899
/* RR funct field */
7900
enum {
7901
  RR_JR = 0x00,
7902
  RR_SDBBP = 0x01,
7903
  RR_SLT = 0x02,
7904
  RR_SLTU = 0x03,
7905
  RR_SLLV = 0x04,
7906
  RR_BREAK = 0x05,
7907
  RR_SRLV = 0x06,
7908
  RR_SRAV = 0x07,
7909
  RR_DSRL = 0x08,
7910
  RR_CMP = 0x0a,
7911
  RR_NEG = 0x0b,
7912
  RR_AND = 0x0c,
7913
  RR_OR = 0x0d,
7914
  RR_XOR = 0x0e,
7915
  RR_NOT = 0x0f,
7916
  RR_MFHI = 0x10,
7917
  RR_CNVT = 0x11,
7918
  RR_MFLO = 0x12,
7919
  RR_DSRA = 0x13,
7920
  RR_DSLLV = 0x14,
7921
  RR_DSRLV = 0x16,
7922
  RR_DSRAV = 0x17,
7923
  RR_MULT = 0x18,
7924
  RR_MULTU = 0x19,
7925
  RR_DIV = 0x1a,
7926
  RR_DIVU = 0x1b,
7927
  RR_DMULT = 0x1c,
7928
  RR_DMULTU = 0x1d,
7929
  RR_DDIV = 0x1e,
7930
  RR_DDIVU = 0x1f
7931
};
7932

    
7933
/* I64 funct field */
7934
enum {
7935
  I64_LDSP = 0x0,
7936
  I64_SDSP = 0x1,
7937
  I64_SDRASP = 0x2,
7938
  I64_DADJSP = 0x3,
7939
  I64_LDPC = 0x4,
7940
  I64_DADDIU5 = 0x5,
7941
  I64_DADDIUPC = 0x6,
7942
  I64_DADDIUSP = 0x7
7943
};
7944

    
7945
/* RR ry field for CNVT */
7946
enum {
7947
  RR_RY_CNVT_ZEB = 0x0,
7948
  RR_RY_CNVT_ZEH = 0x1,
7949
  RR_RY_CNVT_ZEW = 0x2,
7950
  RR_RY_CNVT_SEB = 0x4,
7951
  RR_RY_CNVT_SEH = 0x5,
7952
  RR_RY_CNVT_SEW = 0x6,
7953
};
7954

    
7955
static int xlat (int r)
7956
{
7957
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
7958

    
7959
  return map[r];
7960
}
7961

    
7962
static void gen_mips16_save (DisasContext *ctx,
7963
                             int xsregs, int aregs,
7964
                             int do_ra, int do_s0, int do_s1,
7965
                             int framesize)
7966
{
7967
    TCGv t0 = tcg_temp_new();
7968
    TCGv t1 = tcg_temp_new();
7969
    int args, astatic;
7970

    
7971
    switch (aregs) {
7972
    case 0:
7973
    case 1:
7974
    case 2:
7975
    case 3:
7976
    case 11:
7977
        args = 0;
7978
        break;
7979
    case 4:
7980
    case 5:
7981
    case 6:
7982
    case 7:
7983
        args = 1;
7984
        break;
7985
    case 8:
7986
    case 9:
7987
    case 10:
7988
        args = 2;
7989
        break;
7990
    case 12:
7991
    case 13:
7992
        args = 3;
7993
        break;
7994
    case 14:
7995
        args = 4;
7996
        break;
7997
    default:
7998
        generate_exception(ctx, EXCP_RI);
7999
        return;
8000
    }
8001

    
8002
    switch (args) {
8003
    case 4:
8004
        gen_base_offset_addr(ctx, t0, 29, 12);
8005
        gen_load_gpr(t1, 7);
8006
        op_ldst_sw(t1, t0, ctx);
8007
        /* Fall through */
8008
    case 3:
8009
        gen_base_offset_addr(ctx, t0, 29, 8);
8010
        gen_load_gpr(t1, 6);
8011
        op_ldst_sw(t1, t0, ctx);
8012
        /* Fall through */
8013
    case 2:
8014
        gen_base_offset_addr(ctx, t0, 29, 4);
8015
        gen_load_gpr(t1, 5);
8016
        op_ldst_sw(t1, t0, ctx);
8017
        /* Fall through */
8018
    case 1:
8019
        gen_base_offset_addr(ctx, t0, 29, 0);
8020
        gen_load_gpr(t1, 4);
8021
        op_ldst_sw(t1, t0, ctx);
8022
    }
8023

    
8024
    gen_load_gpr(t0, 29);
8025

    
8026
#define DECR_AND_STORE(reg) do {                \
8027
        tcg_gen_subi_tl(t0, t0, 4);             \
8028
        gen_load_gpr(t1, reg);                  \
8029
        op_ldst_sw(t1, t0, ctx);                \
8030
    } while (0)
8031

    
8032
    if (do_ra) {
8033
        DECR_AND_STORE(31);
8034
    }
8035

    
8036
    switch (xsregs) {
8037
    case 7:
8038
        DECR_AND_STORE(30);
8039
        /* Fall through */
8040
    case 6:
8041
        DECR_AND_STORE(23);
8042
        /* Fall through */
8043
    case 5:
8044
        DECR_AND_STORE(22);
8045
        /* Fall through */
8046
    case 4:
8047
        DECR_AND_STORE(21);
8048
        /* Fall through */
8049
    case 3:
8050
        DECR_AND_STORE(20);
8051
        /* Fall through */
8052
    case 2:
8053
        DECR_AND_STORE(19);
8054
        /* Fall through */
8055
    case 1:
8056
        DECR_AND_STORE(18);
8057
    }
8058

    
8059
    if (do_s1) {
8060
        DECR_AND_STORE(17);
8061
    }
8062
    if (do_s0) {
8063
        DECR_AND_STORE(16);
8064
    }
8065

    
8066
    switch (aregs) {
8067
    case 0:
8068
    case 4:
8069
    case 8:
8070
    case 12:
8071
    case 14:
8072
        astatic = 0;
8073
        break;
8074
    case 1:
8075
    case 5:
8076
    case 9:
8077
    case 13:
8078
        astatic = 1;
8079
        break;
8080
    case 2:
8081
    case 6:
8082
    case 10:
8083
        astatic = 2;
8084
        break;
8085
    case 3:
8086
    case 7:
8087
        astatic = 3;
8088
        break;
8089
    case 11:
8090
        astatic = 4;
8091
        break;
8092
    default:
8093
        generate_exception(ctx, EXCP_RI);
8094
        return;
8095
    }
8096

    
8097
    if (astatic > 0) {
8098
        DECR_AND_STORE(7);
8099
        if (astatic > 1) {
8100
            DECR_AND_STORE(6);
8101
            if (astatic > 2) {
8102
                DECR_AND_STORE(5);
8103
                if (astatic > 3) {
8104
                    DECR_AND_STORE(4);
8105
                }
8106
            }
8107
        }
8108
    }
8109
#undef DECR_AND_STORE
8110

    
8111
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8112
    tcg_temp_free(t0);
8113
    tcg_temp_free(t1);
8114
}
8115

    
8116
static void gen_mips16_restore (DisasContext *ctx,
8117
                                int xsregs, int aregs,
8118
                                int do_ra, int do_s0, int do_s1,
8119
                                int framesize)
8120
{
8121
    int astatic;
8122
    TCGv t0 = tcg_temp_new();
8123
    TCGv t1 = tcg_temp_new();
8124

    
8125
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8126

    
8127
#define DECR_AND_LOAD(reg) do {                 \
8128
        tcg_gen_subi_tl(t0, t0, 4);             \
8129
        op_ldst_lw(t1, t0, ctx);                \
8130
        gen_store_gpr(t1, reg);                 \
8131
    } while (0)
8132

    
8133
    if (do_ra) {
8134
        DECR_AND_LOAD(31);
8135
    }
8136

    
8137
    switch (xsregs) {
8138
    case 7:
8139
        DECR_AND_LOAD(30);
8140
        /* Fall through */
8141
    case 6:
8142
        DECR_AND_LOAD(23);
8143
        /* Fall through */
8144
    case 5:
8145
        DECR_AND_LOAD(22);
8146
        /* Fall through */
8147
    case 4:
8148
        DECR_AND_LOAD(21);
8149
        /* Fall through */
8150
    case 3:
8151
        DECR_AND_LOAD(20);
8152
        /* Fall through */
8153
    case 2:
8154
        DECR_AND_LOAD(19);
8155
        /* Fall through */
8156
    case 1:
8157
        DECR_AND_LOAD(18);
8158
    }
8159

    
8160
    if (do_s1) {
8161
        DECR_AND_LOAD(17);
8162
    }
8163
    if (do_s0) {
8164
        DECR_AND_LOAD(16);
8165
    }
8166

    
8167
    switch (aregs) {
8168
    case 0:
8169
    case 4:
8170
    case 8:
8171
    case 12:
8172
    case 14:
8173
        astatic = 0;
8174
        break;
8175
    case 1:
8176
    case 5:
8177
    case 9:
8178
    case 13:
8179
        astatic = 1;
8180
        break;
8181
    case 2:
8182
    case 6:
8183
    case 10:
8184
        astatic = 2;
8185
        break;
8186
    case 3:
8187
    case 7:
8188
        astatic = 3;
8189
        break;
8190
    case 11:
8191
        astatic = 4;
8192
        break;
8193
    default:
8194
        generate_exception(ctx, EXCP_RI);
8195
        return;
8196
    }
8197

    
8198
    if (astatic > 0) {
8199
        DECR_AND_LOAD(7);
8200
        if (astatic > 1) {
8201
            DECR_AND_LOAD(6);
8202
            if (astatic > 2) {
8203
                DECR_AND_LOAD(5);
8204
                if (astatic > 3) {
8205
                    DECR_AND_LOAD(4);
8206
                }
8207
            }
8208
        }
8209
    }
8210
#undef DECR_AND_LOAD
8211

    
8212
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8213
    tcg_temp_free(t0);
8214
    tcg_temp_free(t1);
8215
}
8216

    
8217
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8218
                         int is_64_bit, int extended)
8219
{
8220
    TCGv t0;
8221

    
8222
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8223
        generate_exception(ctx, EXCP_RI);
8224
        return;
8225
    }
8226

    
8227
    t0 = tcg_temp_new();
8228

    
8229
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8230
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8231
    if (!is_64_bit) {
8232
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8233
    }
8234

    
8235
    tcg_temp_free(t0);
8236
}
8237

    
8238
#if defined(TARGET_MIPS64)
8239
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8240
                               int ry, int funct, int16_t offset,
8241
                               int extended)
8242
{
8243
    switch (funct) {
8244
    case I64_LDSP:
8245
        check_mips_64(ctx);
8246
        offset = extended ? offset : offset << 3;
8247
        gen_ldst(ctx, OPC_LD, ry, 29, offset);
8248
        break;
8249
    case I64_SDSP:
8250
        check_mips_64(ctx);
8251
        offset = extended ? offset : offset << 3;
8252
        gen_ldst(ctx, OPC_SD, ry, 29, offset);
8253
        break;
8254
    case I64_SDRASP:
8255
        check_mips_64(ctx);
8256
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8257
        gen_ldst(ctx, OPC_SD, 31, 29, offset);
8258
        break;
8259
    case I64_DADJSP:
8260
        check_mips_64(ctx);
8261
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8262
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8263
        break;
8264
    case I64_LDPC:
8265
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8266
            generate_exception(ctx, EXCP_RI);
8267
        } else {
8268
            offset = extended ? offset : offset << 3;
8269
            gen_ldst(ctx, OPC_LDPC, ry, 0, offset);
8270
        }
8271
        break;
8272
    case I64_DADDIU5:
8273
        check_mips_64(ctx);
8274
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8275
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8276
        break;
8277
    case I64_DADDIUPC:
8278
        check_mips_64(ctx);
8279
        offset = extended ? offset : offset << 2;
8280
        gen_addiupc(ctx, ry, offset, 1, extended);
8281
        break;
8282
    case I64_DADDIUSP:
8283
        check_mips_64(ctx);
8284
        offset = extended ? offset : offset << 2;
8285
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8286
        break;
8287
    }
8288
}
8289
#endif
8290

    
8291
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8292
                                       int *is_branch)
8293
{
8294
    int extend = lduw_code(ctx->pc + 2);
8295
    int op, rx, ry, funct, sa;
8296
    int16_t imm, offset;
8297

    
8298
    ctx->opcode = (ctx->opcode << 16) | extend;
8299
    op = (ctx->opcode >> 11) & 0x1f;
8300
    sa = (ctx->opcode >> 22) & 0x1f;
8301
    funct = (ctx->opcode >> 8) & 0x7;
8302
    rx = xlat((ctx->opcode >> 8) & 0x7);
8303
    ry = xlat((ctx->opcode >> 5) & 0x7);
8304
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8305
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8306
                              | (ctx->opcode & 0x1f));
8307

    
8308
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8309
       counterparts.  */
8310
    switch (op) {
8311
    case M16_OPC_ADDIUSP:
8312
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8313
        break;
8314
    case M16_OPC_ADDIUPC:
8315
        gen_addiupc(ctx, rx, imm, 0, 1);
8316
        break;
8317
    case M16_OPC_B:
8318
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8319
        /* No delay slot, so just process as a normal instruction */
8320
        break;
8321
    case M16_OPC_BEQZ:
8322
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8323
        /* No delay slot, so just process as a normal instruction */
8324
        break;
8325
    case M16_OPC_BNEQZ:
8326
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8327
        /* No delay slot, so just process as a normal instruction */
8328
        break;
8329
    case M16_OPC_SHIFT:
8330
        switch (ctx->opcode & 0x3) {
8331
        case 0x0:
8332
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8333
            break;
8334
        case 0x1:
8335
#if defined(TARGET_MIPS64)
8336
            check_mips_64(ctx);
8337
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8338
#else
8339
            generate_exception(ctx, EXCP_RI);
8340
#endif
8341
            break;
8342
        case 0x2:
8343
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8344
            break;
8345
        case 0x3:
8346
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8347
            break;
8348
        }
8349
        break;
8350
#if defined(TARGET_MIPS64)
8351
    case M16_OPC_LD:
8352
            check_mips_64(ctx);
8353
        gen_ldst(ctx, OPC_LD, ry, rx, offset);
8354
        break;
8355
#endif
8356
    case M16_OPC_RRIA:
8357
        imm = ctx->opcode & 0xf;
8358
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8359
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8360
        imm = (int16_t) (imm << 1) >> 1;
8361
        if ((ctx->opcode >> 4) & 0x1) {
8362
#if defined(TARGET_MIPS64)
8363
            check_mips_64(ctx);
8364
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8365
#else
8366
            generate_exception(ctx, EXCP_RI);
8367
#endif
8368
        } else {
8369
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8370
        }
8371
        break;
8372
    case M16_OPC_ADDIU8:
8373
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8374
        break;
8375
    case M16_OPC_SLTI:
8376
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8377
        break;
8378
    case M16_OPC_SLTIU:
8379
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8380
        break;
8381
    case M16_OPC_I8:
8382
        switch (funct) {
8383
        case I8_BTEQZ:
8384
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8385
            break;
8386
        case I8_BTNEZ:
8387
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8388
            break;
8389
        case I8_SWRASP:
8390
            gen_ldst(ctx, OPC_SW, 31, 29, imm);
8391
            break;
8392
        case I8_ADJSP:
8393
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8394
            break;
8395
        case I8_SVRS:
8396
            {
8397
                int xsregs = (ctx->opcode >> 24) & 0x7;
8398
                int aregs = (ctx->opcode >> 16) & 0xf;
8399
                int do_ra = (ctx->opcode >> 6) & 0x1;
8400
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8401
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8402
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8403
                                 | (ctx->opcode & 0xf)) << 3;
8404

    
8405
                if (ctx->opcode & (1 << 7)) {
8406
                    gen_mips16_save(ctx, xsregs, aregs,
8407
                                    do_ra, do_s0, do_s1,
8408
                                    framesize);
8409
                } else {
8410
                    gen_mips16_restore(ctx, xsregs, aregs,
8411
                                       do_ra, do_s0, do_s1,
8412
                                       framesize);
8413
                }
8414
            }
8415
            break;
8416
        default:
8417
            generate_exception(ctx, EXCP_RI);
8418
            break;
8419
        }
8420
        break;
8421
    case M16_OPC_LI:
8422
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8423
        break;
8424
    case M16_OPC_CMPI:
8425
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8426
        break;
8427
#if defined(TARGET_MIPS64)
8428
    case M16_OPC_SD:
8429
        gen_ldst(ctx, OPC_SD, ry, rx, offset);
8430
        break;
8431
#endif
8432
    case M16_OPC_LB:
8433
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8434
        break;
8435
    case M16_OPC_LH:
8436
        gen_ldst(ctx, OPC_LH, ry, rx, offset);
8437
        break;
8438
    case M16_OPC_LWSP:
8439
        gen_ldst(ctx, OPC_LW, rx, 29, offset);
8440
        break;
8441
    case M16_OPC_LW:
8442
        gen_ldst(ctx, OPC_LW, ry, rx, offset);
8443
        break;
8444
    case M16_OPC_LBU:
8445
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8446
        break;
8447
    case M16_OPC_LHU:
8448
        gen_ldst(ctx, OPC_LHU, ry, rx, offset);
8449
        break;
8450
    case M16_OPC_LWPC:
8451
        gen_ldst(ctx, OPC_LWPC, rx, 0, offset);
8452
        break;
8453
#if defined(TARGET_MIPS64)
8454
    case M16_OPC_LWU:
8455
        gen_ldst(ctx, OPC_LWU, ry, rx, offset);
8456
        break;
8457
#endif
8458
    case M16_OPC_SB:
8459
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8460
        break;
8461
    case M16_OPC_SH:
8462
        gen_ldst(ctx, OPC_SH, ry, rx, offset);
8463
        break;
8464
    case M16_OPC_SWSP:
8465
        gen_ldst(ctx, OPC_SW, rx, 29, offset);
8466
        break;
8467
    case M16_OPC_SW:
8468
        gen_ldst(ctx, OPC_SW, ry, rx, offset);
8469
        break;
8470
#if defined(TARGET_MIPS64)
8471
    case M16_OPC_I64:
8472
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8473
        break;
8474
#endif
8475
    default:
8476
        generate_exception(ctx, EXCP_RI);
8477
        break;
8478
    }
8479

    
8480
    return 4;
8481
}
8482

    
8483
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8484
                              int *is_branch)
8485
{
8486
    int rx, ry;
8487
    int sa;
8488
    int op, cnvt_op, op1, offset;
8489
    int funct;
8490
    int n_bytes;
8491

    
8492
    op = (ctx->opcode >> 11) & 0x1f;
8493
    sa = (ctx->opcode >> 2) & 0x7;
8494
    sa = sa == 0 ? 8 : sa;
8495
    rx = xlat((ctx->opcode >> 8) & 0x7);
8496
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8497
    ry = xlat((ctx->opcode >> 5) & 0x7);
8498
    op1 = offset = ctx->opcode & 0x1f;
8499

    
8500
    n_bytes = 2;
8501

    
8502
    switch (op) {
8503
    case M16_OPC_ADDIUSP:
8504
        {
8505
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8506

    
8507
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8508
        }
8509
        break;
8510
    case M16_OPC_ADDIUPC:
8511
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8512
        break;
8513
    case M16_OPC_B:
8514
        offset = (ctx->opcode & 0x7ff) << 1;
8515
        offset = (int16_t)(offset << 4) >> 4;
8516
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8517
        /* No delay slot, so just process as a normal instruction */
8518
        break;
8519
    case M16_OPC_JAL:
8520
        offset = lduw_code(ctx->pc + 2);
8521
        offset = (((ctx->opcode & 0x1f) << 21)
8522
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8523
                  | offset) << 2;
8524
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8525
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8526
        n_bytes = 4;
8527
        *is_branch = 1;
8528
        break;
8529
    case M16_OPC_BEQZ:
8530
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8531
        /* No delay slot, so just process as a normal instruction */
8532
        break;
8533
    case M16_OPC_BNEQZ:
8534
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8535
        /* No delay slot, so just process as a normal instruction */
8536
        break;
8537
    case M16_OPC_SHIFT:
8538
        switch (ctx->opcode & 0x3) {
8539
        case 0x0:
8540
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8541
            break;
8542
        case 0x1:
8543
#if defined(TARGET_MIPS64)
8544
            check_mips_64(ctx);
8545
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8546
#else
8547
            generate_exception(ctx, EXCP_RI);
8548
#endif
8549
            break;
8550
        case 0x2:
8551
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8552
            break;
8553
        case 0x3:
8554
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8555
            break;
8556
        }
8557
        break;
8558
#if defined(TARGET_MIPS64)
8559
    case M16_OPC_LD:
8560
        check_mips_64(ctx);
8561
        gen_ldst(ctx, OPC_LD, ry, rx, offset << 3);
8562
        break;
8563
#endif
8564
    case M16_OPC_RRIA:
8565
        {
8566
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8567

    
8568
            if ((ctx->opcode >> 4) & 1) {
8569
#if defined(TARGET_MIPS64)
8570
                check_mips_64(ctx);
8571
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8572
#else
8573
                generate_exception(ctx, EXCP_RI);
8574
#endif
8575
            } else {
8576
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8577
            }
8578
        }
8579
        break;
8580
    case M16_OPC_ADDIU8:
8581
        {
8582
            int16_t imm = (int8_t) ctx->opcode;
8583

    
8584
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8585
        }
8586
        break;
8587
    case M16_OPC_SLTI:
8588
        {
8589
            int16_t imm = (uint8_t) ctx->opcode;
8590

    
8591
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8592
        }
8593
        break;
8594
    case M16_OPC_SLTIU:
8595
        {
8596
            int16_t imm = (uint8_t) ctx->opcode;
8597

    
8598
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8599
        }
8600
        break;
8601
    case M16_OPC_I8:
8602
        {
8603
            int reg32;
8604

    
8605
            funct = (ctx->opcode >> 8) & 0x7;
8606
            switch (funct) {
8607
            case I8_BTEQZ:
8608
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8609
                                   ((int8_t)ctx->opcode) << 1);
8610
                break;
8611
            case I8_BTNEZ:
8612
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8613
                                   ((int8_t)ctx->opcode) << 1);
8614
                break;
8615
            case I8_SWRASP:
8616
                gen_ldst(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8617
                break;
8618
            case I8_ADJSP:
8619
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8620
                              ((int8_t)ctx->opcode) << 3);
8621
                break;
8622
            case I8_SVRS:
8623
                {
8624
                    int do_ra = ctx->opcode & (1 << 6);
8625
                    int do_s0 = ctx->opcode & (1 << 5);
8626
                    int do_s1 = ctx->opcode & (1 << 4);
8627
                    int framesize = ctx->opcode & 0xf;
8628

    
8629
                    if (framesize == 0) {
8630
                        framesize = 128;
8631
                    } else {
8632
                        framesize = framesize << 3;
8633
                    }
8634

    
8635
                    if (ctx->opcode & (1 << 7)) {
8636
                        gen_mips16_save(ctx, 0, 0,
8637
                                        do_ra, do_s0, do_s1, framesize);
8638
                    } else {
8639
                        gen_mips16_restore(ctx, 0, 0,
8640
                                           do_ra, do_s0, do_s1, framesize);
8641
                    }
8642
                }
8643
                break;
8644
            case I8_MOV32R:
8645
                {
8646
                    int rz = xlat(ctx->opcode & 0x7);
8647

    
8648
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8649
                        ((ctx->opcode >> 5) & 0x7);
8650
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8651
                }
8652
                break;
8653
            case I8_MOVR32:
8654
                reg32 = ctx->opcode & 0x1f;
8655
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8656
                break;
8657
            default:
8658
                generate_exception(ctx, EXCP_RI);
8659
                break;
8660
            }
8661
        }
8662
        break;
8663
    case M16_OPC_LI:
8664
        {
8665
            int16_t imm = (uint8_t) ctx->opcode;
8666

    
8667
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8668
        }
8669
        break;
8670
    case M16_OPC_CMPI:
8671
        {
8672
            int16_t imm = (uint8_t) ctx->opcode;
8673

    
8674
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8675
        }
8676
        break;
8677
#if defined(TARGET_MIPS64)
8678
    case M16_OPC_SD:
8679
        check_mips_64(ctx);
8680
        gen_ldst(ctx, OPC_SD, ry, rx, offset << 3);
8681
        break;
8682
#endif
8683
    case M16_OPC_LB:
8684
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8685
        break;
8686
    case M16_OPC_LH:
8687
        gen_ldst(ctx, OPC_LH, ry, rx, offset << 1);
8688
        break;
8689
    case M16_OPC_LWSP:
8690
        gen_ldst(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8691
        break;
8692
    case M16_OPC_LW:
8693
        gen_ldst(ctx, OPC_LW, ry, rx, offset << 2);
8694
        break;
8695
    case M16_OPC_LBU:
8696
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8697
        break;
8698
    case M16_OPC_LHU:
8699
        gen_ldst(ctx, OPC_LHU, ry, rx, offset << 1);
8700
        break;
8701
    case M16_OPC_LWPC:
8702
        gen_ldst(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
8703
        break;
8704
#if defined (TARGET_MIPS64)
8705
    case M16_OPC_LWU:
8706
        check_mips_64(ctx);
8707
        gen_ldst(ctx, OPC_LWU, ry, rx, offset << 2);
8708
        break;
8709
#endif
8710
    case M16_OPC_SB:
8711
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8712
        break;
8713
    case M16_OPC_SH:
8714
        gen_ldst(ctx, OPC_SH, ry, rx, offset << 1);
8715
        break;
8716
    case M16_OPC_SWSP:
8717
        gen_ldst(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8718
        break;
8719
    case M16_OPC_SW:
8720
        gen_ldst(ctx, OPC_SW, ry, rx, offset << 2);
8721
        break;
8722
    case M16_OPC_RRR:
8723
        {
8724
            int rz = xlat((ctx->opcode >> 2) & 0x7);
8725
            int mips32_op;
8726

    
8727
            switch (ctx->opcode & 0x3) {
8728
            case RRR_ADDU:
8729
                mips32_op = OPC_ADDU;
8730
                break;
8731
            case RRR_SUBU:
8732
                mips32_op = OPC_SUBU;
8733
                break;
8734
#if defined(TARGET_MIPS64)
8735
            case RRR_DADDU:
8736
                mips32_op = OPC_DADDU;
8737
                check_mips_64(ctx);
8738
                break;
8739
            case RRR_DSUBU:
8740
                mips32_op = OPC_DSUBU;
8741
                check_mips_64(ctx);
8742
                break;
8743
#endif
8744
            default:
8745
                generate_exception(ctx, EXCP_RI);
8746
                goto done;
8747
            }
8748

    
8749
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
8750
        done:
8751
            ;
8752
        }
8753
        break;
8754
    case M16_OPC_RR:
8755
        switch (op1) {
8756
        case RR_JR:
8757
            {
8758
                int nd = (ctx->opcode >> 7) & 0x1;
8759
                int link = (ctx->opcode >> 6) & 0x1;
8760
                int ra = (ctx->opcode >> 5) & 0x1;
8761

    
8762
                if (link) {
8763
                    op = nd ? OPC_JALRC : OPC_JALRS;
8764
                } else {
8765
                    op = OPC_JR;
8766
                }
8767

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

    
8930
    return n_bytes;
8931
}
8932

    
8933
/* microMIPS extension to MIPS32 */
8934

    
8935
/* microMIPS32 major opcodes */
8936

    
8937
enum {
8938
    POOL32A = 0x00,
8939
    POOL16A = 0x01,
8940
    LBU16 = 0x02,
8941
    MOVE16 = 0x03,
8942
    ADDI32 = 0x04,
8943
    LBU32 = 0x05,
8944
    SB32 = 0x06,
8945
    LB32 = 0x07,
8946

    
8947
    POOL32B = 0x08,
8948
    POOL16B = 0x09,
8949
    LHU16 = 0x0a,
8950
    ANDI16 = 0x0b,
8951
    ADDIU32 = 0x0c,
8952
    LHU32 = 0x0d,
8953
    SH32 = 0x0e,
8954
    LH32 = 0x0f,
8955

    
8956
    POOL32I = 0x10,
8957
    POOL16C = 0x11,
8958
    LWSP16 = 0x12,
8959
    POOL16D = 0x13,
8960
    ORI32 = 0x14,
8961
    POOL32F = 0x15,
8962
    POOL32S = 0x16,
8963
    DADDIU32 = 0x17,
8964

    
8965
    POOL32C = 0x18,
8966
    LWGP16 = 0x19,
8967
    LW16 = 0x1a,
8968
    POOL16E = 0x1b,
8969
    XORI32 = 0x1c,
8970
    JALS32 = 0x1d,
8971
    ADDIUPC = 0x1e,
8972
    POOL48A = 0x1f,
8973

    
8974
    /* 0x20 is reserved */
8975
    RES_20 = 0x20,
8976
    POOL16F = 0x21,
8977
    SB16 = 0x22,
8978
    BEQZ16 = 0x23,
8979
    SLTI32 = 0x24,
8980
    BEQ32 = 0x25,
8981
    SWC132 = 0x26,
8982
    LWC132 = 0x27,
8983

    
8984
    /* 0x28 and 0x29 are reserved */
8985
    RES_28 = 0x28,
8986
    RES_29 = 0x29,
8987
    SH16 = 0x2a,
8988
    BNEZ16 = 0x2b,
8989
    SLTIU32 = 0x2c,
8990
    BNE32 = 0x2d,
8991
    SDC132 = 0x2e,
8992
    LDC132 = 0x2f,
8993

    
8994
    /* 0x30 and 0x31 are reserved */
8995
    RES_30 = 0x30,
8996
    RES_31 = 0x31,
8997
    SWSP16 = 0x32,
8998
    B16 = 0x33,
8999
    ANDI32 = 0x34,
9000
    J32 = 0x35,
9001
    SD32 = 0x36,
9002
    LD32 = 0x37,
9003

    
9004
    /* 0x38 and 0x39 are reserved */
9005
    RES_38 = 0x38,
9006
    RES_39 = 0x39,
9007
    SW16 = 0x3a,
9008
    LI16 = 0x3b,
9009
    JALX32 = 0x3c,
9010
    JAL32 = 0x3d,
9011
    SW32 = 0x3e,
9012
    LW32 = 0x3f
9013
};
9014

    
9015
/* POOL32A encoding of minor opcode field */
9016

    
9017
enum {
9018
    /* These opcodes are distinguished only by bits 9..6; those bits are
9019
     * what are recorded below. */
9020
    SLL32 = 0x0,
9021
    SRL32 = 0x1,
9022
    SRA = 0x2,
9023
    ROTR = 0x3,
9024

    
9025
    SLLV = 0x0,
9026
    SRLV = 0x1,
9027
    SRAV = 0x2,
9028
    ROTRV = 0x3,
9029
    ADD = 0x4,
9030
    ADDU32 = 0x5,
9031
    SUB = 0x6,
9032
    SUBU32 = 0x7,
9033
    MUL = 0x8,
9034
    AND = 0x9,
9035
    OR32 = 0xa,
9036
    NOR = 0xb,
9037
    XOR32 = 0xc,
9038
    SLT = 0xd,
9039
    SLTU = 0xe,
9040

    
9041
    MOVN = 0x0,
9042
    MOVZ = 0x1,
9043
    LWXS = 0x4,
9044

    
9045
    /* The following can be distinguished by their lower 6 bits. */
9046
    INS = 0x0c,
9047
    EXT = 0x2c,
9048
    POOL32AXF = 0x3c
9049
};
9050

    
9051
/* POOL32AXF encoding of minor opcode field extension */
9052

    
9053
enum {
9054
    /* bits 11..6 */
9055
    TEQ = 0x00,
9056
    TGE = 0x08,
9057
    TGEU = 0x10,
9058
    TLT = 0x20,
9059
    TLTU = 0x28,
9060
    TNE = 0x30,
9061

    
9062
    MFC0 = 0x03,
9063
    MTC0 = 0x0b,
9064

    
9065
    /* bits 13..12 for 0x01 */
9066
    MFHI_ACC = 0x0,
9067
    MFLO_ACC = 0x1,
9068
    MTHI_ACC = 0x2,
9069
    MTLO_ACC = 0x3,
9070

    
9071
    /* bits 13..12 for 0x2a */
9072
    MADD_ACC = 0x0,
9073
    MADDU_ACC = 0x1,
9074
    MSUB_ACC = 0x2,
9075
    MSUBU_ACC = 0x3,
9076

    
9077
    /* bits 13..12 for 0x32 */
9078
    MULT_ACC = 0x0,
9079
    MULTU_ACC = 0x0,
9080

    
9081
    /* bits 15..12 for 0x2c */
9082
    SEB = 0x2,
9083
    SEH = 0x3,
9084
    CLO = 0x4,
9085
    CLZ = 0x5,
9086
    RDHWR = 0x6,
9087
    WSBH = 0x7,
9088
    MULT = 0x8,
9089
    MULTU = 0x9,
9090
    DIV = 0xa,
9091
    DIVU = 0xb,
9092
    MADD = 0xc,
9093
    MADDU = 0xd,
9094
    MSUB = 0xe,
9095
    MSUBU = 0xf,
9096

    
9097
    /* bits 15..12 for 0x34 */
9098
    MFC2 = 0x4,
9099
    MTC2 = 0x5,
9100
    MFHC2 = 0x8,
9101
    MTHC2 = 0x9,
9102
    CFC2 = 0xc,
9103
    CTC2 = 0xd,
9104

    
9105
    /* bits 15..12 for 0x3c */
9106
    JALR = 0x0,
9107
    JR = 0x0,                   /* alias */
9108
    JALR_HB = 0x1,
9109
    JALRS = 0x4,
9110
    JALRS_HB = 0x5,
9111

    
9112
    /* bits 15..12 for 0x05 */
9113
    RDPGPR = 0xe,
9114
    WRPGPR = 0xf,
9115

    
9116
    /* bits 15..12 for 0x0d */
9117
    TLBP = 0x0,
9118
    TLBR = 0x1,
9119
    TLBWI = 0x2,
9120
    TLBWR = 0x3,
9121
    WAIT = 0x9,
9122
    IRET = 0xd,
9123
    DERET = 0xe,
9124
    ERET = 0xf,
9125

    
9126
    /* bits 15..12 for 0x15 */
9127
    DMT = 0x0,
9128
    DVPE = 0x1,
9129
    EMT = 0x2,
9130
    EVPE = 0x3,
9131

    
9132
    /* bits 15..12 for 0x1d */
9133
    DI = 0x4,
9134
    EI = 0x5,
9135

    
9136
    /* bits 15..12 for 0x2d */
9137
    SYNC = 0x6,
9138
    SYSCALL = 0x8,
9139
    SDBBP = 0xd,
9140

    
9141
    /* bits 15..12 for 0x35 */
9142
    MFHI32 = 0x0,
9143
    MFLO32 = 0x1,
9144
    MTHI32 = 0x2,
9145
    MTLO32 = 0x3,
9146
};
9147

    
9148
/* POOL32B encoding of minor opcode field (bits 15..12) */
9149

    
9150
enum {
9151
    LWC2 = 0x0,
9152
    LWP = 0x1,
9153
    LDP = 0x4,
9154
    LWM32 = 0x5,
9155
    CACHE = 0x6,
9156
    LDM = 0x7,
9157
    SWC2 = 0x8,
9158
    SWP = 0x9,
9159
    SDP = 0xc,
9160
    SWM32 = 0xd,
9161
    SDM = 0xf
9162
};
9163

    
9164
/* POOL32C encoding of minor opcode field (bits 15..12) */
9165

    
9166
enum {
9167
    LWL = 0x0,
9168
    SWL = 0x8,
9169
    LWR = 0x1,
9170
    SWR = 0x9,
9171
    PREF = 0x2,
9172
    /* 0xa is reserved */
9173
    LL = 0x3,
9174
    SC = 0xb,
9175
    LDL = 0x4,
9176
    SDL = 0xc,
9177
    LDR = 0x5,
9178
    SDR = 0xd,
9179
    /* 0x6 is reserved */
9180
    LWU = 0xe,
9181
    LLD = 0x7,
9182
    SCD = 0xf
9183
};
9184

    
9185
/* POOL32F encoding of minor opcode field (bits 5..0) */
9186

    
9187
enum {
9188
    /* These are the bit 7..6 values */
9189
    ADD_FMT = 0x0,
9190
    MOVN_FMT = 0x0,
9191

    
9192
    SUB_FMT = 0x1,
9193
    MOVZ_FMT = 0x1,
9194

    
9195
    MUL_FMT = 0x2,
9196

    
9197
    DIV_FMT = 0x3,
9198

    
9199
    /* These are the bit 8..6 values */
9200
    RSQRT2_FMT = 0x0,
9201
    MOVF_FMT = 0x0,
9202

    
9203
    LWXC1 = 0x1,
9204
    MOVT_FMT = 0x1,
9205

    
9206
    PLL_PS = 0x2,
9207
    SWXC1 = 0x2,
9208

    
9209
    PLU_PS = 0x3,
9210
    LDXC1 = 0x3,
9211

    
9212
    PUL_PS = 0x4,
9213
    SDXC1 = 0x4,
9214
    RECIP2_FMT = 0x4,
9215

    
9216
    PUU_PS = 0x5,
9217
    LUXC1 = 0x5,
9218

    
9219
    CVT_PS_S = 0x6,
9220
    SUXC1 = 0x6,
9221
    ADDR_PS = 0x6,
9222
    PREFX = 0x6,
9223

    
9224
    MULR_PS = 0x7,
9225

    
9226
    MADD_S = 0x01,
9227
    MADD_D = 0x09,
9228
    MADD_PS = 0x11,
9229
    ALNV_PS = 0x19,
9230
    MSUB_S = 0x21,
9231
    MSUB_D = 0x29,
9232
    MSUB_PS = 0x31,
9233

    
9234
    NMADD_S = 0x02,
9235
    NMADD_D = 0x0a,
9236
    NMADD_PS = 0x12,
9237
    NMSUB_S = 0x22,
9238
    NMSUB_D = 0x2a,
9239
    NMSUB_PS = 0x32,
9240

    
9241
    POOL32FXF = 0x3b,
9242

    
9243
    CABS_COND_FMT = 0x1c,              /* MIPS3D */
9244
    C_COND_FMT = 0x3c
9245
};
9246

    
9247
/* POOL32Fxf encoding of minor opcode extension field */
9248

    
9249
enum {
9250
    CVT_L = 0x04,
9251
    RSQRT_FMT = 0x08,
9252
    FLOOR_L = 0x0c,
9253
    CVT_PW_PS = 0x1c,
9254
    CVT_W = 0x24,
9255
    SQRT_FMT = 0x28,
9256
    FLOOR_W = 0x2c,
9257
    CVT_PS_PW = 0x3c,
9258
    CFC1 = 0x40,
9259
    RECIP_FMT = 0x48,
9260
    CEIL_L = 0x4c,
9261
    CTC1 = 0x60,
9262
    CEIL_W = 0x6c,
9263
    MFC1 = 0x80,
9264
    CVT_S_PL = 0x84,
9265
    TRUNC_L = 0x8c,
9266
    MTC1 = 0xa0,
9267
    CVT_S_PU = 0xa4,
9268
    TRUNC_W = 0xac,
9269
    MFHC1 = 0xc0,
9270
    ROUND_L = 0xcc,
9271
    MTHC1 = 0xe0,
9272
    ROUND_W = 0xec,
9273

    
9274
    MOV_FMT = 0x01,
9275
    MOVF = 0x05,
9276
    ABS_FMT = 0x0d,
9277
    RSQRT1_FMT = 0x1d,
9278
    MOVT = 0x25,
9279
    NEG_FMT = 0x2d,
9280
    CVT_D = 0x4d,
9281
    RECIP1_FMT = 0x5d,
9282
    CVT_S = 0x6d
9283
};
9284

    
9285
/* POOL32I encoding of minor opcode field (bits 25..21) */
9286

    
9287
enum {
9288
    BLTZ = 0x00,
9289
    BLTZAL = 0x01,
9290
    BGEZ = 0x02,
9291
    BGEZAL = 0x03,
9292
    BLEZ = 0x04,
9293
    BNEZC = 0x05,
9294
    BGTZ = 0x06,
9295
    BEQZC = 0x07,
9296
    TLTI = 0x08,
9297
    TGEI = 0x09,
9298
    TLTIU = 0x0a,
9299
    TGEIU = 0x0b,
9300
    TNEI = 0x0c,
9301
    LUI = 0x0d,
9302
    TEQI = 0x0e,
9303
    SYNCI = 0x10,
9304
    BLTZALS = 0x11,
9305
    BGEZALS = 0x13,
9306
    BC2F = 0x14,
9307
    BC2T = 0x15,
9308
    BPOSGE64 = 0x1a,
9309
    BPOSGE32 = 0x1b,
9310
    /* These overlap and are distinguished by bit16 of the instruction */
9311
    BC1F = 0x1c,
9312
    BC1T = 0x1d,
9313
    BC1ANY2F = 0x1c,
9314
    BC1ANY2T = 0x1d,
9315
    BC1ANY4F = 0x1e,
9316
    BC1ANY4T = 0x1f
9317
};
9318

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

    
9321
enum {
9322
    ADDU16 = 0x0,
9323
    SUBU16 = 0x1
9324
};
9325

    
9326
/* POOL16B encoding of minor opcode field */
9327

    
9328
enum {
9329
    SLL16 = 0x0,
9330
    SRL16 = 0x1
9331
};
9332

    
9333
/* POOL16C encoding of minor opcode field */
9334

    
9335
enum {
9336
    NOT16 = 0x00,
9337
    XOR16 = 0x04,
9338
    AND16 = 0x08,
9339
    OR16 = 0x0c,
9340
    LWM16 = 0x10,
9341
    SWM16 = 0x14,
9342
    JR16 = 0x18,
9343
    JRC16 = 0x1a,
9344
    JALR16 = 0x1c,
9345
    JALR16S = 0x1e,
9346
    MFHI16 = 0x20,
9347
    MFLO16 = 0x24,
9348
    BREAK16 = 0x28,
9349
    SDBBP16 = 0x2c,
9350
    JRADDIUSP = 0x30
9351
};
9352

    
9353
/* POOL16D encoding of minor opcode field */
9354

    
9355
enum {
9356
    ADDIUS5 = 0x0,
9357
    ADDIUSP = 0x1
9358
};
9359

    
9360
/* POOL16E encoding of minor opcode field */
9361

    
9362
enum {
9363
    ADDIUR2 = 0x0,
9364
    ADDIUR1SP = 0x1
9365
};
9366

    
9367
static int mmreg (int r)
9368
{
9369
    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9370

    
9371
    return map[r];
9372
}
9373

    
9374
/* Used for 16-bit store instructions.  */
9375
static int mmreg2 (int r)
9376
{
9377
    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9378

    
9379
    return map[r];
9380
}
9381

    
9382
#define uMIPS_RD(op) ((op >> 7) & 0x7)
9383
#define uMIPS_RS(op) ((op >> 4) & 0x7)
9384
#define uMIPS_RS2(op) uMIPS_RS(op)
9385
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
9386
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9387
#define uMIPS_RS5(op) (op & 0x1f)
9388

    
9389
/* Signed immediate */
9390
#define SIMM(op, start, width)                                          \
9391
    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
9392
               << (32-width))                                           \
9393
     >> (32-width))
9394
/* Zero-extended immediate */
9395
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9396

    
9397
static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9398
{
9399
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9400

    
9401
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9402
}
9403

    
9404
static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9405
{
9406
    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9407
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9408
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9409

    
9410
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9411
}
9412

    
9413
static void gen_addiusp (CPUState *env, DisasContext *ctx)
9414
{
9415
    int encoded = ZIMM(ctx->opcode, 1, 9);
9416
    int decoded;
9417

    
9418
    if (encoded <= 1) {
9419
        decoded = 256 + encoded;
9420
    } else if (encoded <= 255) {
9421
        decoded = encoded;
9422
    } else if (encoded <= 509) {
9423
        decoded = encoded - 512;
9424
    } else {
9425
        decoded = encoded - 768;
9426
    }
9427

    
9428
    gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9429
}
9430

    
9431
static void gen_addius5 (CPUState *env, DisasContext *ctx)
9432
{
9433
    int imm = SIMM(ctx->opcode, 1, 4);
9434
    int rd = (ctx->opcode >> 5) & 0x1f;
9435

    
9436
    gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9437
}
9438

    
9439
static void gen_andi16 (CPUState *env, DisasContext *ctx)
9440
{
9441
    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9442
                                 31, 32, 63, 64, 255, 32768, 65535 };
9443
    int rd = mmreg(uMIPS_RD(ctx->opcode));
9444
    int rs = mmreg(uMIPS_RS(ctx->opcode));
9445
    int encoded = ZIMM(ctx->opcode, 0, 4);
9446

    
9447
    gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9448
}
9449

    
9450
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9451
                               int base, int16_t offset)
9452
{
9453
    TCGv t0, t1;
9454
    TCGv_i32 t2;
9455

    
9456
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9457
        generate_exception(ctx, EXCP_RI);
9458
        return;
9459
    }
9460

    
9461
    t0 = tcg_temp_new();
9462

    
9463
    gen_base_offset_addr(ctx, t0, base, offset);
9464

    
9465
    t1 = tcg_const_tl(reglist);
9466
    t2 = tcg_const_i32(ctx->mem_idx);
9467

    
9468
    save_cpu_state(ctx, 1);
9469
    switch (opc) {
9470
    case LWM32:
9471
        gen_helper_lwm(t0, t1, t2);
9472
        break;
9473
    case SWM32:
9474
        gen_helper_swm(t0, t1, t2);
9475
        break;
9476
#ifdef TARGET_MIPS64
9477
    case LDM:
9478
        gen_helper_ldm(t0, t1, t2);
9479
        break;
9480
    case SDM:
9481
        gen_helper_sdm(t0, t1, t2);
9482
        break;
9483
#endif
9484
    }
9485
    MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9486
    tcg_temp_free(t0);
9487
    tcg_temp_free(t1);
9488
    tcg_temp_free_i32(t2);
9489
}
9490

    
9491

    
9492
static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9493
{
9494
    int rd = mmreg((ctx->opcode >> 3) & 0x7);
9495
    int rs = mmreg(ctx->opcode & 0x7);
9496
    int opc;
9497

    
9498
    switch (((ctx->opcode) >> 4) & 0x3f) {
9499
    case NOT16 + 0:
9500
    case NOT16 + 1:
9501
    case NOT16 + 2:
9502
    case NOT16 + 3:
9503
        gen_logic(env, OPC_NOR, rd, rs, 0);
9504
        break;
9505
    case XOR16 + 0:
9506
    case XOR16 + 1:
9507
    case XOR16 + 2:
9508
    case XOR16 + 3:
9509
        gen_logic(env, OPC_XOR, rd, rd, rs);
9510
        break;
9511
    case AND16 + 0:
9512
    case AND16 + 1:
9513
    case AND16 + 2:
9514
    case AND16 + 3:
9515
        gen_logic(env, OPC_AND, rd, rd, rs);
9516
        break;
9517
    case OR16 + 0:
9518
    case OR16 + 1:
9519
    case OR16 + 2:
9520
    case OR16 + 3:
9521
        gen_logic(env, OPC_OR, rd, rd, rs);
9522
        break;
9523
    case LWM16 + 0:
9524
    case LWM16 + 1:
9525
    case LWM16 + 2:
9526
    case LWM16 + 3:
9527
        {
9528
            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9529
            int offset = ZIMM(ctx->opcode, 0, 4);
9530

    
9531
            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9532
                              29, offset << 2);
9533
        }
9534
        break;
9535
    case SWM16 + 0:
9536
    case SWM16 + 1:
9537
    case SWM16 + 2:
9538
    case SWM16 + 3:
9539
        {
9540
            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9541
            int offset = ZIMM(ctx->opcode, 0, 4);
9542

    
9543
            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9544
                              29, offset << 2);
9545
        }
9546
        break;
9547
    case JR16 + 0:
9548
    case JR16 + 1:
9549
        {
9550
            int reg = ctx->opcode & 0x1f;
9551

    
9552
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9553
        }
9554
        *is_branch = 1;
9555
        break;
9556
    case JRC16 + 0:
9557
    case JRC16 + 1:
9558
        {
9559
            int reg = ctx->opcode & 0x1f;
9560

    
9561
            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9562
            /* Let normal delay slot handling in our caller take us
9563
               to the branch target.  */
9564
        }
9565
        break;
9566
    case JALR16 + 0:
9567
    case JALR16 + 1:
9568
        opc = OPC_JALR;
9569
        goto do_jalr;
9570
    case JALR16S + 0:
9571
    case JALR16S + 1:
9572
        opc = OPC_JALRS;
9573
    do_jalr:
9574
        {
9575
            int reg = ctx->opcode & 0x1f;
9576

    
9577
            gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9578
        }
9579
        *is_branch = 1;
9580
        break;
9581
    case MFHI16 + 0:
9582
    case MFHI16 + 1:
9583
        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9584
        break;
9585
    case MFLO16 + 0:
9586
    case MFLO16 + 1:
9587
        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9588
        break;
9589
    case BREAK16:
9590
        generate_exception(ctx, EXCP_BREAK);
9591
        break;
9592
    case SDBBP16:
9593
        /* XXX: not clear which exception should be raised
9594
         *      when in debug mode...
9595
         */
9596
        check_insn(env, ctx, ISA_MIPS32);
9597
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9598
            generate_exception(ctx, EXCP_DBp);
9599
        } else {
9600
            generate_exception(ctx, EXCP_DBp);
9601
        }
9602
        break;
9603
    case JRADDIUSP + 0:
9604
    case JRADDIUSP + 1:
9605
        {
9606
            int imm = ZIMM(ctx->opcode, 0, 5);
9607

    
9608
            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9609
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9610
            /* Let normal delay slot handling in our caller take us
9611
               to the branch target.  */
9612
        }
9613
        break;
9614
    default:
9615
        generate_exception(ctx, EXCP_RI);
9616
        break;
9617
    }
9618
}
9619

    
9620
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
9621
{
9622
    TCGv t0 = tcg_temp_new();
9623
    TCGv t1 = tcg_temp_new();
9624

    
9625
    gen_load_gpr(t0, base);
9626

    
9627
    if (index != 0) {
9628
        gen_load_gpr(t1, index);
9629
        tcg_gen_shli_tl(t1, t1, 2);
9630
        gen_op_addr_add(ctx, t0, t1, t0);
9631
    }
9632

    
9633
    save_cpu_state(ctx, 0);
9634
    op_ldst_lw(t1, t0, ctx);
9635
    gen_store_gpr(t1, rd);
9636

    
9637
    tcg_temp_free(t0);
9638
    tcg_temp_free(t1);
9639
}
9640

    
9641
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
9642
                           int base, int16_t offset)
9643
{
9644
    const char *opn = "ldst_pair";
9645
    TCGv t0, t1;
9646

    
9647
    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
9648
        generate_exception(ctx, EXCP_RI);
9649
        return;
9650
    }
9651

    
9652
    t0 = tcg_temp_new();
9653
    t1 = tcg_temp_new();
9654

    
9655
    gen_base_offset_addr(ctx, t0, base, offset);
9656

    
9657
    switch (opc) {
9658
    case LWP:
9659
        save_cpu_state(ctx, 0);
9660
        op_ldst_lw(t1, t0, ctx);
9661
        gen_store_gpr(t1, rd);
9662
        tcg_gen_movi_tl(t1, 4);
9663
        gen_op_addr_add(ctx, t0, t0, t1);
9664
        op_ldst_lw(t1, t0, ctx);
9665
        gen_store_gpr(t1, rd+1);
9666
        opn = "lwp";
9667
        break;
9668
    case SWP:
9669
        save_cpu_state(ctx, 1);
9670
        gen_load_gpr(t1, rd);
9671
        op_ldst_sw(t1, t0, ctx);
9672
        tcg_gen_movi_tl(t1, 4);
9673
        gen_op_addr_add(ctx, t0, t0, t1);
9674
        gen_load_gpr(t1, rd+1);
9675
        op_ldst_sw(t1, t0, ctx);
9676
        opn = "swp";
9677
        break;
9678
#ifdef TARGET_MIPS64
9679
    case LDP:
9680
        save_cpu_state(ctx, 0);
9681
        op_ldst_ld(t1, t0, ctx);
9682
        gen_store_gpr(t1, rd);
9683
        tcg_gen_movi_tl(t1, 8);
9684
        gen_op_addr_add(ctx, t0, t0, t1);
9685
        op_ldst_ld(t1, t0, ctx);
9686
        gen_store_gpr(t1, rd+1);
9687
        opn = "ldp";
9688
        break;
9689
    case SDP:
9690
        save_cpu_state(ctx, 1);
9691
        gen_load_gpr(t1, rd);
9692
        op_ldst_sd(t1, t0, ctx);
9693
        tcg_gen_movi_tl(t1, 8);
9694
        gen_op_addr_add(ctx, t0, t0, t1);
9695
        gen_load_gpr(t1, rd+1);
9696
        op_ldst_sd(t1, t0, ctx);
9697
        opn = "sdp";
9698
        break;
9699
#endif
9700
    }
9701
    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
9702
    tcg_temp_free(t0);
9703
    tcg_temp_free(t1);
9704
}
9705

    
9706
static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
9707
                           int *is_branch)
9708
{
9709
    int extension = (ctx->opcode >> 6) & 0x3f;
9710
    int minor = (ctx->opcode >> 12) & 0xf;
9711
    uint32_t mips32_op;
9712

    
9713
    switch (extension) {
9714
    case TEQ:
9715
        mips32_op = OPC_TEQ;
9716
        goto do_trap;
9717
    case TGE:
9718
        mips32_op = OPC_TGE;
9719
        goto do_trap;
9720
    case TGEU:
9721
        mips32_op = OPC_TGEU;
9722
        goto do_trap;
9723
    case TLT:
9724
        mips32_op = OPC_TLT;
9725
        goto do_trap;
9726
    case TLTU:
9727
        mips32_op = OPC_TLTU;
9728
        goto do_trap;
9729
    case TNE:
9730
        mips32_op = OPC_TNE;
9731
    do_trap:
9732
        gen_trap(ctx, mips32_op, rs, rt, -1);
9733
        break;
9734
#ifndef CONFIG_USER_ONLY
9735
    case MFC0:
9736
    case MFC0 + 32:
9737
        if (rt == 0) {
9738
            /* Treat as NOP. */
9739
            break;
9740
        }
9741
        gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
9742
        break;
9743
    case MTC0:
9744
    case MTC0 + 32:
9745
        {
9746
            TCGv t0 = tcg_temp_new();
9747

    
9748
            gen_load_gpr(t0, rt);
9749
            gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
9750
            tcg_temp_free(t0);
9751
        }
9752
        break;
9753
#endif
9754
    case 0x2c:
9755
        switch (minor) {
9756
        case SEB:
9757
            gen_bshfl(ctx, OPC_SEB, rs, rt);
9758
            break;
9759
        case SEH:
9760
            gen_bshfl(ctx, OPC_SEH, rs, rt);
9761
            break;
9762
        case CLO:
9763
            mips32_op = OPC_CLO;
9764
            goto do_cl;
9765
        case CLZ:
9766
            mips32_op = OPC_CLZ;
9767
        do_cl:
9768
            check_insn(env, ctx, ISA_MIPS32);
9769
            gen_cl(ctx, mips32_op, rt, rs);
9770
            break;
9771
        case RDHWR:
9772
            gen_rdhwr(env, ctx, rt, rs);
9773
            break;
9774
        case WSBH:
9775
            gen_bshfl(ctx, OPC_WSBH, rs, rt);
9776
            break;
9777
        case MULT:
9778
            mips32_op = OPC_MULT;
9779
            goto do_muldiv;
9780
        case MULTU:
9781
            mips32_op = OPC_MULTU;
9782
            goto do_muldiv;
9783
        case DIV:
9784
            mips32_op = OPC_DIV;
9785
            goto do_muldiv;
9786
        case DIVU:
9787
            mips32_op = OPC_DIVU;
9788
            goto do_muldiv;
9789
        case MADD:
9790
            mips32_op = OPC_MADD;
9791
            goto do_muldiv;
9792
        case MADDU:
9793
            mips32_op = OPC_MADDU;
9794
            goto do_muldiv;
9795
        case MSUB:
9796
            mips32_op = OPC_MSUB;
9797
            goto do_muldiv;
9798
        case MSUBU:
9799
            mips32_op = OPC_MSUBU;
9800
        do_muldiv:
9801
            check_insn(env, ctx, ISA_MIPS32);
9802
            gen_muldiv(ctx, mips32_op, rs, rt);
9803
            break;
9804
        default:
9805
            goto pool32axf_invalid;
9806
        }
9807
        break;
9808
    case 0x34:
9809
        switch (minor) {
9810
        case MFC2:
9811
        case MTC2:
9812
        case MFHC2:
9813
        case MTHC2:
9814
        case CFC2:
9815
        case CTC2:
9816
            generate_exception_err(ctx, EXCP_CpU, 2);
9817
            break;
9818
        default:
9819
            goto pool32axf_invalid;
9820
        }
9821
        break;
9822
    case 0x3c:
9823
        switch (minor) {
9824
        case JALR:
9825
        case JALR_HB:
9826
            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
9827
            *is_branch = 1;
9828
            break;
9829
        case JALRS:
9830
        case JALRS_HB:
9831
            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
9832
            *is_branch = 1;
9833
            break;
9834
        default:
9835
            goto pool32axf_invalid;
9836
        }
9837
        break;
9838
    case 0x05:
9839
        switch (minor) {
9840
        case RDPGPR:
9841
            check_insn(env, ctx, ISA_MIPS32R2);
9842
            gen_load_srsgpr(rt, rs);
9843
            break;
9844
        case WRPGPR:
9845
            check_insn(env, ctx, ISA_MIPS32R2);
9846
            gen_store_srsgpr(rt, rs);
9847
            break;
9848
        default:
9849
            goto pool32axf_invalid;
9850
        }
9851
        break;
9852
#ifndef CONFIG_USER_ONLY
9853
    case 0x0d:
9854
        switch (minor) {
9855
        case TLBP:
9856
            mips32_op = OPC_TLBP;
9857
            goto do_cp0;
9858
        case TLBR:
9859
            mips32_op = OPC_TLBR;
9860
            goto do_cp0;
9861
        case TLBWI:
9862
            mips32_op = OPC_TLBWI;
9863
            goto do_cp0;
9864
        case TLBWR:
9865
            mips32_op = OPC_TLBWR;
9866
            goto do_cp0;
9867
        case WAIT:
9868
            mips32_op = OPC_WAIT;
9869
            goto do_cp0;
9870
        case DERET:
9871
            mips32_op = OPC_DERET;
9872
            goto do_cp0;
9873
        case ERET:
9874
            mips32_op = OPC_ERET;
9875
        do_cp0:
9876
            gen_cp0(env, ctx, mips32_op, rt, rs);
9877
            break;
9878
        default:
9879
            goto pool32axf_invalid;
9880
        }
9881
        break;
9882
    case 0x1d:
9883
        switch (minor) {
9884
        case DI:
9885
            {
9886
                TCGv t0 = tcg_temp_new();
9887

    
9888
                save_cpu_state(ctx, 1);
9889
                gen_helper_di(t0);
9890
                gen_store_gpr(t0, rs);
9891
                /* Stop translation as we may have switched the execution mode */
9892
                ctx->bstate = BS_STOP;
9893
                tcg_temp_free(t0);
9894
            }
9895
            break;
9896
        case EI:
9897
            {
9898
                TCGv t0 = tcg_temp_new();
9899

    
9900
                save_cpu_state(ctx, 1);
9901
                gen_helper_ei(t0);
9902
                gen_store_gpr(t0, rs);
9903
                /* Stop translation as we may have switched the execution mode */
9904
                ctx->bstate = BS_STOP;
9905
                tcg_temp_free(t0);
9906
            }
9907
            break;
9908
        default:
9909
            goto pool32axf_invalid;
9910
        }
9911
        break;
9912
#endif
9913
    case 0x2d:
9914
        switch (minor) {
9915
        case SYNC:
9916
            /* NOP */
9917
            break;
9918
        case SYSCALL:
9919
            generate_exception(ctx, EXCP_SYSCALL);
9920
            ctx->bstate = BS_STOP;
9921
            break;
9922
        case SDBBP:
9923
            check_insn(env, ctx, ISA_MIPS32);
9924
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9925
                generate_exception(ctx, EXCP_DBp);
9926
            } else {
9927
                generate_exception(ctx, EXCP_DBp);
9928
            }
9929
            break;
9930
        default:
9931
            goto pool32axf_invalid;
9932
        }
9933
        break;
9934
    case 0x35:
9935
        switch (minor) {
9936
        case MFHI32:
9937
            gen_HILO(ctx, OPC_MFHI, rs);
9938
            break;
9939
        case MFLO32:
9940
            gen_HILO(ctx, OPC_MFLO, rs);
9941
            break;
9942
        case MTHI32:
9943
            gen_HILO(ctx, OPC_MTHI, rs);
9944
            break;
9945
        case MTLO32:
9946
            gen_HILO(ctx, OPC_MTLO, rs);
9947
            break;
9948
        default:
9949
            goto pool32axf_invalid;
9950
        }
9951
        break;
9952
    default:
9953
    pool32axf_invalid:
9954
        MIPS_INVAL("pool32axf");
9955
        generate_exception(ctx, EXCP_RI);
9956
        break;
9957
    }
9958
}
9959

    
9960
/* Values for microMIPS fmt field.  Variable-width, depending on which
9961
   formats the instruction supports.  */
9962

    
9963
enum {
9964
    FMT_SD_S = 0,
9965
    FMT_SD_D = 1,
9966

    
9967
    FMT_SDPS_S = 0,
9968
    FMT_SDPS_D = 1,
9969
    FMT_SDPS_PS = 2,
9970

    
9971
    FMT_SWL_S = 0,
9972
    FMT_SWL_W = 1,
9973
    FMT_SWL_L = 2,
9974

    
9975
    FMT_DWL_D = 0,
9976
    FMT_DWL_W = 1,
9977
    FMT_DWL_L = 2
9978
};
9979

    
9980
static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
9981
{
9982
    int extension = (ctx->opcode >> 6) & 0x3ff;
9983
    uint32_t mips32_op;
9984

    
9985
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
9986
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
9987
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
9988

    
9989
    switch (extension) {
9990
    case FLOAT_1BIT_FMT(CFC1, 0):
9991
        mips32_op = OPC_CFC1;
9992
        goto do_cp1;
9993
    case FLOAT_1BIT_FMT(CTC1, 0):
9994
        mips32_op = OPC_CTC1;
9995
        goto do_cp1;
9996
    case FLOAT_1BIT_FMT(MFC1, 0):
9997
        mips32_op = OPC_MFC1;
9998
        goto do_cp1;
9999
    case FLOAT_1BIT_FMT(MTC1, 0):
10000
        mips32_op = OPC_MTC1;
10001
        goto do_cp1;
10002
    case FLOAT_1BIT_FMT(MFHC1, 0):
10003
        mips32_op = OPC_MFHC1;
10004
        goto do_cp1;
10005
    case FLOAT_1BIT_FMT(MTHC1, 0):
10006
        mips32_op = OPC_MTHC1;
10007
    do_cp1:
10008
        gen_cp1(ctx, mips32_op, rt, rs);
10009
        break;
10010

    
10011
        /* Reciprocal square root */
10012
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10013
        mips32_op = OPC_RSQRT_S;
10014
        goto do_unaryfp;
10015
    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10016
        mips32_op = OPC_RSQRT_D;
10017
        goto do_unaryfp;
10018

    
10019
        /* Square root */
10020
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10021
        mips32_op = OPC_SQRT_S;
10022
        goto do_unaryfp;
10023
    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10024
        mips32_op = OPC_SQRT_D;
10025
        goto do_unaryfp;
10026

    
10027
        /* Reciprocal */
10028
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10029
        mips32_op = OPC_RECIP_S;
10030
        goto do_unaryfp;
10031
    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10032
        mips32_op = OPC_RECIP_D;
10033
        goto do_unaryfp;
10034

    
10035
        /* Floor */
10036
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10037
        mips32_op = OPC_FLOOR_L_S;
10038
        goto do_unaryfp;
10039
    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10040
        mips32_op = OPC_FLOOR_L_D;
10041
        goto do_unaryfp;
10042
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10043
        mips32_op = OPC_FLOOR_W_S;
10044
        goto do_unaryfp;
10045
    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10046
        mips32_op = OPC_FLOOR_W_D;
10047
        goto do_unaryfp;
10048

    
10049
        /* Ceiling */
10050
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10051
        mips32_op = OPC_CEIL_L_S;
10052
        goto do_unaryfp;
10053
    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10054
        mips32_op = OPC_CEIL_L_D;
10055
        goto do_unaryfp;
10056
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10057
        mips32_op = OPC_CEIL_W_S;
10058
        goto do_unaryfp;
10059
    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10060
        mips32_op = OPC_CEIL_W_D;
10061
        goto do_unaryfp;
10062

    
10063
        /* Truncation */
10064
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10065
        mips32_op = OPC_TRUNC_L_S;
10066
        goto do_unaryfp;
10067
    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10068
        mips32_op = OPC_TRUNC_L_D;
10069
        goto do_unaryfp;
10070
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10071
        mips32_op = OPC_TRUNC_W_S;
10072
        goto do_unaryfp;
10073
    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10074
        mips32_op = OPC_TRUNC_W_D;
10075
        goto do_unaryfp;
10076

    
10077
        /* Round */
10078
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10079
        mips32_op = OPC_ROUND_L_S;
10080
        goto do_unaryfp;
10081
    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10082
        mips32_op = OPC_ROUND_L_D;
10083
        goto do_unaryfp;
10084
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10085
        mips32_op = OPC_ROUND_W_S;
10086
        goto do_unaryfp;
10087
    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10088
        mips32_op = OPC_ROUND_W_D;
10089
        goto do_unaryfp;
10090

    
10091
        /* Integer to floating-point conversion */
10092
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10093
        mips32_op = OPC_CVT_L_S;
10094
        goto do_unaryfp;
10095
    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10096
        mips32_op = OPC_CVT_L_D;
10097
        goto do_unaryfp;
10098
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10099
        mips32_op = OPC_CVT_W_S;
10100
        goto do_unaryfp;
10101
    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10102
        mips32_op = OPC_CVT_W_D;
10103
        goto do_unaryfp;
10104

    
10105
        /* Paired-foo conversions */
10106
    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10107
        mips32_op = OPC_CVT_S_PL;
10108
        goto do_unaryfp;
10109
    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10110
        mips32_op = OPC_CVT_S_PU;
10111
        goto do_unaryfp;
10112
    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10113
        mips32_op = OPC_CVT_PW_PS;
10114
        goto do_unaryfp;
10115
    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10116
        mips32_op = OPC_CVT_PS_PW;
10117
        goto do_unaryfp;
10118

    
10119
        /* Floating-point moves */
10120
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10121
        mips32_op = OPC_MOV_S;
10122
        goto do_unaryfp;
10123
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10124
        mips32_op = OPC_MOV_D;
10125
        goto do_unaryfp;
10126
    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10127
        mips32_op = OPC_MOV_PS;
10128
        goto do_unaryfp;
10129

    
10130
        /* Absolute value */
10131
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10132
        mips32_op = OPC_ABS_S;
10133
        goto do_unaryfp;
10134
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10135
        mips32_op = OPC_ABS_D;
10136
        goto do_unaryfp;
10137
    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10138
        mips32_op = OPC_ABS_PS;
10139
        goto do_unaryfp;
10140

    
10141
        /* Negation */
10142
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10143
        mips32_op = OPC_NEG_S;
10144
        goto do_unaryfp;
10145
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10146
        mips32_op = OPC_NEG_D;
10147
        goto do_unaryfp;
10148
    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10149
        mips32_op = OPC_NEG_PS;
10150
        goto do_unaryfp;
10151

    
10152
        /* Reciprocal square root step */
10153
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10154
        mips32_op = OPC_RSQRT1_S;
10155
        goto do_unaryfp;
10156
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10157
        mips32_op = OPC_RSQRT1_D;
10158
        goto do_unaryfp;
10159
    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10160
        mips32_op = OPC_RSQRT1_PS;
10161
        goto do_unaryfp;
10162

    
10163
        /* Reciprocal step */
10164
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10165
        mips32_op = OPC_RECIP1_S;
10166
        goto do_unaryfp;
10167
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10168
        mips32_op = OPC_RECIP1_S;
10169
        goto do_unaryfp;
10170
    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10171
        mips32_op = OPC_RECIP1_PS;
10172
        goto do_unaryfp;
10173

    
10174
        /* Conversions from double */
10175
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10176
        mips32_op = OPC_CVT_D_S;
10177
        goto do_unaryfp;
10178
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10179
        mips32_op = OPC_CVT_D_W;
10180
        goto do_unaryfp;
10181
    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10182
        mips32_op = OPC_CVT_D_L;
10183
        goto do_unaryfp;
10184

    
10185
        /* Conversions from single */
10186
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10187
        mips32_op = OPC_CVT_S_D;
10188
        goto do_unaryfp;
10189
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10190
        mips32_op = OPC_CVT_S_W;
10191
        goto do_unaryfp;
10192
    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10193
        mips32_op = OPC_CVT_S_L;
10194
    do_unaryfp:
10195
        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10196
        break;
10197

    
10198
        /* Conditional moves on floating-point codes */
10199
    case COND_FLOAT_MOV(MOVT, 0):
10200
    case COND_FLOAT_MOV(MOVT, 1):
10201
    case COND_FLOAT_MOV(MOVT, 2):
10202
    case COND_FLOAT_MOV(MOVT, 3):
10203
    case COND_FLOAT_MOV(MOVT, 4):
10204
    case COND_FLOAT_MOV(MOVT, 5):
10205
    case COND_FLOAT_MOV(MOVT, 6):
10206
    case COND_FLOAT_MOV(MOVT, 7):
10207
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10208
        break;
10209
    case COND_FLOAT_MOV(MOVF, 0):
10210
    case COND_FLOAT_MOV(MOVF, 1):
10211
    case COND_FLOAT_MOV(MOVF, 2):
10212
    case COND_FLOAT_MOV(MOVF, 3):
10213
    case COND_FLOAT_MOV(MOVF, 4):
10214
    case COND_FLOAT_MOV(MOVF, 5):
10215
    case COND_FLOAT_MOV(MOVF, 6):
10216
    case COND_FLOAT_MOV(MOVF, 7):
10217
        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10218
        break;
10219
    default:
10220
        MIPS_INVAL("pool32fxf");
10221
        generate_exception(ctx, EXCP_RI);
10222
        break;
10223
    }
10224
}
10225

    
10226
static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10227
                                    uint16_t insn_hw1, int *is_branch)
10228
{
10229
    int32_t offset;
10230
    uint16_t insn;
10231
    int rt, rs, rd, rr;
10232
    int16_t imm;
10233
    uint32_t op, minor, mips32_op;
10234
    uint32_t cond, fmt, cc;
10235

    
10236
    insn = lduw_code(ctx->pc + 2);
10237
    ctx->opcode = (ctx->opcode << 16) | insn;
10238

    
10239
    rt = (ctx->opcode >> 21) & 0x1f;
10240
    rs = (ctx->opcode >> 16) & 0x1f;
10241
    rd = (ctx->opcode >> 11) & 0x1f;
10242
    rr = (ctx->opcode >> 6) & 0x1f;
10243
    imm = (int16_t) ctx->opcode;
10244

    
10245
    op = (ctx->opcode >> 26) & 0x3f;
10246
    switch (op) {
10247
    case POOL32A:
10248
        minor = ctx->opcode & 0x3f;
10249
        switch (minor) {
10250
        case 0x00:
10251
            minor = (ctx->opcode >> 6) & 0xf;
10252
            switch (minor) {
10253
            case SLL32:
10254
                mips32_op = OPC_SLL;
10255
                goto do_shifti;
10256
            case SRA:
10257
                mips32_op = OPC_SRA;
10258
                goto do_shifti;
10259
            case SRL32:
10260
                mips32_op = OPC_SRL;
10261
                goto do_shifti;
10262
            case ROTR:
10263
                mips32_op = OPC_ROTR;
10264
            do_shifti:
10265
                gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10266
                break;
10267
            default:
10268
                goto pool32a_invalid;
10269
            }
10270
            break;
10271
        case 0x10:
10272
            minor = (ctx->opcode >> 6) & 0xf;
10273
            switch (minor) {
10274
                /* Arithmetic */
10275
            case ADD:
10276
                mips32_op = OPC_ADD;
10277
                goto do_arith;
10278
            case ADDU32:
10279
                mips32_op = OPC_ADDU;
10280
                goto do_arith;
10281
            case SUB:
10282
                mips32_op = OPC_SUB;
10283
                goto do_arith;
10284
            case SUBU32:
10285
                mips32_op = OPC_SUBU;
10286
                goto do_arith;
10287
            case MUL:
10288
                mips32_op = OPC_MUL;
10289
            do_arith:
10290
                gen_arith(env, ctx, mips32_op, rd, rs, rt);
10291
                break;
10292
                /* Shifts */
10293
            case SLLV:
10294
                mips32_op = OPC_SLLV;
10295
                goto do_shift;
10296
            case SRLV:
10297
                mips32_op = OPC_SRLV;
10298
                goto do_shift;
10299
            case SRAV:
10300
                mips32_op = OPC_SRAV;
10301
                goto do_shift;
10302
            case ROTRV:
10303
                mips32_op = OPC_ROTRV;
10304
            do_shift:
10305
                gen_shift(env, ctx, mips32_op, rd, rs, rt);
10306
                break;
10307
                /* Logical operations */
10308
            case AND:
10309
                mips32_op = OPC_AND;
10310
                goto do_logic;
10311
            case OR32:
10312
                mips32_op = OPC_OR;
10313
                goto do_logic;
10314
            case NOR:
10315
                mips32_op = OPC_NOR;
10316
                goto do_logic;
10317
            case XOR32:
10318
                mips32_op = OPC_XOR;
10319
            do_logic:
10320
                gen_logic(env, mips32_op, rd, rs, rt);
10321
                break;
10322
                /* Set less than */
10323
            case SLT:
10324
                mips32_op = OPC_SLT;
10325
                goto do_slt;
10326
            case SLTU:
10327
                mips32_op = OPC_SLTU;
10328
            do_slt:
10329
                gen_slt(env, mips32_op, rd, rs, rt);
10330
                break;
10331
            default:
10332
                goto pool32a_invalid;
10333
            }
10334
            break;
10335
        case 0x18:
10336
            minor = (ctx->opcode >> 6) & 0xf;
10337
            switch (minor) {
10338
                /* Conditional moves */
10339
            case MOVN:
10340
                mips32_op = OPC_MOVN;
10341
                goto do_cmov;
10342
            case MOVZ:
10343
                mips32_op = OPC_MOVZ;
10344
            do_cmov:
10345
                gen_cond_move(env, mips32_op, rd, rs, rt);
10346
                break;
10347
            case LWXS:
10348
                gen_ldxs(ctx, rs, rt, rd);
10349
                break;
10350
            default:
10351
                goto pool32a_invalid;
10352
            }
10353
            break;
10354
        case INS:
10355
            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10356
            return;
10357
        case EXT:
10358
            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10359
            return;
10360
        case POOL32AXF:
10361
            gen_pool32axf(env, ctx, rt, rs, is_branch);
10362
            break;
10363
        case 0x07:
10364
            generate_exception(ctx, EXCP_BREAK);
10365
            break;
10366
        default:
10367
        pool32a_invalid:
10368
                MIPS_INVAL("pool32a");
10369
                generate_exception(ctx, EXCP_RI);
10370
                break;
10371
        }
10372
        break;
10373
    case POOL32B:
10374
        minor = (ctx->opcode >> 12) & 0xf;
10375
        switch (minor) {
10376
        case CACHE:
10377
            /* Treat as no-op. */
10378
            break;
10379
        case LWC2:
10380
        case SWC2:
10381
            /* COP2: Not implemented. */
10382
            generate_exception_err(ctx, EXCP_CpU, 2);
10383
            break;
10384
        case LWP:
10385
        case SWP:
10386
#ifdef TARGET_MIPS64
10387
        case LDP:
10388
        case SDP:
10389
#endif
10390
            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10391
            break;
10392
        case LWM32:
10393
        case SWM32:
10394
#ifdef TARGET_MIPS64
10395
        case LDM:
10396
        case SDM:
10397
#endif
10398
            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10399
            break;
10400
        default:
10401
            MIPS_INVAL("pool32b");
10402
            generate_exception(ctx, EXCP_RI);
10403
            break;
10404
        }
10405
        break;
10406
    case POOL32F:
10407
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10408
            minor = ctx->opcode & 0x3f;
10409
            check_cp1_enabled(ctx);
10410
            switch (minor) {
10411
            case ALNV_PS:
10412
                mips32_op = OPC_ALNV_PS;
10413
                goto do_madd;
10414
            case MADD_S:
10415
                mips32_op = OPC_MADD_S;
10416
                goto do_madd;
10417
            case MADD_D:
10418
                mips32_op = OPC_MADD_D;
10419
                goto do_madd;
10420
            case MADD_PS:
10421
                mips32_op = OPC_MADD_PS;
10422
                goto do_madd;
10423
            case MSUB_S:
10424
                mips32_op = OPC_MSUB_S;
10425
                goto do_madd;
10426
            case MSUB_D:
10427
                mips32_op = OPC_MSUB_D;
10428
                goto do_madd;
10429
            case MSUB_PS:
10430
                mips32_op = OPC_MSUB_PS;
10431
                goto do_madd;
10432
            case NMADD_S:
10433
                mips32_op = OPC_NMADD_S;
10434
                goto do_madd;
10435
            case NMADD_D:
10436
                mips32_op = OPC_NMADD_D;
10437
                goto do_madd;
10438
            case NMADD_PS:
10439
                mips32_op = OPC_NMADD_PS;
10440
                goto do_madd;
10441
            case NMSUB_S:
10442
                mips32_op = OPC_NMSUB_S;
10443
                goto do_madd;
10444
            case NMSUB_D:
10445
                mips32_op = OPC_NMSUB_D;
10446
                goto do_madd;
10447
            case NMSUB_PS:
10448
                mips32_op = OPC_NMSUB_PS;
10449
            do_madd:
10450
                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10451
                break;
10452
            case CABS_COND_FMT:
10453
                cond = (ctx->opcode >> 6) & 0xf;
10454
                cc = (ctx->opcode >> 13) & 0x7;
10455
                fmt = (ctx->opcode >> 10) & 0x3;
10456
                switch (fmt) {
10457
                case 0x0:
10458
                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
10459
                    break;
10460
                case 0x1:
10461
                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
10462
                    break;
10463
                case 0x2:
10464
                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10465
                    break;
10466
                default:
10467
                    goto pool32f_invalid;
10468
                }
10469
                break;
10470
            case C_COND_FMT:
10471
                cond = (ctx->opcode >> 6) & 0xf;
10472
                cc = (ctx->opcode >> 13) & 0x7;
10473
                fmt = (ctx->opcode >> 10) & 0x3;
10474
                switch (fmt) {
10475
                case 0x0:
10476
                    gen_cmp_s(ctx, cond, rt, rs, cc);
10477
                    break;
10478
                case 0x1:
10479
                    gen_cmp_d(ctx, cond, rt, rs, cc);
10480
                    break;
10481
                case 0x2:
10482
                    gen_cmp_ps(ctx, cond, rt, rs, cc);
10483
                    break;
10484
                default:
10485
                    goto pool32f_invalid;
10486
                }
10487
                break;
10488
            case POOL32FXF:
10489
                gen_pool32fxf(env, ctx, rt, rs);
10490
                break;
10491
            case 0x00:
10492
                /* PLL foo */
10493
                switch ((ctx->opcode >> 6) & 0x7) {
10494
                case PLL_PS:
10495
                    mips32_op = OPC_PLL_PS;
10496
                    goto do_ps;
10497
                case PLU_PS:
10498
                    mips32_op = OPC_PLU_PS;
10499
                    goto do_ps;
10500
                case PUL_PS:
10501
                    mips32_op = OPC_PUL_PS;
10502
                    goto do_ps;
10503
                case PUU_PS:
10504
                    mips32_op = OPC_PUU_PS;
10505
                    goto do_ps;
10506
                case CVT_PS_S:
10507
                    mips32_op = OPC_CVT_PS_S;
10508
                do_ps:
10509
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10510
                    break;
10511
                default:
10512
                    goto pool32f_invalid;
10513
                }
10514
                break;
10515
            case 0x08:
10516
                /* [LS][WDU]XC1 */
10517
                switch ((ctx->opcode >> 6) & 0x7) {
10518
                case LWXC1:
10519
                    mips32_op = OPC_LWXC1;
10520
                    goto do_ldst_cp1;
10521
                case SWXC1:
10522
                    mips32_op = OPC_SWXC1;
10523
                    goto do_ldst_cp1;
10524
                case LDXC1:
10525
                    mips32_op = OPC_LDXC1;
10526
                    goto do_ldst_cp1;
10527
                case SDXC1:
10528
                    mips32_op = OPC_SDXC1;
10529
                    goto do_ldst_cp1;
10530
                case LUXC1:
10531
                    mips32_op = OPC_LUXC1;
10532
                    goto do_ldst_cp1;
10533
                case SUXC1:
10534
                    mips32_op = OPC_SUXC1;
10535
                do_ldst_cp1:
10536
                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10537
                    break;
10538
                default:
10539
                    goto pool32f_invalid;
10540
                }
10541
                break;
10542
            case 0x18:
10543
                /* 3D insns */
10544
                fmt = (ctx->opcode >> 9) & 0x3;
10545
                switch ((ctx->opcode >> 6) & 0x7) {
10546
                case RSQRT2_FMT:
10547
                    switch (fmt) {
10548
                    case FMT_SDPS_S:
10549
                        mips32_op = OPC_RSQRT2_S;
10550
                        goto do_3d;
10551
                    case FMT_SDPS_D:
10552
                        mips32_op = OPC_RSQRT2_D;
10553
                        goto do_3d;
10554
                    case FMT_SDPS_PS:
10555
                        mips32_op = OPC_RSQRT2_PS;
10556
                        goto do_3d;
10557
                    default:
10558
                        goto pool32f_invalid;
10559
                    }
10560
                    break;
10561
                case RECIP2_FMT:
10562
                    switch (fmt) {
10563
                    case FMT_SDPS_S:
10564
                        mips32_op = OPC_RECIP2_S;
10565
                        goto do_3d;
10566
                    case FMT_SDPS_D:
10567
                        mips32_op = OPC_RECIP2_D;
10568
                        goto do_3d;
10569
                    case FMT_SDPS_PS:
10570
                        mips32_op = OPC_RECIP2_PS;
10571
                        goto do_3d;
10572
                    default:
10573
                        goto pool32f_invalid;
10574
                    }
10575
                    break;
10576
                case ADDR_PS:
10577
                    mips32_op = OPC_ADDR_PS;
10578
                    goto do_3d;
10579
                case MULR_PS:
10580
                    mips32_op = OPC_MULR_PS;
10581
                do_3d:
10582
                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10583
                    break;
10584
                default:
10585
                    goto pool32f_invalid;
10586
                }
10587
                break;
10588
            case 0x20:
10589
                /* MOV[FT].fmt and PREFX */
10590
                cc = (ctx->opcode >> 13) & 0x7;
10591
                fmt = (ctx->opcode >> 9) & 0x3;
10592
                switch ((ctx->opcode >> 6) & 0x7) {
10593
                case MOVF_FMT:
10594
                    switch (fmt) {
10595
                    case FMT_SDPS_S:
10596
                        gen_movcf_s(rs, rt, cc, 0);
10597
                        break;
10598
                    case FMT_SDPS_D:
10599
                        gen_movcf_d(ctx, rs, rt, cc, 0);
10600
                        break;
10601
                    case FMT_SDPS_PS:
10602
                        gen_movcf_ps(rs, rt, cc, 0);
10603
                        break;
10604
                    default:
10605
                        goto pool32f_invalid;
10606
                    }
10607
                    break;
10608
                case MOVT_FMT:
10609
                    switch (fmt) {
10610
                    case FMT_SDPS_S:
10611
                        gen_movcf_s(rs, rt, cc, 1);
10612
                        break;
10613
                    case FMT_SDPS_D:
10614
                        gen_movcf_d(ctx, rs, rt, cc, 1);
10615
                        break;
10616
                    case FMT_SDPS_PS:
10617
                        gen_movcf_ps(rs, rt, cc, 1);
10618
                        break;
10619
                    default:
10620
                        goto pool32f_invalid;
10621
                    }
10622
                    break;
10623
                case PREFX:
10624
                    break;
10625
                default:
10626
                    goto pool32f_invalid;
10627
                }
10628
                break;
10629
#define FINSN_3ARG_SDPS(prfx)                           \
10630
                switch ((ctx->opcode >> 8) & 0x3) {     \
10631
                case FMT_SDPS_S:                        \
10632
                    mips32_op = OPC_##prfx##_S;         \
10633
                    goto do_fpop;                       \
10634
                case FMT_SDPS_D:                        \
10635
                    mips32_op = OPC_##prfx##_D;         \
10636
                    goto do_fpop;                       \
10637
                case FMT_SDPS_PS:                       \
10638
                    mips32_op = OPC_##prfx##_PS;        \
10639
                    goto do_fpop;                       \
10640
                default:                                \
10641
                    goto pool32f_invalid;               \
10642
                }
10643
            case 0x30:
10644
                /* regular FP ops */
10645
                switch ((ctx->opcode >> 6) & 0x3) {
10646
                case ADD_FMT:
10647
                    FINSN_3ARG_SDPS(ADD);
10648
                    break;
10649
                case SUB_FMT:
10650
                    FINSN_3ARG_SDPS(SUB);
10651
                    break;
10652
                case MUL_FMT:
10653
                    FINSN_3ARG_SDPS(MUL);
10654
                    break;
10655
                case DIV_FMT:
10656
                    fmt = (ctx->opcode >> 8) & 0x3;
10657
                    if (fmt == 1) {
10658
                        mips32_op = OPC_DIV_D;
10659
                    } else if (fmt == 0) {
10660
                        mips32_op = OPC_DIV_S;
10661
                    } else {
10662
                        goto pool32f_invalid;
10663
                    }
10664
                    goto do_fpop;
10665
                default:
10666
                    goto pool32f_invalid;
10667
                }
10668
                break;
10669
            case 0x38:
10670
                /* cmovs */
10671
                switch ((ctx->opcode >> 6) & 0x3) {
10672
                case MOVN_FMT:
10673
                    FINSN_3ARG_SDPS(MOVN);
10674
                    break;
10675
                case MOVZ_FMT:
10676
                    FINSN_3ARG_SDPS(MOVZ);
10677
                    break;
10678
                default:
10679
                    goto pool32f_invalid;
10680
                }
10681
                break;
10682
            do_fpop:
10683
                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10684
                break;
10685
            default:
10686
            pool32f_invalid:
10687
                MIPS_INVAL("pool32f");
10688
                generate_exception(ctx, EXCP_RI);
10689
                break;
10690
            }
10691
        } else {
10692
            generate_exception_err(ctx, EXCP_CpU, 1);
10693
        }
10694
        break;
10695
    case POOL32I:
10696
        minor = (ctx->opcode >> 21) & 0x1f;
10697
        switch (minor) {
10698
        case BLTZ:
10699
            mips32_op = OPC_BLTZ;
10700
            goto do_branch;
10701
        case BLTZAL:
10702
            mips32_op = OPC_BLTZAL;
10703
            goto do_branch;
10704
        case BLTZALS:
10705
            mips32_op = OPC_BLTZALS;
10706
            goto do_branch;
10707
        case BGEZ:
10708
            mips32_op = OPC_BGEZ;
10709
            goto do_branch;
10710
        case BGEZAL:
10711
            mips32_op = OPC_BGEZAL;
10712
            goto do_branch;
10713
        case BGEZALS:
10714
            mips32_op = OPC_BGEZALS;
10715
            goto do_branch;
10716
        case BLEZ:
10717
            mips32_op = OPC_BLEZ;
10718
            goto do_branch;
10719
        case BGTZ:
10720
            mips32_op = OPC_BGTZ;
10721
        do_branch:
10722
            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
10723
            *is_branch = 1;
10724
            break;
10725

    
10726
            /* Traps */
10727
        case TLTI:
10728
            mips32_op = OPC_TLTI;
10729
            goto do_trapi;
10730
        case TGEI:
10731
            mips32_op = OPC_TGEI;
10732
            goto do_trapi;
10733
        case TLTIU:
10734
            mips32_op = OPC_TLTIU;
10735
            goto do_trapi;
10736
        case TGEIU:
10737
            mips32_op = OPC_TGEIU;
10738
            goto do_trapi;
10739
        case TNEI:
10740
            mips32_op = OPC_TNEI;
10741
            goto do_trapi;
10742
        case TEQI:
10743
            mips32_op = OPC_TEQI;
10744
        do_trapi:
10745
            gen_trap(ctx, mips32_op, rs, -1, imm);
10746
            break;
10747

    
10748
        case BNEZC:
10749
        case BEQZC:
10750
            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
10751
                               4, rs, 0, imm << 1);
10752
            /* Compact branches don't have a delay slot, so just let
10753
               the normal delay slot handling take us to the branch
10754
               target. */
10755
            break;
10756
        case LUI:
10757
            gen_logic_imm(env, OPC_LUI, rs, -1, imm);
10758
            break;
10759
        case SYNCI:
10760
            break;
10761
        case BC2F:
10762
        case BC2T:
10763
            /* COP2: Not implemented. */
10764
            generate_exception_err(ctx, EXCP_CpU, 2);
10765
            break;
10766
        case BC1F:
10767
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
10768
            goto do_cp1branch;
10769
        case BC1T:
10770
            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
10771
            goto do_cp1branch;
10772
        case BC1ANY4F:
10773
            mips32_op = OPC_BC1FANY4;
10774
            goto do_cp1mips3d;
10775
        case BC1ANY4T:
10776
            mips32_op = OPC_BC1TANY4;
10777
        do_cp1mips3d:
10778
            check_cop1x(ctx);
10779
            check_insn(env, ctx, ASE_MIPS3D);
10780
            /* Fall through */
10781
        do_cp1branch:
10782
            gen_compute_branch1(env, ctx, mips32_op,
10783
                                (ctx->opcode >> 18) & 0x7, imm << 1);
10784
            *is_branch = 1;
10785
            break;
10786
        case BPOSGE64:
10787
        case BPOSGE32:
10788
            /* MIPS DSP: not implemented */
10789
            /* Fall through */
10790
        default:
10791
            MIPS_INVAL("pool32i");
10792
            generate_exception(ctx, EXCP_RI);
10793
            break;
10794
        }
10795
        break;
10796
    case POOL32C:
10797
        minor = (ctx->opcode >> 12) & 0xf;
10798
        switch (minor) {
10799
        case LWL:
10800
            mips32_op = OPC_LWL;
10801
            goto do_ldst_lr;
10802
        case SWL:
10803
            mips32_op = OPC_SWL;
10804
            goto do_ldst_lr;
10805
        case LWR:
10806
            mips32_op = OPC_LWR;
10807
            goto do_ldst_lr;
10808
        case SWR:
10809
            mips32_op = OPC_SWR;
10810
            goto do_ldst_lr;
10811
#if defined(TARGET_MIPS64)
10812
        case LDL:
10813
            mips32_op = OPC_LDL;
10814
            goto do_ldst_lr;
10815
        case SDL:
10816
            mips32_op = OPC_SDL;
10817
            goto do_ldst_lr;
10818
        case LDR:
10819
            mips32_op = OPC_LDR;
10820
            goto do_ldst_lr;
10821
        case SDR:
10822
            mips32_op = OPC_SDR;
10823
            goto do_ldst_lr;
10824
        case LWU:
10825
            mips32_op = OPC_LWU;
10826
            goto do_ldst_lr;
10827
        case LLD:
10828
            mips32_op = OPC_LLD;
10829
            goto do_ldst_lr;
10830
#endif
10831
        case LL:
10832
            mips32_op = OPC_LL;
10833
        do_ldst_lr:
10834
            gen_ldst(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
10835
            break;
10836
        case SC:
10837
            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
10838
            break;
10839
#if defined(TARGET_MIPS64)
10840
        case SCD:
10841
            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
10842
            break;
10843
#endif
10844
        case PREF:
10845
            /* Treat as no-op */
10846
            break;
10847
        default:
10848
            MIPS_INVAL("pool32c");
10849
            generate_exception(ctx, EXCP_RI);
10850
            break;
10851
        }
10852
        break;
10853
    case ADDI32:
10854
        mips32_op = OPC_ADDI;
10855
        goto do_addi;
10856
    case ADDIU32:
10857
        mips32_op = OPC_ADDIU;
10858
    do_addi:
10859
        gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
10860
        break;
10861

    
10862
        /* Logical operations */
10863
    case ORI32:
10864
        mips32_op = OPC_ORI;
10865
        goto do_logici;
10866
    case XORI32:
10867
        mips32_op = OPC_XORI;
10868
        goto do_logici;
10869
    case ANDI32:
10870
        mips32_op = OPC_ANDI;
10871
    do_logici:
10872
        gen_logic_imm(env, mips32_op, rt, rs, imm);
10873
        break;
10874

    
10875
        /* Set less than immediate */
10876
    case SLTI32:
10877
        mips32_op = OPC_SLTI;
10878
        goto do_slti;
10879
    case SLTIU32:
10880
        mips32_op = OPC_SLTIU;
10881
    do_slti:
10882
        gen_slt_imm(env, mips32_op, rt, rs, imm);
10883
        break;
10884
    case JALX32:
10885
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
10886
        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
10887
        *is_branch = 1;
10888
        break;
10889
    case JALS32:
10890
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
10891
        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
10892
        *is_branch = 1;
10893
        break;
10894
    case BEQ32:
10895
        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
10896
        *is_branch = 1;
10897
        break;
10898
    case BNE32:
10899
        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
10900
        *is_branch = 1;
10901
        break;
10902
    case J32:
10903
        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
10904
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
10905
        *is_branch = 1;
10906
        break;
10907
    case JAL32:
10908
        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
10909
                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
10910
        *is_branch = 1;
10911
        break;
10912
        /* Floating point (COP1) */
10913
    case LWC132:
10914
        mips32_op = OPC_LWC1;
10915
        goto do_cop1;
10916
    case LDC132:
10917
        mips32_op = OPC_LDC1;
10918
        goto do_cop1;
10919
    case SWC132:
10920
        mips32_op = OPC_SWC1;
10921
        goto do_cop1;
10922
    case SDC132:
10923
        mips32_op = OPC_SDC1;
10924
    do_cop1:
10925
        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
10926
        break;
10927
    case ADDIUPC:
10928
        {
10929
            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
10930
            int offset = SIMM(ctx->opcode, 0, 23) << 2;
10931

    
10932
            gen_addiupc(ctx, reg, offset, 0, 0);
10933
        }
10934
        break;
10935
        /* Loads and stores */
10936
    case LB32:
10937
        mips32_op = OPC_LB;
10938
        goto do_ldst;
10939
    case LBU32:
10940
        mips32_op = OPC_LBU;
10941
        goto do_ldst;
10942
    case LH32:
10943
        mips32_op = OPC_LH;
10944
        goto do_ldst;
10945
    case LHU32:
10946
        mips32_op = OPC_LHU;
10947
        goto do_ldst;
10948
    case LW32:
10949
        mips32_op = OPC_LW;
10950
        goto do_ldst;
10951
#ifdef TARGET_MIPS64
10952
    case LD32:
10953
        mips32_op = OPC_LD;
10954
        goto do_ldst;
10955
    case SD32:
10956
        mips32_op = OPC_SD;
10957
        goto do_ldst;
10958
#endif
10959
    case SB32:
10960
        mips32_op = OPC_SB;
10961
        goto do_ldst;
10962
    case SH32:
10963
        mips32_op = OPC_SH;
10964
        goto do_ldst;
10965
    case SW32:
10966
        mips32_op = OPC_SW;
10967
    do_ldst:
10968
        gen_ldst(ctx, mips32_op, rt, rs, imm);
10969
        break;
10970
    default:
10971
        generate_exception(ctx, EXCP_RI);
10972
        break;
10973
    }
10974
}
10975

    
10976
static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
10977
{
10978
    uint32_t op;
10979

    
10980
    /* make sure instructions are on a halfword boundary */
10981
    if (ctx->pc & 0x1) {
10982
        env->CP0_BadVAddr = ctx->pc;
10983
        generate_exception(ctx, EXCP_AdEL);
10984
        ctx->bstate = BS_STOP;
10985
        return 2;
10986
    }
10987

    
10988
    op = (ctx->opcode >> 10) & 0x3f;
10989
    /* Enforce properly-sized instructions in a delay slot */
10990
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10991
        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
10992

    
10993
        switch (op) {
10994
        case POOL32A:
10995
        case POOL32B:
10996
        case POOL32I:
10997
        case POOL32C:
10998
        case ADDI32:
10999
        case ADDIU32:
11000
        case ORI32:
11001
        case XORI32:
11002
        case SLTI32:
11003
        case SLTIU32:
11004
        case ANDI32:
11005
        case JALX32:
11006
        case LBU32:
11007
        case LHU32:
11008
        case POOL32F:
11009
        case JALS32:
11010
        case BEQ32:
11011
        case BNE32:
11012
        case J32:
11013
        case JAL32:
11014
        case SB32:
11015
        case SH32:
11016
        case POOL32S:
11017
        case ADDIUPC:
11018
        case SWC132:
11019
        case SDC132:
11020
        case SD32:
11021
        case SW32:
11022
        case LB32:
11023
        case LH32:
11024
        case DADDIU32:
11025
        case POOL48A:           /* ??? */
11026
        case LWC132:
11027
        case LDC132:
11028
        case LD32:
11029
        case LW32:
11030
            if (bits & MIPS_HFLAG_BDS16) {
11031
                generate_exception(ctx, EXCP_RI);
11032
                /* Just stop translation; the user is confused.  */
11033
                ctx->bstate = BS_STOP;
11034
                return 2;
11035
            }
11036
            break;
11037
        case POOL16A:
11038
        case POOL16B:
11039
        case POOL16C:
11040
        case LWGP16:
11041
        case POOL16F:
11042
        case LBU16:
11043
        case LHU16:
11044
        case LWSP16:
11045
        case LW16:
11046
        case SB16:
11047
        case SH16:
11048
        case SWSP16:
11049
        case SW16:
11050
        case MOVE16:
11051
        case ANDI16:
11052
        case POOL16D:
11053
        case POOL16E:
11054
        case BEQZ16:
11055
        case BNEZ16:
11056
        case B16:
11057
        case LI16:
11058
            if (bits & MIPS_HFLAG_BDS32) {
11059
                generate_exception(ctx, EXCP_RI);
11060
                /* Just stop translation; the user is confused.  */
11061
                ctx->bstate = BS_STOP;
11062
                return 2;
11063
            }
11064
            break;
11065
        default:
11066
            break;
11067
        }
11068
    }
11069
    switch (op) {
11070
    case POOL16A:
11071
        {
11072
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11073
            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11074
            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11075
            uint32_t opc = 0;
11076

    
11077
            switch (ctx->opcode & 0x1) {
11078
            case ADDU16:
11079
                opc = OPC_ADDU;
11080
                break;
11081
            case SUBU16:
11082
                opc = OPC_SUBU;
11083
                break;
11084
            }
11085

    
11086
            gen_arith(env, ctx, opc, rd, rs1, rs2);
11087
        }
11088
        break;
11089
    case POOL16B:
11090
        {
11091
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11092
            int rs = mmreg(uMIPS_RS(ctx->opcode));
11093
            int amount = (ctx->opcode >> 1) & 0x7;
11094
            uint32_t opc = 0;
11095
            amount = amount == 0 ? 8 : amount;
11096

    
11097
            switch (ctx->opcode & 0x1) {
11098
            case SLL16:
11099
                opc = OPC_SLL;
11100
                break;
11101
            case SRL16:
11102
                opc = OPC_SRL;
11103
                break;
11104
            }
11105

    
11106
            gen_shift_imm(env, ctx, opc, rd, rs, amount);
11107
        }
11108
        break;
11109
    case POOL16C:
11110
        gen_pool16c_insn(env, ctx, is_branch);
11111
        break;
11112
    case LWGP16:
11113
        {
11114
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11115
            int rb = 28;            /* GP */
11116
            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11117

    
11118
            gen_ldst(ctx, OPC_LW, rd, rb, offset);
11119
        }
11120
        break;
11121
    case POOL16F:
11122
        if (ctx->opcode & 1) {
11123
            generate_exception(ctx, EXCP_RI);
11124
        } else {
11125
            /* MOVEP */
11126
            int enc_dest = uMIPS_RD(ctx->opcode);
11127
            int enc_rt = uMIPS_RS2(ctx->opcode);
11128
            int enc_rs = uMIPS_RS1(ctx->opcode);
11129
            int rd, rs, re, rt;
11130
            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11131
            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11132
            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11133

    
11134
            rd = rd_enc[enc_dest];
11135
            re = re_enc[enc_dest];
11136
            rs = rs_rt_enc[enc_rs];
11137
            rt = rs_rt_enc[enc_rt];
11138

    
11139
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11140
            gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11141
        }
11142
        break;
11143
    case LBU16:
11144
        {
11145
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11146
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11147
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11148
            offset = (offset == 0xf ? -1 : offset);
11149

    
11150
            gen_ldst(ctx, OPC_LBU, rd, rb, offset);
11151
        }
11152
        break;
11153
    case LHU16:
11154
        {
11155
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11156
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11157
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11158

    
11159
            gen_ldst(ctx, OPC_LHU, rd, rb, offset);
11160
        }
11161
        break;
11162
    case LWSP16:
11163
        {
11164
            int rd = (ctx->opcode >> 5) & 0x1f;
11165
            int rb = 29;            /* SP */
11166
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11167

    
11168
            gen_ldst(ctx, OPC_LW, rd, rb, offset);
11169
        }
11170
        break;
11171
    case LW16:
11172
        {
11173
            int rd = mmreg(uMIPS_RD(ctx->opcode));
11174
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11175
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11176

    
11177
            gen_ldst(ctx, OPC_LW, rd, rb, offset);
11178
        }
11179
        break;
11180
    case SB16:
11181
        {
11182
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11183
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11184
            int16_t offset = ZIMM(ctx->opcode, 0, 4);
11185

    
11186
            gen_ldst(ctx, OPC_SB, rd, rb, offset);
11187
        }
11188
        break;
11189
    case SH16:
11190
        {
11191
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11192
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11193
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11194

    
11195
            gen_ldst(ctx, OPC_SH, rd, rb, offset);
11196
        }
11197
        break;
11198
    case SWSP16:
11199
        {
11200
            int rd = (ctx->opcode >> 5) & 0x1f;
11201
            int rb = 29;            /* SP */
11202
            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11203

    
11204
            gen_ldst(ctx, OPC_SW, rd, rb, offset);
11205
        }
11206
        break;
11207
    case SW16:
11208
        {
11209
            int rd = mmreg2(uMIPS_RD(ctx->opcode));
11210
            int rb = mmreg(uMIPS_RS(ctx->opcode));
11211
            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11212

    
11213
            gen_ldst(ctx, OPC_SW, rd, rb, offset);
11214
        }
11215
        break;
11216
    case MOVE16:
11217
        {
11218
            int rd = uMIPS_RD5(ctx->opcode);
11219
            int rs = uMIPS_RS5(ctx->opcode);
11220

    
11221
            gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11222
        }
11223
        break;
11224
    case ANDI16:
11225
        gen_andi16(env, ctx);
11226
        break;
11227
    case POOL16D:
11228
        switch (ctx->opcode & 0x1) {
11229
        case ADDIUS5:
11230
            gen_addius5(env, ctx);
11231
            break;
11232
        case ADDIUSP:
11233
            gen_addiusp(env, ctx);
11234
            break;
11235
        }
11236
        break;
11237
    case POOL16E:
11238
        switch (ctx->opcode & 0x1) {
11239
        case ADDIUR2:
11240
            gen_addiur2(env, ctx);
11241
            break;
11242
        case ADDIUR1SP:
11243
            gen_addiur1sp(env, ctx);
11244
            break;
11245
        }
11246
        break;
11247
    case B16:
11248
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11249
                           SIMM(ctx->opcode, 0, 10) << 1);
11250
        *is_branch = 1;
11251
        break;
11252
    case BNEZ16:
11253
    case BEQZ16:
11254
        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11255
                           mmreg(uMIPS_RD(ctx->opcode)),
11256
                           0, SIMM(ctx->opcode, 0, 7) << 1);
11257
        *is_branch = 1;
11258
        break;
11259
    case LI16:
11260
        {
11261
            int reg = mmreg(uMIPS_RD(ctx->opcode));
11262
            int imm = ZIMM(ctx->opcode, 0, 7);
11263

    
11264
            imm = (imm == 0x7f ? -1 : imm);
11265
            tcg_gen_movi_tl(cpu_gpr[reg], imm);
11266
        }
11267
        break;
11268
    case RES_20:
11269
    case RES_28:
11270
    case RES_29:
11271
    case RES_30:
11272
    case RES_31:
11273
    case RES_38:
11274
    case RES_39:
11275
        generate_exception(ctx, EXCP_RI);
11276
        break;
11277
    default:
11278
        decode_micromips32_opc (env, ctx, op, is_branch);
11279
        return 4;
11280
    }
11281

    
11282
    return 2;
11283
}
11284

    
11285
/* SmartMIPS extension to MIPS32 */
11286

    
11287
#if defined(TARGET_MIPS64)
11288

    
11289
/* MDMX extension to MIPS64 */
11290

    
11291
#endif
11292

    
11293
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11294
{
11295
    int32_t offset;
11296
    int rs, rt, rd, sa;
11297
    uint32_t op, op1, op2;
11298
    int16_t imm;
11299

    
11300
    /* make sure instructions are on a word boundary */
11301
    if (ctx->pc & 0x3) {
11302
        env->CP0_BadVAddr = ctx->pc;
11303
        generate_exception(ctx, EXCP_AdEL);
11304
        return;
11305
    }
11306

    
11307
    /* Handle blikely not taken case */
11308
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11309
        int l1 = gen_new_label();
11310

    
11311
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11312
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11313
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11314
        gen_goto_tb(ctx, 1, ctx->pc + 4);
11315
        gen_set_label(l1);
11316
    }
11317

    
11318
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11319
        tcg_gen_debug_insn_start(ctx->pc);
11320

    
11321
    op = MASK_OP_MAJOR(ctx->opcode);
11322
    rs = (ctx->opcode >> 21) & 0x1f;
11323
    rt = (ctx->opcode >> 16) & 0x1f;
11324
    rd = (ctx->opcode >> 11) & 0x1f;
11325
    sa = (ctx->opcode >> 6) & 0x1f;
11326
    imm = (int16_t)ctx->opcode;
11327
    switch (op) {
11328
    case OPC_SPECIAL:
11329
        op1 = MASK_SPECIAL(ctx->opcode);
11330
        switch (op1) {
11331
        case OPC_SLL:          /* Shift with immediate */
11332
        case OPC_SRA:
11333
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11334
            break;
11335
        case OPC_SRL:
11336
            switch ((ctx->opcode >> 21) & 0x1f) {
11337
            case 1:
11338
                /* rotr is decoded as srl on non-R2 CPUs */
11339
                if (env->insn_flags & ISA_MIPS32R2) {
11340
                    op1 = OPC_ROTR;
11341
                }
11342
                /* Fallthrough */
11343
            case 0:
11344
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11345
                break;
11346
            default:
11347
                generate_exception(ctx, EXCP_RI);
11348
                break;
11349
            }
11350
            break;
11351
        case OPC_MOVN:         /* Conditional move */
11352
        case OPC_MOVZ:
11353
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11354
                                 INSN_LOONGSON2E | INSN_LOONGSON2F);
11355
            gen_cond_move(env, op1, rd, rs, rt);
11356
            break;
11357
        case OPC_ADD ... OPC_SUBU:
11358
            gen_arith(env, ctx, op1, rd, rs, rt);
11359
            break;
11360
        case OPC_SLLV:         /* Shifts */
11361
        case OPC_SRAV:
11362
            gen_shift(env, ctx, op1, rd, rs, rt);
11363
            break;
11364
        case OPC_SRLV:
11365
            switch ((ctx->opcode >> 6) & 0x1f) {
11366
            case 1:
11367
                /* rotrv is decoded as srlv on non-R2 CPUs */
11368
                if (env->insn_flags & ISA_MIPS32R2) {
11369
                    op1 = OPC_ROTRV;
11370
                }
11371
                /* Fallthrough */
11372
            case 0:
11373
                gen_shift(env, ctx, op1, rd, rs, rt);
11374
                break;
11375
            default:
11376
                generate_exception(ctx, EXCP_RI);
11377
                break;
11378
            }
11379
            break;
11380
        case OPC_SLT:          /* Set on less than */
11381
        case OPC_SLTU:
11382
            gen_slt(env, op1, rd, rs, rt);
11383
            break;
11384
        case OPC_AND:          /* Logic*/
11385
        case OPC_OR:
11386
        case OPC_NOR:
11387
        case OPC_XOR:
11388
            gen_logic(env, op1, rd, rs, rt);
11389
            break;
11390
        case OPC_MULT ... OPC_DIVU:
11391
            if (sa) {
11392
                check_insn(env, ctx, INSN_VR54XX);
11393
                op1 = MASK_MUL_VR54XX(ctx->opcode);
11394
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11395
            } else
11396
                gen_muldiv(ctx, op1, rs, rt);
11397
            break;
11398
        case OPC_JR ... OPC_JALR:
11399
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11400
            *is_branch = 1;
11401
            break;
11402
        case OPC_TGE ... OPC_TEQ: /* Traps */
11403
        case OPC_TNE:
11404
            gen_trap(ctx, op1, rs, rt, -1);
11405
            break;
11406
        case OPC_MFHI:          /* Move from HI/LO */
11407
        case OPC_MFLO:
11408
            gen_HILO(ctx, op1, rd);
11409
            break;
11410
        case OPC_MTHI:
11411
        case OPC_MTLO:          /* Move to HI/LO */
11412
            gen_HILO(ctx, op1, rs);
11413
            break;
11414
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
11415
#ifdef MIPS_STRICT_STANDARD
11416
            MIPS_INVAL("PMON / selsl");
11417
            generate_exception(ctx, EXCP_RI);
11418
#else
11419
            gen_helper_0i(pmon, sa);
11420
#endif
11421
            break;
11422
        case OPC_SYSCALL:
11423
            generate_exception(ctx, EXCP_SYSCALL);
11424
            ctx->bstate = BS_STOP;
11425
            break;
11426
        case OPC_BREAK:
11427
            generate_exception(ctx, EXCP_BREAK);
11428
            break;
11429
        case OPC_SPIM:
11430
#ifdef MIPS_STRICT_STANDARD
11431
            MIPS_INVAL("SPIM");
11432
            generate_exception(ctx, EXCP_RI);
11433
#else
11434
           /* Implemented as RI exception for now. */
11435
            MIPS_INVAL("spim (unofficial)");
11436
            generate_exception(ctx, EXCP_RI);
11437
#endif
11438
            break;
11439
        case OPC_SYNC:
11440
            /* Treat as NOP. */
11441
            break;
11442

    
11443
        case OPC_MOVCI:
11444
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11445
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11446
                check_cp1_enabled(ctx);
11447
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11448
                          (ctx->opcode >> 16) & 1);
11449
            } else {
11450
                generate_exception_err(ctx, EXCP_CpU, 1);
11451
            }
11452
            break;
11453

    
11454
#if defined(TARGET_MIPS64)
11455
       /* MIPS64 specific opcodes */
11456
        case OPC_DSLL:
11457
        case OPC_DSRA:
11458
        case OPC_DSLL32:
11459
        case OPC_DSRA32:
11460
            check_insn(env, ctx, ISA_MIPS3);
11461
            check_mips_64(ctx);
11462
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
11463
            break;
11464
        case OPC_DSRL:
11465
            switch ((ctx->opcode >> 21) & 0x1f) {
11466
            case 1:
11467
                /* drotr is decoded as dsrl on non-R2 CPUs */
11468
                if (env->insn_flags & ISA_MIPS32R2) {
11469
                    op1 = OPC_DROTR;
11470
                }
11471
                /* Fallthrough */
11472
            case 0:
11473
                check_insn(env, ctx, ISA_MIPS3);
11474
                check_mips_64(ctx);
11475
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11476
                break;
11477
            default:
11478
                generate_exception(ctx, EXCP_RI);
11479
                break;
11480
            }
11481
            break;
11482
        case OPC_DSRL32:
11483
            switch ((ctx->opcode >> 21) & 0x1f) {
11484
            case 1:
11485
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11486
                if (env->insn_flags & ISA_MIPS32R2) {
11487
                    op1 = OPC_DROTR32;
11488
                }
11489
                /* Fallthrough */
11490
            case 0:
11491
                check_insn(env, ctx, ISA_MIPS3);
11492
                check_mips_64(ctx);
11493
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
11494
                break;
11495
            default:
11496
                generate_exception(ctx, EXCP_RI);
11497
                break;
11498
            }
11499
            break;
11500
        case OPC_DADD ... OPC_DSUBU:
11501
            check_insn(env, ctx, ISA_MIPS3);
11502
            check_mips_64(ctx);
11503
            gen_arith(env, ctx, op1, rd, rs, rt);
11504
            break;
11505
        case OPC_DSLLV:
11506
        case OPC_DSRAV:
11507
            check_insn(env, ctx, ISA_MIPS3);
11508
            check_mips_64(ctx);
11509
            gen_shift(env, ctx, op1, rd, rs, rt);
11510
            break;
11511
        case OPC_DSRLV:
11512
            switch ((ctx->opcode >> 6) & 0x1f) {
11513
            case 1:
11514
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
11515
                if (env->insn_flags & ISA_MIPS32R2) {
11516
                    op1 = OPC_DROTRV;
11517
                }
11518
                /* Fallthrough */
11519
            case 0:
11520
                check_insn(env, ctx, ISA_MIPS3);
11521
                check_mips_64(ctx);
11522
                gen_shift(env, ctx, op1, rd, rs, rt);
11523
                break;
11524
            default:
11525
                generate_exception(ctx, EXCP_RI);
11526
                break;
11527
            }
11528
            break;
11529
        case OPC_DMULT ... OPC_DDIVU:
11530
            check_insn(env, ctx, ISA_MIPS3);
11531
            check_mips_64(ctx);
11532
            gen_muldiv(ctx, op1, rs, rt);
11533
            break;
11534
#endif
11535
        default:            /* Invalid */
11536
            MIPS_INVAL("special");
11537
            generate_exception(ctx, EXCP_RI);
11538
            break;
11539
        }
11540
        break;
11541
    case OPC_SPECIAL2:
11542
        op1 = MASK_SPECIAL2(ctx->opcode);
11543
        switch (op1) {
11544
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11545
        case OPC_MSUB ... OPC_MSUBU:
11546
            check_insn(env, ctx, ISA_MIPS32);
11547
            gen_muldiv(ctx, op1, rs, rt);
11548
            break;
11549
        case OPC_MUL:
11550
            gen_arith(env, ctx, op1, rd, rs, rt);
11551
            break;
11552
        case OPC_CLO:
11553
        case OPC_CLZ:
11554
            check_insn(env, ctx, ISA_MIPS32);
11555
            gen_cl(ctx, op1, rd, rs);
11556
            break;
11557
        case OPC_SDBBP:
11558
            /* XXX: not clear which exception should be raised
11559
             *      when in debug mode...
11560
             */
11561
            check_insn(env, ctx, ISA_MIPS32);
11562
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11563
                generate_exception(ctx, EXCP_DBp);
11564
            } else {
11565
                generate_exception(ctx, EXCP_DBp);
11566
            }
11567
            /* Treat as NOP. */
11568
            break;
11569
#if defined(TARGET_MIPS64)
11570
        case OPC_DCLO:
11571
        case OPC_DCLZ:
11572
            check_insn(env, ctx, ISA_MIPS64);
11573
            check_mips_64(ctx);
11574
            gen_cl(ctx, op1, rd, rs);
11575
            break;
11576
#endif
11577
        default:            /* Invalid */
11578
            MIPS_INVAL("special2");
11579
            generate_exception(ctx, EXCP_RI);
11580
            break;
11581
        }
11582
        break;
11583
    case OPC_SPECIAL3:
11584
        op1 = MASK_SPECIAL3(ctx->opcode);
11585
        switch (op1) {
11586
        case OPC_EXT:
11587
        case OPC_INS:
11588
            check_insn(env, ctx, ISA_MIPS32R2);
11589
            gen_bitops(ctx, op1, rt, rs, sa, rd);
11590
            break;
11591
        case OPC_BSHFL:
11592
            check_insn(env, ctx, ISA_MIPS32R2);
11593
            op2 = MASK_BSHFL(ctx->opcode);
11594
            gen_bshfl(ctx, op2, rt, rd);
11595
            break;
11596
        case OPC_RDHWR:
11597
            gen_rdhwr(env, ctx, rt, rd);
11598
            break;
11599
        case OPC_FORK:
11600
            check_insn(env, ctx, ASE_MT);
11601
            {
11602
                TCGv t0 = tcg_temp_new();
11603
                TCGv t1 = tcg_temp_new();
11604

    
11605
                gen_load_gpr(t0, rt);
11606
                gen_load_gpr(t1, rs);
11607
                gen_helper_fork(t0, t1);
11608
                tcg_temp_free(t0);
11609
                tcg_temp_free(t1);
11610
            }
11611
            break;
11612
        case OPC_YIELD:
11613
            check_insn(env, ctx, ASE_MT);
11614
            {
11615
                TCGv t0 = tcg_temp_new();
11616

    
11617
                save_cpu_state(ctx, 1);
11618
                gen_load_gpr(t0, rs);
11619
                gen_helper_yield(t0, t0);
11620
                gen_store_gpr(t0, rd);
11621
                tcg_temp_free(t0);
11622
            }
11623
            break;
11624
#if defined(TARGET_MIPS64)
11625
        case OPC_DEXTM ... OPC_DEXT:
11626
        case OPC_DINSM ... OPC_DINS:
11627
            check_insn(env, ctx, ISA_MIPS64R2);
11628
            check_mips_64(ctx);
11629
            gen_bitops(ctx, op1, rt, rs, sa, rd);
11630
            break;
11631
        case OPC_DBSHFL:
11632
            check_insn(env, ctx, ISA_MIPS64R2);
11633
            check_mips_64(ctx);
11634
            op2 = MASK_DBSHFL(ctx->opcode);
11635
            gen_bshfl(ctx, op2, rt, rd);
11636
            break;
11637
#endif
11638
        default:            /* Invalid */
11639
            MIPS_INVAL("special3");
11640
            generate_exception(ctx, EXCP_RI);
11641
            break;
11642
        }
11643
        break;
11644
    case OPC_REGIMM:
11645
        op1 = MASK_REGIMM(ctx->opcode);
11646
        switch (op1) {
11647
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
11648
        case OPC_BLTZAL ... OPC_BGEZALL:
11649
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
11650
            *is_branch = 1;
11651
            break;
11652
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
11653
        case OPC_TNEI:
11654
            gen_trap(ctx, op1, rs, -1, imm);
11655
            break;
11656
        case OPC_SYNCI:
11657
            check_insn(env, ctx, ISA_MIPS32R2);
11658
            /* Treat as NOP. */
11659
            break;
11660
        default:            /* Invalid */
11661
            MIPS_INVAL("regimm");
11662
            generate_exception(ctx, EXCP_RI);
11663
            break;
11664
        }
11665
        break;
11666
    case OPC_CP0:
11667
        check_cp0_enabled(ctx);
11668
        op1 = MASK_CP0(ctx->opcode);
11669
        switch (op1) {
11670
        case OPC_MFC0:
11671
        case OPC_MTC0:
11672
        case OPC_MFTR:
11673
        case OPC_MTTR:
11674
#if defined(TARGET_MIPS64)
11675
        case OPC_DMFC0:
11676
        case OPC_DMTC0:
11677
#endif
11678
#ifndef CONFIG_USER_ONLY
11679
            gen_cp0(env, ctx, op1, rt, rd);
11680
#endif /* !CONFIG_USER_ONLY */
11681
            break;
11682
        case OPC_C0_FIRST ... OPC_C0_LAST:
11683
#ifndef CONFIG_USER_ONLY
11684
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
11685
#endif /* !CONFIG_USER_ONLY */
11686
            break;
11687
        case OPC_MFMC0:
11688
#ifndef CONFIG_USER_ONLY
11689
            {
11690
                TCGv t0 = tcg_temp_new();
11691

    
11692
                op2 = MASK_MFMC0(ctx->opcode);
11693
                switch (op2) {
11694
                case OPC_DMT:
11695
                    check_insn(env, ctx, ASE_MT);
11696
                    gen_helper_dmt(t0, t0);
11697
                    gen_store_gpr(t0, rt);
11698
                    break;
11699
                case OPC_EMT:
11700
                    check_insn(env, ctx, ASE_MT);
11701
                    gen_helper_emt(t0, t0);
11702
                    gen_store_gpr(t0, rt);
11703
                    break;
11704
                case OPC_DVPE:
11705
                    check_insn(env, ctx, ASE_MT);
11706
                    gen_helper_dvpe(t0, t0);
11707
                    gen_store_gpr(t0, rt);
11708
                    break;
11709
                case OPC_EVPE:
11710
                    check_insn(env, ctx, ASE_MT);
11711
                    gen_helper_evpe(t0, t0);
11712
                    gen_store_gpr(t0, rt);
11713
                    break;
11714
                case OPC_DI:
11715
                    check_insn(env, ctx, ISA_MIPS32R2);
11716
                    save_cpu_state(ctx, 1);
11717
                    gen_helper_di(t0);
11718
                    gen_store_gpr(t0, rt);
11719
                    /* Stop translation as we may have switched the execution mode */
11720
                    ctx->bstate = BS_STOP;
11721
                    break;
11722
                case OPC_EI:
11723
                    check_insn(env, ctx, ISA_MIPS32R2);
11724
                    save_cpu_state(ctx, 1);
11725
                    gen_helper_ei(t0);
11726
                    gen_store_gpr(t0, rt);
11727
                    /* Stop translation as we may have switched the execution mode */
11728
                    ctx->bstate = BS_STOP;
11729
                    break;
11730
                default:            /* Invalid */
11731
                    MIPS_INVAL("mfmc0");
11732
                    generate_exception(ctx, EXCP_RI);
11733
                    break;
11734
                }
11735
                tcg_temp_free(t0);
11736
            }
11737
#endif /* !CONFIG_USER_ONLY */
11738
            break;
11739
        case OPC_RDPGPR:
11740
            check_insn(env, ctx, ISA_MIPS32R2);
11741
            gen_load_srsgpr(rt, rd);
11742
            break;
11743
        case OPC_WRPGPR:
11744
            check_insn(env, ctx, ISA_MIPS32R2);
11745
            gen_store_srsgpr(rt, rd);
11746
            break;
11747
        default:
11748
            MIPS_INVAL("cp0");
11749
            generate_exception(ctx, EXCP_RI);
11750
            break;
11751
        }
11752
        break;
11753
    case OPC_ADDI: /* Arithmetic with immediate opcode */
11754
    case OPC_ADDIU:
11755
         gen_arith_imm(env, ctx, op, rt, rs, imm);
11756
         break;
11757
    case OPC_SLTI: /* Set on less than with immediate opcode */
11758
    case OPC_SLTIU:
11759
         gen_slt_imm(env, op, rt, rs, imm);
11760
         break;
11761
    case OPC_ANDI: /* Arithmetic with immediate opcode */
11762
    case OPC_LUI:
11763
    case OPC_ORI:
11764
    case OPC_XORI:
11765
         gen_logic_imm(env, op, rt, rs, imm);
11766
         break;
11767
    case OPC_J ... OPC_JAL: /* Jump */
11768
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11769
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
11770
         *is_branch = 1;
11771
         break;
11772
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
11773
    case OPC_BEQL ... OPC_BGTZL:
11774
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
11775
         *is_branch = 1;
11776
         break;
11777
    case OPC_LB ... OPC_LWR: /* Load and stores */
11778
    case OPC_SB ... OPC_SW:
11779
    case OPC_SWR:
11780
    case OPC_LL:
11781
         gen_ldst(ctx, op, rt, rs, imm);
11782
         break;
11783
    case OPC_SC:
11784
         gen_st_cond(ctx, op, rt, rs, imm);
11785
         break;
11786
    case OPC_CACHE:
11787
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
11788
        /* Treat as NOP. */
11789
        break;
11790
    case OPC_PREF:
11791
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11792
        /* Treat as NOP. */
11793
        break;
11794

    
11795
    /* Floating point (COP1). */
11796
    case OPC_LWC1:
11797
    case OPC_LDC1:
11798
    case OPC_SWC1:
11799
    case OPC_SDC1:
11800
        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
11801
        break;
11802

    
11803
    case OPC_CP1:
11804
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11805
            check_cp1_enabled(ctx);
11806
            op1 = MASK_CP1(ctx->opcode);
11807
            switch (op1) {
11808
            case OPC_MFHC1:
11809
            case OPC_MTHC1:
11810
                check_insn(env, ctx, ISA_MIPS32R2);
11811
            case OPC_MFC1:
11812
            case OPC_CFC1:
11813
            case OPC_MTC1:
11814
            case OPC_CTC1:
11815
                gen_cp1(ctx, op1, rt, rd);
11816
                break;
11817
#if defined(TARGET_MIPS64)
11818
            case OPC_DMFC1:
11819
            case OPC_DMTC1:
11820
                check_insn(env, ctx, ISA_MIPS3);
11821
                gen_cp1(ctx, op1, rt, rd);
11822
                break;
11823
#endif
11824
            case OPC_BC1ANY2:
11825
            case OPC_BC1ANY4:
11826
                check_cop1x(ctx);
11827
                check_insn(env, ctx, ASE_MIPS3D);
11828
                /* fall through */
11829
            case OPC_BC1:
11830
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
11831
                                    (rt >> 2) & 0x7, imm << 2);
11832
                *is_branch = 1;
11833
                break;
11834
            case OPC_S_FMT:
11835
            case OPC_D_FMT:
11836
            case OPC_W_FMT:
11837
            case OPC_L_FMT:
11838
            case OPC_PS_FMT:
11839
                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
11840
                           (imm >> 8) & 0x7);
11841
                break;
11842
            default:
11843
                MIPS_INVAL("cp1");
11844
                generate_exception (ctx, EXCP_RI);
11845
                break;
11846
            }
11847
        } else {
11848
            generate_exception_err(ctx, EXCP_CpU, 1);
11849
        }
11850
        break;
11851

    
11852
    /* COP2.  */
11853
    case OPC_LWC2:
11854
    case OPC_LDC2:
11855
    case OPC_SWC2:
11856
    case OPC_SDC2:
11857
    case OPC_CP2:
11858
        /* COP2: Not implemented. */
11859
        generate_exception_err(ctx, EXCP_CpU, 2);
11860
        break;
11861

    
11862
    case OPC_CP3:
11863
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11864
            check_cp1_enabled(ctx);
11865
            op1 = MASK_CP3(ctx->opcode);
11866
            switch (op1) {
11867
            case OPC_LWXC1:
11868
            case OPC_LDXC1:
11869
            case OPC_LUXC1:
11870
            case OPC_SWXC1:
11871
            case OPC_SDXC1:
11872
            case OPC_SUXC1:
11873
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
11874
                break;
11875
            case OPC_PREFX:
11876
                /* Treat as NOP. */
11877
                break;
11878
            case OPC_ALNV_PS:
11879
            case OPC_MADD_S:
11880
            case OPC_MADD_D:
11881
            case OPC_MADD_PS:
11882
            case OPC_MSUB_S:
11883
            case OPC_MSUB_D:
11884
            case OPC_MSUB_PS:
11885
            case OPC_NMADD_S:
11886
            case OPC_NMADD_D:
11887
            case OPC_NMADD_PS:
11888
            case OPC_NMSUB_S:
11889
            case OPC_NMSUB_D:
11890
            case OPC_NMSUB_PS:
11891
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
11892
                break;
11893
            default:
11894
                MIPS_INVAL("cp3");
11895
                generate_exception (ctx, EXCP_RI);
11896
                break;
11897
            }
11898
        } else {
11899
            generate_exception_err(ctx, EXCP_CpU, 1);
11900
        }
11901
        break;
11902

    
11903
#if defined(TARGET_MIPS64)
11904
    /* MIPS64 opcodes */
11905
    case OPC_LWU:
11906
    case OPC_LDL ... OPC_LDR:
11907
    case OPC_SDL ... OPC_SDR:
11908
    case OPC_LLD:
11909
    case OPC_LD:
11910
    case OPC_SD:
11911
        check_insn(env, ctx, ISA_MIPS3);
11912
        check_mips_64(ctx);
11913
        gen_ldst(ctx, op, rt, rs, imm);
11914
        break;
11915
    case OPC_SCD:
11916
        check_insn(env, ctx, ISA_MIPS3);
11917
        check_mips_64(ctx);
11918
        gen_st_cond(ctx, op, rt, rs, imm);
11919
        break;
11920
    case OPC_DADDI:
11921
    case OPC_DADDIU:
11922
        check_insn(env, ctx, ISA_MIPS3);
11923
        check_mips_64(ctx);
11924
        gen_arith_imm(env, ctx, op, rt, rs, imm);
11925
        break;
11926
#endif
11927
    case OPC_JALX:
11928
        check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
11929
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11930
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
11931
        *is_branch = 1;
11932
        break;
11933
    case OPC_MDMX:
11934
        check_insn(env, ctx, ASE_MDMX);
11935
        /* MDMX: Not implemented. */
11936
    default:            /* Invalid */
11937
        MIPS_INVAL("major opcode");
11938
        generate_exception(ctx, EXCP_RI);
11939
        break;
11940
    }
11941
}
11942

    
11943
static inline void
11944
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
11945
                                int search_pc)
11946
{
11947
    DisasContext ctx;
11948
    target_ulong pc_start;
11949
    uint16_t *gen_opc_end;
11950
    CPUBreakpoint *bp;
11951
    int j, lj = -1;
11952
    int num_insns;
11953
    int max_insns;
11954
    int insn_bytes;
11955
    int is_branch;
11956

    
11957
    if (search_pc)
11958
        qemu_log("search pc %d\n", search_pc);
11959

    
11960
    pc_start = tb->pc;
11961
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
11962
    ctx.pc = pc_start;
11963
    ctx.saved_pc = -1;
11964
    ctx.singlestep_enabled = env->singlestep_enabled;
11965
    ctx.tb = tb;
11966
    ctx.bstate = BS_NONE;
11967
    /* Restore delay slot state from the tb context.  */
11968
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
11969
    restore_cpu_state(env, &ctx);
11970
#ifdef CONFIG_USER_ONLY
11971
        ctx.mem_idx = MIPS_HFLAG_UM;
11972
#else
11973
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
11974
#endif
11975
    num_insns = 0;
11976
    max_insns = tb->cflags & CF_COUNT_MASK;
11977
    if (max_insns == 0)
11978
        max_insns = CF_COUNT_MASK;
11979
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
11980
    gen_icount_start();
11981
    while (ctx.bstate == BS_NONE) {
11982
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
11983
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
11984
                if (bp->pc == ctx.pc) {
11985
                    save_cpu_state(&ctx, 1);
11986
                    ctx.bstate = BS_BRANCH;
11987
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
11988
                    /* Include the breakpoint location or the tb won't
11989
                     * be flushed when it must be.  */
11990
                    ctx.pc += 4;
11991
                    goto done_generating;
11992
                }
11993
            }
11994
        }
11995

    
11996
        if (search_pc) {
11997
            j = gen_opc_ptr - gen_opc_buf;
11998
            if (lj < j) {
11999
                lj++;
12000
                while (lj < j)
12001
                    gen_opc_instr_start[lj++] = 0;
12002
            }
12003
            gen_opc_pc[lj] = ctx.pc;
12004
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12005
            gen_opc_instr_start[lj] = 1;
12006
            gen_opc_icount[lj] = num_insns;
12007
        }
12008
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12009
            gen_io_start();
12010

    
12011
        is_branch = 0;
12012
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12013
            ctx.opcode = ldl_code(ctx.pc);
12014
            insn_bytes = 4;
12015
            decode_opc(env, &ctx, &is_branch);
12016
        } else if (env->insn_flags & ASE_MICROMIPS) {
12017
            ctx.opcode = lduw_code(ctx.pc);
12018
            insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12019
        } else if (env->insn_flags & ASE_MIPS16) {
12020
            ctx.opcode = lduw_code(ctx.pc);
12021
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12022
        } else {
12023
            generate_exception(&ctx, EXCP_RI);
12024
            ctx.bstate = BS_STOP;
12025
            break;
12026
        }
12027
        if (!is_branch) {
12028
            handle_delay_slot(env, &ctx, insn_bytes);
12029
        }
12030
        ctx.pc += insn_bytes;
12031

    
12032
        num_insns++;
12033

    
12034
        /* Execute a branch and its delay slot as a single instruction.
12035
           This is what GDB expects and is consistent with what the
12036
           hardware does (e.g. if a delay slot instruction faults, the
12037
           reported PC is the PC of the branch).  */
12038
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12039
            break;
12040

    
12041
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12042
            break;
12043

    
12044
        if (gen_opc_ptr >= gen_opc_end)
12045
            break;
12046

    
12047
        if (num_insns >= max_insns)
12048
            break;
12049

    
12050
        if (singlestep)
12051
            break;
12052
    }
12053
    if (tb->cflags & CF_LAST_IO)
12054
        gen_io_end();
12055
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12056
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12057
        gen_helper_0i(raise_exception, EXCP_DEBUG);
12058
    } else {
12059
        switch (ctx.bstate) {
12060
        case BS_STOP:
12061
            gen_helper_interrupt_restart();
12062
            gen_goto_tb(&ctx, 0, ctx.pc);
12063
            break;
12064
        case BS_NONE:
12065
            save_cpu_state(&ctx, 0);
12066
            gen_goto_tb(&ctx, 0, ctx.pc);
12067
            break;
12068
        case BS_EXCP:
12069
            gen_helper_interrupt_restart();
12070
            tcg_gen_exit_tb(0);
12071
            break;
12072
        case BS_BRANCH:
12073
        default:
12074
            break;
12075
        }
12076
    }
12077
done_generating:
12078
    gen_icount_end(tb, num_insns);
12079
    *gen_opc_ptr = INDEX_op_end;
12080
    if (search_pc) {
12081
        j = gen_opc_ptr - gen_opc_buf;
12082
        lj++;
12083
        while (lj <= j)
12084
            gen_opc_instr_start[lj++] = 0;
12085
    } else {
12086
        tb->size = ctx.pc - pc_start;
12087
        tb->icount = num_insns;
12088
    }
12089
#ifdef DEBUG_DISAS
12090
    LOG_DISAS("\n");
12091
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12092
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
12093
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
12094
        qemu_log("\n");
12095
    }
12096
#endif
12097
}
12098

    
12099
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12100
{
12101
    gen_intermediate_code_internal(env, tb, 0);
12102
}
12103

    
12104
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12105
{
12106
    gen_intermediate_code_internal(env, tb, 1);
12107
}
12108

    
12109
static void fpu_dump_state(CPUState *env, FILE *f,
12110
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
12111
                           int flags)
12112
{
12113
    int i;
12114
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12115

    
12116
#define printfpr(fp)                                                    \
12117
    do {                                                                \
12118
        if (is_fpu64)                                                   \
12119
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12120
                        " fd:%13g fs:%13g psu: %13g\n",                 \
12121
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
12122
                        (double)(fp)->fd,                               \
12123
                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
12124
                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
12125
        else {                                                          \
12126
            fpr_t tmp;                                                  \
12127
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
12128
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
12129
            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
12130
                        " fd:%13g fs:%13g psu:%13g\n",                  \
12131
                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
12132
                        (double)tmp.fd,                                 \
12133
                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
12134
                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
12135
        }                                                               \
12136
    } while(0)
12137

    
12138

    
12139
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
12140
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
12141
                get_float_exception_flags(&env->active_fpu.fp_status));
12142
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12143
        fpu_fprintf(f, "%3s: ", fregnames[i]);
12144
        printfpr(&env->active_fpu.fpr[i]);
12145
    }
12146

    
12147
#undef printfpr
12148
}
12149

    
12150
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12151
/* Debug help: The architecture requires 32bit code to maintain proper
12152
   sign-extended values on 64bit machines.  */
12153

    
12154
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12155

    
12156
static void
12157
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12158
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
12159
                                int flags)
12160
{
12161
    int i;
12162

    
12163
    if (!SIGN_EXT_P(env->active_tc.PC))
12164
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12165
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
12166
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12167
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
12168
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12169
    if (!SIGN_EXT_P(env->btarget))
12170
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12171

    
12172
    for (i = 0; i < 32; i++) {
12173
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12174
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12175
    }
12176

    
12177
    if (!SIGN_EXT_P(env->CP0_EPC))
12178
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12179
    if (!SIGN_EXT_P(env->lladdr))
12180
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12181
}
12182
#endif
12183

    
12184
void cpu_dump_state (CPUState *env, FILE *f,
12185
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
12186
                     int flags)
12187
{
12188
    int i;
12189

    
12190
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12191
                " LO=0x" TARGET_FMT_lx " ds %04x "
12192
                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12193
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12194
                env->hflags, env->btarget, env->bcond);
12195
    for (i = 0; i < 32; i++) {
12196
        if ((i & 3) == 0)
12197
            cpu_fprintf(f, "GPR%02d:", i);
12198
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12199
        if ((i & 3) == 3)
12200
            cpu_fprintf(f, "\n");
12201
    }
12202

    
12203
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
12204
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12205
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12206
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
12207
    if (env->hflags & MIPS_HFLAG_FPU)
12208
        fpu_dump_state(env, f, cpu_fprintf, flags);
12209
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12210
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12211
#endif
12212
}
12213

    
12214
static void mips_tcg_init(void)
12215
{
12216
    int i;
12217
    static int inited;
12218

    
12219
    /* Initialize various static tables. */
12220
    if (inited)
12221
        return;
12222

    
12223
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12224
    TCGV_UNUSED(cpu_gpr[0]);
12225
    for (i = 1; i < 32; i++)
12226
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12227
                                        offsetof(CPUState, active_tc.gpr[i]),
12228
                                        regnames[i]);
12229
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
12230
                                offsetof(CPUState, active_tc.PC), "PC");
12231
    for (i = 0; i < MIPS_DSP_ACC; i++) {
12232
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12233
                                       offsetof(CPUState, active_tc.HI[i]),
12234
                                       regnames_HI[i]);
12235
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12236
                                       offsetof(CPUState, active_tc.LO[i]),
12237
                                       regnames_LO[i]);
12238
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12239
                                        offsetof(CPUState, active_tc.ACX[i]),
12240
                                        regnames_ACX[i]);
12241
    }
12242
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12243
                                     offsetof(CPUState, active_tc.DSPControl),
12244
                                     "DSPControl");
12245
    bcond = tcg_global_mem_new(TCG_AREG0,
12246
                               offsetof(CPUState, bcond), "bcond");
12247
    btarget = tcg_global_mem_new(TCG_AREG0,
12248
                                 offsetof(CPUState, btarget), "btarget");
12249
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
12250
                                    offsetof(CPUState, hflags), "hflags");
12251

    
12252
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12253
                                      offsetof(CPUState, active_fpu.fcr0),
12254
                                      "fcr0");
12255
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12256
                                       offsetof(CPUState, active_fpu.fcr31),
12257
                                       "fcr31");
12258

    
12259
    /* register helpers */
12260
#define GEN_HELPER 2
12261
#include "helper.h"
12262

    
12263
    inited = 1;
12264
}
12265

    
12266
#include "translate_init.c"
12267

    
12268
CPUMIPSState *cpu_mips_init (const char *cpu_model)
12269
{
12270
    CPUMIPSState *env;
12271
    const mips_def_t *def;
12272

    
12273
    def = cpu_mips_find_by_name(cpu_model);
12274
    if (!def)
12275
        return NULL;
12276
    env = qemu_mallocz(sizeof(CPUMIPSState));
12277
    env->cpu_model = def;
12278
    env->cpu_model_str = cpu_model;
12279

    
12280
    cpu_exec_init(env);
12281
#ifndef CONFIG_USER_ONLY
12282
    mmu_init(env, def);
12283
#endif
12284
    fpu_init(env, def);
12285
    mvp_init(env, def);
12286
    mips_tcg_init();
12287
    cpu_reset(env);
12288
    qemu_init_vcpu(env);
12289
    return env;
12290
}
12291

    
12292
void cpu_reset (CPUMIPSState *env)
12293
{
12294
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12295
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12296
        log_cpu_state(env, 0);
12297
    }
12298

    
12299
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12300
    tlb_flush(env, 1);
12301

    
12302
    /* Reset registers to their default values */
12303
    env->CP0_PRid = env->cpu_model->CP0_PRid;
12304
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
12305
#ifdef TARGET_WORDS_BIGENDIAN
12306
    env->CP0_Config0 |= (1 << CP0C0_BE);
12307
#endif
12308
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
12309
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
12310
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
12311
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
12312
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
12313
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12314
                                 << env->cpu_model->CP0_LLAddr_shift;
12315
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12316
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12317
    env->CCRes = env->cpu_model->CCRes;
12318
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12319
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12320
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12321
    env->current_tc = 0;
12322
    env->SEGBITS = env->cpu_model->SEGBITS;
12323
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12324
#if defined(TARGET_MIPS64)
12325
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12326
        env->SEGMask |= 3ULL << 62;
12327
    }
12328
#endif
12329
    env->PABITS = env->cpu_model->PABITS;
12330
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12331
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12332
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12333
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12334
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12335
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12336
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12337
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12338
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12339
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12340
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12341
    env->insn_flags = env->cpu_model->insn_flags;
12342

    
12343
#if defined(CONFIG_USER_ONLY)
12344
    env->hflags = MIPS_HFLAG_UM;
12345
    /* Enable access to the SYNCI_Step register.  */
12346
    env->CP0_HWREna |= (1 << 1);
12347
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12348
        env->hflags |= MIPS_HFLAG_FPU;
12349
    }
12350
#ifdef TARGET_MIPS64
12351
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12352
        env->hflags |= MIPS_HFLAG_F64;
12353
    }
12354
#endif
12355
#else
12356
    if (env->hflags & MIPS_HFLAG_BMASK) {
12357
        /* If the exception was raised from a delay slot,
12358
           come back to the jump.  */
12359
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
12360
    } else {
12361
        env->CP0_ErrorEPC = env->active_tc.PC;
12362
    }
12363
    env->active_tc.PC = (int32_t)0xBFC00000;
12364
    env->CP0_Random = env->tlb->nb_tlb - 1;
12365
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
12366
    env->CP0_Wired = 0;
12367
    /* SMP not implemented */
12368
    env->CP0_EBase = 0x80000000;
12369
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12370
    /* vectored interrupts not implemented, timer on int 7,
12371
       no performance counters. */
12372
    env->CP0_IntCtl = 0xe0000000;
12373
    {
12374
        int i;
12375

    
12376
        for (i = 0; i < 7; i++) {
12377
            env->CP0_WatchLo[i] = 0;
12378
            env->CP0_WatchHi[i] = 0x80000000;
12379
        }
12380
        env->CP0_WatchLo[7] = 0;
12381
        env->CP0_WatchHi[7] = 0;
12382
    }
12383
    /* Count register increments in debug mode, EJTAG version 1 */
12384
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12385
    env->hflags = MIPS_HFLAG_CP0;
12386
#endif
12387
#if defined(TARGET_MIPS64)
12388
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
12389
        env->hflags |= MIPS_HFLAG_64;
12390
    }
12391
#endif
12392
    env->exception_index = EXCP_NONE;
12393
}
12394

    
12395
void gen_pc_load(CPUState *env, TranslationBlock *tb,
12396
                unsigned long searched_pc, int pc_pos, void *puc)
12397
{
12398
    env->active_tc.PC = gen_opc_pc[pc_pos];
12399
    env->hflags &= ~MIPS_HFLAG_BMASK;
12400
    env->hflags |= gen_opc_hflags[pc_pos];
12401
}