Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 698235aa

History | View | Annotate | Download (284.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 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_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
72
    OPC_BEQL     = (0x14 << 26),
73
    OPC_BNE      = (0x05 << 26),
74
    OPC_BNEL     = (0x15 << 26),
75
    OPC_BLEZ     = (0x06 << 26),
76
    OPC_BLEZL    = (0x16 << 26),
77
    OPC_BGTZ     = (0x07 << 26),
78
    OPC_BGTZL    = (0x17 << 26),
79
    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
80
    /* Load and stores */
81
    OPC_LDL      = (0x1A << 26),
82
    OPC_LDR      = (0x1B << 26),
83
    OPC_LB       = (0x20 << 26),
84
    OPC_LH       = (0x21 << 26),
85
    OPC_LWL      = (0x22 << 26),
86
    OPC_LW       = (0x23 << 26),
87
    OPC_LWPC     = OPC_LW | 0x5,
88
    OPC_LBU      = (0x24 << 26),
89
    OPC_LHU      = (0x25 << 26),
90
    OPC_LWR      = (0x26 << 26),
91
    OPC_LWU      = (0x27 << 26),
92
    OPC_SB       = (0x28 << 26),
93
    OPC_SH       = (0x29 << 26),
94
    OPC_SWL      = (0x2A << 26),
95
    OPC_SW       = (0x2B << 26),
96
    OPC_SDL      = (0x2C << 26),
97
    OPC_SDR      = (0x2D << 26),
98
    OPC_SWR      = (0x2E << 26),
99
    OPC_LL       = (0x30 << 26),
100
    OPC_LLD      = (0x34 << 26),
101
    OPC_LD       = (0x37 << 26),
102
    OPC_LDPC     = OPC_LD | 0x5,
103
    OPC_SC       = (0x38 << 26),
104
    OPC_SCD      = (0x3C << 26),
105
    OPC_SD       = (0x3F << 26),
106
    /* Floating point load/store */
107
    OPC_LWC1     = (0x31 << 26),
108
    OPC_LWC2     = (0x32 << 26),
109
    OPC_LDC1     = (0x35 << 26),
110
    OPC_LDC2     = (0x36 << 26),
111
    OPC_SWC1     = (0x39 << 26),
112
    OPC_SWC2     = (0x3A << 26),
113
    OPC_SDC1     = (0x3D << 26),
114
    OPC_SDC2     = (0x3E << 26),
115
    /* MDMX ASE specific */
116
    OPC_MDMX     = (0x1E << 26),
117
    /* Cache and prefetch */
118
    OPC_CACHE    = (0x2F << 26),
119
    OPC_PREF     = (0x33 << 26),
120
    /* Reserved major opcode */
121
    OPC_MAJOR3B_RESERVED = (0x3B << 26),
122
};
123

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

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

    
196
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
197

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

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

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

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

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

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

    
255
/* Special2 opcodes */
256
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
257

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

    
274
/* Special3 opcodes */
275
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
276

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

    
293
/* BSHFL opcodes */
294
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
295

    
296
enum {
297
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
298
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
299
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
300
};
301

    
302
/* DBSHFL opcodes */
303
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
304

    
305
enum {
306
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
307
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
308
};
309

    
310
/* Coprocessor 0 (rs field) */
311
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
312

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

    
328
/* MFMC0 opcodes */
329
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
330

    
331
enum {
332
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
333
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
334
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
335
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
336
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
337
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
338
};
339

    
340
/* Coprocessor 0 (with rs == C0) */
341
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
342

    
343
enum {
344
    OPC_TLBR     = 0x01 | OPC_C0,
345
    OPC_TLBWI    = 0x02 | OPC_C0,
346
    OPC_TLBWR    = 0x06 | OPC_C0,
347
    OPC_TLBP     = 0x08 | OPC_C0,
348
    OPC_RFE      = 0x10 | OPC_C0,
349
    OPC_ERET     = 0x18 | OPC_C0,
350
    OPC_DERET    = 0x1F | OPC_C0,
351
    OPC_WAIT     = 0x20 | OPC_C0,
352
};
353

    
354
/* Coprocessor 1 (rs field) */
355
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
356

    
357
enum {
358
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
359
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
360
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
361
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
362
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
363
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
364
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
365
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
366
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
367
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
368
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
369
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
370
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
371
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
372
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
373
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
374
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
375
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
376
};
377

    
378
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
379
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
380

    
381
enum {
382
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
383
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
384
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
385
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
386
};
387

    
388
enum {
389
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
390
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
391
};
392

    
393
enum {
394
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
395
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
396
};
397

    
398
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
399

    
400
enum {
401
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
402
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
403
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
404
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
405
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
406
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
407
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
408
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
409
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
410
};
411

    
412
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
413

    
414
enum {
415
    OPC_LWXC1   = 0x00 | OPC_CP3,
416
    OPC_LDXC1   = 0x01 | OPC_CP3,
417
    OPC_LUXC1   = 0x05 | OPC_CP3,
418
    OPC_SWXC1   = 0x08 | OPC_CP3,
419
    OPC_SDXC1   = 0x09 | OPC_CP3,
420
    OPC_SUXC1   = 0x0D | OPC_CP3,
421
    OPC_PREFX   = 0x0F | OPC_CP3,
422
    OPC_ALNV_PS = 0x1E | OPC_CP3,
423
    OPC_MADD_S  = 0x20 | OPC_CP3,
424
    OPC_MADD_D  = 0x21 | OPC_CP3,
425
    OPC_MADD_PS = 0x26 | OPC_CP3,
426
    OPC_MSUB_S  = 0x28 | OPC_CP3,
427
    OPC_MSUB_D  = 0x29 | OPC_CP3,
428
    OPC_MSUB_PS = 0x2E | OPC_CP3,
429
    OPC_NMADD_S = 0x30 | OPC_CP3,
430
    OPC_NMADD_D = 0x31 | OPC_CP3,
431
    OPC_NMADD_PS= 0x36 | OPC_CP3,
432
    OPC_NMSUB_S = 0x38 | OPC_CP3,
433
    OPC_NMSUB_D = 0x39 | OPC_CP3,
434
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
435
};
436

    
437
/* global register indices */
438
static TCGv_ptr cpu_env;
439
static TCGv cpu_gpr[32], cpu_PC;
440
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
441
static TCGv cpu_dspctrl, btarget, bcond;
442
static TCGv_i32 hflags;
443
static TCGv_i32 fpu_fcr0, fpu_fcr31;
444

    
445
#include "gen-icount.h"
446

    
447
#define gen_helper_0i(name, arg) do {                             \
448
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
449
    gen_helper_##name(helper_tmp);                                \
450
    tcg_temp_free_i32(helper_tmp);                                \
451
    } while(0)
452

    
453
#define gen_helper_1i(name, arg1, arg2) do {                      \
454
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
455
    gen_helper_##name(arg1, helper_tmp);                          \
456
    tcg_temp_free_i32(helper_tmp);                                \
457
    } while(0)
458

    
459
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
460
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
461
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
462
    tcg_temp_free_i32(helper_tmp);                                \
463
    } while(0)
464

    
465
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
466
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
467
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
468
    tcg_temp_free_i32(helper_tmp);                                \
469
    } while(0)
470

    
471
typedef struct DisasContext {
472
    struct TranslationBlock *tb;
473
    target_ulong pc, saved_pc;
474
    uint32_t opcode;
475
    int singlestep_enabled;
476
    /* Routine used to access memory */
477
    int mem_idx;
478
    uint32_t hflags, saved_hflags;
479
    int bstate;
480
    target_ulong btarget;
481
} DisasContext;
482

    
483
enum {
484
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
485
                      * exception condition */
486
    BS_STOP     = 1, /* We want to stop translation for any reason */
487
    BS_BRANCH   = 2, /* We reached a branch condition     */
488
    BS_EXCP     = 3, /* We reached an exception condition */
489
};
490

    
491
static const char *regnames[] =
492
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
493
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
494
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
495
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
496

    
497
static const char *regnames_HI[] =
498
    { "HI0", "HI1", "HI2", "HI3", };
499

    
500
static const char *regnames_LO[] =
501
    { "LO0", "LO1", "LO2", "LO3", };
502

    
503
static const char *regnames_ACX[] =
504
    { "ACX0", "ACX1", "ACX2", "ACX3", };
505

    
506
static const char *fregnames[] =
507
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
508
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
509
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
510
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
511

    
512
#ifdef MIPS_DEBUG_DISAS
513
#define MIPS_DEBUG(fmt, ...)                         \
514
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
515
                       TARGET_FMT_lx ": %08x " fmt "\n", \
516
                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
517
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
518
#else
519
#define MIPS_DEBUG(fmt, ...) do { } while(0)
520
#define LOG_DISAS(...) do { } while (0)
521
#endif
522

    
523
#define MIPS_INVAL(op)                                                        \
524
do {                                                                          \
525
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
526
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
527
} while (0)
528

    
529
/* General purpose registers moves. */
530
static inline void gen_load_gpr (TCGv t, int reg)
531
{
532
    if (reg == 0)
533
        tcg_gen_movi_tl(t, 0);
534
    else
535
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
536
}
537

    
538
static inline void gen_store_gpr (TCGv t, int reg)
539
{
540
    if (reg != 0)
541
        tcg_gen_mov_tl(cpu_gpr[reg], t);
542
}
543

    
544
/* Moves to/from ACX register.  */
545
static inline void gen_load_ACX (TCGv t, int reg)
546
{
547
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
548
}
549

    
550
static inline void gen_store_ACX (TCGv t, int reg)
551
{
552
    tcg_gen_mov_tl(cpu_ACX[reg], t);
553
}
554

    
555
/* Moves to/from shadow registers. */
556
static inline void gen_load_srsgpr (int from, int to)
557
{
558
    TCGv t0 = tcg_temp_new();
559

    
560
    if (from == 0)
561
        tcg_gen_movi_tl(t0, 0);
562
    else {
563
        TCGv_i32 t2 = tcg_temp_new_i32();
564
        TCGv_ptr addr = tcg_temp_new_ptr();
565

    
566
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
567
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
568
        tcg_gen_andi_i32(t2, t2, 0xf);
569
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
570
        tcg_gen_ext_i32_ptr(addr, t2);
571
        tcg_gen_add_ptr(addr, cpu_env, addr);
572

    
573
        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
574
        tcg_temp_free_ptr(addr);
575
        tcg_temp_free_i32(t2);
576
    }
577
    gen_store_gpr(t0, to);
578
    tcg_temp_free(t0);
579
}
580

    
581
static inline void gen_store_srsgpr (int from, int to)
582
{
583
    if (to != 0) {
584
        TCGv t0 = tcg_temp_new();
585
        TCGv_i32 t2 = tcg_temp_new_i32();
586
        TCGv_ptr addr = tcg_temp_new_ptr();
587

    
588
        gen_load_gpr(t0, from);
589
        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
590
        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
591
        tcg_gen_andi_i32(t2, t2, 0xf);
592
        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
593
        tcg_gen_ext_i32_ptr(addr, t2);
594
        tcg_gen_add_ptr(addr, cpu_env, addr);
595

    
596
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
597
        tcg_temp_free_ptr(addr);
598
        tcg_temp_free_i32(t2);
599
        tcg_temp_free(t0);
600
    }
601
}
602

    
603
/* Floating point register moves. */
604
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
605
{
606
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
607
}
608

    
609
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
610
{
611
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
612
}
613

    
614
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
615
{
616
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
617
}
618

    
619
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
620
{
621
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
622
}
623

    
624
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
625
{
626
    if (ctx->hflags & MIPS_HFLAG_F64) {
627
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
628
    } else {
629
        TCGv_i32 t0 = tcg_temp_new_i32();
630
        TCGv_i32 t1 = tcg_temp_new_i32();
631
        gen_load_fpr32(t0, reg & ~1);
632
        gen_load_fpr32(t1, reg | 1);
633
        tcg_gen_concat_i32_i64(t, t0, t1);
634
        tcg_temp_free_i32(t0);
635
        tcg_temp_free_i32(t1);
636
    }
637
}
638

    
639
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
640
{
641
    if (ctx->hflags & MIPS_HFLAG_F64) {
642
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
643
    } else {
644
        TCGv_i64 t0 = tcg_temp_new_i64();
645
        TCGv_i32 t1 = tcg_temp_new_i32();
646
        tcg_gen_trunc_i64_i32(t1, t);
647
        gen_store_fpr32(t1, reg & ~1);
648
        tcg_gen_shri_i64(t0, t, 32);
649
        tcg_gen_trunc_i64_i32(t1, t0);
650
        gen_store_fpr32(t1, reg | 1);
651
        tcg_temp_free_i32(t1);
652
        tcg_temp_free_i64(t0);
653
    }
654
}
655

    
656
static inline int get_fp_bit (int cc)
657
{
658
    if (cc)
659
        return 24 + cc;
660
    else
661
        return 23;
662
}
663

    
664
#define FOP_CONDS(type, fmt, bits)                                            \
665
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
666
                                               TCGv_i##bits b, int cc)        \
667
{                                                                             \
668
    switch (n) {                                                              \
669
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
670
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
671
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
672
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
673
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
674
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
675
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
676
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
677
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
678
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
679
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
680
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
681
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
682
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
683
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
684
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
685
    default: abort();                                                         \
686
    }                                                                         \
687
}
688

    
689
FOP_CONDS(, d, 64)
690
FOP_CONDS(abs, d, 64)
691
FOP_CONDS(, s, 32)
692
FOP_CONDS(abs, s, 32)
693
FOP_CONDS(, ps, 64)
694
FOP_CONDS(abs, ps, 64)
695
#undef FOP_CONDS
696

    
697
/* Tests */
698
#define OP_COND(name, cond)                                         \
699
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
700
{                                                                   \
701
    int l1 = gen_new_label();                                       \
702
    int l2 = gen_new_label();                                       \
703
                                                                    \
704
    tcg_gen_brcond_tl(cond, t0, t1, l1);                            \
705
    tcg_gen_movi_tl(ret, 0);                                        \
706
    tcg_gen_br(l2);                                                 \
707
    gen_set_label(l1);                                              \
708
    tcg_gen_movi_tl(ret, 1);                                        \
709
    gen_set_label(l2);                                              \
710
}
711
OP_COND(eq, TCG_COND_EQ);
712
OP_COND(ne, TCG_COND_NE);
713
OP_COND(ge, TCG_COND_GE);
714
OP_COND(geu, TCG_COND_GEU);
715
OP_COND(lt, TCG_COND_LT);
716
OP_COND(ltu, TCG_COND_LTU);
717
#undef OP_COND
718

    
719
#define OP_CONDI(name, cond)                                                 \
720
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
721
{                                                                            \
722
    int l1 = gen_new_label();                                                \
723
    int l2 = gen_new_label();                                                \
724
                                                                             \
725
    tcg_gen_brcondi_tl(cond, t0, val, l1);                                   \
726
    tcg_gen_movi_tl(ret, 0);                                                 \
727
    tcg_gen_br(l2);                                                          \
728
    gen_set_label(l1);                                                       \
729
    tcg_gen_movi_tl(ret, 1);                                                 \
730
    gen_set_label(l2);                                                       \
731
}
732
OP_CONDI(lti, TCG_COND_LT);
733
OP_CONDI(ltiu, TCG_COND_LTU);
734
#undef OP_CONDI
735

    
736
#define OP_CONDZ(name, cond)                                  \
737
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0)    \
738
{                                                             \
739
    int l1 = gen_new_label();                                 \
740
    int l2 = gen_new_label();                                 \
741
                                                              \
742
    tcg_gen_brcondi_tl(cond, t0, 0, l1);                      \
743
    tcg_gen_movi_tl(ret, 0);                                  \
744
    tcg_gen_br(l2);                                           \
745
    gen_set_label(l1);                                        \
746
    tcg_gen_movi_tl(ret, 1);                                  \
747
    gen_set_label(l2);                                        \
748
}
749
OP_CONDZ(gez, TCG_COND_GE);
750
OP_CONDZ(gtz, TCG_COND_GT);
751
OP_CONDZ(lez, TCG_COND_LE);
752
OP_CONDZ(ltz, TCG_COND_LT);
753
#undef OP_CONDZ
754

    
755
static inline void gen_save_pc(target_ulong pc)
756
{
757
    tcg_gen_movi_tl(cpu_PC, pc);
758
}
759

    
760
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
761
{
762
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
763
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
764
        gen_save_pc(ctx->pc);
765
        ctx->saved_pc = ctx->pc;
766
    }
767
    if (ctx->hflags != ctx->saved_hflags) {
768
        tcg_gen_movi_i32(hflags, ctx->hflags);
769
        ctx->saved_hflags = ctx->hflags;
770
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
771
        case MIPS_HFLAG_BR:
772
            break;
773
        case MIPS_HFLAG_BC:
774
        case MIPS_HFLAG_BL:
775
        case MIPS_HFLAG_B:
776
            tcg_gen_movi_tl(btarget, ctx->btarget);
777
            break;
778
        }
779
    }
780
}
781

    
782
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
783
{
784
    ctx->saved_hflags = ctx->hflags;
785
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
786
    case MIPS_HFLAG_BR:
787
        break;
788
    case MIPS_HFLAG_BC:
789
    case MIPS_HFLAG_BL:
790
    case MIPS_HFLAG_B:
791
        ctx->btarget = env->btarget;
792
        break;
793
    }
794
}
795

    
796
static inline void
797
generate_exception_err (DisasContext *ctx, int excp, int err)
798
{
799
    TCGv_i32 texcp = tcg_const_i32(excp);
800
    TCGv_i32 terr = tcg_const_i32(err);
801
    save_cpu_state(ctx, 1);
802
    gen_helper_raise_exception_err(texcp, terr);
803
    tcg_temp_free_i32(terr);
804
    tcg_temp_free_i32(texcp);
805
}
806

    
807
static inline void
808
generate_exception (DisasContext *ctx, int excp)
809
{
810
    save_cpu_state(ctx, 1);
811
    gen_helper_0i(raise_exception, excp);
812
}
813

    
814
/* Addresses computation */
815
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
816
{
817
    tcg_gen_add_tl(ret, arg0, arg1);
818

    
819
#if defined(TARGET_MIPS64)
820
    /* For compatibility with 32-bit code, data reference in user mode
821
       with Status_UX = 0 should be casted to 32-bit and sign extended.
822
       See the MIPS64 PRA manual, section 4.10. */
823
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
824
        !(ctx->hflags & MIPS_HFLAG_UX)) {
825
        tcg_gen_ext32s_i64(ret, ret);
826
    }
827
#endif
828
}
829

    
830
static inline void check_cp0_enabled(DisasContext *ctx)
831
{
832
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
833
        generate_exception_err(ctx, EXCP_CpU, 1);
834
}
835

    
836
static inline void check_cp1_enabled(DisasContext *ctx)
837
{
838
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
839
        generate_exception_err(ctx, EXCP_CpU, 1);
840
}
841

    
842
/* Verify that the processor is running with COP1X instructions enabled.
843
   This is associated with the nabla symbol in the MIPS32 and MIPS64
844
   opcode tables.  */
845

    
846
static inline void check_cop1x(DisasContext *ctx)
847
{
848
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
849
        generate_exception(ctx, EXCP_RI);
850
}
851

    
852
/* Verify that the processor is running with 64-bit floating-point
853
   operations enabled.  */
854

    
855
static inline void check_cp1_64bitmode(DisasContext *ctx)
856
{
857
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
858
        generate_exception(ctx, EXCP_RI);
859
}
860

    
861
/*
862
 * Verify if floating point register is valid; an operation is not defined
863
 * if bit 0 of any register specification is set and the FR bit in the
864
 * Status register equals zero, since the register numbers specify an
865
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
866
 * in the Status register equals one, both even and odd register numbers
867
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
868
 *
869
 * Multiple 64 bit wide registers can be checked by calling
870
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
871
 */
872
static inline void check_cp1_registers(DisasContext *ctx, int regs)
873
{
874
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
875
        generate_exception(ctx, EXCP_RI);
876
}
877

    
878
/* This code generates a "reserved instruction" exception if the
879
   CPU does not support the instruction set corresponding to flags. */
880
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
881
{
882
    if (unlikely(!(env->insn_flags & flags)))
883
        generate_exception(ctx, EXCP_RI);
884
}
885

    
886
/* This code generates a "reserved instruction" exception if 64-bit
887
   instructions are not enabled. */
888
static inline void check_mips_64(DisasContext *ctx)
889
{
890
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
891
        generate_exception(ctx, EXCP_RI);
892
}
893

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

    
911
#define OP_ST(insn,fname)                                                  \
912
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
913
{                                                                          \
914
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
915
}
916
OP_ST(sb,st8);
917
OP_ST(sh,st16);
918
OP_ST(sw,st32);
919
#if defined(TARGET_MIPS64)
920
OP_ST(sd,st64);
921
#endif
922
#undef OP_ST
923

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

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

    
988
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
989
                                  int base, int16_t offset)
990
{
991
    if (base == 0) {
992
        tcg_gen_movi_tl(addr, offset);
993
    } else if (offset == 0) {
994
        gen_load_gpr(addr, base);
995
    } else {
996
        tcg_gen_movi_tl(addr, offset);
997
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
998
    }
999
}
1000

    
1001
static target_ulong pc_relative_pc (DisasContext *ctx)
1002
{
1003
    target_ulong pc = ctx->pc;
1004

    
1005
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1006
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1007

    
1008
        pc -= branch_bytes;
1009
    }
1010

    
1011
    pc &= ~(target_ulong)3;
1012
    return pc;
1013
}
1014

    
1015
/* Load and store */
1016
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1017
                      int base, int16_t offset)
1018
{
1019
    const char *opn = "ldst";
1020
    TCGv t0 = tcg_temp_new();
1021
    TCGv t1 = tcg_temp_new();
1022

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

    
1179
/* Store conditional */
1180
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1181
                         int base, int16_t offset)
1182
{
1183
    const char *opn = "st_cond";
1184
    TCGv t0, t1;
1185

    
1186
    t0 = tcg_temp_local_new();
1187

    
1188
    gen_base_offset_addr(ctx, t0, base, offset);
1189
    /* Don't do NOP if destination is zero: we must perform the actual
1190
       memory access. */
1191

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

    
1213
/* Load and store */
1214
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1215
                          int base, int16_t offset)
1216
{
1217
    const char *opn = "flt_ldst";
1218
    TCGv t0 = tcg_temp_new();
1219

    
1220
    gen_base_offset_addr(ctx, t0, base, offset);
1221
    /* Don't do NOP if destination is zero: we must perform the actual
1222
       memory access. */
1223
    switch (opc) {
1224
    case OPC_LWC1:
1225
        {
1226
            TCGv_i32 fp0 = tcg_temp_new_i32();
1227

    
1228
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1229
            tcg_gen_trunc_tl_i32(fp0, t0);
1230
            gen_store_fpr32(fp0, ft);
1231
            tcg_temp_free_i32(fp0);
1232
        }
1233
        opn = "lwc1";
1234
        break;
1235
    case OPC_SWC1:
1236
        {
1237
            TCGv_i32 fp0 = tcg_temp_new_i32();
1238
            TCGv t1 = tcg_temp_new();
1239

    
1240
            gen_load_fpr32(fp0, ft);
1241
            tcg_gen_extu_i32_tl(t1, fp0);
1242
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1243
            tcg_temp_free(t1);
1244
            tcg_temp_free_i32(fp0);
1245
        }
1246
        opn = "swc1";
1247
        break;
1248
    case OPC_LDC1:
1249
        {
1250
            TCGv_i64 fp0 = tcg_temp_new_i64();
1251

    
1252
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1253
            gen_store_fpr64(ctx, fp0, ft);
1254
            tcg_temp_free_i64(fp0);
1255
        }
1256
        opn = "ldc1";
1257
        break;
1258
    case OPC_SDC1:
1259
        {
1260
            TCGv_i64 fp0 = tcg_temp_new_i64();
1261

    
1262
            gen_load_fpr64(ctx, fp0, ft);
1263
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1264
            tcg_temp_free_i64(fp0);
1265
        }
1266
        opn = "sdc1";
1267
        break;
1268
    default:
1269
        MIPS_INVAL(opn);
1270
        generate_exception(ctx, EXCP_RI);
1271
        goto out;
1272
    }
1273
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1274
 out:
1275
    tcg_temp_free(t0);
1276
}
1277

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

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

    
1299
            gen_load_gpr(t1, rs);
1300
            tcg_gen_addi_tl(t0, t1, uimm);
1301
            tcg_gen_ext32s_tl(t0, t0);
1302

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

    
1335
            gen_load_gpr(t1, rs);
1336
            tcg_gen_addi_tl(t0, t1, uimm);
1337

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

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

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

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

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

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

    
1443
    if (rt == 0) {
1444
        /* If no destination, treat it as a NOP. */
1445
        MIPS_DEBUG("NOP");
1446
        return;
1447
    }
1448

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

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

    
1523
/* Arithmetic */
1524
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1525
                       int rd, int rs, int rt)
1526
{
1527
    const char *opn = "arith";
1528

    
1529
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1530
       && opc != OPC_DADD && opc != OPC_DSUB) {
1531
        /* If no destination, treat it as a NOP.
1532
           For add & sub, we must generate the overflow exception when needed. */
1533
        MIPS_DEBUG("NOP");
1534
        return;
1535
    }
1536

    
1537
    switch (opc) {
1538
    case OPC_ADD:
1539
        {
1540
            TCGv t0 = tcg_temp_local_new();
1541
            TCGv t1 = tcg_temp_new();
1542
            TCGv t2 = tcg_temp_new();
1543
            int l1 = gen_new_label();
1544

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

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

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

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

    
1704
/* Conditional move */
1705
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1706
{
1707
    const char *opn = "cond move";
1708
    int l1;
1709

    
1710
    if (rd == 0) {
1711
        /* If no destination, treat it as a NOP.
1712
           For add & sub, we must generate the overflow exception when needed. */
1713
        MIPS_DEBUG("NOP");
1714
        return;
1715
    }
1716

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

    
1738
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1739
}
1740

    
1741
/* Logic */
1742
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1743
{
1744
    const char *opn = "logic";
1745

    
1746
    if (rd == 0) {
1747
        /* If no destination, treat it as a NOP. */
1748
        MIPS_DEBUG("NOP");
1749
        return;
1750
    }
1751

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

    
1801
/* Set on lower than */
1802
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1803
{
1804
    const char *opn = "slt";
1805
    TCGv t0, t1;
1806

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

    
1813
    t0 = tcg_temp_new();
1814
    t1 = tcg_temp_new();
1815
    gen_load_gpr(t0, rs);
1816
    gen_load_gpr(t1, rt);
1817
    switch (opc) {
1818
    case OPC_SLT:
1819
        gen_op_lt(cpu_gpr[rd], t0, t1);
1820
        opn = "slt";
1821
        break;
1822
    case OPC_SLTU:
1823
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1824
        opn = "sltu";
1825
        break;
1826
    }
1827
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1828
    tcg_temp_free(t0);
1829
    tcg_temp_free(t1);
1830
}
1831

    
1832
/* Shifts */
1833
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1834
                       int rd, int rs, int rt)
1835
{
1836
    const char *opn = "shifts";
1837
    TCGv t0, t1;
1838

    
1839
    if (rd == 0) {
1840
        /* If no destination, treat it as a NOP.
1841
           For add & sub, we must generate the overflow exception when needed. */
1842
        MIPS_DEBUG("NOP");
1843
        return;
1844
    }
1845

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

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

    
1913
/* Arithmetic on HI/LO registers */
1914
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1915
{
1916
    const char *opn = "hilo";
1917

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

    
1950
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1951
                        int rs, int rt)
1952
{
1953
    const char *opn = "mul/div";
1954
    TCGv t0, t1;
1955

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

    
1972
    gen_load_gpr(t0, rs);
1973
    gen_load_gpr(t1, rt);
1974
    switch (opc) {
1975
    case OPC_DIV:
1976
        {
1977
            int l1 = gen_new_label();
1978
            int l2 = gen_new_label();
1979

    
1980
            tcg_gen_ext32s_tl(t0, t0);
1981
            tcg_gen_ext32s_tl(t1, t1);
1982
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1983
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1984
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1985

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

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

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

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

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

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

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

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

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

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

    
2185
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2186
                            int rd, int rs, int rt)
2187
{
2188
    const char *opn = "mul vr54xx";
2189
    TCGv t0 = tcg_temp_new();
2190
    TCGv t1 = tcg_temp_new();
2191

    
2192
    gen_load_gpr(t0, rs);
2193
    gen_load_gpr(t1, rt);
2194

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

    
2260
 out:
2261
    tcg_temp_free(t0);
2262
    tcg_temp_free(t1);
2263
}
2264

    
2265
static void gen_cl (DisasContext *ctx, uint32_t opc,
2266
                    int rd, int rs)
2267
{
2268
    const char *opn = "CLx";
2269
    TCGv t0;
2270

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

    
2302
/* Traps */
2303
static void gen_trap (DisasContext *ctx, uint32_t opc,
2304
                      int rs, int rt, int16_t imm)
2305
{
2306
    int cond;
2307
    TCGv t0 = tcg_temp_new();
2308
    TCGv t1 = tcg_temp_new();
2309

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

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

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

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

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

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

    
2655
    ctx->btarget = btgt;
2656
    if (blink > 0) {
2657
        int post_delay = insn_bytes;
2658
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2659

    
2660
        if (opc != OPC_JALRC)
2661
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2662

    
2663
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2664
    }
2665

    
2666
 out:
2667
    if (insn_bytes == 2)
2668
        ctx->hflags |= MIPS_HFLAG_B16;
2669
    tcg_temp_free(t0);
2670
    tcg_temp_free(t1);
2671
}
2672

    
2673
/* special3 bitfield operations */
2674
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2675
                        int rs, int lsb, int msb)
2676
{
2677
    TCGv t0 = tcg_temp_new();
2678
    TCGv t1 = tcg_temp_new();
2679
    target_ulong mask;
2680

    
2681
    gen_load_gpr(t1, rs);
2682
    switch (opc) {
2683
    case OPC_EXT:
2684
        if (lsb + msb > 31)
2685
            goto fail;
2686
        tcg_gen_shri_tl(t0, t1, lsb);
2687
        if (msb != 31) {
2688
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2689
        } else {
2690
            tcg_gen_ext32s_tl(t0, t0);
2691
        }
2692
        break;
2693
#if defined(TARGET_MIPS64)
2694
    case OPC_DEXTM:
2695
        tcg_gen_shri_tl(t0, t1, lsb);
2696
        if (msb != 31) {
2697
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2698
        }
2699
        break;
2700
    case OPC_DEXTU:
2701
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2702
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2703
        break;
2704
    case OPC_DEXT:
2705
        tcg_gen_shri_tl(t0, t1, lsb);
2706
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2707
        break;
2708
#endif
2709
    case OPC_INS:
2710
        if (lsb > msb)
2711
            goto fail;
2712
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2713
        gen_load_gpr(t0, rt);
2714
        tcg_gen_andi_tl(t0, t0, ~mask);
2715
        tcg_gen_shli_tl(t1, t1, lsb);
2716
        tcg_gen_andi_tl(t1, t1, mask);
2717
        tcg_gen_or_tl(t0, t0, t1);
2718
        tcg_gen_ext32s_tl(t0, t0);
2719
        break;
2720
#if defined(TARGET_MIPS64)
2721
    case OPC_DINSM:
2722
        if (lsb > msb)
2723
            goto fail;
2724
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2725
        gen_load_gpr(t0, rt);
2726
        tcg_gen_andi_tl(t0, t0, ~mask);
2727
        tcg_gen_shli_tl(t1, t1, lsb);
2728
        tcg_gen_andi_tl(t1, t1, mask);
2729
        tcg_gen_or_tl(t0, t0, t1);
2730
        break;
2731
    case OPC_DINSU:
2732
        if (lsb > msb)
2733
            goto fail;
2734
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2735
        gen_load_gpr(t0, rt);
2736
        tcg_gen_andi_tl(t0, t0, ~mask);
2737
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2738
        tcg_gen_andi_tl(t1, t1, mask);
2739
        tcg_gen_or_tl(t0, t0, t1);
2740
        break;
2741
    case OPC_DINS:
2742
        if (lsb > msb)
2743
            goto fail;
2744
        gen_load_gpr(t0, rt);
2745
        mask = ((1ULL << (msb - lsb + 1)) - 1) << 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
        break;
2752
#endif
2753
    default:
2754
fail:
2755
        MIPS_INVAL("bitops");
2756
        generate_exception(ctx, EXCP_RI);
2757
        tcg_temp_free(t0);
2758
        tcg_temp_free(t1);
2759
        return;
2760
    }
2761
    gen_store_gpr(t0, rt);
2762
    tcg_temp_free(t0);
2763
    tcg_temp_free(t1);
2764
}
2765

    
2766
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2767
{
2768
    TCGv t0;
2769

    
2770
    if (rd == 0) {
2771
        /* If no destination, treat it as a NOP. */
2772
        MIPS_DEBUG("NOP");
2773
        return;
2774
    }
2775

    
2776
    t0 = tcg_temp_new();
2777
    gen_load_gpr(t0, rt);
2778
    switch (op2) {
2779
    case OPC_WSBH:
2780
        {
2781
            TCGv t1 = tcg_temp_new();
2782

    
2783
            tcg_gen_shri_tl(t1, t0, 8);
2784
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2785
            tcg_gen_shli_tl(t0, t0, 8);
2786
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2787
            tcg_gen_or_tl(t0, t0, t1);
2788
            tcg_temp_free(t1);
2789
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2790
        }
2791
        break;
2792
    case OPC_SEB:
2793
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2794
        break;
2795
    case OPC_SEH:
2796
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2797
        break;
2798
#if defined(TARGET_MIPS64)
2799
    case OPC_DSBH:
2800
        {
2801
            TCGv t1 = tcg_temp_new();
2802

    
2803
            tcg_gen_shri_tl(t1, t0, 8);
2804
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2805
            tcg_gen_shli_tl(t0, t0, 8);
2806
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2807
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2808
            tcg_temp_free(t1);
2809
        }
2810
        break;
2811
    case OPC_DSHD:
2812
        {
2813
            TCGv t1 = tcg_temp_new();
2814

    
2815
            tcg_gen_shri_tl(t1, t0, 16);
2816
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2817
            tcg_gen_shli_tl(t0, t0, 16);
2818
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2819
            tcg_gen_or_tl(t0, t0, t1);
2820
            tcg_gen_shri_tl(t1, t0, 32);
2821
            tcg_gen_shli_tl(t0, t0, 32);
2822
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2823
            tcg_temp_free(t1);
2824
        }
2825
        break;
2826
#endif
2827
    default:
2828
        MIPS_INVAL("bsfhl");
2829
        generate_exception(ctx, EXCP_RI);
2830
        tcg_temp_free(t0);
2831
        return;
2832
    }
2833
    tcg_temp_free(t0);
2834
}
2835

    
2836
#ifndef CONFIG_USER_ONLY
2837
/* CP0 (MMU and control) */
2838
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2839
{
2840
    TCGv_i32 t0 = tcg_temp_new_i32();
2841

    
2842
    tcg_gen_ld_i32(t0, cpu_env, off);
2843
    tcg_gen_ext_i32_tl(arg, t0);
2844
    tcg_temp_free_i32(t0);
2845
}
2846

    
2847
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2848
{
2849
    tcg_gen_ld_tl(arg, cpu_env, off);
2850
    tcg_gen_ext32s_tl(arg, arg);
2851
}
2852

    
2853
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2854
{
2855
    TCGv_i32 t0 = tcg_temp_new_i32();
2856

    
2857
    tcg_gen_trunc_tl_i32(t0, arg);
2858
    tcg_gen_st_i32(t0, cpu_env, off);
2859
    tcg_temp_free_i32(t0);
2860
}
2861

    
2862
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2863
{
2864
    tcg_gen_ext32s_tl(arg, arg);
2865
    tcg_gen_st_tl(arg, cpu_env, off);
2866
}
2867

    
2868
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2869
{
2870
    const char *rn = "invalid";
2871

    
2872
    if (sel != 0)
2873
        check_insn(env, ctx, ISA_MIPS32);
2874

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

    
3440
die:
3441
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3442
    generate_exception(ctx, EXCP_RI);
3443
}
3444

    
3445
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3446
{
3447
    const char *rn = "invalid";
3448

    
3449
    if (sel != 0)
3450
        check_insn(env, ctx, ISA_MIPS32);
3451

    
3452
    if (use_icount)
3453
        gen_io_start();
3454

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

    
4035
die:
4036
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4037
    generate_exception(ctx, EXCP_RI);
4038
}
4039

    
4040
#if defined(TARGET_MIPS64)
4041
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4042
{
4043
    const char *rn = "invalid";
4044

    
4045
    if (sel != 0)
4046
        check_insn(env, ctx, ISA_MIPS64);
4047

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

    
4602
die:
4603
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4604
    generate_exception(ctx, EXCP_RI);
4605
}
4606

    
4607
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4608
{
4609
    const char *rn = "invalid";
4610

    
4611
    if (sel != 0)
4612
        check_insn(env, ctx, ISA_MIPS64);
4613

    
4614
    if (use_icount)
4615
        gen_io_start();
4616

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

    
5188
die:
5189
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5190
    generate_exception(ctx, EXCP_RI);
5191
}
5192
#endif /* TARGET_MIPS64 */
5193

    
5194
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5195
                     int u, int sel, int h)
5196
{
5197
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5198
    TCGv t0 = tcg_temp_local_new();
5199

    
5200
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5201
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5202
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5203
        tcg_gen_movi_tl(t0, -1);
5204
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5205
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5206
        tcg_gen_movi_tl(t0, -1);
5207
    else if (u == 0) {
5208
        switch (rt) {
5209
        case 2:
5210
            switch (sel) {
5211
            case 1:
5212
                gen_helper_mftc0_tcstatus(t0);
5213
                break;
5214
            case 2:
5215
                gen_helper_mftc0_tcbind(t0);
5216
                break;
5217
            case 3:
5218
                gen_helper_mftc0_tcrestart(t0);
5219
                break;
5220
            case 4:
5221
                gen_helper_mftc0_tchalt(t0);
5222
                break;
5223
            case 5:
5224
                gen_helper_mftc0_tccontext(t0);
5225
                break;
5226
            case 6:
5227
                gen_helper_mftc0_tcschedule(t0);
5228
                break;
5229
            case 7:
5230
                gen_helper_mftc0_tcschefback(t0);
5231
                break;
5232
            default:
5233
                gen_mfc0(env, ctx, t0, rt, sel);
5234
                break;
5235
            }
5236
            break;
5237
        case 10:
5238
            switch (sel) {
5239
            case 0:
5240
                gen_helper_mftc0_entryhi(t0);
5241
                break;
5242
            default:
5243
                gen_mfc0(env, ctx, t0, rt, sel);
5244
                break;
5245
            }
5246
        case 12:
5247
            switch (sel) {
5248
            case 0:
5249
                gen_helper_mftc0_status(t0);
5250
                break;
5251
            default:
5252
                gen_mfc0(env, ctx, t0, rt, sel);
5253
                break;
5254
            }
5255
        case 23:
5256
            switch (sel) {
5257
            case 0:
5258
                gen_helper_mftc0_debug(t0);
5259
                break;
5260
            default:
5261
                gen_mfc0(env, ctx, t0, rt, sel);
5262
                break;
5263
            }
5264
            break;
5265
        default:
5266
            gen_mfc0(env, ctx, t0, rt, sel);
5267
        }
5268
    } else switch (sel) {
5269
    /* GPR registers. */
5270
    case 0:
5271
        gen_helper_1i(mftgpr, t0, rt);
5272
        break;
5273
    /* Auxiliary CPU registers */
5274
    case 1:
5275
        switch (rt) {
5276
        case 0:
5277
            gen_helper_1i(mftlo, t0, 0);
5278
            break;
5279
        case 1:
5280
            gen_helper_1i(mfthi, t0, 0);
5281
            break;
5282
        case 2:
5283
            gen_helper_1i(mftacx, t0, 0);
5284
            break;
5285
        case 4:
5286
            gen_helper_1i(mftlo, t0, 1);
5287
            break;
5288
        case 5:
5289
            gen_helper_1i(mfthi, t0, 1);
5290
            break;
5291
        case 6:
5292
            gen_helper_1i(mftacx, t0, 1);
5293
            break;
5294
        case 8:
5295
            gen_helper_1i(mftlo, t0, 2);
5296
            break;
5297
        case 9:
5298
            gen_helper_1i(mfthi, t0, 2);
5299
            break;
5300
        case 10:
5301
            gen_helper_1i(mftacx, t0, 2);
5302
            break;
5303
        case 12:
5304
            gen_helper_1i(mftlo, t0, 3);
5305
            break;
5306
        case 13:
5307
            gen_helper_1i(mfthi, t0, 3);
5308
            break;
5309
        case 14:
5310
            gen_helper_1i(mftacx, t0, 3);
5311
            break;
5312
        case 16:
5313
            gen_helper_mftdsp(t0);
5314
            break;
5315
        default:
5316
            goto die;
5317
        }
5318
        break;
5319
    /* Floating point (COP1). */
5320
    case 2:
5321
        /* XXX: For now we support only a single FPU context. */
5322
        if (h == 0) {
5323
            TCGv_i32 fp0 = tcg_temp_new_i32();
5324

    
5325
            gen_load_fpr32(fp0, rt);
5326
            tcg_gen_ext_i32_tl(t0, fp0);
5327
            tcg_temp_free_i32(fp0);
5328
        } else {
5329
            TCGv_i32 fp0 = tcg_temp_new_i32();
5330

    
5331
            gen_load_fpr32h(fp0, rt);
5332
            tcg_gen_ext_i32_tl(t0, fp0);
5333
            tcg_temp_free_i32(fp0);
5334
        }
5335
        break;
5336
    case 3:
5337
        /* XXX: For now we support only a single FPU context. */
5338
        gen_helper_1i(cfc1, t0, rt);
5339
        break;
5340
    /* COP2: Not implemented. */
5341
    case 4:
5342
    case 5:
5343
        /* fall through */
5344
    default:
5345
        goto die;
5346
    }
5347
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5348
    gen_store_gpr(t0, rd);
5349
    tcg_temp_free(t0);
5350
    return;
5351

    
5352
die:
5353
    tcg_temp_free(t0);
5354
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5355
    generate_exception(ctx, EXCP_RI);
5356
}
5357

    
5358
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5359
                     int u, int sel, int h)
5360
{
5361
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5362
    TCGv t0 = tcg_temp_local_new();
5363

    
5364
    gen_load_gpr(t0, rt);
5365
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5366
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5367
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5368
        /* NOP */ ;
5369
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5370
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5371
        /* NOP */ ;
5372
    else if (u == 0) {
5373
        switch (rd) {
5374
        case 2:
5375
            switch (sel) {
5376
            case 1:
5377
                gen_helper_mttc0_tcstatus(t0);
5378
                break;
5379
            case 2:
5380
                gen_helper_mttc0_tcbind(t0);
5381
                break;
5382
            case 3:
5383
                gen_helper_mttc0_tcrestart(t0);
5384
                break;
5385
            case 4:
5386
                gen_helper_mttc0_tchalt(t0);
5387
                break;
5388
            case 5:
5389
                gen_helper_mttc0_tccontext(t0);
5390
                break;
5391
            case 6:
5392
                gen_helper_mttc0_tcschedule(t0);
5393
                break;
5394
            case 7:
5395
                gen_helper_mttc0_tcschefback(t0);
5396
                break;
5397
            default:
5398
                gen_mtc0(env, ctx, t0, rd, sel);
5399
                break;
5400
            }
5401
            break;
5402
        case 10:
5403
            switch (sel) {
5404
            case 0:
5405
                gen_helper_mttc0_entryhi(t0);
5406
                break;
5407
            default:
5408
                gen_mtc0(env, ctx, t0, rd, sel);
5409
                break;
5410
            }
5411
        case 12:
5412
            switch (sel) {
5413
            case 0:
5414
                gen_helper_mttc0_status(t0);
5415
                break;
5416
            default:
5417
                gen_mtc0(env, ctx, t0, rd, sel);
5418
                break;
5419
            }
5420
        case 23:
5421
            switch (sel) {
5422
            case 0:
5423
                gen_helper_mttc0_debug(t0);
5424
                break;
5425
            default:
5426
                gen_mtc0(env, ctx, t0, rd, sel);
5427
                break;
5428
            }
5429
            break;
5430
        default:
5431
            gen_mtc0(env, ctx, t0, rd, sel);
5432
        }
5433
    } else switch (sel) {
5434
    /* GPR registers. */
5435
    case 0:
5436
        gen_helper_1i(mttgpr, t0, rd);
5437
        break;
5438
    /* Auxiliary CPU registers */
5439
    case 1:
5440
        switch (rd) {
5441
        case 0:
5442
            gen_helper_1i(mttlo, t0, 0);
5443
            break;
5444
        case 1:
5445
            gen_helper_1i(mtthi, t0, 0);
5446
            break;
5447
        case 2:
5448
            gen_helper_1i(mttacx, t0, 0);
5449
            break;
5450
        case 4:
5451
            gen_helper_1i(mttlo, t0, 1);
5452
            break;
5453
        case 5:
5454
            gen_helper_1i(mtthi, t0, 1);
5455
            break;
5456
        case 6:
5457
            gen_helper_1i(mttacx, t0, 1);
5458
            break;
5459
        case 8:
5460
            gen_helper_1i(mttlo, t0, 2);
5461
            break;
5462
        case 9:
5463
            gen_helper_1i(mtthi, t0, 2);
5464
            break;
5465
        case 10:
5466
            gen_helper_1i(mttacx, t0, 2);
5467
            break;
5468
        case 12:
5469
            gen_helper_1i(mttlo, t0, 3);
5470
            break;
5471
        case 13:
5472
            gen_helper_1i(mtthi, t0, 3);
5473
            break;
5474
        case 14:
5475
            gen_helper_1i(mttacx, t0, 3);
5476
            break;
5477
        case 16:
5478
            gen_helper_mttdsp(t0);
5479
            break;
5480
        default:
5481
            goto die;
5482
        }
5483
        break;
5484
    /* Floating point (COP1). */
5485
    case 2:
5486
        /* XXX: For now we support only a single FPU context. */
5487
        if (h == 0) {
5488
            TCGv_i32 fp0 = tcg_temp_new_i32();
5489

    
5490
            tcg_gen_trunc_tl_i32(fp0, t0);
5491
            gen_store_fpr32(fp0, rd);
5492
            tcg_temp_free_i32(fp0);
5493
        } else {
5494
            TCGv_i32 fp0 = tcg_temp_new_i32();
5495

    
5496
            tcg_gen_trunc_tl_i32(fp0, t0);
5497
            gen_store_fpr32h(fp0, rd);
5498
            tcg_temp_free_i32(fp0);
5499
        }
5500
        break;
5501
    case 3:
5502
        /* XXX: For now we support only a single FPU context. */
5503
        gen_helper_1i(ctc1, t0, rd);
5504
        break;
5505
    /* COP2: Not implemented. */
5506
    case 4:
5507
    case 5:
5508
        /* fall through */
5509
    default:
5510
        goto die;
5511
    }
5512
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5513
    tcg_temp_free(t0);
5514
    return;
5515

    
5516
die:
5517
    tcg_temp_free(t0);
5518
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5519
    generate_exception(ctx, EXCP_RI);
5520
}
5521

    
5522
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5523
{
5524
    const char *opn = "ldst";
5525

    
5526
    switch (opc) {
5527
    case OPC_MFC0:
5528
        if (rt == 0) {
5529
            /* Treat as NOP. */
5530
            return;
5531
        }
5532
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5533
        opn = "mfc0";
5534
        break;
5535
    case OPC_MTC0:
5536
        {
5537
            TCGv t0 = tcg_temp_new();
5538

    
5539
            gen_load_gpr(t0, rt);
5540
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5541
            tcg_temp_free(t0);
5542
        }
5543
        opn = "mtc0";
5544
        break;
5545
#if defined(TARGET_MIPS64)
5546
    case OPC_DMFC0:
5547
        check_insn(env, ctx, ISA_MIPS3);
5548
        if (rt == 0) {
5549
            /* Treat as NOP. */
5550
            return;
5551
        }
5552
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5553
        opn = "dmfc0";
5554
        break;
5555
    case OPC_DMTC0:
5556
        check_insn(env, ctx, ISA_MIPS3);
5557
        {
5558
            TCGv t0 = tcg_temp_new();
5559

    
5560
            gen_load_gpr(t0, rt);
5561
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5562
            tcg_temp_free(t0);
5563
        }
5564
        opn = "dmtc0";
5565
        break;
5566
#endif
5567
    case OPC_MFTR:
5568
        check_insn(env, ctx, ASE_MT);
5569
        if (rd == 0) {
5570
            /* Treat as NOP. */
5571
            return;
5572
        }
5573
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5574
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5575
        opn = "mftr";
5576
        break;
5577
    case OPC_MTTR:
5578
        check_insn(env, ctx, ASE_MT);
5579
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5580
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5581
        opn = "mttr";
5582
        break;
5583
    case OPC_TLBWI:
5584
        opn = "tlbwi";
5585
        if (!env->tlb->helper_tlbwi)
5586
            goto die;
5587
        gen_helper_tlbwi();
5588
        break;
5589
    case OPC_TLBWR:
5590
        opn = "tlbwr";
5591
        if (!env->tlb->helper_tlbwr)
5592
            goto die;
5593
        gen_helper_tlbwr();
5594
        break;
5595
    case OPC_TLBP:
5596
        opn = "tlbp";
5597
        if (!env->tlb->helper_tlbp)
5598
            goto die;
5599
        gen_helper_tlbp();
5600
        break;
5601
    case OPC_TLBR:
5602
        opn = "tlbr";
5603
        if (!env->tlb->helper_tlbr)
5604
            goto die;
5605
        gen_helper_tlbr();
5606
        break;
5607
    case OPC_ERET:
5608
        opn = "eret";
5609
        check_insn(env, ctx, ISA_MIPS2);
5610
        gen_helper_eret();
5611
        ctx->bstate = BS_EXCP;
5612
        break;
5613
    case OPC_DERET:
5614
        opn = "deret";
5615
        check_insn(env, ctx, ISA_MIPS32);
5616
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5617
            MIPS_INVAL(opn);
5618
            generate_exception(ctx, EXCP_RI);
5619
        } else {
5620
            gen_helper_deret();
5621
            ctx->bstate = BS_EXCP;
5622
        }
5623
        break;
5624
    case OPC_WAIT:
5625
        opn = "wait";
5626
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5627
        /* If we get an exception, we want to restart at next instruction */
5628
        ctx->pc += 4;
5629
        save_cpu_state(ctx, 1);
5630
        ctx->pc -= 4;
5631
        gen_helper_wait();
5632
        ctx->bstate = BS_EXCP;
5633
        break;
5634
    default:
5635
 die:
5636
        MIPS_INVAL(opn);
5637
        generate_exception(ctx, EXCP_RI);
5638
        return;
5639
    }
5640
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5641
}
5642
#endif /* !CONFIG_USER_ONLY */
5643

    
5644
/* CP1 Branches (before delay slot) */
5645
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5646
                                 int32_t cc, int32_t offset)
5647
{
5648
    target_ulong btarget;
5649
    const char *opn = "cp1 cond branch";
5650
    TCGv_i32 t0 = tcg_temp_new_i32();
5651

    
5652
    if (cc != 0)
5653
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5654

    
5655
    btarget = ctx->pc + 4 + offset;
5656

    
5657
    switch (op) {
5658
    case OPC_BC1F:
5659
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5660
        tcg_gen_not_i32(t0, t0);
5661
        tcg_gen_andi_i32(t0, t0, 1);
5662
        tcg_gen_extu_i32_tl(bcond, t0);
5663
        opn = "bc1f";
5664
        goto not_likely;
5665
    case OPC_BC1FL:
5666
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5667
        tcg_gen_not_i32(t0, t0);
5668
        tcg_gen_andi_i32(t0, t0, 1);
5669
        tcg_gen_extu_i32_tl(bcond, t0);
5670
        opn = "bc1fl";
5671
        goto likely;
5672
    case OPC_BC1T:
5673
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5674
        tcg_gen_andi_i32(t0, t0, 1);
5675
        tcg_gen_extu_i32_tl(bcond, t0);
5676
        opn = "bc1t";
5677
        goto not_likely;
5678
    case OPC_BC1TL:
5679
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5680
        tcg_gen_andi_i32(t0, t0, 1);
5681
        tcg_gen_extu_i32_tl(bcond, t0);
5682
        opn = "bc1tl";
5683
    likely:
5684
        ctx->hflags |= MIPS_HFLAG_BL;
5685
        break;
5686
    case OPC_BC1FANY2:
5687
        {
5688
            TCGv_i32 t1 = tcg_temp_new_i32();
5689
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5690
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5691
            tcg_gen_or_i32(t0, t0, t1);
5692
            tcg_temp_free_i32(t1);
5693
            tcg_gen_not_i32(t0, t0);
5694
            tcg_gen_andi_i32(t0, t0, 1);
5695
            tcg_gen_extu_i32_tl(bcond, t0);
5696
        }
5697
        opn = "bc1any2f";
5698
        goto not_likely;
5699
    case OPC_BC1TANY2:
5700
        {
5701
            TCGv_i32 t1 = tcg_temp_new_i32();
5702
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5703
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5704
            tcg_gen_or_i32(t0, t0, t1);
5705
            tcg_temp_free_i32(t1);
5706
            tcg_gen_andi_i32(t0, t0, 1);
5707
            tcg_gen_extu_i32_tl(bcond, t0);
5708
        }
5709
        opn = "bc1any2t";
5710
        goto not_likely;
5711
    case OPC_BC1FANY4:
5712
        {
5713
            TCGv_i32 t1 = tcg_temp_new_i32();
5714
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5715
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5716
            tcg_gen_or_i32(t0, t0, t1);
5717
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5718
            tcg_gen_or_i32(t0, t0, t1);
5719
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5720
            tcg_gen_or_i32(t0, t0, t1);
5721
            tcg_temp_free_i32(t1);
5722
            tcg_gen_not_i32(t0, t0);
5723
            tcg_gen_andi_i32(t0, t0, 1);
5724
            tcg_gen_extu_i32_tl(bcond, t0);
5725
        }
5726
        opn = "bc1any4f";
5727
        goto not_likely;
5728
    case OPC_BC1TANY4:
5729
        {
5730
            TCGv_i32 t1 = tcg_temp_new_i32();
5731
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5732
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5733
            tcg_gen_or_i32(t0, t0, t1);
5734
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5735
            tcg_gen_or_i32(t0, t0, t1);
5736
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5737
            tcg_gen_or_i32(t0, t0, t1);
5738
            tcg_temp_free_i32(t1);
5739
            tcg_gen_andi_i32(t0, t0, 1);
5740
            tcg_gen_extu_i32_tl(bcond, t0);
5741
        }
5742
        opn = "bc1any4t";
5743
    not_likely:
5744
        ctx->hflags |= MIPS_HFLAG_BC;
5745
        break;
5746
    default:
5747
        MIPS_INVAL(opn);
5748
        generate_exception (ctx, EXCP_RI);
5749
        goto out;
5750
    }
5751
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5752
               ctx->hflags, btarget);
5753
    ctx->btarget = btarget;
5754

    
5755
 out:
5756
    tcg_temp_free_i32(t0);
5757
}
5758

    
5759
/* Coprocessor 1 (FPU) */
5760

    
5761
#define FOP(func, fmt) (((fmt) << 21) | (func))
5762

    
5763
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5764
{
5765
    const char *opn = "cp1 move";
5766
    TCGv t0 = tcg_temp_new();
5767

    
5768
    switch (opc) {
5769
    case OPC_MFC1:
5770
        {
5771
            TCGv_i32 fp0 = tcg_temp_new_i32();
5772

    
5773
            gen_load_fpr32(fp0, fs);
5774
            tcg_gen_ext_i32_tl(t0, fp0);
5775
            tcg_temp_free_i32(fp0);
5776
        }
5777
        gen_store_gpr(t0, rt);
5778
        opn = "mfc1";
5779
        break;
5780
    case OPC_MTC1:
5781
        gen_load_gpr(t0, rt);
5782
        {
5783
            TCGv_i32 fp0 = tcg_temp_new_i32();
5784

    
5785
            tcg_gen_trunc_tl_i32(fp0, t0);
5786
            gen_store_fpr32(fp0, fs);
5787
            tcg_temp_free_i32(fp0);
5788
        }
5789
        opn = "mtc1";
5790
        break;
5791
    case OPC_CFC1:
5792
        gen_helper_1i(cfc1, t0, fs);
5793
        gen_store_gpr(t0, rt);
5794
        opn = "cfc1";
5795
        break;
5796
    case OPC_CTC1:
5797
        gen_load_gpr(t0, rt);
5798
        gen_helper_1i(ctc1, t0, fs);
5799
        opn = "ctc1";
5800
        break;
5801
#if defined(TARGET_MIPS64)
5802
    case OPC_DMFC1:
5803
        gen_load_fpr64(ctx, t0, fs);
5804
        gen_store_gpr(t0, rt);
5805
        opn = "dmfc1";
5806
        break;
5807
    case OPC_DMTC1:
5808
        gen_load_gpr(t0, rt);
5809
        gen_store_fpr64(ctx, t0, fs);
5810
        opn = "dmtc1";
5811
        break;
5812
#endif
5813
    case OPC_MFHC1:
5814
        {
5815
            TCGv_i32 fp0 = tcg_temp_new_i32();
5816

    
5817
            gen_load_fpr32h(fp0, fs);
5818
            tcg_gen_ext_i32_tl(t0, fp0);
5819
            tcg_temp_free_i32(fp0);
5820
        }
5821
        gen_store_gpr(t0, rt);
5822
        opn = "mfhc1";
5823
        break;
5824
    case OPC_MTHC1:
5825
        gen_load_gpr(t0, rt);
5826
        {
5827
            TCGv_i32 fp0 = tcg_temp_new_i32();
5828

    
5829
            tcg_gen_trunc_tl_i32(fp0, t0);
5830
            gen_store_fpr32h(fp0, fs);
5831
            tcg_temp_free_i32(fp0);
5832
        }
5833
        opn = "mthc1";
5834
        break;
5835
    default:
5836
        MIPS_INVAL(opn);
5837
        generate_exception (ctx, EXCP_RI);
5838
        goto out;
5839
    }
5840
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5841

    
5842
 out:
5843
    tcg_temp_free(t0);
5844
}
5845

    
5846
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5847
{
5848
    int l1;
5849
    TCGCond cond;
5850
    TCGv_i32 t0;
5851

    
5852
    if (rd == 0) {
5853
        /* Treat as NOP. */
5854
        return;
5855
    }
5856

    
5857
    if (tf)
5858
        cond = TCG_COND_EQ;
5859
    else
5860
        cond = TCG_COND_NE;
5861

    
5862
    l1 = gen_new_label();
5863
    t0 = tcg_temp_new_i32();
5864
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5865
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5866
    tcg_temp_free_i32(t0);
5867
    if (rs == 0) {
5868
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5869
    } else {
5870
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5871
    }
5872
    gen_set_label(l1);
5873
}
5874

    
5875
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5876
{
5877
    int cond;
5878
    TCGv_i32 t0 = tcg_temp_new_i32();
5879
    int l1 = gen_new_label();
5880

    
5881
    if (tf)
5882
        cond = TCG_COND_EQ;
5883
    else
5884
        cond = TCG_COND_NE;
5885

    
5886
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5887
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5888
    gen_load_fpr32(t0, fs);
5889
    gen_store_fpr32(t0, fd);
5890
    gen_set_label(l1);
5891
    tcg_temp_free_i32(t0);
5892
}
5893

    
5894
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5895
{
5896
    int cond;
5897
    TCGv_i32 t0 = tcg_temp_new_i32();
5898
    TCGv_i64 fp0;
5899
    int l1 = gen_new_label();
5900

    
5901
    if (tf)
5902
        cond = TCG_COND_EQ;
5903
    else
5904
        cond = TCG_COND_NE;
5905

    
5906
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5907
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5908
    tcg_temp_free_i32(t0);
5909
    fp0 = tcg_temp_new_i64();
5910
    gen_load_fpr64(ctx, fp0, fs);
5911
    gen_store_fpr64(ctx, fp0, fd);
5912
    tcg_temp_free_i64(fp0);
5913
    gen_set_label(l1);
5914
}
5915

    
5916
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5917
{
5918
    int cond;
5919
    TCGv_i32 t0 = tcg_temp_new_i32();
5920
    int l1 = gen_new_label();
5921
    int l2 = gen_new_label();
5922

    
5923
    if (tf)
5924
        cond = TCG_COND_EQ;
5925
    else
5926
        cond = TCG_COND_NE;
5927

    
5928
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5929
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5930
    gen_load_fpr32(t0, fs);
5931
    gen_store_fpr32(t0, fd);
5932
    gen_set_label(l1);
5933

    
5934
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
5935
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5936
    gen_load_fpr32h(t0, fs);
5937
    gen_store_fpr32h(t0, fd);
5938
    tcg_temp_free_i32(t0);
5939
    gen_set_label(l2);
5940
}
5941

    
5942

    
5943
static void gen_farith (DisasContext *ctx, uint32_t op1,
5944
                        int ft, int fs, int fd, int cc)
5945
{
5946
    const char *opn = "farith";
5947
    const char *condnames[] = {
5948
            "c.f",
5949
            "c.un",
5950
            "c.eq",
5951
            "c.ueq",
5952
            "c.olt",
5953
            "c.ult",
5954
            "c.ole",
5955
            "c.ule",
5956
            "c.sf",
5957
            "c.ngle",
5958
            "c.seq",
5959
            "c.ngl",
5960
            "c.lt",
5961
            "c.nge",
5962
            "c.le",
5963
            "c.ngt",
5964
    };
5965
    const char *condnames_abs[] = {
5966
            "cabs.f",
5967
            "cabs.un",
5968
            "cabs.eq",
5969
            "cabs.ueq",
5970
            "cabs.olt",
5971
            "cabs.ult",
5972
            "cabs.ole",
5973
            "cabs.ule",
5974
            "cabs.sf",
5975
            "cabs.ngle",
5976
            "cabs.seq",
5977
            "cabs.ngl",
5978
            "cabs.lt",
5979
            "cabs.nge",
5980
            "cabs.le",
5981
            "cabs.ngt",
5982
    };
5983
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5984
    uint32_t func = ctx->opcode & 0x3f;
5985

    
5986
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5987
    case FOP(0, 16):
5988
        {
5989
            TCGv_i32 fp0 = tcg_temp_new_i32();
5990
            TCGv_i32 fp1 = tcg_temp_new_i32();
5991

    
5992
            gen_load_fpr32(fp0, fs);
5993
            gen_load_fpr32(fp1, ft);
5994
            gen_helper_float_add_s(fp0, fp0, fp1);
5995
            tcg_temp_free_i32(fp1);
5996
            gen_store_fpr32(fp0, fd);
5997
            tcg_temp_free_i32(fp0);
5998
        }
5999
        opn = "add.s";
6000
        optype = BINOP;
6001
        break;
6002
    case FOP(1, 16):
6003
        {
6004
            TCGv_i32 fp0 = tcg_temp_new_i32();
6005
            TCGv_i32 fp1 = tcg_temp_new_i32();
6006

    
6007
            gen_load_fpr32(fp0, fs);
6008
            gen_load_fpr32(fp1, ft);
6009
            gen_helper_float_sub_s(fp0, fp0, fp1);
6010
            tcg_temp_free_i32(fp1);
6011
            gen_store_fpr32(fp0, fd);
6012
            tcg_temp_free_i32(fp0);
6013
        }
6014
        opn = "sub.s";
6015
        optype = BINOP;
6016
        break;
6017
    case FOP(2, 16):
6018
        {
6019
            TCGv_i32 fp0 = tcg_temp_new_i32();
6020
            TCGv_i32 fp1 = tcg_temp_new_i32();
6021

    
6022
            gen_load_fpr32(fp0, fs);
6023
            gen_load_fpr32(fp1, ft);
6024
            gen_helper_float_mul_s(fp0, fp0, fp1);
6025
            tcg_temp_free_i32(fp1);
6026
            gen_store_fpr32(fp0, fd);
6027
            tcg_temp_free_i32(fp0);
6028
        }
6029
        opn = "mul.s";
6030
        optype = BINOP;
6031
        break;
6032
    case FOP(3, 16):
6033
        {
6034
            TCGv_i32 fp0 = tcg_temp_new_i32();
6035
            TCGv_i32 fp1 = tcg_temp_new_i32();
6036

    
6037
            gen_load_fpr32(fp0, fs);
6038
            gen_load_fpr32(fp1, ft);
6039
            gen_helper_float_div_s(fp0, fp0, fp1);
6040
            tcg_temp_free_i32(fp1);
6041
            gen_store_fpr32(fp0, fd);
6042
            tcg_temp_free_i32(fp0);
6043
        }
6044
        opn = "div.s";
6045
        optype = BINOP;
6046
        break;
6047
    case FOP(4, 16):
6048
        {
6049
            TCGv_i32 fp0 = tcg_temp_new_i32();
6050

    
6051
            gen_load_fpr32(fp0, fs);
6052
            gen_helper_float_sqrt_s(fp0, fp0);
6053
            gen_store_fpr32(fp0, fd);
6054
            tcg_temp_free_i32(fp0);
6055
        }
6056
        opn = "sqrt.s";
6057
        break;
6058
    case FOP(5, 16):
6059
        {
6060
            TCGv_i32 fp0 = tcg_temp_new_i32();
6061

    
6062
            gen_load_fpr32(fp0, fs);
6063
            gen_helper_float_abs_s(fp0, fp0);
6064
            gen_store_fpr32(fp0, fd);
6065
            tcg_temp_free_i32(fp0);
6066
        }
6067
        opn = "abs.s";
6068
        break;
6069
    case FOP(6, 16):
6070
        {
6071
            TCGv_i32 fp0 = tcg_temp_new_i32();
6072

    
6073
            gen_load_fpr32(fp0, fs);
6074
            gen_store_fpr32(fp0, fd);
6075
            tcg_temp_free_i32(fp0);
6076
        }
6077
        opn = "mov.s";
6078
        break;
6079
    case FOP(7, 16):
6080
        {
6081
            TCGv_i32 fp0 = tcg_temp_new_i32();
6082

    
6083
            gen_load_fpr32(fp0, fs);
6084
            gen_helper_float_chs_s(fp0, fp0);
6085
            gen_store_fpr32(fp0, fd);
6086
            tcg_temp_free_i32(fp0);
6087
        }
6088
        opn = "neg.s";
6089
        break;
6090
    case FOP(8, 16):
6091
        check_cp1_64bitmode(ctx);
6092
        {
6093
            TCGv_i32 fp32 = tcg_temp_new_i32();
6094
            TCGv_i64 fp64 = tcg_temp_new_i64();
6095

    
6096
            gen_load_fpr32(fp32, fs);
6097
            gen_helper_float_roundl_s(fp64, fp32);
6098
            tcg_temp_free_i32(fp32);
6099
            gen_store_fpr64(ctx, fp64, fd);
6100
            tcg_temp_free_i64(fp64);
6101
        }
6102
        opn = "round.l.s";
6103
        break;
6104
    case FOP(9, 16):
6105
        check_cp1_64bitmode(ctx);
6106
        {
6107
            TCGv_i32 fp32 = tcg_temp_new_i32();
6108
            TCGv_i64 fp64 = tcg_temp_new_i64();
6109

    
6110
            gen_load_fpr32(fp32, fs);
6111
            gen_helper_float_truncl_s(fp64, fp32);
6112
            tcg_temp_free_i32(fp32);
6113
            gen_store_fpr64(ctx, fp64, fd);
6114
            tcg_temp_free_i64(fp64);
6115
        }
6116
        opn = "trunc.l.s";
6117
        break;
6118
    case FOP(10, 16):
6119
        check_cp1_64bitmode(ctx);
6120
        {
6121
            TCGv_i32 fp32 = tcg_temp_new_i32();
6122
            TCGv_i64 fp64 = tcg_temp_new_i64();
6123

    
6124
            gen_load_fpr32(fp32, fs);
6125
            gen_helper_float_ceill_s(fp64, fp32);
6126
            tcg_temp_free_i32(fp32);
6127
            gen_store_fpr64(ctx, fp64, fd);
6128
            tcg_temp_free_i64(fp64);
6129
        }
6130
        opn = "ceil.l.s";
6131
        break;
6132
    case FOP(11, 16):
6133
        check_cp1_64bitmode(ctx);
6134
        {
6135
            TCGv_i32 fp32 = tcg_temp_new_i32();
6136
            TCGv_i64 fp64 = tcg_temp_new_i64();
6137

    
6138
            gen_load_fpr32(fp32, fs);
6139
            gen_helper_float_floorl_s(fp64, fp32);
6140
            tcg_temp_free_i32(fp32);
6141
            gen_store_fpr64(ctx, fp64, fd);
6142
            tcg_temp_free_i64(fp64);
6143
        }
6144
        opn = "floor.l.s";
6145
        break;
6146
    case FOP(12, 16):
6147
        {
6148
            TCGv_i32 fp0 = tcg_temp_new_i32();
6149

    
6150
            gen_load_fpr32(fp0, fs);
6151
            gen_helper_float_roundw_s(fp0, fp0);
6152
            gen_store_fpr32(fp0, fd);
6153
            tcg_temp_free_i32(fp0);
6154
        }
6155
        opn = "round.w.s";
6156
        break;
6157
    case FOP(13, 16):
6158
        {
6159
            TCGv_i32 fp0 = tcg_temp_new_i32();
6160

    
6161
            gen_load_fpr32(fp0, fs);
6162
            gen_helper_float_truncw_s(fp0, fp0);
6163
            gen_store_fpr32(fp0, fd);
6164
            tcg_temp_free_i32(fp0);
6165
        }
6166
        opn = "trunc.w.s";
6167
        break;
6168
    case FOP(14, 16):
6169
        {
6170
            TCGv_i32 fp0 = tcg_temp_new_i32();
6171

    
6172
            gen_load_fpr32(fp0, fs);
6173
            gen_helper_float_ceilw_s(fp0, fp0);
6174
            gen_store_fpr32(fp0, fd);
6175
            tcg_temp_free_i32(fp0);
6176
        }
6177
        opn = "ceil.w.s";
6178
        break;
6179
    case FOP(15, 16):
6180
        {
6181
            TCGv_i32 fp0 = tcg_temp_new_i32();
6182

    
6183
            gen_load_fpr32(fp0, fs);
6184
            gen_helper_float_floorw_s(fp0, fp0);
6185
            gen_store_fpr32(fp0, fd);
6186
            tcg_temp_free_i32(fp0);
6187
        }
6188
        opn = "floor.w.s";
6189
        break;
6190
    case FOP(17, 16):
6191
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6192
        opn = "movcf.s";
6193
        break;
6194
    case FOP(18, 16):
6195
        {
6196
            int l1 = gen_new_label();
6197
            TCGv_i32 fp0;
6198

    
6199
            if (ft != 0) {
6200
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6201
            }
6202
            fp0 = tcg_temp_new_i32();
6203
            gen_load_fpr32(fp0, fs);
6204
            gen_store_fpr32(fp0, fd);
6205
            tcg_temp_free_i32(fp0);
6206
            gen_set_label(l1);
6207
        }
6208
        opn = "movz.s";
6209
        break;
6210
    case FOP(19, 16):
6211
        {
6212
            int l1 = gen_new_label();
6213
            TCGv_i32 fp0;
6214

    
6215
            if (ft != 0) {
6216
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6217
                fp0 = tcg_temp_new_i32();
6218
                gen_load_fpr32(fp0, fs);
6219
                gen_store_fpr32(fp0, fd);
6220
                tcg_temp_free_i32(fp0);
6221
                gen_set_label(l1);
6222
            }
6223
        }
6224
        opn = "movn.s";
6225
        break;
6226
    case FOP(21, 16):
6227
        check_cop1x(ctx);
6228
        {
6229
            TCGv_i32 fp0 = tcg_temp_new_i32();
6230

    
6231
            gen_load_fpr32(fp0, fs);
6232
            gen_helper_float_recip_s(fp0, fp0);
6233
            gen_store_fpr32(fp0, fd);
6234
            tcg_temp_free_i32(fp0);
6235
        }
6236
        opn = "recip.s";
6237
        break;
6238
    case FOP(22, 16):
6239
        check_cop1x(ctx);
6240
        {
6241
            TCGv_i32 fp0 = tcg_temp_new_i32();
6242

    
6243
            gen_load_fpr32(fp0, fs);
6244
            gen_helper_float_rsqrt_s(fp0, fp0);
6245
            gen_store_fpr32(fp0, fd);
6246
            tcg_temp_free_i32(fp0);
6247
        }
6248
        opn = "rsqrt.s";
6249
        break;
6250
    case FOP(28, 16):
6251
        check_cp1_64bitmode(ctx);
6252
        {
6253
            TCGv_i32 fp0 = tcg_temp_new_i32();
6254
            TCGv_i32 fp1 = tcg_temp_new_i32();
6255

    
6256
            gen_load_fpr32(fp0, fs);
6257
            gen_load_fpr32(fp1, fd);
6258
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6259
            tcg_temp_free_i32(fp1);
6260
            gen_store_fpr32(fp0, fd);
6261
            tcg_temp_free_i32(fp0);
6262
        }
6263
        opn = "recip2.s";
6264
        break;
6265
    case FOP(29, 16):
6266
        check_cp1_64bitmode(ctx);
6267
        {
6268
            TCGv_i32 fp0 = tcg_temp_new_i32();
6269

    
6270
            gen_load_fpr32(fp0, fs);
6271
            gen_helper_float_recip1_s(fp0, fp0);
6272
            gen_store_fpr32(fp0, fd);
6273
            tcg_temp_free_i32(fp0);
6274
        }
6275
        opn = "recip1.s";
6276
        break;
6277
    case FOP(30, 16):
6278
        check_cp1_64bitmode(ctx);
6279
        {
6280
            TCGv_i32 fp0 = tcg_temp_new_i32();
6281

    
6282
            gen_load_fpr32(fp0, fs);
6283
            gen_helper_float_rsqrt1_s(fp0, fp0);
6284
            gen_store_fpr32(fp0, fd);
6285
            tcg_temp_free_i32(fp0);
6286
        }
6287
        opn = "rsqrt1.s";
6288
        break;
6289
    case FOP(31, 16):
6290
        check_cp1_64bitmode(ctx);
6291
        {
6292
            TCGv_i32 fp0 = tcg_temp_new_i32();
6293
            TCGv_i32 fp1 = tcg_temp_new_i32();
6294

    
6295
            gen_load_fpr32(fp0, fs);
6296
            gen_load_fpr32(fp1, ft);
6297
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6298
            tcg_temp_free_i32(fp1);
6299
            gen_store_fpr32(fp0, fd);
6300
            tcg_temp_free_i32(fp0);
6301
        }
6302
        opn = "rsqrt2.s";
6303
        break;
6304
    case FOP(33, 16):
6305
        check_cp1_registers(ctx, fd);
6306
        {
6307
            TCGv_i32 fp32 = tcg_temp_new_i32();
6308
            TCGv_i64 fp64 = tcg_temp_new_i64();
6309

    
6310
            gen_load_fpr32(fp32, fs);
6311
            gen_helper_float_cvtd_s(fp64, fp32);
6312
            tcg_temp_free_i32(fp32);
6313
            gen_store_fpr64(ctx, fp64, fd);
6314
            tcg_temp_free_i64(fp64);
6315
        }
6316
        opn = "cvt.d.s";
6317
        break;
6318
    case FOP(36, 16):
6319
        {
6320
            TCGv_i32 fp0 = tcg_temp_new_i32();
6321

    
6322
            gen_load_fpr32(fp0, fs);
6323
            gen_helper_float_cvtw_s(fp0, fp0);
6324
            gen_store_fpr32(fp0, fd);
6325
            tcg_temp_free_i32(fp0);
6326
        }
6327
        opn = "cvt.w.s";
6328
        break;
6329
    case FOP(37, 16):
6330
        check_cp1_64bitmode(ctx);
6331
        {
6332
            TCGv_i32 fp32 = tcg_temp_new_i32();
6333
            TCGv_i64 fp64 = tcg_temp_new_i64();
6334

    
6335
            gen_load_fpr32(fp32, fs);
6336
            gen_helper_float_cvtl_s(fp64, fp32);
6337
            tcg_temp_free_i32(fp32);
6338
            gen_store_fpr64(ctx, fp64, fd);
6339
            tcg_temp_free_i64(fp64);
6340
        }
6341
        opn = "cvt.l.s";
6342
        break;
6343
    case FOP(38, 16):
6344
        check_cp1_64bitmode(ctx);
6345
        {
6346
            TCGv_i64 fp64 = tcg_temp_new_i64();
6347
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6348
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6349

    
6350
            gen_load_fpr32(fp32_0, fs);
6351
            gen_load_fpr32(fp32_1, ft);
6352
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6353
            tcg_temp_free_i32(fp32_1);
6354
            tcg_temp_free_i32(fp32_0);
6355
            gen_store_fpr64(ctx, fp64, fd);
6356
            tcg_temp_free_i64(fp64);
6357
        }
6358
        opn = "cvt.ps.s";
6359
        break;
6360
    case FOP(48, 16):
6361
    case FOP(49, 16):
6362
    case FOP(50, 16):
6363
    case FOP(51, 16):
6364
    case FOP(52, 16):
6365
    case FOP(53, 16):
6366
    case FOP(54, 16):
6367
    case FOP(55, 16):
6368
    case FOP(56, 16):
6369
    case FOP(57, 16):
6370
    case FOP(58, 16):
6371
    case FOP(59, 16):
6372
    case FOP(60, 16):
6373
    case FOP(61, 16):
6374
    case FOP(62, 16):
6375
    case FOP(63, 16):
6376
        {
6377
            TCGv_i32 fp0 = tcg_temp_new_i32();
6378
            TCGv_i32 fp1 = tcg_temp_new_i32();
6379

    
6380
            gen_load_fpr32(fp0, fs);
6381
            gen_load_fpr32(fp1, ft);
6382
            if (ctx->opcode & (1 << 6)) {
6383
                check_cop1x(ctx);
6384
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6385
                opn = condnames_abs[func-48];
6386
            } else {
6387
                gen_cmp_s(func-48, fp0, fp1, cc);
6388
                opn = condnames[func-48];
6389
            }
6390
            tcg_temp_free_i32(fp0);
6391
            tcg_temp_free_i32(fp1);
6392
        }
6393
        break;
6394
    case FOP(0, 17):
6395
        check_cp1_registers(ctx, fs | ft | fd);
6396
        {
6397
            TCGv_i64 fp0 = tcg_temp_new_i64();
6398
            TCGv_i64 fp1 = tcg_temp_new_i64();
6399

    
6400
            gen_load_fpr64(ctx, fp0, fs);
6401
            gen_load_fpr64(ctx, fp1, ft);
6402
            gen_helper_float_add_d(fp0, fp0, fp1);
6403
            tcg_temp_free_i64(fp1);
6404
            gen_store_fpr64(ctx, fp0, fd);
6405
            tcg_temp_free_i64(fp0);
6406
        }
6407
        opn = "add.d";
6408
        optype = BINOP;
6409
        break;
6410
    case FOP(1, 17):
6411
        check_cp1_registers(ctx, fs | ft | fd);
6412
        {
6413
            TCGv_i64 fp0 = tcg_temp_new_i64();
6414
            TCGv_i64 fp1 = tcg_temp_new_i64();
6415

    
6416
            gen_load_fpr64(ctx, fp0, fs);
6417
            gen_load_fpr64(ctx, fp1, ft);
6418
            gen_helper_float_sub_d(fp0, fp0, fp1);
6419
            tcg_temp_free_i64(fp1);
6420
            gen_store_fpr64(ctx, fp0, fd);
6421
            tcg_temp_free_i64(fp0);
6422
        }
6423
        opn = "sub.d";
6424
        optype = BINOP;
6425
        break;
6426
    case FOP(2, 17):
6427
        check_cp1_registers(ctx, fs | ft | fd);
6428
        {
6429
            TCGv_i64 fp0 = tcg_temp_new_i64();
6430
            TCGv_i64 fp1 = tcg_temp_new_i64();
6431

    
6432
            gen_load_fpr64(ctx, fp0, fs);
6433
            gen_load_fpr64(ctx, fp1, ft);
6434
            gen_helper_float_mul_d(fp0, fp0, fp1);
6435
            tcg_temp_free_i64(fp1);
6436
            gen_store_fpr64(ctx, fp0, fd);
6437
            tcg_temp_free_i64(fp0);
6438
        }
6439
        opn = "mul.d";
6440
        optype = BINOP;
6441
        break;
6442
    case FOP(3, 17):
6443
        check_cp1_registers(ctx, fs | ft | fd);
6444
        {
6445
            TCGv_i64 fp0 = tcg_temp_new_i64();
6446
            TCGv_i64 fp1 = tcg_temp_new_i64();
6447

    
6448
            gen_load_fpr64(ctx, fp0, fs);
6449
            gen_load_fpr64(ctx, fp1, ft);
6450
            gen_helper_float_div_d(fp0, fp0, fp1);
6451
            tcg_temp_free_i64(fp1);
6452
            gen_store_fpr64(ctx, fp0, fd);
6453
            tcg_temp_free_i64(fp0);
6454
        }
6455
        opn = "div.d";
6456
        optype = BINOP;
6457
        break;
6458
    case FOP(4, 17):
6459
        check_cp1_registers(ctx, fs | fd);
6460
        {
6461
            TCGv_i64 fp0 = tcg_temp_new_i64();
6462

    
6463
            gen_load_fpr64(ctx, fp0, fs);
6464
            gen_helper_float_sqrt_d(fp0, fp0);
6465
            gen_store_fpr64(ctx, fp0, fd);
6466
            tcg_temp_free_i64(fp0);
6467
        }
6468
        opn = "sqrt.d";
6469
        break;
6470
    case FOP(5, 17):
6471
        check_cp1_registers(ctx, fs | fd);
6472
        {
6473
            TCGv_i64 fp0 = tcg_temp_new_i64();
6474

    
6475
            gen_load_fpr64(ctx, fp0, fs);
6476
            gen_helper_float_abs_d(fp0, fp0);
6477
            gen_store_fpr64(ctx, fp0, fd);
6478
            tcg_temp_free_i64(fp0);
6479
        }
6480
        opn = "abs.d";
6481
        break;
6482
    case FOP(6, 17):
6483
        check_cp1_registers(ctx, fs | fd);
6484
        {
6485
            TCGv_i64 fp0 = tcg_temp_new_i64();
6486

    
6487
            gen_load_fpr64(ctx, fp0, fs);
6488
            gen_store_fpr64(ctx, fp0, fd);
6489
            tcg_temp_free_i64(fp0);
6490
        }
6491
        opn = "mov.d";
6492
        break;
6493
    case FOP(7, 17):
6494
        check_cp1_registers(ctx, fs | fd);
6495
        {
6496
            TCGv_i64 fp0 = tcg_temp_new_i64();
6497

    
6498
            gen_load_fpr64(ctx, fp0, fs);
6499
            gen_helper_float_chs_d(fp0, fp0);
6500
            gen_store_fpr64(ctx, fp0, fd);
6501
            tcg_temp_free_i64(fp0);
6502
        }
6503
        opn = "neg.d";
6504
        break;
6505
    case FOP(8, 17):
6506
        check_cp1_64bitmode(ctx);
6507
        {
6508
            TCGv_i64 fp0 = tcg_temp_new_i64();
6509

    
6510
            gen_load_fpr64(ctx, fp0, fs);
6511
            gen_helper_float_roundl_d(fp0, fp0);
6512
            gen_store_fpr64(ctx, fp0, fd);
6513
            tcg_temp_free_i64(fp0);
6514
        }
6515
        opn = "round.l.d";
6516
        break;
6517
    case FOP(9, 17):
6518
        check_cp1_64bitmode(ctx);
6519
        {
6520
            TCGv_i64 fp0 = tcg_temp_new_i64();
6521

    
6522
            gen_load_fpr64(ctx, fp0, fs);
6523
            gen_helper_float_truncl_d(fp0, fp0);
6524
            gen_store_fpr64(ctx, fp0, fd);
6525
            tcg_temp_free_i64(fp0);
6526
        }
6527
        opn = "trunc.l.d";
6528
        break;
6529
    case FOP(10, 17):
6530
        check_cp1_64bitmode(ctx);
6531
        {
6532
            TCGv_i64 fp0 = tcg_temp_new_i64();
6533

    
6534
            gen_load_fpr64(ctx, fp0, fs);
6535
            gen_helper_float_ceill_d(fp0, fp0);
6536
            gen_store_fpr64(ctx, fp0, fd);
6537
            tcg_temp_free_i64(fp0);
6538
        }
6539
        opn = "ceil.l.d";
6540
        break;
6541
    case FOP(11, 17):
6542
        check_cp1_64bitmode(ctx);
6543
        {
6544
            TCGv_i64 fp0 = tcg_temp_new_i64();
6545

    
6546
            gen_load_fpr64(ctx, fp0, fs);
6547
            gen_helper_float_floorl_d(fp0, fp0);
6548
            gen_store_fpr64(ctx, fp0, fd);
6549
            tcg_temp_free_i64(fp0);
6550
        }
6551
        opn = "floor.l.d";
6552
        break;
6553
    case FOP(12, 17):
6554
        check_cp1_registers(ctx, fs);
6555
        {
6556
            TCGv_i32 fp32 = tcg_temp_new_i32();
6557
            TCGv_i64 fp64 = tcg_temp_new_i64();
6558

    
6559
            gen_load_fpr64(ctx, fp64, fs);
6560
            gen_helper_float_roundw_d(fp32, fp64);
6561
            tcg_temp_free_i64(fp64);
6562
            gen_store_fpr32(fp32, fd);
6563
            tcg_temp_free_i32(fp32);
6564
        }
6565
        opn = "round.w.d";
6566
        break;
6567
    case FOP(13, 17):
6568
        check_cp1_registers(ctx, fs);
6569
        {
6570
            TCGv_i32 fp32 = tcg_temp_new_i32();
6571
            TCGv_i64 fp64 = tcg_temp_new_i64();
6572

    
6573
            gen_load_fpr64(ctx, fp64, fs);
6574
            gen_helper_float_truncw_d(fp32, fp64);
6575
            tcg_temp_free_i64(fp64);
6576
            gen_store_fpr32(fp32, fd);
6577
            tcg_temp_free_i32(fp32);
6578
        }
6579
        opn = "trunc.w.d";
6580
        break;
6581
    case FOP(14, 17):
6582
        check_cp1_registers(ctx, fs);
6583
        {
6584
            TCGv_i32 fp32 = tcg_temp_new_i32();
6585
            TCGv_i64 fp64 = tcg_temp_new_i64();
6586

    
6587
            gen_load_fpr64(ctx, fp64, fs);
6588
            gen_helper_float_ceilw_d(fp32, fp64);
6589
            tcg_temp_free_i64(fp64);
6590
            gen_store_fpr32(fp32, fd);
6591
            tcg_temp_free_i32(fp32);
6592
        }
6593
        opn = "ceil.w.d";
6594
        break;
6595
    case FOP(15, 17):
6596
        check_cp1_registers(ctx, fs);
6597
        {
6598
            TCGv_i32 fp32 = tcg_temp_new_i32();
6599
            TCGv_i64 fp64 = tcg_temp_new_i64();
6600

    
6601
            gen_load_fpr64(ctx, fp64, fs);
6602
            gen_helper_float_floorw_d(fp32, fp64);
6603
            tcg_temp_free_i64(fp64);
6604
            gen_store_fpr32(fp32, fd);
6605
            tcg_temp_free_i32(fp32);
6606
        }
6607
        opn = "floor.w.d";
6608
        break;
6609
    case FOP(17, 17):
6610
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6611
        opn = "movcf.d";
6612
        break;
6613
    case FOP(18, 17):
6614
        {
6615
            int l1 = gen_new_label();
6616
            TCGv_i64 fp0;
6617

    
6618
            if (ft != 0) {
6619
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6620
            }
6621
            fp0 = tcg_temp_new_i64();
6622
            gen_load_fpr64(ctx, fp0, fs);
6623
            gen_store_fpr64(ctx, fp0, fd);
6624
            tcg_temp_free_i64(fp0);
6625
            gen_set_label(l1);
6626
        }
6627
        opn = "movz.d";
6628
        break;
6629
    case FOP(19, 17):
6630
        {
6631
            int l1 = gen_new_label();
6632
            TCGv_i64 fp0;
6633

    
6634
            if (ft != 0) {
6635
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6636
                fp0 = tcg_temp_new_i64();
6637
                gen_load_fpr64(ctx, fp0, fs);
6638
                gen_store_fpr64(ctx, fp0, fd);
6639
                tcg_temp_free_i64(fp0);
6640
                gen_set_label(l1);
6641
            }
6642
        }
6643
        opn = "movn.d";
6644
        break;
6645
    case FOP(21, 17):
6646
        check_cp1_64bitmode(ctx);
6647
        {
6648
            TCGv_i64 fp0 = tcg_temp_new_i64();
6649

    
6650
            gen_load_fpr64(ctx, fp0, fs);
6651
            gen_helper_float_recip_d(fp0, fp0);
6652
            gen_store_fpr64(ctx, fp0, fd);
6653
            tcg_temp_free_i64(fp0);
6654
        }
6655
        opn = "recip.d";
6656
        break;
6657
    case FOP(22, 17):
6658
        check_cp1_64bitmode(ctx);
6659
        {
6660
            TCGv_i64 fp0 = tcg_temp_new_i64();
6661

    
6662
            gen_load_fpr64(ctx, fp0, fs);
6663
            gen_helper_float_rsqrt_d(fp0, fp0);
6664
            gen_store_fpr64(ctx, fp0, fd);
6665
            tcg_temp_free_i64(fp0);
6666
        }
6667
        opn = "rsqrt.d";
6668
        break;
6669
    case FOP(28, 17):
6670
        check_cp1_64bitmode(ctx);
6671
        {
6672
            TCGv_i64 fp0 = tcg_temp_new_i64();
6673
            TCGv_i64 fp1 = tcg_temp_new_i64();
6674

    
6675
            gen_load_fpr64(ctx, fp0, fs);
6676
            gen_load_fpr64(ctx, fp1, ft);
6677
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6678
            tcg_temp_free_i64(fp1);
6679
            gen_store_fpr64(ctx, fp0, fd);
6680
            tcg_temp_free_i64(fp0);
6681
        }
6682
        opn = "recip2.d";
6683
        break;
6684
    case FOP(29, 17):
6685
        check_cp1_64bitmode(ctx);
6686
        {
6687
            TCGv_i64 fp0 = tcg_temp_new_i64();
6688

    
6689
            gen_load_fpr64(ctx, fp0, fs);
6690
            gen_helper_float_recip1_d(fp0, fp0);
6691
            gen_store_fpr64(ctx, fp0, fd);
6692
            tcg_temp_free_i64(fp0);
6693
        }
6694
        opn = "recip1.d";
6695
        break;
6696
    case FOP(30, 17):
6697
        check_cp1_64bitmode(ctx);
6698
        {
6699
            TCGv_i64 fp0 = tcg_temp_new_i64();
6700

    
6701
            gen_load_fpr64(ctx, fp0, fs);
6702
            gen_helper_float_rsqrt1_d(fp0, fp0);
6703
            gen_store_fpr64(ctx, fp0, fd);
6704
            tcg_temp_free_i64(fp0);
6705
        }
6706
        opn = "rsqrt1.d";
6707
        break;
6708
    case FOP(31, 17):
6709
        check_cp1_64bitmode(ctx);
6710
        {
6711
            TCGv_i64 fp0 = tcg_temp_new_i64();
6712
            TCGv_i64 fp1 = tcg_temp_new_i64();
6713

    
6714
            gen_load_fpr64(ctx, fp0, fs);
6715
            gen_load_fpr64(ctx, fp1, ft);
6716
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6717
            tcg_temp_free_i64(fp1);
6718
            gen_store_fpr64(ctx, fp0, fd);
6719
            tcg_temp_free_i64(fp0);
6720
        }
6721
        opn = "rsqrt2.d";
6722
        break;
6723
    case FOP(48, 17):
6724
    case FOP(49, 17):
6725
    case FOP(50, 17):
6726
    case FOP(51, 17):
6727
    case FOP(52, 17):
6728
    case FOP(53, 17):
6729
    case FOP(54, 17):
6730
    case FOP(55, 17):
6731
    case FOP(56, 17):
6732
    case FOP(57, 17):
6733
    case FOP(58, 17):
6734
    case FOP(59, 17):
6735
    case FOP(60, 17):
6736
    case FOP(61, 17):
6737
    case FOP(62, 17):
6738
    case FOP(63, 17):
6739
        {
6740
            TCGv_i64 fp0 = tcg_temp_new_i64();
6741
            TCGv_i64 fp1 = tcg_temp_new_i64();
6742

    
6743
            gen_load_fpr64(ctx, fp0, fs);
6744
            gen_load_fpr64(ctx, fp1, ft);
6745
            if (ctx->opcode & (1 << 6)) {
6746
                check_cop1x(ctx);
6747
                check_cp1_registers(ctx, fs | ft);
6748
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6749
                opn = condnames_abs[func-48];
6750
            } else {
6751
                check_cp1_registers(ctx, fs | ft);
6752
                gen_cmp_d(func-48, fp0, fp1, cc);
6753
                opn = condnames[func-48];
6754
            }
6755
            tcg_temp_free_i64(fp0);
6756
            tcg_temp_free_i64(fp1);
6757
        }
6758
        break;
6759
    case FOP(32, 17):
6760
        check_cp1_registers(ctx, fs);
6761
        {
6762
            TCGv_i32 fp32 = tcg_temp_new_i32();
6763
            TCGv_i64 fp64 = tcg_temp_new_i64();
6764

    
6765
            gen_load_fpr64(ctx, fp64, fs);
6766
            gen_helper_float_cvts_d(fp32, fp64);
6767
            tcg_temp_free_i64(fp64);
6768
            gen_store_fpr32(fp32, fd);
6769
            tcg_temp_free_i32(fp32);
6770
        }
6771
        opn = "cvt.s.d";
6772
        break;
6773
    case FOP(36, 17):
6774
        check_cp1_registers(ctx, fs);
6775
        {
6776
            TCGv_i32 fp32 = tcg_temp_new_i32();
6777
            TCGv_i64 fp64 = tcg_temp_new_i64();
6778

    
6779
            gen_load_fpr64(ctx, fp64, fs);
6780
            gen_helper_float_cvtw_d(fp32, fp64);
6781
            tcg_temp_free_i64(fp64);
6782
            gen_store_fpr32(fp32, fd);
6783
            tcg_temp_free_i32(fp32);
6784
        }
6785
        opn = "cvt.w.d";
6786
        break;
6787
    case FOP(37, 17):
6788
        check_cp1_64bitmode(ctx);
6789
        {
6790
            TCGv_i64 fp0 = tcg_temp_new_i64();
6791

    
6792
            gen_load_fpr64(ctx, fp0, fs);
6793
            gen_helper_float_cvtl_d(fp0, fp0);
6794
            gen_store_fpr64(ctx, fp0, fd);
6795
            tcg_temp_free_i64(fp0);
6796
        }
6797
        opn = "cvt.l.d";
6798
        break;
6799
    case FOP(32, 20):
6800
        {
6801
            TCGv_i32 fp0 = tcg_temp_new_i32();
6802

    
6803
            gen_load_fpr32(fp0, fs);
6804
            gen_helper_float_cvts_w(fp0, fp0);
6805
            gen_store_fpr32(fp0, fd);
6806
            tcg_temp_free_i32(fp0);
6807
        }
6808
        opn = "cvt.s.w";
6809
        break;
6810
    case FOP(33, 20):
6811
        check_cp1_registers(ctx, fd);
6812
        {
6813
            TCGv_i32 fp32 = tcg_temp_new_i32();
6814
            TCGv_i64 fp64 = tcg_temp_new_i64();
6815

    
6816
            gen_load_fpr32(fp32, fs);
6817
            gen_helper_float_cvtd_w(fp64, fp32);
6818
            tcg_temp_free_i32(fp32);
6819
            gen_store_fpr64(ctx, fp64, fd);
6820
            tcg_temp_free_i64(fp64);
6821
        }
6822
        opn = "cvt.d.w";
6823
        break;
6824
    case FOP(32, 21):
6825
        check_cp1_64bitmode(ctx);
6826
        {
6827
            TCGv_i32 fp32 = tcg_temp_new_i32();
6828
            TCGv_i64 fp64 = tcg_temp_new_i64();
6829

    
6830
            gen_load_fpr64(ctx, fp64, fs);
6831
            gen_helper_float_cvts_l(fp32, fp64);
6832
            tcg_temp_free_i64(fp64);
6833
            gen_store_fpr32(fp32, fd);
6834
            tcg_temp_free_i32(fp32);
6835
        }
6836
        opn = "cvt.s.l";
6837
        break;
6838
    case FOP(33, 21):
6839
        check_cp1_64bitmode(ctx);
6840
        {
6841
            TCGv_i64 fp0 = tcg_temp_new_i64();
6842

    
6843
            gen_load_fpr64(ctx, fp0, fs);
6844
            gen_helper_float_cvtd_l(fp0, fp0);
6845
            gen_store_fpr64(ctx, fp0, fd);
6846
            tcg_temp_free_i64(fp0);
6847
        }
6848
        opn = "cvt.d.l";
6849
        break;
6850
    case FOP(38, 20):
6851
        check_cp1_64bitmode(ctx);
6852
        {
6853
            TCGv_i64 fp0 = tcg_temp_new_i64();
6854

    
6855
            gen_load_fpr64(ctx, fp0, fs);
6856
            gen_helper_float_cvtps_pw(fp0, fp0);
6857
            gen_store_fpr64(ctx, fp0, fd);
6858
            tcg_temp_free_i64(fp0);
6859
        }
6860
        opn = "cvt.ps.pw";
6861
        break;
6862
    case FOP(0, 22):
6863
        check_cp1_64bitmode(ctx);
6864
        {
6865
            TCGv_i64 fp0 = tcg_temp_new_i64();
6866
            TCGv_i64 fp1 = tcg_temp_new_i64();
6867

    
6868
            gen_load_fpr64(ctx, fp0, fs);
6869
            gen_load_fpr64(ctx, fp1, ft);
6870
            gen_helper_float_add_ps(fp0, fp0, fp1);
6871
            tcg_temp_free_i64(fp1);
6872
            gen_store_fpr64(ctx, fp0, fd);
6873
            tcg_temp_free_i64(fp0);
6874
        }
6875
        opn = "add.ps";
6876
        break;
6877
    case FOP(1, 22):
6878
        check_cp1_64bitmode(ctx);
6879
        {
6880
            TCGv_i64 fp0 = tcg_temp_new_i64();
6881
            TCGv_i64 fp1 = tcg_temp_new_i64();
6882

    
6883
            gen_load_fpr64(ctx, fp0, fs);
6884
            gen_load_fpr64(ctx, fp1, ft);
6885
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6886
            tcg_temp_free_i64(fp1);
6887
            gen_store_fpr64(ctx, fp0, fd);
6888
            tcg_temp_free_i64(fp0);
6889
        }
6890
        opn = "sub.ps";
6891
        break;
6892
    case FOP(2, 22):
6893
        check_cp1_64bitmode(ctx);
6894
        {
6895
            TCGv_i64 fp0 = tcg_temp_new_i64();
6896
            TCGv_i64 fp1 = tcg_temp_new_i64();
6897

    
6898
            gen_load_fpr64(ctx, fp0, fs);
6899
            gen_load_fpr64(ctx, fp1, ft);
6900
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6901
            tcg_temp_free_i64(fp1);
6902
            gen_store_fpr64(ctx, fp0, fd);
6903
            tcg_temp_free_i64(fp0);
6904
        }
6905
        opn = "mul.ps";
6906
        break;
6907
    case FOP(5, 22):
6908
        check_cp1_64bitmode(ctx);
6909
        {
6910
            TCGv_i64 fp0 = tcg_temp_new_i64();
6911

    
6912
            gen_load_fpr64(ctx, fp0, fs);
6913
            gen_helper_float_abs_ps(fp0, fp0);
6914
            gen_store_fpr64(ctx, fp0, fd);
6915
            tcg_temp_free_i64(fp0);
6916
        }
6917
        opn = "abs.ps";
6918
        break;
6919
    case FOP(6, 22):
6920
        check_cp1_64bitmode(ctx);
6921
        {
6922
            TCGv_i64 fp0 = tcg_temp_new_i64();
6923

    
6924
            gen_load_fpr64(ctx, fp0, fs);
6925
            gen_store_fpr64(ctx, fp0, fd);
6926
            tcg_temp_free_i64(fp0);
6927
        }
6928
        opn = "mov.ps";
6929
        break;
6930
    case FOP(7, 22):
6931
        check_cp1_64bitmode(ctx);
6932
        {
6933
            TCGv_i64 fp0 = tcg_temp_new_i64();
6934

    
6935
            gen_load_fpr64(ctx, fp0, fs);
6936
            gen_helper_float_chs_ps(fp0, fp0);
6937
            gen_store_fpr64(ctx, fp0, fd);
6938
            tcg_temp_free_i64(fp0);
6939
        }
6940
        opn = "neg.ps";
6941
        break;
6942
    case FOP(17, 22):
6943
        check_cp1_64bitmode(ctx);
6944
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6945
        opn = "movcf.ps";
6946
        break;
6947
    case FOP(18, 22):
6948
        check_cp1_64bitmode(ctx);
6949
        {
6950
            int l1 = gen_new_label();
6951
            TCGv_i64 fp0;
6952

    
6953
            if (ft != 0)
6954
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6955
            fp0 = tcg_temp_new_i64();
6956
            gen_load_fpr64(ctx, fp0, fs);
6957
            gen_store_fpr64(ctx, fp0, fd);
6958
            tcg_temp_free_i64(fp0);
6959
            gen_set_label(l1);
6960
        }
6961
        opn = "movz.ps";
6962
        break;
6963
    case FOP(19, 22):
6964
        check_cp1_64bitmode(ctx);
6965
        {
6966
            int l1 = gen_new_label();
6967
            TCGv_i64 fp0;
6968

    
6969
            if (ft != 0) {
6970
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6971
                fp0 = tcg_temp_new_i64();
6972
                gen_load_fpr64(ctx, fp0, fs);
6973
                gen_store_fpr64(ctx, fp0, fd);
6974
                tcg_temp_free_i64(fp0);
6975
                gen_set_label(l1);
6976
            }
6977
        }
6978
        opn = "movn.ps";
6979
        break;
6980
    case FOP(24, 22):
6981
        check_cp1_64bitmode(ctx);
6982
        {
6983
            TCGv_i64 fp0 = tcg_temp_new_i64();
6984
            TCGv_i64 fp1 = tcg_temp_new_i64();
6985

    
6986
            gen_load_fpr64(ctx, fp0, ft);
6987
            gen_load_fpr64(ctx, fp1, fs);
6988
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6989
            tcg_temp_free_i64(fp1);
6990
            gen_store_fpr64(ctx, fp0, fd);
6991
            tcg_temp_free_i64(fp0);
6992
        }
6993
        opn = "addr.ps";
6994
        break;
6995
    case FOP(26, 22):
6996
        check_cp1_64bitmode(ctx);
6997
        {
6998
            TCGv_i64 fp0 = tcg_temp_new_i64();
6999
            TCGv_i64 fp1 = tcg_temp_new_i64();
7000

    
7001
            gen_load_fpr64(ctx, fp0, ft);
7002
            gen_load_fpr64(ctx, fp1, fs);
7003
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7004
            tcg_temp_free_i64(fp1);
7005
            gen_store_fpr64(ctx, fp0, fd);
7006
            tcg_temp_free_i64(fp0);
7007
        }
7008
        opn = "mulr.ps";
7009
        break;
7010
    case FOP(28, 22):
7011
        check_cp1_64bitmode(ctx);
7012
        {
7013
            TCGv_i64 fp0 = tcg_temp_new_i64();
7014
            TCGv_i64 fp1 = tcg_temp_new_i64();
7015

    
7016
            gen_load_fpr64(ctx, fp0, fs);
7017
            gen_load_fpr64(ctx, fp1, fd);
7018
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7019
            tcg_temp_free_i64(fp1);
7020
            gen_store_fpr64(ctx, fp0, fd);
7021
            tcg_temp_free_i64(fp0);
7022
        }
7023
        opn = "recip2.ps";
7024
        break;
7025
    case FOP(29, 22):
7026
        check_cp1_64bitmode(ctx);
7027
        {
7028
            TCGv_i64 fp0 = tcg_temp_new_i64();
7029

    
7030
            gen_load_fpr64(ctx, fp0, fs);
7031
            gen_helper_float_recip1_ps(fp0, fp0);
7032
            gen_store_fpr64(ctx, fp0, fd);
7033
            tcg_temp_free_i64(fp0);
7034
        }
7035
        opn = "recip1.ps";
7036
        break;
7037
    case FOP(30, 22):
7038
        check_cp1_64bitmode(ctx);
7039
        {
7040
            TCGv_i64 fp0 = tcg_temp_new_i64();
7041

    
7042
            gen_load_fpr64(ctx, fp0, fs);
7043
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7044
            gen_store_fpr64(ctx, fp0, fd);
7045
            tcg_temp_free_i64(fp0);
7046
        }
7047
        opn = "rsqrt1.ps";
7048
        break;
7049
    case FOP(31, 22):
7050
        check_cp1_64bitmode(ctx);
7051
        {
7052
            TCGv_i64 fp0 = tcg_temp_new_i64();
7053
            TCGv_i64 fp1 = tcg_temp_new_i64();
7054

    
7055
            gen_load_fpr64(ctx, fp0, fs);
7056
            gen_load_fpr64(ctx, fp1, ft);
7057
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7058
            tcg_temp_free_i64(fp1);
7059
            gen_store_fpr64(ctx, fp0, fd);
7060
            tcg_temp_free_i64(fp0);
7061
        }
7062
        opn = "rsqrt2.ps";
7063
        break;
7064
    case FOP(32, 22):
7065
        check_cp1_64bitmode(ctx);
7066
        {
7067
            TCGv_i32 fp0 = tcg_temp_new_i32();
7068

    
7069
            gen_load_fpr32h(fp0, fs);
7070
            gen_helper_float_cvts_pu(fp0, fp0);
7071
            gen_store_fpr32(fp0, fd);
7072
            tcg_temp_free_i32(fp0);
7073
        }
7074
        opn = "cvt.s.pu";
7075
        break;
7076
    case FOP(36, 22):
7077
        check_cp1_64bitmode(ctx);
7078
        {
7079
            TCGv_i64 fp0 = tcg_temp_new_i64();
7080

    
7081
            gen_load_fpr64(ctx, fp0, fs);
7082
            gen_helper_float_cvtpw_ps(fp0, fp0);
7083
            gen_store_fpr64(ctx, fp0, fd);
7084
            tcg_temp_free_i64(fp0);
7085
        }
7086
        opn = "cvt.pw.ps";
7087
        break;
7088
    case FOP(40, 22):
7089
        check_cp1_64bitmode(ctx);
7090
        {
7091
            TCGv_i32 fp0 = tcg_temp_new_i32();
7092

    
7093
            gen_load_fpr32(fp0, fs);
7094
            gen_helper_float_cvts_pl(fp0, fp0);
7095
            gen_store_fpr32(fp0, fd);
7096
            tcg_temp_free_i32(fp0);
7097
        }
7098
        opn = "cvt.s.pl";
7099
        break;
7100
    case FOP(44, 22):
7101
        check_cp1_64bitmode(ctx);
7102
        {
7103
            TCGv_i32 fp0 = tcg_temp_new_i32();
7104
            TCGv_i32 fp1 = tcg_temp_new_i32();
7105

    
7106
            gen_load_fpr32(fp0, fs);
7107
            gen_load_fpr32(fp1, ft);
7108
            gen_store_fpr32h(fp0, fd);
7109
            gen_store_fpr32(fp1, fd);
7110
            tcg_temp_free_i32(fp0);
7111
            tcg_temp_free_i32(fp1);
7112
        }
7113
        opn = "pll.ps";
7114
        break;
7115
    case FOP(45, 22):
7116
        check_cp1_64bitmode(ctx);
7117
        {
7118
            TCGv_i32 fp0 = tcg_temp_new_i32();
7119
            TCGv_i32 fp1 = tcg_temp_new_i32();
7120

    
7121
            gen_load_fpr32(fp0, fs);
7122
            gen_load_fpr32h(fp1, ft);
7123
            gen_store_fpr32(fp1, fd);
7124
            gen_store_fpr32h(fp0, fd);
7125
            tcg_temp_free_i32(fp0);
7126
            tcg_temp_free_i32(fp1);
7127
        }
7128
        opn = "plu.ps";
7129
        break;
7130
    case FOP(46, 22):
7131
        check_cp1_64bitmode(ctx);
7132
        {
7133
            TCGv_i32 fp0 = tcg_temp_new_i32();
7134
            TCGv_i32 fp1 = tcg_temp_new_i32();
7135

    
7136
            gen_load_fpr32h(fp0, fs);
7137
            gen_load_fpr32(fp1, ft);
7138
            gen_store_fpr32(fp1, fd);
7139
            gen_store_fpr32h(fp0, fd);
7140
            tcg_temp_free_i32(fp0);
7141
            tcg_temp_free_i32(fp1);
7142
        }
7143
        opn = "pul.ps";
7144
        break;
7145
    case FOP(47, 22):
7146
        check_cp1_64bitmode(ctx);
7147
        {
7148
            TCGv_i32 fp0 = tcg_temp_new_i32();
7149
            TCGv_i32 fp1 = tcg_temp_new_i32();
7150

    
7151
            gen_load_fpr32h(fp0, fs);
7152
            gen_load_fpr32h(fp1, ft);
7153
            gen_store_fpr32(fp1, fd);
7154
            gen_store_fpr32h(fp0, fd);
7155
            tcg_temp_free_i32(fp0);
7156
            tcg_temp_free_i32(fp1);
7157
        }
7158
        opn = "puu.ps";
7159
        break;
7160
    case FOP(48, 22):
7161
    case FOP(49, 22):
7162
    case FOP(50, 22):
7163
    case FOP(51, 22):
7164
    case FOP(52, 22):
7165
    case FOP(53, 22):
7166
    case FOP(54, 22):
7167
    case FOP(55, 22):
7168
    case FOP(56, 22):
7169
    case FOP(57, 22):
7170
    case FOP(58, 22):
7171
    case FOP(59, 22):
7172
    case FOP(60, 22):
7173
    case FOP(61, 22):
7174
    case FOP(62, 22):
7175
    case FOP(63, 22):
7176
        check_cp1_64bitmode(ctx);
7177
        {
7178
            TCGv_i64 fp0 = tcg_temp_new_i64();
7179
            TCGv_i64 fp1 = tcg_temp_new_i64();
7180

    
7181
            gen_load_fpr64(ctx, fp0, fs);
7182
            gen_load_fpr64(ctx, fp1, ft);
7183
            if (ctx->opcode & (1 << 6)) {
7184
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7185
                opn = condnames_abs[func-48];
7186
            } else {
7187
                gen_cmp_ps(func-48, fp0, fp1, cc);
7188
                opn = condnames[func-48];
7189
            }
7190
            tcg_temp_free_i64(fp0);
7191
            tcg_temp_free_i64(fp1);
7192
        }
7193
        break;
7194
    default:
7195
        MIPS_INVAL(opn);
7196
        generate_exception (ctx, EXCP_RI);
7197
        return;
7198
    }
7199
    switch (optype) {
7200
    case BINOP:
7201
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7202
        break;
7203
    case CMPOP:
7204
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7205
        break;
7206
    default:
7207
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7208
        break;
7209
    }
7210
}
7211

    
7212
/* Coprocessor 3 (FPU) */
7213
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7214
                           int fd, int fs, int base, int index)
7215
{
7216
    const char *opn = "extended float load/store";
7217
    int store = 0;
7218
    TCGv t0 = tcg_temp_new();
7219

    
7220
    if (base == 0) {
7221
        gen_load_gpr(t0, index);
7222
    } else if (index == 0) {
7223
        gen_load_gpr(t0, base);
7224
    } else {
7225
        gen_load_gpr(t0, index);
7226
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7227
    }
7228
    /* Don't do NOP if destination is zero: we must perform the actual
7229
       memory access. */
7230
    save_cpu_state(ctx, 0);
7231
    switch (opc) {
7232
    case OPC_LWXC1:
7233
        check_cop1x(ctx);
7234
        {
7235
            TCGv_i32 fp0 = tcg_temp_new_i32();
7236

    
7237
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7238
            tcg_gen_trunc_tl_i32(fp0, t0);
7239
            gen_store_fpr32(fp0, fd);
7240
            tcg_temp_free_i32(fp0);
7241
        }
7242
        opn = "lwxc1";
7243
        break;
7244
    case OPC_LDXC1:
7245
        check_cop1x(ctx);
7246
        check_cp1_registers(ctx, fd);
7247
        {
7248
            TCGv_i64 fp0 = tcg_temp_new_i64();
7249

    
7250
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7251
            gen_store_fpr64(ctx, fp0, fd);
7252
            tcg_temp_free_i64(fp0);
7253
        }
7254
        opn = "ldxc1";
7255
        break;
7256
    case OPC_LUXC1:
7257
        check_cp1_64bitmode(ctx);
7258
        tcg_gen_andi_tl(t0, t0, ~0x7);
7259
        {
7260
            TCGv_i64 fp0 = tcg_temp_new_i64();
7261

    
7262
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7263
            gen_store_fpr64(ctx, fp0, fd);
7264
            tcg_temp_free_i64(fp0);
7265
        }
7266
        opn = "luxc1";
7267
        break;
7268
    case OPC_SWXC1:
7269
        check_cop1x(ctx);
7270
        {
7271
            TCGv_i32 fp0 = tcg_temp_new_i32();
7272
            TCGv t1 = tcg_temp_new();
7273

    
7274
            gen_load_fpr32(fp0, fs);
7275
            tcg_gen_extu_i32_tl(t1, fp0);
7276
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7277
            tcg_temp_free_i32(fp0);
7278
            tcg_temp_free(t1);
7279
        }
7280
        opn = "swxc1";
7281
        store = 1;
7282
        break;
7283
    case OPC_SDXC1:
7284
        check_cop1x(ctx);
7285
        check_cp1_registers(ctx, fs);
7286
        {
7287
            TCGv_i64 fp0 = tcg_temp_new_i64();
7288

    
7289
            gen_load_fpr64(ctx, fp0, fs);
7290
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7291
            tcg_temp_free_i64(fp0);
7292
        }
7293
        opn = "sdxc1";
7294
        store = 1;
7295
        break;
7296
    case OPC_SUXC1:
7297
        check_cp1_64bitmode(ctx);
7298
        tcg_gen_andi_tl(t0, t0, ~0x7);
7299
        {
7300
            TCGv_i64 fp0 = tcg_temp_new_i64();
7301

    
7302
            gen_load_fpr64(ctx, fp0, fs);
7303
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7304
            tcg_temp_free_i64(fp0);
7305
        }
7306
        opn = "suxc1";
7307
        store = 1;
7308
        break;
7309
    }
7310
    tcg_temp_free(t0);
7311
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7312
               regnames[index], regnames[base]);
7313
}
7314

    
7315
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7316
                            int fd, int fr, int fs, int ft)
7317
{
7318
    const char *opn = "flt3_arith";
7319

    
7320
    switch (opc) {
7321
    case OPC_ALNV_PS:
7322
        check_cp1_64bitmode(ctx);
7323
        {
7324
            TCGv t0 = tcg_temp_local_new();
7325
            TCGv_i32 fp = tcg_temp_new_i32();
7326
            TCGv_i32 fph = tcg_temp_new_i32();
7327
            int l1 = gen_new_label();
7328
            int l2 = gen_new_label();
7329

    
7330
            gen_load_gpr(t0, fr);
7331
            tcg_gen_andi_tl(t0, t0, 0x7);
7332

    
7333
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7334
            gen_load_fpr32(fp, fs);
7335
            gen_load_fpr32h(fph, fs);
7336
            gen_store_fpr32(fp, fd);
7337
            gen_store_fpr32h(fph, fd);
7338
            tcg_gen_br(l2);
7339
            gen_set_label(l1);
7340
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7341
            tcg_temp_free(t0);
7342
#ifdef TARGET_WORDS_BIGENDIAN
7343
            gen_load_fpr32(fp, fs);
7344
            gen_load_fpr32h(fph, ft);
7345
            gen_store_fpr32h(fp, fd);
7346
            gen_store_fpr32(fph, fd);
7347
#else
7348
            gen_load_fpr32h(fph, fs);
7349
            gen_load_fpr32(fp, ft);
7350
            gen_store_fpr32(fph, fd);
7351
            gen_store_fpr32h(fp, fd);
7352
#endif
7353
            gen_set_label(l2);
7354
            tcg_temp_free_i32(fp);
7355
            tcg_temp_free_i32(fph);
7356
        }
7357
        opn = "alnv.ps";
7358
        break;
7359
    case OPC_MADD_S:
7360
        check_cop1x(ctx);
7361
        {
7362
            TCGv_i32 fp0 = tcg_temp_new_i32();
7363
            TCGv_i32 fp1 = tcg_temp_new_i32();
7364
            TCGv_i32 fp2 = tcg_temp_new_i32();
7365

    
7366
            gen_load_fpr32(fp0, fs);
7367
            gen_load_fpr32(fp1, ft);
7368
            gen_load_fpr32(fp2, fr);
7369
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7370
            tcg_temp_free_i32(fp0);
7371
            tcg_temp_free_i32(fp1);
7372
            gen_store_fpr32(fp2, fd);
7373
            tcg_temp_free_i32(fp2);
7374
        }
7375
        opn = "madd.s";
7376
        break;
7377
    case OPC_MADD_D:
7378
        check_cop1x(ctx);
7379
        check_cp1_registers(ctx, fd | fs | ft | fr);
7380
        {
7381
            TCGv_i64 fp0 = tcg_temp_new_i64();
7382
            TCGv_i64 fp1 = tcg_temp_new_i64();
7383
            TCGv_i64 fp2 = tcg_temp_new_i64();
7384

    
7385
            gen_load_fpr64(ctx, fp0, fs);
7386
            gen_load_fpr64(ctx, fp1, ft);
7387
            gen_load_fpr64(ctx, fp2, fr);
7388
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7389
            tcg_temp_free_i64(fp0);
7390
            tcg_temp_free_i64(fp1);
7391
            gen_store_fpr64(ctx, fp2, fd);
7392
            tcg_temp_free_i64(fp2);
7393
        }
7394
        opn = "madd.d";
7395
        break;
7396
    case OPC_MADD_PS:
7397
        check_cp1_64bitmode(ctx);
7398
        {
7399
            TCGv_i64 fp0 = tcg_temp_new_i64();
7400
            TCGv_i64 fp1 = tcg_temp_new_i64();
7401
            TCGv_i64 fp2 = tcg_temp_new_i64();
7402

    
7403
            gen_load_fpr64(ctx, fp0, fs);
7404
            gen_load_fpr64(ctx, fp1, ft);
7405
            gen_load_fpr64(ctx, fp2, fr);
7406
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7407
            tcg_temp_free_i64(fp0);
7408
            tcg_temp_free_i64(fp1);
7409
            gen_store_fpr64(ctx, fp2, fd);
7410
            tcg_temp_free_i64(fp2);
7411
        }
7412
        opn = "madd.ps";
7413
        break;
7414
    case OPC_MSUB_S:
7415
        check_cop1x(ctx);
7416
        {
7417
            TCGv_i32 fp0 = tcg_temp_new_i32();
7418
            TCGv_i32 fp1 = tcg_temp_new_i32();
7419
            TCGv_i32 fp2 = tcg_temp_new_i32();
7420

    
7421
            gen_load_fpr32(fp0, fs);
7422
            gen_load_fpr32(fp1, ft);
7423
            gen_load_fpr32(fp2, fr);
7424
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7425
            tcg_temp_free_i32(fp0);
7426
            tcg_temp_free_i32(fp1);
7427
            gen_store_fpr32(fp2, fd);
7428
            tcg_temp_free_i32(fp2);
7429
        }
7430
        opn = "msub.s";
7431
        break;
7432
    case OPC_MSUB_D:
7433
        check_cop1x(ctx);
7434
        check_cp1_registers(ctx, fd | fs | ft | fr);
7435
        {
7436
            TCGv_i64 fp0 = tcg_temp_new_i64();
7437
            TCGv_i64 fp1 = tcg_temp_new_i64();
7438
            TCGv_i64 fp2 = tcg_temp_new_i64();
7439

    
7440
            gen_load_fpr64(ctx, fp0, fs);
7441
            gen_load_fpr64(ctx, fp1, ft);
7442
            gen_load_fpr64(ctx, fp2, fr);
7443
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7444
            tcg_temp_free_i64(fp0);
7445
            tcg_temp_free_i64(fp1);
7446
            gen_store_fpr64(ctx, fp2, fd);
7447
            tcg_temp_free_i64(fp2);
7448
        }
7449
        opn = "msub.d";
7450
        break;
7451
    case OPC_MSUB_PS:
7452
        check_cp1_64bitmode(ctx);
7453
        {
7454
            TCGv_i64 fp0 = tcg_temp_new_i64();
7455
            TCGv_i64 fp1 = tcg_temp_new_i64();
7456
            TCGv_i64 fp2 = tcg_temp_new_i64();
7457

    
7458
            gen_load_fpr64(ctx, fp0, fs);
7459
            gen_load_fpr64(ctx, fp1, ft);
7460
            gen_load_fpr64(ctx, fp2, fr);
7461
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7462
            tcg_temp_free_i64(fp0);
7463
            tcg_temp_free_i64(fp1);
7464
            gen_store_fpr64(ctx, fp2, fd);
7465
            tcg_temp_free_i64(fp2);
7466
        }
7467
        opn = "msub.ps";
7468
        break;
7469
    case OPC_NMADD_S:
7470
        check_cop1x(ctx);
7471
        {
7472
            TCGv_i32 fp0 = tcg_temp_new_i32();
7473
            TCGv_i32 fp1 = tcg_temp_new_i32();
7474
            TCGv_i32 fp2 = tcg_temp_new_i32();
7475

    
7476
            gen_load_fpr32(fp0, fs);
7477
            gen_load_fpr32(fp1, ft);
7478
            gen_load_fpr32(fp2, fr);
7479
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7480
            tcg_temp_free_i32(fp0);
7481
            tcg_temp_free_i32(fp1);
7482
            gen_store_fpr32(fp2, fd);
7483
            tcg_temp_free_i32(fp2);
7484
        }
7485
        opn = "nmadd.s";
7486
        break;
7487
    case OPC_NMADD_D:
7488
        check_cop1x(ctx);
7489
        check_cp1_registers(ctx, fd | fs | ft | fr);
7490
        {
7491
            TCGv_i64 fp0 = tcg_temp_new_i64();
7492
            TCGv_i64 fp1 = tcg_temp_new_i64();
7493
            TCGv_i64 fp2 = tcg_temp_new_i64();
7494

    
7495
            gen_load_fpr64(ctx, fp0, fs);
7496
            gen_load_fpr64(ctx, fp1, ft);
7497
            gen_load_fpr64(ctx, fp2, fr);
7498
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7499
            tcg_temp_free_i64(fp0);
7500
            tcg_temp_free_i64(fp1);
7501
            gen_store_fpr64(ctx, fp2, fd);
7502
            tcg_temp_free_i64(fp2);
7503
        }
7504
        opn = "nmadd.d";
7505
        break;
7506
    case OPC_NMADD_PS:
7507
        check_cp1_64bitmode(ctx);
7508
        {
7509
            TCGv_i64 fp0 = tcg_temp_new_i64();
7510
            TCGv_i64 fp1 = tcg_temp_new_i64();
7511
            TCGv_i64 fp2 = tcg_temp_new_i64();
7512

    
7513
            gen_load_fpr64(ctx, fp0, fs);
7514
            gen_load_fpr64(ctx, fp1, ft);
7515
            gen_load_fpr64(ctx, fp2, fr);
7516
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7517
            tcg_temp_free_i64(fp0);
7518
            tcg_temp_free_i64(fp1);
7519
            gen_store_fpr64(ctx, fp2, fd);
7520
            tcg_temp_free_i64(fp2);
7521
        }
7522
        opn = "nmadd.ps";
7523
        break;
7524
    case OPC_NMSUB_S:
7525
        check_cop1x(ctx);
7526
        {
7527
            TCGv_i32 fp0 = tcg_temp_new_i32();
7528
            TCGv_i32 fp1 = tcg_temp_new_i32();
7529
            TCGv_i32 fp2 = tcg_temp_new_i32();
7530

    
7531
            gen_load_fpr32(fp0, fs);
7532
            gen_load_fpr32(fp1, ft);
7533
            gen_load_fpr32(fp2, fr);
7534
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7535
            tcg_temp_free_i32(fp0);
7536
            tcg_temp_free_i32(fp1);
7537
            gen_store_fpr32(fp2, fd);
7538
            tcg_temp_free_i32(fp2);
7539
        }
7540
        opn = "nmsub.s";
7541
        break;
7542
    case OPC_NMSUB_D:
7543
        check_cop1x(ctx);
7544
        check_cp1_registers(ctx, fd | fs | ft | fr);
7545
        {
7546
            TCGv_i64 fp0 = tcg_temp_new_i64();
7547
            TCGv_i64 fp1 = tcg_temp_new_i64();
7548
            TCGv_i64 fp2 = tcg_temp_new_i64();
7549

    
7550
            gen_load_fpr64(ctx, fp0, fs);
7551
            gen_load_fpr64(ctx, fp1, ft);
7552
            gen_load_fpr64(ctx, fp2, fr);
7553
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7554
            tcg_temp_free_i64(fp0);
7555
            tcg_temp_free_i64(fp1);
7556
            gen_store_fpr64(ctx, fp2, fd);
7557
            tcg_temp_free_i64(fp2);
7558
        }
7559
        opn = "nmsub.d";
7560
        break;
7561
    case OPC_NMSUB_PS:
7562
        check_cp1_64bitmode(ctx);
7563
        {
7564
            TCGv_i64 fp0 = tcg_temp_new_i64();
7565
            TCGv_i64 fp1 = tcg_temp_new_i64();
7566
            TCGv_i64 fp2 = tcg_temp_new_i64();
7567

    
7568
            gen_load_fpr64(ctx, fp0, fs);
7569
            gen_load_fpr64(ctx, fp1, ft);
7570
            gen_load_fpr64(ctx, fp2, fr);
7571
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7572
            tcg_temp_free_i64(fp0);
7573
            tcg_temp_free_i64(fp1);
7574
            gen_store_fpr64(ctx, fp2, fd);
7575
            tcg_temp_free_i64(fp2);
7576
        }
7577
        opn = "nmsub.ps";
7578
        break;
7579
    default:
7580
        MIPS_INVAL(opn);
7581
        generate_exception (ctx, EXCP_RI);
7582
        return;
7583
    }
7584
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7585
               fregnames[fs], fregnames[ft]);
7586
}
7587

    
7588
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
7589
                               int insn_bytes)
7590
{
7591
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7592
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7593
        /* Branches completion */
7594
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7595
        ctx->bstate = BS_BRANCH;
7596
        save_cpu_state(ctx, 0);
7597
        /* FIXME: Need to clear can_do_io.  */
7598
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
7599
        case MIPS_HFLAG_B:
7600
            /* unconditional branch */
7601
            MIPS_DEBUG("unconditional branch");
7602
            if (proc_hflags & MIPS_HFLAG_BX) {
7603
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
7604
            }
7605
            gen_goto_tb(ctx, 0, ctx->btarget);
7606
            break;
7607
        case MIPS_HFLAG_BL:
7608
            /* blikely taken case */
7609
            MIPS_DEBUG("blikely branch taken");
7610
            gen_goto_tb(ctx, 0, ctx->btarget);
7611
            break;
7612
        case MIPS_HFLAG_BC:
7613
            /* Conditional branch */
7614
            MIPS_DEBUG("conditional branch");
7615
            {
7616
                int l1 = gen_new_label();
7617

    
7618
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7619
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
7620
                gen_set_label(l1);
7621
                gen_goto_tb(ctx, 0, ctx->btarget);
7622
            }
7623
            break;
7624
        case MIPS_HFLAG_BR:
7625
            /* unconditional branch to register */
7626
            MIPS_DEBUG("branch to register");
7627
            if (env->insn_flags & ASE_MIPS16) {
7628
                TCGv t0 = tcg_temp_new();
7629
                TCGv_i32 t1 = tcg_temp_new_i32();
7630

    
7631
                tcg_gen_andi_tl(t0, btarget, 0x1);
7632
                tcg_gen_trunc_tl_i32(t1, t0);
7633
                tcg_temp_free(t0);
7634
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
7635
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
7636
                tcg_gen_or_i32(hflags, hflags, t1);
7637
                tcg_temp_free_i32(t1);
7638

    
7639
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
7640
            } else {
7641
                tcg_gen_mov_tl(cpu_PC, btarget);
7642
            }
7643
            if (ctx->singlestep_enabled) {
7644
                save_cpu_state(ctx, 0);
7645
                gen_helper_0i(raise_exception, EXCP_DEBUG);
7646
            }
7647
            tcg_gen_exit_tb(0);
7648
            break;
7649
        default:
7650
            MIPS_DEBUG("unknown branch");
7651
            break;
7652
        }
7653
    }
7654
}
7655

    
7656
/* ISA extensions (ASEs) */
7657
/* MIPS16 extension to MIPS32 */
7658

    
7659
/* MIPS16 major opcodes */
7660
enum {
7661
  M16_OPC_ADDIUSP = 0x00,
7662
  M16_OPC_ADDIUPC = 0x01,
7663
  M16_OPC_B = 0x02,
7664
  M16_OPC_JAL = 0x03,
7665
  M16_OPC_BEQZ = 0x04,
7666
  M16_OPC_BNEQZ = 0x05,
7667
  M16_OPC_SHIFT = 0x06,
7668
  M16_OPC_LD = 0x07,
7669
  M16_OPC_RRIA = 0x08,
7670
  M16_OPC_ADDIU8 = 0x09,
7671
  M16_OPC_SLTI = 0x0a,
7672
  M16_OPC_SLTIU = 0x0b,
7673
  M16_OPC_I8 = 0x0c,
7674
  M16_OPC_LI = 0x0d,
7675
  M16_OPC_CMPI = 0x0e,
7676
  M16_OPC_SD = 0x0f,
7677
  M16_OPC_LB = 0x10,
7678
  M16_OPC_LH = 0x11,
7679
  M16_OPC_LWSP = 0x12,
7680
  M16_OPC_LW = 0x13,
7681
  M16_OPC_LBU = 0x14,
7682
  M16_OPC_LHU = 0x15,
7683
  M16_OPC_LWPC = 0x16,
7684
  M16_OPC_LWU = 0x17,
7685
  M16_OPC_SB = 0x18,
7686
  M16_OPC_SH = 0x19,
7687
  M16_OPC_SWSP = 0x1a,
7688
  M16_OPC_SW = 0x1b,
7689
  M16_OPC_RRR = 0x1c,
7690
  M16_OPC_RR = 0x1d,
7691
  M16_OPC_EXTEND = 0x1e,
7692
  M16_OPC_I64 = 0x1f
7693
};
7694

    
7695
/* I8 funct field */
7696
enum {
7697
  I8_BTEQZ = 0x0,
7698
  I8_BTNEZ = 0x1,
7699
  I8_SWRASP = 0x2,
7700
  I8_ADJSP = 0x3,
7701
  I8_SVRS = 0x4,
7702
  I8_MOV32R = 0x5,
7703
  I8_MOVR32 = 0x7
7704
};
7705

    
7706
/* RRR f field */
7707
enum {
7708
  RRR_DADDU = 0x0,
7709
  RRR_ADDU = 0x1,
7710
  RRR_DSUBU = 0x2,
7711
  RRR_SUBU = 0x3
7712
};
7713

    
7714
/* RR funct field */
7715
enum {
7716
  RR_JR = 0x00,
7717
  RR_SDBBP = 0x01,
7718
  RR_SLT = 0x02,
7719
  RR_SLTU = 0x03,
7720
  RR_SLLV = 0x04,
7721
  RR_BREAK = 0x05,
7722
  RR_SRLV = 0x06,
7723
  RR_SRAV = 0x07,
7724
  RR_DSRL = 0x08,
7725
  RR_CMP = 0x0a,
7726
  RR_NEG = 0x0b,
7727
  RR_AND = 0x0c,
7728
  RR_OR = 0x0d,
7729
  RR_XOR = 0x0e,
7730
  RR_NOT = 0x0f,
7731
  RR_MFHI = 0x10,
7732
  RR_CNVT = 0x11,
7733
  RR_MFLO = 0x12,
7734
  RR_DSRA = 0x13,
7735
  RR_DSLLV = 0x14,
7736
  RR_DSRLV = 0x16,
7737
  RR_DSRAV = 0x17,
7738
  RR_MULT = 0x18,
7739
  RR_MULTU = 0x19,
7740
  RR_DIV = 0x1a,
7741
  RR_DIVU = 0x1b,
7742
  RR_DMULT = 0x1c,
7743
  RR_DMULTU = 0x1d,
7744
  RR_DDIV = 0x1e,
7745
  RR_DDIVU = 0x1f
7746
};
7747

    
7748
/* I64 funct field */
7749
enum {
7750
  I64_LDSP = 0x0,
7751
  I64_SDSP = 0x1,
7752
  I64_SDRASP = 0x2,
7753
  I64_DADJSP = 0x3,
7754
  I64_LDPC = 0x4,
7755
  I64_DADDIU5 = 0x5,
7756
  I64_DADDIUPC = 0x6,
7757
  I64_DADDIUSP = 0x7
7758
};
7759

    
7760
/* RR ry field for CNVT */
7761
enum {
7762
  RR_RY_CNVT_ZEB = 0x0,
7763
  RR_RY_CNVT_ZEH = 0x1,
7764
  RR_RY_CNVT_ZEW = 0x2,
7765
  RR_RY_CNVT_SEB = 0x4,
7766
  RR_RY_CNVT_SEH = 0x5,
7767
  RR_RY_CNVT_SEW = 0x6,
7768
};
7769

    
7770
static int xlat (int r)
7771
{
7772
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
7773

    
7774
  return map[r];
7775
}
7776

    
7777
static void gen_mips16_save (DisasContext *ctx,
7778
                             int xsregs, int aregs,
7779
                             int do_ra, int do_s0, int do_s1,
7780
                             int framesize)
7781
{
7782
    TCGv t0 = tcg_temp_new();
7783
    TCGv t1 = tcg_temp_new();
7784
    int args, astatic;
7785

    
7786
    switch (aregs) {
7787
    case 0:
7788
    case 1:
7789
    case 2:
7790
    case 3:
7791
    case 11:
7792
        args = 0;
7793
        break;
7794
    case 4:
7795
    case 5:
7796
    case 6:
7797
    case 7:
7798
        args = 1;
7799
        break;
7800
    case 8:
7801
    case 9:
7802
    case 10:
7803
        args = 2;
7804
        break;
7805
    case 12:
7806
    case 13:
7807
        args = 3;
7808
        break;
7809
    case 14:
7810
        args = 4;
7811
        break;
7812
    default:
7813
        generate_exception(ctx, EXCP_RI);
7814
        return;
7815
    }
7816

    
7817
    switch (args) {
7818
    case 4:
7819
        gen_base_offset_addr(ctx, t0, 29, 12);
7820
        gen_load_gpr(t1, 7);
7821
        op_ldst_sw(t1, t0, ctx);
7822
        /* Fall through */
7823
    case 3:
7824
        gen_base_offset_addr(ctx, t0, 29, 8);
7825
        gen_load_gpr(t1, 6);
7826
        op_ldst_sw(t1, t0, ctx);
7827
        /* Fall through */
7828
    case 2:
7829
        gen_base_offset_addr(ctx, t0, 29, 4);
7830
        gen_load_gpr(t1, 5);
7831
        op_ldst_sw(t1, t0, ctx);
7832
        /* Fall through */
7833
    case 1:
7834
        gen_base_offset_addr(ctx, t0, 29, 0);
7835
        gen_load_gpr(t1, 4);
7836
        op_ldst_sw(t1, t0, ctx);
7837
    }
7838

    
7839
    gen_load_gpr(t0, 29);
7840

    
7841
#define DECR_AND_STORE(reg) do {                \
7842
        tcg_gen_subi_tl(t0, t0, 4);             \
7843
        gen_load_gpr(t1, reg);                  \
7844
        op_ldst_sw(t1, t0, ctx);                \
7845
    } while (0)
7846

    
7847
    if (do_ra) {
7848
        DECR_AND_STORE(31);
7849
    }
7850

    
7851
    switch (xsregs) {
7852
    case 7:
7853
        DECR_AND_STORE(30);
7854
        /* Fall through */
7855
    case 6:
7856
        DECR_AND_STORE(23);
7857
        /* Fall through */
7858
    case 5:
7859
        DECR_AND_STORE(22);
7860
        /* Fall through */
7861
    case 4:
7862
        DECR_AND_STORE(21);
7863
        /* Fall through */
7864
    case 3:
7865
        DECR_AND_STORE(20);
7866
        /* Fall through */
7867
    case 2:
7868
        DECR_AND_STORE(19);
7869
        /* Fall through */
7870
    case 1:
7871
        DECR_AND_STORE(18);
7872
    }
7873

    
7874
    if (do_s1) {
7875
        DECR_AND_STORE(17);
7876
    }
7877
    if (do_s0) {
7878
        DECR_AND_STORE(16);
7879
    }
7880

    
7881
    switch (aregs) {
7882
    case 0:
7883
    case 4:
7884
    case 8:
7885
    case 12:
7886
    case 14:
7887
        astatic = 0;
7888
        break;
7889
    case 1:
7890
    case 5:
7891
    case 9:
7892
    case 13:
7893
        astatic = 1;
7894
        break;
7895
    case 2:
7896
    case 6:
7897
    case 10:
7898
        astatic = 2;
7899
        break;
7900
    case 3:
7901
    case 7:
7902
        astatic = 3;
7903
        break;
7904
    case 11:
7905
        astatic = 4;
7906
        break;
7907
    default:
7908
        generate_exception(ctx, EXCP_RI);
7909
        return;
7910
    }
7911

    
7912
    if (astatic > 0) {
7913
        DECR_AND_STORE(7);
7914
        if (astatic > 1) {
7915
            DECR_AND_STORE(6);
7916
            if (astatic > 2) {
7917
                DECR_AND_STORE(5);
7918
                if (astatic > 3) {
7919
                    DECR_AND_STORE(4);
7920
                }
7921
            }
7922
        }
7923
    }
7924
#undef DECR_AND_STORE
7925

    
7926
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
7927
    tcg_temp_free(t0);
7928
    tcg_temp_free(t1);
7929
}
7930

    
7931
static void gen_mips16_restore (DisasContext *ctx,
7932
                                int xsregs, int aregs,
7933
                                int do_ra, int do_s0, int do_s1,
7934
                                int framesize)
7935
{
7936
    int astatic;
7937
    TCGv t0 = tcg_temp_new();
7938
    TCGv t1 = tcg_temp_new();
7939

    
7940
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
7941

    
7942
#define DECR_AND_LOAD(reg) do {                 \
7943
        tcg_gen_subi_tl(t0, t0, 4);             \
7944
        op_ldst_lw(t1, t0, ctx);                \
7945
        gen_store_gpr(t1, reg);                 \
7946
    } while (0)
7947

    
7948
    if (do_ra) {
7949
        DECR_AND_LOAD(31);
7950
    }
7951

    
7952
    switch (xsregs) {
7953
    case 7:
7954
        DECR_AND_LOAD(30);
7955
        /* Fall through */
7956
    case 6:
7957
        DECR_AND_LOAD(23);
7958
        /* Fall through */
7959
    case 5:
7960
        DECR_AND_LOAD(22);
7961
        /* Fall through */
7962
    case 4:
7963
        DECR_AND_LOAD(21);
7964
        /* Fall through */
7965
    case 3:
7966
        DECR_AND_LOAD(20);
7967
        /* Fall through */
7968
    case 2:
7969
        DECR_AND_LOAD(19);
7970
        /* Fall through */
7971
    case 1:
7972
        DECR_AND_LOAD(18);
7973
    }
7974

    
7975
    if (do_s1) {
7976
        DECR_AND_LOAD(17);
7977
    }
7978
    if (do_s0) {
7979
        DECR_AND_LOAD(16);
7980
    }
7981

    
7982
    switch (aregs) {
7983
    case 0:
7984
    case 4:
7985
    case 8:
7986
    case 12:
7987
    case 14:
7988
        astatic = 0;
7989
        break;
7990
    case 1:
7991
    case 5:
7992
    case 9:
7993
    case 13:
7994
        astatic = 1;
7995
        break;
7996
    case 2:
7997
    case 6:
7998
    case 10:
7999
        astatic = 2;
8000
        break;
8001
    case 3:
8002
    case 7:
8003
        astatic = 3;
8004
        break;
8005
    case 11:
8006
        astatic = 4;
8007
        break;
8008
    default:
8009
        generate_exception(ctx, EXCP_RI);
8010
        return;
8011
    }
8012

    
8013
    if (astatic > 0) {
8014
        DECR_AND_LOAD(7);
8015
        if (astatic > 1) {
8016
            DECR_AND_LOAD(6);
8017
            if (astatic > 2) {
8018
                DECR_AND_LOAD(5);
8019
                if (astatic > 3) {
8020
                    DECR_AND_LOAD(4);
8021
                }
8022
            }
8023
        }
8024
    }
8025
#undef DECR_AND_LOAD
8026

    
8027
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8028
    tcg_temp_free(t0);
8029
    tcg_temp_free(t1);
8030
}
8031

    
8032
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8033
                         int is_64_bit, int extended)
8034
{
8035
    TCGv t0;
8036

    
8037
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8038
        generate_exception(ctx, EXCP_RI);
8039
        return;
8040
    }
8041

    
8042
    t0 = tcg_temp_new();
8043

    
8044
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8045
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8046
    if (!is_64_bit) {
8047
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8048
    }
8049

    
8050
    tcg_temp_free(t0);
8051
}
8052

    
8053
#if defined(TARGET_MIPS64)
8054
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8055
                               int ry, int funct, int16_t offset,
8056
                               int extended)
8057
{
8058
    switch (funct) {
8059
    case I64_LDSP:
8060
        check_mips_64(ctx);
8061
        offset = extended ? offset : offset << 3;
8062
        gen_ldst(ctx, OPC_LD, ry, 29, offset);
8063
        break;
8064
    case I64_SDSP:
8065
        check_mips_64(ctx);
8066
        offset = extended ? offset : offset << 3;
8067
        gen_ldst(ctx, OPC_SD, ry, 29, offset);
8068
        break;
8069
    case I64_SDRASP:
8070
        check_mips_64(ctx);
8071
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8072
        gen_ldst(ctx, OPC_SD, 31, 29, offset);
8073
        break;
8074
    case I64_DADJSP:
8075
        check_mips_64(ctx);
8076
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8077
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8078
        break;
8079
    case I64_LDPC:
8080
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8081
            generate_exception(ctx, EXCP_RI);
8082
        } else {
8083
            offset = extended ? offset : offset << 3;
8084
            gen_ldst(ctx, OPC_LDPC, ry, 0, offset);
8085
        }
8086
        break;
8087
    case I64_DADDIU5:
8088
        check_mips_64(ctx);
8089
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8090
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8091
        break;
8092
    case I64_DADDIUPC:
8093
        check_mips_64(ctx);
8094
        offset = extended ? offset : offset << 2;
8095
        gen_addiupc(ctx, ry, offset, 1, extended);
8096
        break;
8097
    case I64_DADDIUSP:
8098
        check_mips_64(ctx);
8099
        offset = extended ? offset : offset << 2;
8100
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8101
        break;
8102
    }
8103
}
8104
#endif
8105

    
8106
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8107
                                       int *is_branch)
8108
{
8109
    int extend = lduw_code(ctx->pc + 2);
8110
    int op, rx, ry, funct, sa;
8111
    int16_t imm, offset;
8112

    
8113
    ctx->opcode = (ctx->opcode << 16) | extend;
8114
    op = (ctx->opcode >> 11) & 0x1f;
8115
    sa = (ctx->opcode >> 22) & 0x1f;
8116
    funct = (ctx->opcode >> 8) & 0x7;
8117
    rx = xlat((ctx->opcode >> 8) & 0x7);
8118
    ry = xlat((ctx->opcode >> 5) & 0x7);
8119
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8120
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8121
                              | (ctx->opcode & 0x1f));
8122

    
8123
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8124
       counterparts.  */
8125
    switch (op) {
8126
    case M16_OPC_ADDIUSP:
8127
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8128
        break;
8129
    case M16_OPC_ADDIUPC:
8130
        gen_addiupc(ctx, rx, imm, 0, 1);
8131
        break;
8132
    case M16_OPC_B:
8133
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8134
        /* No delay slot, so just process as a normal instruction */
8135
        break;
8136
    case M16_OPC_BEQZ:
8137
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8138
        /* No delay slot, so just process as a normal instruction */
8139
        break;
8140
    case M16_OPC_BNEQZ:
8141
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8142
        /* No delay slot, so just process as a normal instruction */
8143
        break;
8144
    case M16_OPC_SHIFT:
8145
        switch (ctx->opcode & 0x3) {
8146
        case 0x0:
8147
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8148
            break;
8149
        case 0x1:
8150
#if defined(TARGET_MIPS64)
8151
            check_mips_64(ctx);
8152
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8153
#else
8154
            generate_exception(ctx, EXCP_RI);
8155
#endif
8156
            break;
8157
        case 0x2:
8158
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8159
            break;
8160
        case 0x3:
8161
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8162
            break;
8163
        }
8164
        break;
8165
#if defined(TARGET_MIPS64)
8166
    case M16_OPC_LD:
8167
            check_mips_64(ctx);
8168
        gen_ldst(ctx, OPC_LD, ry, rx, offset);
8169
        break;
8170
#endif
8171
    case M16_OPC_RRIA:
8172
        imm = ctx->opcode & 0xf;
8173
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8174
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8175
        imm = (int16_t) (imm << 1) >> 1;
8176
        if ((ctx->opcode >> 4) & 0x1) {
8177
#if defined(TARGET_MIPS64)
8178
            check_mips_64(ctx);
8179
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8180
#else
8181
            generate_exception(ctx, EXCP_RI);
8182
#endif
8183
        } else {
8184
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8185
        }
8186
        break;
8187
    case M16_OPC_ADDIU8:
8188
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8189
        break;
8190
    case M16_OPC_SLTI:
8191
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8192
        break;
8193
    case M16_OPC_SLTIU:
8194
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8195
        break;
8196
    case M16_OPC_I8:
8197
        switch (funct) {
8198
        case I8_BTEQZ:
8199
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8200
            break;
8201
        case I8_BTNEZ:
8202
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8203
            break;
8204
        case I8_SWRASP:
8205
            gen_ldst(ctx, OPC_SW, 31, 29, imm);
8206
            break;
8207
        case I8_ADJSP:
8208
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8209
            break;
8210
        case I8_SVRS:
8211
            {
8212
                int xsregs = (ctx->opcode >> 24) & 0x7;
8213
                int aregs = (ctx->opcode >> 16) & 0xf;
8214
                int do_ra = (ctx->opcode >> 6) & 0x1;
8215
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8216
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8217
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8218
                                 | (ctx->opcode & 0xf)) << 3;
8219

    
8220
                if (ctx->opcode & (1 << 7)) {
8221
                    gen_mips16_save(ctx, xsregs, aregs,
8222
                                    do_ra, do_s0, do_s1,
8223
                                    framesize);
8224
                } else {
8225
                    gen_mips16_restore(ctx, xsregs, aregs,
8226
                                       do_ra, do_s0, do_s1,
8227
                                       framesize);
8228
                }
8229
            }
8230
            break;
8231
        default:
8232
            generate_exception(ctx, EXCP_RI);
8233
            break;
8234
        }
8235
        break;
8236
    case M16_OPC_LI:
8237
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8238
        break;
8239
    case M16_OPC_CMPI:
8240
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8241
        break;
8242
#if defined(TARGET_MIPS64)
8243
    case M16_OPC_SD:
8244
        gen_ldst(ctx, OPC_SD, ry, rx, offset);
8245
        break;
8246
#endif
8247
    case M16_OPC_LB:
8248
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8249
        break;
8250
    case M16_OPC_LH:
8251
        gen_ldst(ctx, OPC_LH, ry, rx, offset);
8252
        break;
8253
    case M16_OPC_LWSP:
8254
        gen_ldst(ctx, OPC_LW, rx, 29, offset);
8255
        break;
8256
    case M16_OPC_LW:
8257
        gen_ldst(ctx, OPC_LW, ry, rx, offset);
8258
        break;
8259
    case M16_OPC_LBU:
8260
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8261
        break;
8262
    case M16_OPC_LHU:
8263
        gen_ldst(ctx, OPC_LHU, ry, rx, offset);
8264
        break;
8265
    case M16_OPC_LWPC:
8266
        gen_ldst(ctx, OPC_LWPC, rx, 0, offset);
8267
        break;
8268
#if defined(TARGET_MIPS64)
8269
    case M16_OPC_LWU:
8270
        gen_ldst(ctx, OPC_LWU, ry, rx, offset);
8271
        break;
8272
#endif
8273
    case M16_OPC_SB:
8274
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8275
        break;
8276
    case M16_OPC_SH:
8277
        gen_ldst(ctx, OPC_SH, ry, rx, offset);
8278
        break;
8279
    case M16_OPC_SWSP:
8280
        gen_ldst(ctx, OPC_SW, rx, 29, offset);
8281
        break;
8282
    case M16_OPC_SW:
8283
        gen_ldst(ctx, OPC_SW, ry, rx, offset);
8284
        break;
8285
#if defined(TARGET_MIPS64)
8286
    case M16_OPC_I64:
8287
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8288
        break;
8289
#endif
8290
    default:
8291
        generate_exception(ctx, EXCP_RI);
8292
        break;
8293
    }
8294

    
8295
    return 4;
8296
}
8297

    
8298
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8299
                              int *is_branch)
8300
{
8301
    int rx, ry;
8302
    int sa;
8303
    int op, cnvt_op, op1, offset;
8304
    int funct;
8305
    int n_bytes;
8306

    
8307
    op = (ctx->opcode >> 11) & 0x1f;
8308
    sa = (ctx->opcode >> 2) & 0x7;
8309
    sa = sa == 0 ? 8 : sa;
8310
    rx = xlat((ctx->opcode >> 8) & 0x7);
8311
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8312
    ry = xlat((ctx->opcode >> 5) & 0x7);
8313
    op1 = offset = ctx->opcode & 0x1f;
8314

    
8315
    n_bytes = 2;
8316

    
8317
    switch (op) {
8318
    case M16_OPC_ADDIUSP:
8319
        {
8320
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8321

    
8322
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8323
        }
8324
        break;
8325
    case M16_OPC_ADDIUPC:
8326
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8327
        break;
8328
    case M16_OPC_B:
8329
        offset = (ctx->opcode & 0x7ff) << 1;
8330
        offset = (int16_t)(offset << 4) >> 4;
8331
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8332
        /* No delay slot, so just process as a normal instruction */
8333
        break;
8334
    case M16_OPC_JAL:
8335
        offset = lduw_code(ctx->pc + 2);
8336
        offset = (((ctx->opcode & 0x1f) << 21)
8337
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8338
                  | offset) << 2;
8339
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
8340
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8341
        n_bytes = 4;
8342
        *is_branch = 1;
8343
        break;
8344
    case M16_OPC_BEQZ:
8345
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8346
        /* No delay slot, so just process as a normal instruction */
8347
        break;
8348
    case M16_OPC_BNEQZ:
8349
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8350
        /* No delay slot, so just process as a normal instruction */
8351
        break;
8352
    case M16_OPC_SHIFT:
8353
        switch (ctx->opcode & 0x3) {
8354
        case 0x0:
8355
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8356
            break;
8357
        case 0x1:
8358
#if defined(TARGET_MIPS64)
8359
            check_mips_64(ctx);
8360
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8361
#else
8362
            generate_exception(ctx, EXCP_RI);
8363
#endif
8364
            break;
8365
        case 0x2:
8366
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8367
            break;
8368
        case 0x3:
8369
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8370
            break;
8371
        }
8372
        break;
8373
#if defined(TARGET_MIPS64)
8374
    case M16_OPC_LD:
8375
        check_mips_64(ctx);
8376
        gen_ldst(ctx, OPC_LD, ry, rx, offset << 3);
8377
        break;
8378
#endif
8379
    case M16_OPC_RRIA:
8380
        {
8381
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8382

    
8383
            if ((ctx->opcode >> 4) & 1) {
8384
#if defined(TARGET_MIPS64)
8385
                check_mips_64(ctx);
8386
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8387
#else
8388
                generate_exception(ctx, EXCP_RI);
8389
#endif
8390
            } else {
8391
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8392
            }
8393
        }
8394
        break;
8395
    case M16_OPC_ADDIU8:
8396
        {
8397
            int16_t imm = (int8_t) ctx->opcode;
8398

    
8399
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8400
        }
8401
        break;
8402
    case M16_OPC_SLTI:
8403
        {
8404
            int16_t imm = (uint8_t) ctx->opcode;
8405

    
8406
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8407
        }
8408
        break;
8409
    case M16_OPC_SLTIU:
8410
        {
8411
            int16_t imm = (uint8_t) ctx->opcode;
8412

    
8413
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8414
        }
8415
        break;
8416
    case M16_OPC_I8:
8417
        {
8418
            int reg32;
8419

    
8420
            funct = (ctx->opcode >> 8) & 0x7;
8421
            switch (funct) {
8422
            case I8_BTEQZ:
8423
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8424
                                   ((int8_t)ctx->opcode) << 1);
8425
                break;
8426
            case I8_BTNEZ:
8427
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8428
                                   ((int8_t)ctx->opcode) << 1);
8429
                break;
8430
            case I8_SWRASP:
8431
                gen_ldst(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8432
                break;
8433
            case I8_ADJSP:
8434
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8435
                              ((int8_t)ctx->opcode) << 3);
8436
                break;
8437
            case I8_SVRS:
8438
                {
8439
                    int do_ra = ctx->opcode & (1 << 6);
8440
                    int do_s0 = ctx->opcode & (1 << 5);
8441
                    int do_s1 = ctx->opcode & (1 << 4);
8442
                    int framesize = ctx->opcode & 0xf;
8443

    
8444
                    if (framesize == 0) {
8445
                        framesize = 128;
8446
                    } else {
8447
                        framesize = framesize << 3;
8448
                    }
8449

    
8450
                    if (ctx->opcode & (1 << 7)) {
8451
                        gen_mips16_save(ctx, 0, 0,
8452
                                        do_ra, do_s0, do_s1, framesize);
8453
                    } else {
8454
                        gen_mips16_restore(ctx, 0, 0,
8455
                                           do_ra, do_s0, do_s1, framesize);
8456
                    }
8457
                }
8458
                break;
8459
            case I8_MOV32R:
8460
                {
8461
                    int rz = xlat(ctx->opcode & 0x7);
8462

    
8463
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8464
                        ((ctx->opcode >> 5) & 0x7);
8465
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8466
                }
8467
                break;
8468
            case I8_MOVR32:
8469
                reg32 = ctx->opcode & 0x1f;
8470
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8471
                break;
8472
            default:
8473
                generate_exception(ctx, EXCP_RI);
8474
                break;
8475
            }
8476
        }
8477
        break;
8478
    case M16_OPC_LI:
8479
        {
8480
            int16_t imm = (uint8_t) ctx->opcode;
8481

    
8482
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8483
        }
8484
        break;
8485
    case M16_OPC_CMPI:
8486
        {
8487
            int16_t imm = (uint8_t) ctx->opcode;
8488

    
8489
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8490
        }
8491
        break;
8492
#if defined(TARGET_MIPS64)
8493
    case M16_OPC_SD:
8494
        check_mips_64(ctx);
8495
        gen_ldst(ctx, OPC_SD, ry, rx, offset << 3);
8496
        break;
8497
#endif
8498
    case M16_OPC_LB:
8499
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8500
        break;
8501
    case M16_OPC_LH:
8502
        gen_ldst(ctx, OPC_LH, ry, rx, offset << 1);
8503
        break;
8504
    case M16_OPC_LWSP:
8505
        gen_ldst(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8506
        break;
8507
    case M16_OPC_LW:
8508
        gen_ldst(ctx, OPC_LW, ry, rx, offset << 2);
8509
        break;
8510
    case M16_OPC_LBU:
8511
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8512
        break;
8513
    case M16_OPC_LHU:
8514
        gen_ldst(ctx, OPC_LHU, ry, rx, offset << 1);
8515
        break;
8516
    case M16_OPC_LWPC:
8517
        gen_ldst(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
8518
        break;
8519
#if defined (TARGET_MIPS64)
8520
    case M16_OPC_LWU:
8521
        check_mips_64(ctx);
8522
        gen_ldst(ctx, OPC_LWU, ry, rx, offset << 2);
8523
        break;
8524
#endif
8525
    case M16_OPC_SB:
8526
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8527
        break;
8528
    case M16_OPC_SH:
8529
        gen_ldst(ctx, OPC_SH, ry, rx, offset << 1);
8530
        break;
8531
    case M16_OPC_SWSP:
8532
        gen_ldst(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8533
        break;
8534
    case M16_OPC_SW:
8535
        gen_ldst(ctx, OPC_SW, ry, rx, offset << 2);
8536
        break;
8537
    case M16_OPC_RRR:
8538
        {
8539
            int rz = xlat((ctx->opcode >> 2) & 0x7);
8540
            int mips32_op;
8541

    
8542
            switch (ctx->opcode & 0x3) {
8543
            case RRR_ADDU:
8544
                mips32_op = OPC_ADDU;
8545
                break;
8546
            case RRR_SUBU:
8547
                mips32_op = OPC_SUBU;
8548
                break;
8549
#if defined(TARGET_MIPS64)
8550
            case RRR_DADDU:
8551
                mips32_op = OPC_DADDU;
8552
                check_mips_64(ctx);
8553
                break;
8554
            case RRR_DSUBU:
8555
                mips32_op = OPC_DSUBU;
8556
                check_mips_64(ctx);
8557
                break;
8558
#endif
8559
            default:
8560
                generate_exception(ctx, EXCP_RI);
8561
                goto done;
8562
            }
8563

    
8564
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
8565
        done:
8566
            ;
8567
        }
8568
        break;
8569
    case M16_OPC_RR:
8570
        switch (op1) {
8571
        case RR_JR:
8572
            {
8573
                int nd = (ctx->opcode >> 7) & 0x1;
8574
                int link = (ctx->opcode >> 6) & 0x1;
8575
                int ra = (ctx->opcode >> 5) & 0x1;
8576

    
8577
                if (link) {
8578
                    op = nd ? OPC_JALRC : OPC_JALR;
8579
                } else {
8580
                    op = OPC_JR;
8581
                }
8582

    
8583
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
8584
                if (!nd) {
8585
                    *is_branch = 1;
8586
                }
8587
            }
8588
            break;
8589
        case RR_SDBBP:
8590
            /* XXX: not clear which exception should be raised
8591
             *      when in debug mode...
8592
             */
8593
            check_insn(env, ctx, ISA_MIPS32);
8594
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8595
                generate_exception(ctx, EXCP_DBp);
8596
            } else {
8597
                generate_exception(ctx, EXCP_DBp);
8598
            }
8599
            break;
8600
        case RR_SLT:
8601
            gen_slt(env, OPC_SLT, 24, rx, ry);
8602
            break;
8603
        case RR_SLTU:
8604
            gen_slt(env, OPC_SLTU, 24, rx, ry);
8605
            break;
8606
        case RR_BREAK:
8607
            generate_exception(ctx, EXCP_BREAK);
8608
            break;
8609
        case RR_SLLV:
8610
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
8611
            break;
8612
        case RR_SRLV:
8613
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
8614
            break;
8615
        case RR_SRAV:
8616
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
8617
            break;
8618
#if defined (TARGET_MIPS64)
8619
        case RR_DSRL:
8620
            check_mips_64(ctx);
8621
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
8622
            break;
8623
#endif
8624
        case RR_CMP:
8625
            gen_logic(env, OPC_XOR, 24, rx, ry);
8626
            break;
8627
        case RR_NEG:
8628
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
8629
            break;
8630
        case RR_AND:
8631
            gen_logic(env, OPC_AND, rx, rx, ry);
8632
            break;
8633
        case RR_OR:
8634
            gen_logic(env, OPC_OR, rx, rx, ry);
8635
            break;
8636
        case RR_XOR:
8637
            gen_logic(env, OPC_XOR, rx, rx, ry);
8638
            break;
8639
        case RR_NOT:
8640
            gen_logic(env, OPC_NOR, rx, ry, 0);
8641
            break;
8642
        case RR_MFHI:
8643
            gen_HILO(ctx, OPC_MFHI, rx);
8644
            break;
8645
        case RR_CNVT:
8646
            switch (cnvt_op) {
8647
            case RR_RY_CNVT_ZEB:
8648
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8649
                break;
8650
            case RR_RY_CNVT_ZEH:
8651
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8652
                break;
8653
            case RR_RY_CNVT_SEB:
8654
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8655
                break;
8656
            case RR_RY_CNVT_SEH:
8657
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8658
                break;
8659
#if defined (TARGET_MIPS64)
8660
            case RR_RY_CNVT_ZEW:
8661
                check_mips_64(ctx);
8662
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8663
                break;
8664
            case RR_RY_CNVT_SEW:
8665
                check_mips_64(ctx);
8666
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8667
                break;
8668
#endif
8669
            default:
8670
                generate_exception(ctx, EXCP_RI);
8671
                break;
8672
            }
8673
            break;
8674
        case RR_MFLO:
8675
            gen_HILO(ctx, OPC_MFLO, rx);
8676
            break;
8677
#if defined (TARGET_MIPS64)
8678
        case RR_DSRA:
8679
            check_mips_64(ctx);
8680
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
8681
            break;
8682
        case RR_DSLLV:
8683
            check_mips_64(ctx);
8684
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
8685
            break;
8686
        case RR_DSRLV:
8687
            check_mips_64(ctx);
8688
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
8689
            break;
8690
        case RR_DSRAV:
8691
            check_mips_64(ctx);
8692
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
8693
            break;
8694
#endif
8695
        case RR_MULT:
8696
            gen_muldiv(ctx, OPC_MULT, rx, ry);
8697
            break;
8698
        case RR_MULTU:
8699
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
8700
            break;
8701
        case RR_DIV:
8702
            gen_muldiv(ctx, OPC_DIV, rx, ry);
8703
            break;
8704
        case RR_DIVU:
8705
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
8706
            break;
8707
#if defined (TARGET_MIPS64)
8708
        case RR_DMULT:
8709
            check_mips_64(ctx);
8710
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
8711
            break;
8712
        case RR_DMULTU:
8713
            check_mips_64(ctx);
8714
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
8715
            break;
8716
        case RR_DDIV:
8717
            check_mips_64(ctx);
8718
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
8719
            break;
8720
        case RR_DDIVU:
8721
            check_mips_64(ctx);
8722
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
8723
            break;
8724
#endif
8725
        default:
8726
            generate_exception(ctx, EXCP_RI);
8727
            break;
8728
        }
8729
        break;
8730
    case M16_OPC_EXTEND:
8731
        decode_extended_mips16_opc(env, ctx, is_branch);
8732
        n_bytes = 4;
8733
        break;
8734
#if defined(TARGET_MIPS64)
8735
    case M16_OPC_I64:
8736
        funct = (ctx->opcode >> 8) & 0x7;
8737
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
8738
        break;
8739
#endif
8740
    default:
8741
        generate_exception(ctx, EXCP_RI);
8742
        break;
8743
    }
8744

    
8745
    return n_bytes;
8746
}
8747

    
8748
/* SmartMIPS extension to MIPS32 */
8749

    
8750
#if defined(TARGET_MIPS64)
8751

    
8752
/* MDMX extension to MIPS64 */
8753

    
8754
#endif
8755

    
8756
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
8757
{
8758
    int32_t offset;
8759
    int rs, rt, rd, sa;
8760
    uint32_t op, op1, op2;
8761
    int16_t imm;
8762

    
8763
    /* make sure instructions are on a word boundary */
8764
    if (ctx->pc & 0x3) {
8765
        env->CP0_BadVAddr = ctx->pc;
8766
        generate_exception(ctx, EXCP_AdEL);
8767
        return;
8768
    }
8769

    
8770
    /* Handle blikely not taken case */
8771
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
8772
        int l1 = gen_new_label();
8773

    
8774
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
8775
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8776
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
8777
        gen_goto_tb(ctx, 1, ctx->pc + 4);
8778
        gen_set_label(l1);
8779
    }
8780

    
8781
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
8782
        tcg_gen_debug_insn_start(ctx->pc);
8783

    
8784
    op = MASK_OP_MAJOR(ctx->opcode);
8785
    rs = (ctx->opcode >> 21) & 0x1f;
8786
    rt = (ctx->opcode >> 16) & 0x1f;
8787
    rd = (ctx->opcode >> 11) & 0x1f;
8788
    sa = (ctx->opcode >> 6) & 0x1f;
8789
    imm = (int16_t)ctx->opcode;
8790
    switch (op) {
8791
    case OPC_SPECIAL:
8792
        op1 = MASK_SPECIAL(ctx->opcode);
8793
        switch (op1) {
8794
        case OPC_SLL:          /* Shift with immediate */
8795
        case OPC_SRA:
8796
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
8797
            break;
8798
        case OPC_SRL:
8799
            switch ((ctx->opcode >> 21) & 0x1f) {
8800
            case 1:
8801
                /* rotr is decoded as srl on non-R2 CPUs */
8802
                if (env->insn_flags & ISA_MIPS32R2) {
8803
                    op1 = OPC_ROTR;
8804
                }
8805
                /* Fallthrough */
8806
            case 0:
8807
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8808
                break;
8809
            default:
8810
                generate_exception(ctx, EXCP_RI);
8811
                break;
8812
            }
8813
            break;
8814
        case OPC_MOVN:         /* Conditional move */
8815
        case OPC_MOVZ:
8816
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8817
            gen_cond_move(env, op1, rd, rs, rt);
8818
            break;
8819
        case OPC_ADD ... OPC_SUBU:
8820
            gen_arith(env, ctx, op1, rd, rs, rt);
8821
            break;
8822
        case OPC_SLLV:         /* Shifts */
8823
        case OPC_SRAV:
8824
            gen_shift(env, ctx, op1, rd, rs, rt);
8825
            break;
8826
        case OPC_SRLV:
8827
            switch ((ctx->opcode >> 6) & 0x1f) {
8828
            case 1:
8829
                /* rotrv is decoded as srlv on non-R2 CPUs */
8830
                if (env->insn_flags & ISA_MIPS32R2) {
8831
                    op1 = OPC_ROTRV;
8832
                }
8833
                /* Fallthrough */
8834
            case 0:
8835
                gen_shift(env, ctx, op1, rd, rs, rt);
8836
                break;
8837
            default:
8838
                generate_exception(ctx, EXCP_RI);
8839
                break;
8840
            }
8841
            break;
8842
        case OPC_SLT:          /* Set on less than */
8843
        case OPC_SLTU:
8844
            gen_slt(env, op1, rd, rs, rt);
8845
            break;
8846
        case OPC_AND:          /* Logic*/
8847
        case OPC_OR:
8848
        case OPC_NOR:
8849
        case OPC_XOR:
8850
            gen_logic(env, op1, rd, rs, rt);
8851
            break;
8852
        case OPC_MULT ... OPC_DIVU:
8853
            if (sa) {
8854
                check_insn(env, ctx, INSN_VR54XX);
8855
                op1 = MASK_MUL_VR54XX(ctx->opcode);
8856
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
8857
            } else
8858
                gen_muldiv(ctx, op1, rs, rt);
8859
            break;
8860
        case OPC_JR ... OPC_JALR:
8861
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
8862
            *is_branch = 1;
8863
            break;
8864
        case OPC_TGE ... OPC_TEQ: /* Traps */
8865
        case OPC_TNE:
8866
            gen_trap(ctx, op1, rs, rt, -1);
8867
            break;
8868
        case OPC_MFHI:          /* Move from HI/LO */
8869
        case OPC_MFLO:
8870
            gen_HILO(ctx, op1, rd);
8871
            break;
8872
        case OPC_MTHI:
8873
        case OPC_MTLO:          /* Move to HI/LO */
8874
            gen_HILO(ctx, op1, rs);
8875
            break;
8876
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
8877
#ifdef MIPS_STRICT_STANDARD
8878
            MIPS_INVAL("PMON / selsl");
8879
            generate_exception(ctx, EXCP_RI);
8880
#else
8881
            gen_helper_0i(pmon, sa);
8882
#endif
8883
            break;
8884
        case OPC_SYSCALL:
8885
            generate_exception(ctx, EXCP_SYSCALL);
8886
            ctx->bstate = BS_STOP;
8887
            break;
8888
        case OPC_BREAK:
8889
            generate_exception(ctx, EXCP_BREAK);
8890
            break;
8891
        case OPC_SPIM:
8892
#ifdef MIPS_STRICT_STANDARD
8893
            MIPS_INVAL("SPIM");
8894
            generate_exception(ctx, EXCP_RI);
8895
#else
8896
           /* Implemented as RI exception for now. */
8897
            MIPS_INVAL("spim (unofficial)");
8898
            generate_exception(ctx, EXCP_RI);
8899
#endif
8900
            break;
8901
        case OPC_SYNC:
8902
            /* Treat as NOP. */
8903
            break;
8904

    
8905
        case OPC_MOVCI:
8906
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8907
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8908
                check_cp1_enabled(ctx);
8909
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
8910
                          (ctx->opcode >> 16) & 1);
8911
            } else {
8912
                generate_exception_err(ctx, EXCP_CpU, 1);
8913
            }
8914
            break;
8915

    
8916
#if defined(TARGET_MIPS64)
8917
       /* MIPS64 specific opcodes */
8918
        case OPC_DSLL:
8919
        case OPC_DSRA:
8920
        case OPC_DSLL32:
8921
        case OPC_DSRA32:
8922
            check_insn(env, ctx, ISA_MIPS3);
8923
            check_mips_64(ctx);
8924
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
8925
            break;
8926
        case OPC_DSRL:
8927
            switch ((ctx->opcode >> 21) & 0x1f) {
8928
            case 1:
8929
                /* drotr is decoded as dsrl on non-R2 CPUs */
8930
                if (env->insn_flags & ISA_MIPS32R2) {
8931
                    op1 = OPC_DROTR;
8932
                }
8933
                /* Fallthrough */
8934
            case 0:
8935
                check_insn(env, ctx, ISA_MIPS3);
8936
                check_mips_64(ctx);
8937
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8938
                break;
8939
            default:
8940
                generate_exception(ctx, EXCP_RI);
8941
                break;
8942
            }
8943
            break;
8944
        case OPC_DSRL32:
8945
            switch ((ctx->opcode >> 21) & 0x1f) {
8946
            case 1:
8947
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
8948
                if (env->insn_flags & ISA_MIPS32R2) {
8949
                    op1 = OPC_DROTR32;
8950
                }
8951
                /* Fallthrough */
8952
            case 0:
8953
                check_insn(env, ctx, ISA_MIPS3);
8954
                check_mips_64(ctx);
8955
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8956
                break;
8957
            default:
8958
                generate_exception(ctx, EXCP_RI);
8959
                break;
8960
            }
8961
            break;
8962
        case OPC_DADD ... OPC_DSUBU:
8963
            check_insn(env, ctx, ISA_MIPS3);
8964
            check_mips_64(ctx);
8965
            gen_arith(env, ctx, op1, rd, rs, rt);
8966
            break;
8967
        case OPC_DSLLV:
8968
        case OPC_DSRAV:
8969
            check_insn(env, ctx, ISA_MIPS3);
8970
            check_mips_64(ctx);
8971
            gen_shift(env, ctx, op1, rd, rs, rt);
8972
            break;
8973
        case OPC_DSRLV:
8974
            switch ((ctx->opcode >> 6) & 0x1f) {
8975
            case 1:
8976
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
8977
                if (env->insn_flags & ISA_MIPS32R2) {
8978
                    op1 = OPC_DROTRV;
8979
                }
8980
                /* Fallthrough */
8981
            case 0:
8982
                check_insn(env, ctx, ISA_MIPS3);
8983
                check_mips_64(ctx);
8984
                gen_shift(env, ctx, op1, rd, rs, rt);
8985
                break;
8986
            default:
8987
                generate_exception(ctx, EXCP_RI);
8988
                break;
8989
            }
8990
            break;
8991
        case OPC_DMULT ... OPC_DDIVU:
8992
            check_insn(env, ctx, ISA_MIPS3);
8993
            check_mips_64(ctx);
8994
            gen_muldiv(ctx, op1, rs, rt);
8995
            break;
8996
#endif
8997
        default:            /* Invalid */
8998
            MIPS_INVAL("special");
8999
            generate_exception(ctx, EXCP_RI);
9000
            break;
9001
        }
9002
        break;
9003
    case OPC_SPECIAL2:
9004
        op1 = MASK_SPECIAL2(ctx->opcode);
9005
        switch (op1) {
9006
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
9007
        case OPC_MSUB ... OPC_MSUBU:
9008
            check_insn(env, ctx, ISA_MIPS32);
9009
            gen_muldiv(ctx, op1, rs, rt);
9010
            break;
9011
        case OPC_MUL:
9012
            gen_arith(env, ctx, op1, rd, rs, rt);
9013
            break;
9014
        case OPC_CLO:
9015
        case OPC_CLZ:
9016
            check_insn(env, ctx, ISA_MIPS32);
9017
            gen_cl(ctx, op1, rd, rs);
9018
            break;
9019
        case OPC_SDBBP:
9020
            /* XXX: not clear which exception should be raised
9021
             *      when in debug mode...
9022
             */
9023
            check_insn(env, ctx, ISA_MIPS32);
9024
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9025
                generate_exception(ctx, EXCP_DBp);
9026
            } else {
9027
                generate_exception(ctx, EXCP_DBp);
9028
            }
9029
            /* Treat as NOP. */
9030
            break;
9031
#if defined(TARGET_MIPS64)
9032
        case OPC_DCLO:
9033
        case OPC_DCLZ:
9034
            check_insn(env, ctx, ISA_MIPS64);
9035
            check_mips_64(ctx);
9036
            gen_cl(ctx, op1, rd, rs);
9037
            break;
9038
#endif
9039
        default:            /* Invalid */
9040
            MIPS_INVAL("special2");
9041
            generate_exception(ctx, EXCP_RI);
9042
            break;
9043
        }
9044
        break;
9045
    case OPC_SPECIAL3:
9046
        op1 = MASK_SPECIAL3(ctx->opcode);
9047
        switch (op1) {
9048
        case OPC_EXT:
9049
        case OPC_INS:
9050
            check_insn(env, ctx, ISA_MIPS32R2);
9051
            gen_bitops(ctx, op1, rt, rs, sa, rd);
9052
            break;
9053
        case OPC_BSHFL:
9054
            check_insn(env, ctx, ISA_MIPS32R2);
9055
            op2 = MASK_BSHFL(ctx->opcode);
9056
            gen_bshfl(ctx, op2, rt, rd);
9057
            break;
9058
        case OPC_RDHWR:
9059
            check_insn(env, ctx, ISA_MIPS32R2);
9060
            {
9061
                TCGv t0 = tcg_temp_new();
9062

    
9063
                switch (rd) {
9064
                case 0:
9065
                    save_cpu_state(ctx, 1);
9066
                    gen_helper_rdhwr_cpunum(t0);
9067
                    gen_store_gpr(t0, rt);
9068
                    break;
9069
                case 1:
9070
                    save_cpu_state(ctx, 1);
9071
                    gen_helper_rdhwr_synci_step(t0);
9072
                    gen_store_gpr(t0, rt);
9073
                    break;
9074
                case 2:
9075
                    save_cpu_state(ctx, 1);
9076
                    gen_helper_rdhwr_cc(t0);
9077
                    gen_store_gpr(t0, rt);
9078
                    break;
9079
                case 3:
9080
                    save_cpu_state(ctx, 1);
9081
                    gen_helper_rdhwr_ccres(t0);
9082
                    gen_store_gpr(t0, rt);
9083
                    break;
9084
                case 29:
9085
#if defined(CONFIG_USER_ONLY)
9086
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
9087
                    gen_store_gpr(t0, rt);
9088
                    break;
9089
#else
9090
                    /* XXX: Some CPUs implement this in hardware.
9091
                       Not supported yet. */
9092
#endif
9093
                default:            /* Invalid */
9094
                    MIPS_INVAL("rdhwr");
9095
                    generate_exception(ctx, EXCP_RI);
9096
                    break;
9097
                }
9098
                tcg_temp_free(t0);
9099
            }
9100
            break;
9101
        case OPC_FORK:
9102
            check_insn(env, ctx, ASE_MT);
9103
            {
9104
                TCGv t0 = tcg_temp_new();
9105
                TCGv t1 = tcg_temp_new();
9106

    
9107
                gen_load_gpr(t0, rt);
9108
                gen_load_gpr(t1, rs);
9109
                gen_helper_fork(t0, t1);
9110
                tcg_temp_free(t0);
9111
                tcg_temp_free(t1);
9112
            }
9113
            break;
9114
        case OPC_YIELD:
9115
            check_insn(env, ctx, ASE_MT);
9116
            {
9117
                TCGv t0 = tcg_temp_new();
9118

    
9119
                save_cpu_state(ctx, 1);
9120
                gen_load_gpr(t0, rs);
9121
                gen_helper_yield(t0, t0);
9122
                gen_store_gpr(t0, rd);
9123
                tcg_temp_free(t0);
9124
            }
9125
            break;
9126
#if defined(TARGET_MIPS64)
9127
        case OPC_DEXTM ... OPC_DEXT:
9128
        case OPC_DINSM ... OPC_DINS:
9129
            check_insn(env, ctx, ISA_MIPS64R2);
9130
            check_mips_64(ctx);
9131
            gen_bitops(ctx, op1, rt, rs, sa, rd);
9132
            break;
9133
        case OPC_DBSHFL:
9134
            check_insn(env, ctx, ISA_MIPS64R2);
9135
            check_mips_64(ctx);
9136
            op2 = MASK_DBSHFL(ctx->opcode);
9137
            gen_bshfl(ctx, op2, rt, rd);
9138
            break;
9139
#endif
9140
        default:            /* Invalid */
9141
            MIPS_INVAL("special3");
9142
            generate_exception(ctx, EXCP_RI);
9143
            break;
9144
        }
9145
        break;
9146
    case OPC_REGIMM:
9147
        op1 = MASK_REGIMM(ctx->opcode);
9148
        switch (op1) {
9149
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
9150
        case OPC_BLTZAL ... OPC_BGEZALL:
9151
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
9152
            *is_branch = 1;
9153
            break;
9154
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
9155
        case OPC_TNEI:
9156
            gen_trap(ctx, op1, rs, -1, imm);
9157
            break;
9158
        case OPC_SYNCI:
9159
            check_insn(env, ctx, ISA_MIPS32R2);
9160
            /* Treat as NOP. */
9161
            break;
9162
        default:            /* Invalid */
9163
            MIPS_INVAL("regimm");
9164
            generate_exception(ctx, EXCP_RI);
9165
            break;
9166
        }
9167
        break;
9168
    case OPC_CP0:
9169
        check_cp0_enabled(ctx);
9170
        op1 = MASK_CP0(ctx->opcode);
9171
        switch (op1) {
9172
        case OPC_MFC0:
9173
        case OPC_MTC0:
9174
        case OPC_MFTR:
9175
        case OPC_MTTR:
9176
#if defined(TARGET_MIPS64)
9177
        case OPC_DMFC0:
9178
        case OPC_DMTC0:
9179
#endif
9180
#ifndef CONFIG_USER_ONLY
9181
            gen_cp0(env, ctx, op1, rt, rd);
9182
#endif /* !CONFIG_USER_ONLY */
9183
            break;
9184
        case OPC_C0_FIRST ... OPC_C0_LAST:
9185
#ifndef CONFIG_USER_ONLY
9186
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
9187
#endif /* !CONFIG_USER_ONLY */
9188
            break;
9189
        case OPC_MFMC0:
9190
#ifndef CONFIG_USER_ONLY
9191
            {
9192
                TCGv t0 = tcg_temp_new();
9193

    
9194
                op2 = MASK_MFMC0(ctx->opcode);
9195
                switch (op2) {
9196
                case OPC_DMT:
9197
                    check_insn(env, ctx, ASE_MT);
9198
                    gen_helper_dmt(t0, t0);
9199
                    gen_store_gpr(t0, rt);
9200
                    break;
9201
                case OPC_EMT:
9202
                    check_insn(env, ctx, ASE_MT);
9203
                    gen_helper_emt(t0, t0);
9204
                    gen_store_gpr(t0, rt);
9205
                    break;
9206
                case OPC_DVPE:
9207
                    check_insn(env, ctx, ASE_MT);
9208
                    gen_helper_dvpe(t0, t0);
9209
                    gen_store_gpr(t0, rt);
9210
                    break;
9211
                case OPC_EVPE:
9212
                    check_insn(env, ctx, ASE_MT);
9213
                    gen_helper_evpe(t0, t0);
9214
                    gen_store_gpr(t0, rt);
9215
                    break;
9216
                case OPC_DI:
9217
                    check_insn(env, ctx, ISA_MIPS32R2);
9218
                    save_cpu_state(ctx, 1);
9219
                    gen_helper_di(t0);
9220
                    gen_store_gpr(t0, rt);
9221
                    /* Stop translation as we may have switched the execution mode */
9222
                    ctx->bstate = BS_STOP;
9223
                    break;
9224
                case OPC_EI:
9225
                    check_insn(env, ctx, ISA_MIPS32R2);
9226
                    save_cpu_state(ctx, 1);
9227
                    gen_helper_ei(t0);
9228
                    gen_store_gpr(t0, rt);
9229
                    /* Stop translation as we may have switched the execution mode */
9230
                    ctx->bstate = BS_STOP;
9231
                    break;
9232
                default:            /* Invalid */
9233
                    MIPS_INVAL("mfmc0");
9234
                    generate_exception(ctx, EXCP_RI);
9235
                    break;
9236
                }
9237
                tcg_temp_free(t0);
9238
            }
9239
#endif /* !CONFIG_USER_ONLY */
9240
            break;
9241
        case OPC_RDPGPR:
9242
            check_insn(env, ctx, ISA_MIPS32R2);
9243
            gen_load_srsgpr(rt, rd);
9244
            break;
9245
        case OPC_WRPGPR:
9246
            check_insn(env, ctx, ISA_MIPS32R2);
9247
            gen_store_srsgpr(rt, rd);
9248
            break;
9249
        default:
9250
            MIPS_INVAL("cp0");
9251
            generate_exception(ctx, EXCP_RI);
9252
            break;
9253
        }
9254
        break;
9255
    case OPC_ADDI: /* Arithmetic with immediate opcode */
9256
    case OPC_ADDIU:
9257
         gen_arith_imm(env, ctx, op, rt, rs, imm);
9258
         break;
9259
    case OPC_SLTI: /* Set on less than with immediate opcode */
9260
    case OPC_SLTIU:
9261
         gen_slt_imm(env, op, rt, rs, imm);
9262
         break;
9263
    case OPC_ANDI: /* Arithmetic with immediate opcode */
9264
    case OPC_LUI:
9265
    case OPC_ORI:
9266
    case OPC_XORI:
9267
         gen_logic_imm(env, op, rt, rs, imm);
9268
         break;
9269
    case OPC_J ... OPC_JAL: /* Jump */
9270
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
9271
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
9272
         *is_branch = 1;
9273
         break;
9274
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
9275
    case OPC_BEQL ... OPC_BGTZL:
9276
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
9277
         *is_branch = 1;
9278
         break;
9279
    case OPC_LB ... OPC_LWR: /* Load and stores */
9280
    case OPC_SB ... OPC_SW:
9281
    case OPC_SWR:
9282
    case OPC_LL:
9283
         gen_ldst(ctx, op, rt, rs, imm);
9284
         break;
9285
    case OPC_SC:
9286
         gen_st_cond(ctx, op, rt, rs, imm);
9287
         break;
9288
    case OPC_CACHE:
9289
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
9290
        /* Treat as NOP. */
9291
        break;
9292
    case OPC_PREF:
9293
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
9294
        /* Treat as NOP. */
9295
        break;
9296

    
9297
    /* Floating point (COP1). */
9298
    case OPC_LWC1:
9299
    case OPC_LDC1:
9300
    case OPC_SWC1:
9301
    case OPC_SDC1:
9302
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9303
            check_cp1_enabled(ctx);
9304
            gen_flt_ldst(ctx, op, rt, rs, imm);
9305
        } else {
9306
            generate_exception_err(ctx, EXCP_CpU, 1);
9307
        }
9308
        break;
9309

    
9310
    case OPC_CP1:
9311
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9312
            check_cp1_enabled(ctx);
9313
            op1 = MASK_CP1(ctx->opcode);
9314
            switch (op1) {
9315
            case OPC_MFHC1:
9316
            case OPC_MTHC1:
9317
                check_insn(env, ctx, ISA_MIPS32R2);
9318
            case OPC_MFC1:
9319
            case OPC_CFC1:
9320
            case OPC_MTC1:
9321
            case OPC_CTC1:
9322
                gen_cp1(ctx, op1, rt, rd);
9323
                break;
9324
#if defined(TARGET_MIPS64)
9325
            case OPC_DMFC1:
9326
            case OPC_DMTC1:
9327
                check_insn(env, ctx, ISA_MIPS3);
9328
                gen_cp1(ctx, op1, rt, rd);
9329
                break;
9330
#endif
9331
            case OPC_BC1ANY2:
9332
            case OPC_BC1ANY4:
9333
                check_cop1x(ctx);
9334
                check_insn(env, ctx, ASE_MIPS3D);
9335
                /* fall through */
9336
            case OPC_BC1:
9337
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
9338
                                    (rt >> 2) & 0x7, imm << 2);
9339
                *is_branch = 1;
9340
                break;
9341
            case OPC_S_FMT:
9342
            case OPC_D_FMT:
9343
            case OPC_W_FMT:
9344
            case OPC_L_FMT:
9345
            case OPC_PS_FMT:
9346
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
9347
                           (imm >> 8) & 0x7);
9348
                break;
9349
            default:
9350
                MIPS_INVAL("cp1");
9351
                generate_exception (ctx, EXCP_RI);
9352
                break;
9353
            }
9354
        } else {
9355
            generate_exception_err(ctx, EXCP_CpU, 1);
9356
        }
9357
        break;
9358

    
9359
    /* COP2.  */
9360
    case OPC_LWC2:
9361
    case OPC_LDC2:
9362
    case OPC_SWC2:
9363
    case OPC_SDC2:
9364
    case OPC_CP2:
9365
        /* COP2: Not implemented. */
9366
        generate_exception_err(ctx, EXCP_CpU, 2);
9367
        break;
9368

    
9369
    case OPC_CP3:
9370
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9371
            check_cp1_enabled(ctx);
9372
            op1 = MASK_CP3(ctx->opcode);
9373
            switch (op1) {
9374
            case OPC_LWXC1:
9375
            case OPC_LDXC1:
9376
            case OPC_LUXC1:
9377
            case OPC_SWXC1:
9378
            case OPC_SDXC1:
9379
            case OPC_SUXC1:
9380
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
9381
                break;
9382
            case OPC_PREFX:
9383
                /* Treat as NOP. */
9384
                break;
9385
            case OPC_ALNV_PS:
9386
            case OPC_MADD_S:
9387
            case OPC_MADD_D:
9388
            case OPC_MADD_PS:
9389
            case OPC_MSUB_S:
9390
            case OPC_MSUB_D:
9391
            case OPC_MSUB_PS:
9392
            case OPC_NMADD_S:
9393
            case OPC_NMADD_D:
9394
            case OPC_NMADD_PS:
9395
            case OPC_NMSUB_S:
9396
            case OPC_NMSUB_D:
9397
            case OPC_NMSUB_PS:
9398
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
9399
                break;
9400
            default:
9401
                MIPS_INVAL("cp3");
9402
                generate_exception (ctx, EXCP_RI);
9403
                break;
9404
            }
9405
        } else {
9406
            generate_exception_err(ctx, EXCP_CpU, 1);
9407
        }
9408
        break;
9409

    
9410
#if defined(TARGET_MIPS64)
9411
    /* MIPS64 opcodes */
9412
    case OPC_LWU:
9413
    case OPC_LDL ... OPC_LDR:
9414
    case OPC_SDL ... OPC_SDR:
9415
    case OPC_LLD:
9416
    case OPC_LD:
9417
    case OPC_SD:
9418
        check_insn(env, ctx, ISA_MIPS3);
9419
        check_mips_64(ctx);
9420
        gen_ldst(ctx, op, rt, rs, imm);
9421
        break;
9422
    case OPC_SCD:
9423
        check_insn(env, ctx, ISA_MIPS3);
9424
        check_mips_64(ctx);
9425
        gen_st_cond(ctx, op, rt, rs, imm);
9426
        break;
9427
    case OPC_DADDI:
9428
    case OPC_DADDIU:
9429
        check_insn(env, ctx, ISA_MIPS3);
9430
        check_mips_64(ctx);
9431
        gen_arith_imm(env, ctx, op, rt, rs, imm);
9432
        break;
9433
#endif
9434
    case OPC_JALX:
9435
        check_insn(env, ctx, ASE_MIPS16);
9436
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
9437
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
9438
        *is_branch = 1;
9439
        break;
9440
    case OPC_MDMX:
9441
        check_insn(env, ctx, ASE_MDMX);
9442
        /* MDMX: Not implemented. */
9443
    default:            /* Invalid */
9444
        MIPS_INVAL("major opcode");
9445
        generate_exception(ctx, EXCP_RI);
9446
        break;
9447
    }
9448
}
9449

    
9450
static inline void
9451
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
9452
                                int search_pc)
9453
{
9454
    DisasContext ctx;
9455
    target_ulong pc_start;
9456
    uint16_t *gen_opc_end;
9457
    CPUBreakpoint *bp;
9458
    int j, lj = -1;
9459
    int num_insns;
9460
    int max_insns;
9461
    int insn_bytes;
9462
    int is_branch;
9463

    
9464
    if (search_pc)
9465
        qemu_log("search pc %d\n", search_pc);
9466

    
9467
    pc_start = tb->pc;
9468
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9469
    ctx.pc = pc_start;
9470
    ctx.saved_pc = -1;
9471
    ctx.singlestep_enabled = env->singlestep_enabled;
9472
    ctx.tb = tb;
9473
    ctx.bstate = BS_NONE;
9474
    /* Restore delay slot state from the tb context.  */
9475
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
9476
    restore_cpu_state(env, &ctx);
9477
#ifdef CONFIG_USER_ONLY
9478
        ctx.mem_idx = MIPS_HFLAG_UM;
9479
#else
9480
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
9481
#endif
9482
    num_insns = 0;
9483
    max_insns = tb->cflags & CF_COUNT_MASK;
9484
    if (max_insns == 0)
9485
        max_insns = CF_COUNT_MASK;
9486
#ifdef DEBUG_DISAS
9487
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
9488
    /* FIXME: This may print out stale hflags from env... */
9489
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
9490
#endif
9491
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
9492
    gen_icount_start();
9493
    while (ctx.bstate == BS_NONE) {
9494
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9495
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9496
                if (bp->pc == ctx.pc) {
9497
                    save_cpu_state(&ctx, 1);
9498
                    ctx.bstate = BS_BRANCH;
9499
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
9500
                    /* Include the breakpoint location or the tb won't
9501
                     * be flushed when it must be.  */
9502
                    ctx.pc += 4;
9503
                    goto done_generating;
9504
                }
9505
            }
9506
        }
9507

    
9508
        if (search_pc) {
9509
            j = gen_opc_ptr - gen_opc_buf;
9510
            if (lj < j) {
9511
                lj++;
9512
                while (lj < j)
9513
                    gen_opc_instr_start[lj++] = 0;
9514
            }
9515
            gen_opc_pc[lj] = ctx.pc;
9516
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
9517
            gen_opc_instr_start[lj] = 1;
9518
            gen_opc_icount[lj] = num_insns;
9519
        }
9520
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9521
            gen_io_start();
9522

    
9523
        is_branch = 0;
9524
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
9525
            ctx.opcode = ldl_code(ctx.pc);
9526
            insn_bytes = 4;
9527
            decode_opc(env, &ctx, &is_branch);
9528
        } else if (env->insn_flags & ASE_MIPS16) {
9529
            ctx.opcode = lduw_code(ctx.pc);
9530
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
9531
        } else {
9532
            generate_exception(&ctx, EXCP_RI);
9533
            break;
9534
        }
9535
        if (!is_branch) {
9536
            handle_delay_slot(env, &ctx, insn_bytes);
9537
        }
9538
        ctx.pc += insn_bytes;
9539

    
9540
        num_insns++;
9541

    
9542
        /* Execute a branch and its delay slot as a single instruction.
9543
           This is what GDB expects and is consistent with what the
9544
           hardware does (e.g. if a delay slot instruction faults, the
9545
           reported PC is the PC of the branch).  */
9546
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
9547
            break;
9548

    
9549
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
9550
            break;
9551

    
9552
        if (gen_opc_ptr >= gen_opc_end)
9553
            break;
9554

    
9555
        if (num_insns >= max_insns)
9556
            break;
9557

    
9558
        if (singlestep)
9559
            break;
9560
    }
9561
    if (tb->cflags & CF_LAST_IO)
9562
        gen_io_end();
9563
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
9564
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
9565
        gen_helper_0i(raise_exception, EXCP_DEBUG);
9566
    } else {
9567
        switch (ctx.bstate) {
9568
        case BS_STOP:
9569
            gen_helper_interrupt_restart();
9570
            gen_goto_tb(&ctx, 0, ctx.pc);
9571
            break;
9572
        case BS_NONE:
9573
            save_cpu_state(&ctx, 0);
9574
            gen_goto_tb(&ctx, 0, ctx.pc);
9575
            break;
9576
        case BS_EXCP:
9577
            gen_helper_interrupt_restart();
9578
            tcg_gen_exit_tb(0);
9579
            break;
9580
        case BS_BRANCH:
9581
        default:
9582
            break;
9583
        }
9584
    }
9585
done_generating:
9586
    gen_icount_end(tb, num_insns);
9587
    *gen_opc_ptr = INDEX_op_end;
9588
    if (search_pc) {
9589
        j = gen_opc_ptr - gen_opc_buf;
9590
        lj++;
9591
        while (lj <= j)
9592
            gen_opc_instr_start[lj++] = 0;
9593
    } else {
9594
        tb->size = ctx.pc - pc_start;
9595
        tb->icount = num_insns;
9596
    }
9597
#ifdef DEBUG_DISAS
9598
    LOG_DISAS("\n");
9599
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9600
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9601
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
9602
        qemu_log("\n");
9603
    }
9604
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
9605
#endif
9606
}
9607

    
9608
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9609
{
9610
    gen_intermediate_code_internal(env, tb, 0);
9611
}
9612

    
9613
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9614
{
9615
    gen_intermediate_code_internal(env, tb, 1);
9616
}
9617

    
9618
static void fpu_dump_state(CPUState *env, FILE *f,
9619
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
9620
                           int flags)
9621
{
9622
    int i;
9623
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
9624

    
9625
#define printfpr(fp)                                                        \
9626
    do {                                                                    \
9627
        if (is_fpu64)                                                       \
9628
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
9629
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
9630
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
9631
        else {                                                              \
9632
            fpr_t tmp;                                                      \
9633
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
9634
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
9635
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
9636
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
9637
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
9638
        }                                                                   \
9639
    } while(0)
9640

    
9641

    
9642
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
9643
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
9644
                get_float_exception_flags(&env->active_fpu.fp_status));
9645
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
9646
        fpu_fprintf(f, "%3s: ", fregnames[i]);
9647
        printfpr(&env->active_fpu.fpr[i]);
9648
    }
9649

    
9650
#undef printfpr
9651
}
9652

    
9653
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
9654
/* Debug help: The architecture requires 32bit code to maintain proper
9655
   sign-extended values on 64bit machines.  */
9656

    
9657
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
9658

    
9659
static void
9660
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
9661
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9662
                                int flags)
9663
{
9664
    int i;
9665

    
9666
    if (!SIGN_EXT_P(env->active_tc.PC))
9667
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
9668
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
9669
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
9670
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
9671
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
9672
    if (!SIGN_EXT_P(env->btarget))
9673
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
9674

    
9675
    for (i = 0; i < 32; i++) {
9676
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
9677
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
9678
    }
9679

    
9680
    if (!SIGN_EXT_P(env->CP0_EPC))
9681
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
9682
    if (!SIGN_EXT_P(env->lladdr))
9683
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
9684
}
9685
#endif
9686

    
9687
void cpu_dump_state (CPUState *env, FILE *f,
9688
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9689
                     int flags)
9690
{
9691
    int i;
9692

    
9693
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
9694
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
9695
                env->hflags, env->btarget, env->bcond);
9696
    for (i = 0; i < 32; i++) {
9697
        if ((i & 3) == 0)
9698
            cpu_fprintf(f, "GPR%02d:", i);
9699
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
9700
        if ((i & 3) == 3)
9701
            cpu_fprintf(f, "\n");
9702
    }
9703

    
9704
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
9705
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
9706
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
9707
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
9708
    if (env->hflags & MIPS_HFLAG_FPU)
9709
        fpu_dump_state(env, f, cpu_fprintf, flags);
9710
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
9711
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
9712
#endif
9713
}
9714

    
9715
static void mips_tcg_init(void)
9716
{
9717
    int i;
9718
    static int inited;
9719

    
9720
    /* Initialize various static tables. */
9721
    if (inited)
9722
        return;
9723

    
9724
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
9725
    TCGV_UNUSED(cpu_gpr[0]);
9726
    for (i = 1; i < 32; i++)
9727
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
9728
                                        offsetof(CPUState, active_tc.gpr[i]),
9729
                                        regnames[i]);
9730
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
9731
                                offsetof(CPUState, active_tc.PC), "PC");
9732
    for (i = 0; i < MIPS_DSP_ACC; i++) {
9733
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
9734
                                       offsetof(CPUState, active_tc.HI[i]),
9735
                                       regnames_HI[i]);
9736
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
9737
                                       offsetof(CPUState, active_tc.LO[i]),
9738
                                       regnames_LO[i]);
9739
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
9740
                                        offsetof(CPUState, active_tc.ACX[i]),
9741
                                        regnames_ACX[i]);
9742
    }
9743
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
9744
                                     offsetof(CPUState, active_tc.DSPControl),
9745
                                     "DSPControl");
9746
    bcond = tcg_global_mem_new(TCG_AREG0,
9747
                               offsetof(CPUState, bcond), "bcond");
9748
    btarget = tcg_global_mem_new(TCG_AREG0,
9749
                                 offsetof(CPUState, btarget), "btarget");
9750
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
9751
                                    offsetof(CPUState, hflags), "hflags");
9752

    
9753
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
9754
                                      offsetof(CPUState, active_fpu.fcr0),
9755
                                      "fcr0");
9756
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
9757
                                       offsetof(CPUState, active_fpu.fcr31),
9758
                                       "fcr31");
9759

    
9760
    /* register helpers */
9761
#define GEN_HELPER 2
9762
#include "helper.h"
9763

    
9764
    inited = 1;
9765
}
9766

    
9767
#include "translate_init.c"
9768

    
9769
CPUMIPSState *cpu_mips_init (const char *cpu_model)
9770
{
9771
    CPUMIPSState *env;
9772
    const mips_def_t *def;
9773

    
9774
    def = cpu_mips_find_by_name(cpu_model);
9775
    if (!def)
9776
        return NULL;
9777
    env = qemu_mallocz(sizeof(CPUMIPSState));
9778
    env->cpu_model = def;
9779
    env->cpu_model_str = cpu_model;
9780

    
9781
    cpu_exec_init(env);
9782
#ifndef CONFIG_USER_ONLY
9783
    mmu_init(env, def);
9784
#endif
9785
    fpu_init(env, def);
9786
    mvp_init(env, def);
9787
    mips_tcg_init();
9788
    cpu_reset(env);
9789
    qemu_init_vcpu(env);
9790
    return env;
9791
}
9792

    
9793
void cpu_reset (CPUMIPSState *env)
9794
{
9795
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
9796
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
9797
        log_cpu_state(env, 0);
9798
    }
9799

    
9800
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
9801
    tlb_flush(env, 1);
9802

    
9803
    /* Reset registers to their default values */
9804
    env->CP0_PRid = env->cpu_model->CP0_PRid;
9805
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
9806
#ifdef TARGET_WORDS_BIGENDIAN
9807
    env->CP0_Config0 |= (1 << CP0C0_BE);
9808
#endif
9809
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
9810
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
9811
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
9812
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
9813
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
9814
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
9815
                                 << env->cpu_model->CP0_LLAddr_shift;
9816
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
9817
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
9818
    env->CCRes = env->cpu_model->CCRes;
9819
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
9820
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
9821
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
9822
    env->current_tc = 0;
9823
    env->SEGBITS = env->cpu_model->SEGBITS;
9824
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
9825
#if defined(TARGET_MIPS64)
9826
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
9827
        env->SEGMask |= 3ULL << 62;
9828
    }
9829
#endif
9830
    env->PABITS = env->cpu_model->PABITS;
9831
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
9832
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
9833
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
9834
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
9835
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
9836
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
9837
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
9838
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
9839
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
9840
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
9841
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
9842
    env->insn_flags = env->cpu_model->insn_flags;
9843

    
9844
#if defined(CONFIG_USER_ONLY)
9845
    env->hflags = MIPS_HFLAG_UM;
9846
    /* Enable access to the SYNCI_Step register.  */
9847
    env->CP0_HWREna |= (1 << 1);
9848
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9849
        env->hflags |= MIPS_HFLAG_FPU;
9850
    }
9851
#ifdef TARGET_MIPS64
9852
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
9853
        env->hflags |= MIPS_HFLAG_F64;
9854
    }
9855
#endif
9856
#else
9857
    if (env->hflags & MIPS_HFLAG_BMASK) {
9858
        /* If the exception was raised from a delay slot,
9859
           come back to the jump.  */
9860
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
9861
    } else {
9862
        env->CP0_ErrorEPC = env->active_tc.PC;
9863
    }
9864
    env->active_tc.PC = (int32_t)0xBFC00000;
9865
    env->CP0_Random = env->tlb->nb_tlb - 1;
9866
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
9867
    env->CP0_Wired = 0;
9868
    /* SMP not implemented */
9869
    env->CP0_EBase = 0x80000000;
9870
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
9871
    /* vectored interrupts not implemented, timer on int 7,
9872
       no performance counters. */
9873
    env->CP0_IntCtl = 0xe0000000;
9874
    {
9875
        int i;
9876

    
9877
        for (i = 0; i < 7; i++) {
9878
            env->CP0_WatchLo[i] = 0;
9879
            env->CP0_WatchHi[i] = 0x80000000;
9880
        }
9881
        env->CP0_WatchLo[7] = 0;
9882
        env->CP0_WatchHi[7] = 0;
9883
    }
9884
    /* Count register increments in debug mode, EJTAG version 1 */
9885
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9886
    env->hflags = MIPS_HFLAG_CP0;
9887
#endif
9888
#if defined(TARGET_MIPS64)
9889
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
9890
        env->hflags |= MIPS_HFLAG_64;
9891
    }
9892
#endif
9893
    env->exception_index = EXCP_NONE;
9894
}
9895

    
9896
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9897
                unsigned long searched_pc, int pc_pos, void *puc)
9898
{
9899
    env->active_tc.PC = gen_opc_pc[pc_pos];
9900
    env->hflags &= ~MIPS_HFLAG_BMASK;
9901
    env->hflags |= gen_opc_hflags[pc_pos];
9902
}