Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 1a7ff922

History | View | Annotate | Download (281.7 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
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
446

    
447
#include "gen-icount.h"
448

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
699
/* Tests */
700
static inline void gen_save_pc(target_ulong pc)
701
{
702
    tcg_gen_movi_tl(cpu_PC, pc);
703
}
704

    
705
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
706
{
707
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
708
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
709
        gen_save_pc(ctx->pc);
710
        ctx->saved_pc = ctx->pc;
711
    }
712
    if (ctx->hflags != ctx->saved_hflags) {
713
        tcg_gen_movi_i32(hflags, ctx->hflags);
714
        ctx->saved_hflags = ctx->hflags;
715
        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
716
        case MIPS_HFLAG_BR:
717
            break;
718
        case MIPS_HFLAG_BC:
719
        case MIPS_HFLAG_BL:
720
        case MIPS_HFLAG_B:
721
            tcg_gen_movi_tl(btarget, ctx->btarget);
722
            break;
723
        }
724
    }
725
}
726

    
727
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
728
{
729
    ctx->saved_hflags = ctx->hflags;
730
    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
731
    case MIPS_HFLAG_BR:
732
        break;
733
    case MIPS_HFLAG_BC:
734
    case MIPS_HFLAG_BL:
735
    case MIPS_HFLAG_B:
736
        ctx->btarget = env->btarget;
737
        break;
738
    }
739
}
740

    
741
static inline void
742
generate_exception_err (DisasContext *ctx, int excp, int err)
743
{
744
    TCGv_i32 texcp = tcg_const_i32(excp);
745
    TCGv_i32 terr = tcg_const_i32(err);
746
    save_cpu_state(ctx, 1);
747
    gen_helper_raise_exception_err(texcp, terr);
748
    tcg_temp_free_i32(terr);
749
    tcg_temp_free_i32(texcp);
750
}
751

    
752
static inline void
753
generate_exception (DisasContext *ctx, int excp)
754
{
755
    save_cpu_state(ctx, 1);
756
    gen_helper_0i(raise_exception, excp);
757
}
758

    
759
/* Addresses computation */
760
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
761
{
762
    tcg_gen_add_tl(ret, arg0, arg1);
763

    
764
#if defined(TARGET_MIPS64)
765
    /* For compatibility with 32-bit code, data reference in user mode
766
       with Status_UX = 0 should be casted to 32-bit and sign extended.
767
       See the MIPS64 PRA manual, section 4.10. */
768
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
769
        !(ctx->hflags & MIPS_HFLAG_UX)) {
770
        tcg_gen_ext32s_i64(ret, ret);
771
    }
772
#endif
773
}
774

    
775
static inline void check_cp0_enabled(DisasContext *ctx)
776
{
777
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
778
        generate_exception_err(ctx, EXCP_CpU, 0);
779
}
780

    
781
static inline void check_cp1_enabled(DisasContext *ctx)
782
{
783
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
784
        generate_exception_err(ctx, EXCP_CpU, 1);
785
}
786

    
787
/* Verify that the processor is running with COP1X instructions enabled.
788
   This is associated with the nabla symbol in the MIPS32 and MIPS64
789
   opcode tables.  */
790

    
791
static inline void check_cop1x(DisasContext *ctx)
792
{
793
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
794
        generate_exception(ctx, EXCP_RI);
795
}
796

    
797
/* Verify that the processor is running with 64-bit floating-point
798
   operations enabled.  */
799

    
800
static inline void check_cp1_64bitmode(DisasContext *ctx)
801
{
802
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
803
        generate_exception(ctx, EXCP_RI);
804
}
805

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

    
823
/* This code generates a "reserved instruction" exception if the
824
   CPU does not support the instruction set corresponding to flags. */
825
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
826
{
827
    if (unlikely(!(env->insn_flags & flags)))
828
        generate_exception(ctx, EXCP_RI);
829
}
830

    
831
/* This code generates a "reserved instruction" exception if 64-bit
832
   instructions are not enabled. */
833
static inline void check_mips_64(DisasContext *ctx)
834
{
835
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
836
        generate_exception(ctx, EXCP_RI);
837
}
838

    
839
/* load/store instructions. */
840
#define OP_LD(insn,fname)                                                 \
841
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
842
{                                                                         \
843
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
844
}
845
OP_LD(lb,ld8s);
846
OP_LD(lbu,ld8u);
847
OP_LD(lh,ld16s);
848
OP_LD(lhu,ld16u);
849
OP_LD(lw,ld32s);
850
#if defined(TARGET_MIPS64)
851
OP_LD(lwu,ld32u);
852
OP_LD(ld,ld64);
853
#endif
854
#undef OP_LD
855

    
856
#define OP_ST(insn,fname)                                                  \
857
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
858
{                                                                          \
859
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
860
}
861
OP_ST(sb,st8);
862
OP_ST(sh,st16);
863
OP_ST(sw,st32);
864
#if defined(TARGET_MIPS64)
865
OP_ST(sd,st64);
866
#endif
867
#undef OP_ST
868

    
869
#ifdef CONFIG_USER_ONLY
870
#define OP_LD_ATOMIC(insn,fname)                                           \
871
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
872
{                                                                          \
873
    TCGv t0 = tcg_temp_new();                                              \
874
    tcg_gen_mov_tl(t0, arg1);                                              \
875
    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
876
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
877
    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
878
    tcg_temp_free(t0);                                                     \
879
}
880
#else
881
#define OP_LD_ATOMIC(insn,fname)                                           \
882
static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
883
{                                                                          \
884
    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
885
}
886
#endif
887
OP_LD_ATOMIC(ll,ld32s);
888
#if defined(TARGET_MIPS64)
889
OP_LD_ATOMIC(lld,ld64);
890
#endif
891
#undef OP_LD_ATOMIC
892

    
893
#ifdef CONFIG_USER_ONLY
894
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
895
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
896
{                                                                            \
897
    TCGv t0 = tcg_temp_new();                                                \
898
    int l1 = gen_new_label();                                                \
899
    int l2 = gen_new_label();                                                \
900
                                                                             \
901
    tcg_gen_andi_tl(t0, arg2, almask);                                       \
902
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
903
    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
904
    generate_exception(ctx, EXCP_AdES);                                      \
905
    gen_set_label(l1);                                                       \
906
    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
907
    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
908
    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
909
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
910
    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
911
    gen_helper_0i(raise_exception, EXCP_SC);                                 \
912
    gen_set_label(l2);                                                       \
913
    tcg_gen_movi_tl(t0, 0);                                                  \
914
    gen_store_gpr(t0, rt);                                                   \
915
    tcg_temp_free(t0);                                                       \
916
}
917
#else
918
#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
919
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
920
{                                                                            \
921
    TCGv t0 = tcg_temp_new();                                                \
922
    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
923
    gen_store_gpr(t0, rt);                                                   \
924
    tcg_temp_free(t0);                                                       \
925
}
926
#endif
927
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
928
#if defined(TARGET_MIPS64)
929
OP_ST_ATOMIC(scd,st64,ld64,0x7);
930
#endif
931
#undef OP_ST_ATOMIC
932

    
933
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
934
                                  int base, int16_t offset)
935
{
936
    if (base == 0) {
937
        tcg_gen_movi_tl(addr, offset);
938
    } else if (offset == 0) {
939
        gen_load_gpr(addr, base);
940
    } else {
941
        tcg_gen_movi_tl(addr, offset);
942
        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
943
    }
944
}
945

    
946
static target_ulong pc_relative_pc (DisasContext *ctx)
947
{
948
    target_ulong pc = ctx->pc;
949

    
950
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
951
        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
952

    
953
        pc -= branch_bytes;
954
    }
955

    
956
    pc &= ~(target_ulong)3;
957
    return pc;
958
}
959

    
960
/* Load and store */
961
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
962
                      int base, int16_t offset)
963
{
964
    const char *opn = "ldst";
965
    TCGv t0 = tcg_temp_new();
966
    TCGv t1 = tcg_temp_new();
967

    
968
    gen_base_offset_addr(ctx, t0, base, offset);
969
    /* Don't do NOP if destination is zero: we must perform the actual
970
       memory access. */
971
    switch (opc) {
972
#if defined(TARGET_MIPS64)
973
    case OPC_LWU:
974
        save_cpu_state(ctx, 0);
975
        op_ldst_lwu(t0, t0, ctx);
976
        gen_store_gpr(t0, rt);
977
        opn = "lwu";
978
        break;
979
    case OPC_LD:
980
        save_cpu_state(ctx, 0);
981
        op_ldst_ld(t0, t0, ctx);
982
        gen_store_gpr(t0, rt);
983
        opn = "ld";
984
        break;
985
    case OPC_LLD:
986
        save_cpu_state(ctx, 0);
987
        op_ldst_lld(t0, t0, ctx);
988
        gen_store_gpr(t0, rt);
989
        opn = "lld";
990
        break;
991
    case OPC_SD:
992
        save_cpu_state(ctx, 0);
993
        gen_load_gpr(t1, rt);
994
        op_ldst_sd(t1, t0, ctx);
995
        opn = "sd";
996
        break;
997
    case OPC_LDL:
998
        save_cpu_state(ctx, 1);
999
        gen_load_gpr(t1, rt);
1000
        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1001
        gen_store_gpr(t1, rt);
1002
        opn = "ldl";
1003
        break;
1004
    case OPC_SDL:
1005
        save_cpu_state(ctx, 1);
1006
        gen_load_gpr(t1, rt);
1007
        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1008
        opn = "sdl";
1009
        break;
1010
    case OPC_LDR:
1011
        save_cpu_state(ctx, 1);
1012
        gen_load_gpr(t1, rt);
1013
        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1014
        gen_store_gpr(t1, rt);
1015
        opn = "ldr";
1016
        break;
1017
    case OPC_SDR:
1018
        save_cpu_state(ctx, 1);
1019
        gen_load_gpr(t1, rt);
1020
        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1021
        opn = "sdr";
1022
        break;
1023
    case OPC_LDPC:
1024
        save_cpu_state(ctx, 1);
1025
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1026
        gen_op_addr_add(ctx, t0, t0, t1);
1027
        op_ldst_ld(t0, t0, ctx);
1028
        gen_store_gpr(t0, rt);
1029
        break;
1030
#endif
1031
    case OPC_LWPC:
1032
        save_cpu_state(ctx, 1);
1033
        tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1034
        gen_op_addr_add(ctx, t0, t0, t1);
1035
        op_ldst_lw(t0, t0, ctx);
1036
        gen_store_gpr(t0, rt);
1037
        break;
1038
    case OPC_LW:
1039
        save_cpu_state(ctx, 0);
1040
        op_ldst_lw(t0, t0, ctx);
1041
        gen_store_gpr(t0, rt);
1042
        opn = "lw";
1043
        break;
1044
    case OPC_SW:
1045
        save_cpu_state(ctx, 0);
1046
        gen_load_gpr(t1, rt);
1047
        op_ldst_sw(t1, t0, ctx);
1048
        opn = "sw";
1049
        break;
1050
    case OPC_LH:
1051
        save_cpu_state(ctx, 0);
1052
        op_ldst_lh(t0, t0, ctx);
1053
        gen_store_gpr(t0, rt);
1054
        opn = "lh";
1055
        break;
1056
    case OPC_SH:
1057
        save_cpu_state(ctx, 0);
1058
        gen_load_gpr(t1, rt);
1059
        op_ldst_sh(t1, t0, ctx);
1060
        opn = "sh";
1061
        break;
1062
    case OPC_LHU:
1063
        save_cpu_state(ctx, 0);
1064
        op_ldst_lhu(t0, t0, ctx);
1065
        gen_store_gpr(t0, rt);
1066
        opn = "lhu";
1067
        break;
1068
    case OPC_LB:
1069
        save_cpu_state(ctx, 0);
1070
        op_ldst_lb(t0, t0, ctx);
1071
        gen_store_gpr(t0, rt);
1072
        opn = "lb";
1073
        break;
1074
    case OPC_SB:
1075
        save_cpu_state(ctx, 0);
1076
        gen_load_gpr(t1, rt);
1077
        op_ldst_sb(t1, t0, ctx);
1078
        opn = "sb";
1079
        break;
1080
    case OPC_LBU:
1081
        save_cpu_state(ctx, 0);
1082
        op_ldst_lbu(t0, t0, ctx);
1083
        gen_store_gpr(t0, rt);
1084
        opn = "lbu";
1085
        break;
1086
    case OPC_LWL:
1087
        save_cpu_state(ctx, 1);
1088
        gen_load_gpr(t1, rt);
1089
        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1090
        gen_store_gpr(t1, rt);
1091
        opn = "lwl";
1092
        break;
1093
    case OPC_SWL:
1094
        save_cpu_state(ctx, 1);
1095
        gen_load_gpr(t1, rt);
1096
        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1097
        opn = "swr";
1098
        break;
1099
    case OPC_LWR:
1100
        save_cpu_state(ctx, 1);
1101
        gen_load_gpr(t1, rt);
1102
        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1103
        gen_store_gpr(t1, rt);
1104
        opn = "lwr";
1105
        break;
1106
    case OPC_SWR:
1107
        save_cpu_state(ctx, 1);
1108
        gen_load_gpr(t1, rt);
1109
        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1110
        opn = "swr";
1111
        break;
1112
    case OPC_LL:
1113
        save_cpu_state(ctx, 1);
1114
        op_ldst_ll(t0, t0, ctx);
1115
        gen_store_gpr(t0, rt);
1116
        opn = "ll";
1117
        break;
1118
    }
1119
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1120
    tcg_temp_free(t0);
1121
    tcg_temp_free(t1);
1122
}
1123

    
1124
/* Store conditional */
1125
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1126
                         int base, int16_t offset)
1127
{
1128
    const char *opn = "st_cond";
1129
    TCGv t0, t1;
1130

    
1131
    t0 = tcg_temp_local_new();
1132

    
1133
    gen_base_offset_addr(ctx, t0, base, offset);
1134
    /* Don't do NOP if destination is zero: we must perform the actual
1135
       memory access. */
1136

    
1137
    t1 = tcg_temp_local_new();
1138
    gen_load_gpr(t1, rt);
1139
    switch (opc) {
1140
#if defined(TARGET_MIPS64)
1141
    case OPC_SCD:
1142
        save_cpu_state(ctx, 0);
1143
        op_ldst_scd(t1, t0, rt, ctx);
1144
        opn = "scd";
1145
        break;
1146
#endif
1147
    case OPC_SC:
1148
        save_cpu_state(ctx, 1);
1149
        op_ldst_sc(t1, t0, rt, ctx);
1150
        opn = "sc";
1151
        break;
1152
    }
1153
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1154
    tcg_temp_free(t1);
1155
    tcg_temp_free(t0);
1156
}
1157

    
1158
/* Load and store */
1159
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1160
                          int base, int16_t offset)
1161
{
1162
    const char *opn = "flt_ldst";
1163
    TCGv t0 = tcg_temp_new();
1164

    
1165
    gen_base_offset_addr(ctx, t0, base, offset);
1166
    /* Don't do NOP if destination is zero: we must perform the actual
1167
       memory access. */
1168
    switch (opc) {
1169
    case OPC_LWC1:
1170
        {
1171
            TCGv_i32 fp0 = tcg_temp_new_i32();
1172

    
1173
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1174
            tcg_gen_trunc_tl_i32(fp0, t0);
1175
            gen_store_fpr32(fp0, ft);
1176
            tcg_temp_free_i32(fp0);
1177
        }
1178
        opn = "lwc1";
1179
        break;
1180
    case OPC_SWC1:
1181
        {
1182
            TCGv_i32 fp0 = tcg_temp_new_i32();
1183
            TCGv t1 = tcg_temp_new();
1184

    
1185
            gen_load_fpr32(fp0, ft);
1186
            tcg_gen_extu_i32_tl(t1, fp0);
1187
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1188
            tcg_temp_free(t1);
1189
            tcg_temp_free_i32(fp0);
1190
        }
1191
        opn = "swc1";
1192
        break;
1193
    case OPC_LDC1:
1194
        {
1195
            TCGv_i64 fp0 = tcg_temp_new_i64();
1196

    
1197
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1198
            gen_store_fpr64(ctx, fp0, ft);
1199
            tcg_temp_free_i64(fp0);
1200
        }
1201
        opn = "ldc1";
1202
        break;
1203
    case OPC_SDC1:
1204
        {
1205
            TCGv_i64 fp0 = tcg_temp_new_i64();
1206

    
1207
            gen_load_fpr64(ctx, fp0, ft);
1208
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1209
            tcg_temp_free_i64(fp0);
1210
        }
1211
        opn = "sdc1";
1212
        break;
1213
    default:
1214
        MIPS_INVAL(opn);
1215
        generate_exception(ctx, EXCP_RI);
1216
        goto out;
1217
    }
1218
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1219
 out:
1220
    tcg_temp_free(t0);
1221
}
1222

    
1223
/* Arithmetic with immediate operand */
1224
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1225
                           int rt, int rs, int16_t imm)
1226
{
1227
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1228
    const char *opn = "imm arith";
1229

    
1230
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1231
        /* If no destination, treat it as a NOP.
1232
           For addi, we must generate the overflow exception when needed. */
1233
        MIPS_DEBUG("NOP");
1234
        return;
1235
    }
1236
    switch (opc) {
1237
    case OPC_ADDI:
1238
        {
1239
            TCGv t0 = tcg_temp_local_new();
1240
            TCGv t1 = tcg_temp_new();
1241
            TCGv t2 = tcg_temp_new();
1242
            int l1 = gen_new_label();
1243

    
1244
            gen_load_gpr(t1, rs);
1245
            tcg_gen_addi_tl(t0, t1, uimm);
1246
            tcg_gen_ext32s_tl(t0, t0);
1247

    
1248
            tcg_gen_xori_tl(t1, t1, ~uimm);
1249
            tcg_gen_xori_tl(t2, t0, uimm);
1250
            tcg_gen_and_tl(t1, t1, t2);
1251
            tcg_temp_free(t2);
1252
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1253
            tcg_temp_free(t1);
1254
            /* operands of same sign, result different sign */
1255
            generate_exception(ctx, EXCP_OVERFLOW);
1256
            gen_set_label(l1);
1257
            tcg_gen_ext32s_tl(t0, t0);
1258
            gen_store_gpr(t0, rt);
1259
            tcg_temp_free(t0);
1260
        }
1261
        opn = "addi";
1262
        break;
1263
    case OPC_ADDIU:
1264
        if (rs != 0) {
1265
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1266
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1267
        } else {
1268
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1269
        }
1270
        opn = "addiu";
1271
        break;
1272
#if defined(TARGET_MIPS64)
1273
    case OPC_DADDI:
1274
        {
1275
            TCGv t0 = tcg_temp_local_new();
1276
            TCGv t1 = tcg_temp_new();
1277
            TCGv t2 = tcg_temp_new();
1278
            int l1 = gen_new_label();
1279

    
1280
            gen_load_gpr(t1, rs);
1281
            tcg_gen_addi_tl(t0, t1, uimm);
1282

    
1283
            tcg_gen_xori_tl(t1, t1, ~uimm);
1284
            tcg_gen_xori_tl(t2, t0, uimm);
1285
            tcg_gen_and_tl(t1, t1, t2);
1286
            tcg_temp_free(t2);
1287
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1288
            tcg_temp_free(t1);
1289
            /* operands of same sign, result different sign */
1290
            generate_exception(ctx, EXCP_OVERFLOW);
1291
            gen_set_label(l1);
1292
            gen_store_gpr(t0, rt);
1293
            tcg_temp_free(t0);
1294
        }
1295
        opn = "daddi";
1296
        break;
1297
    case OPC_DADDIU:
1298
        if (rs != 0) {
1299
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1300
        } else {
1301
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1302
        }
1303
        opn = "daddiu";
1304
        break;
1305
#endif
1306
    }
1307
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1308
}
1309

    
1310
/* Logic with immediate operand */
1311
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1312
{
1313
    target_ulong uimm;
1314
    const char *opn = "imm logic";
1315

    
1316
    if (rt == 0) {
1317
        /* If no destination, treat it as a NOP. */
1318
        MIPS_DEBUG("NOP");
1319
        return;
1320
    }
1321
    uimm = (uint16_t)imm;
1322
    switch (opc) {
1323
    case OPC_ANDI:
1324
        if (likely(rs != 0))
1325
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1326
        else
1327
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1328
        opn = "andi";
1329
        break;
1330
    case OPC_ORI:
1331
        if (rs != 0)
1332
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1333
        else
1334
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1335
        opn = "ori";
1336
        break;
1337
    case OPC_XORI:
1338
        if (likely(rs != 0))
1339
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1340
        else
1341
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1342
        opn = "xori";
1343
        break;
1344
    case OPC_LUI:
1345
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1346
        opn = "lui";
1347
        break;
1348
    }
1349
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1350
}
1351

    
1352
/* Set on less than with immediate operand */
1353
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1354
{
1355
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1356
    const char *opn = "imm arith";
1357
    TCGv t0;
1358

    
1359
    if (rt == 0) {
1360
        /* If no destination, treat it as a NOP. */
1361
        MIPS_DEBUG("NOP");
1362
        return;
1363
    }
1364
    t0 = tcg_temp_new();
1365
    gen_load_gpr(t0, rs);
1366
    switch (opc) {
1367
    case OPC_SLTI:
1368
        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1369
        opn = "slti";
1370
        break;
1371
    case OPC_SLTIU:
1372
        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1373
        opn = "sltiu";
1374
        break;
1375
    }
1376
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1377
    tcg_temp_free(t0);
1378
}
1379

    
1380
/* Shifts with immediate operand */
1381
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1382
                          int rt, int rs, int16_t imm)
1383
{
1384
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1385
    const char *opn = "imm shift";
1386
    TCGv t0;
1387

    
1388
    if (rt == 0) {
1389
        /* If no destination, treat it as a NOP. */
1390
        MIPS_DEBUG("NOP");
1391
        return;
1392
    }
1393

    
1394
    t0 = tcg_temp_new();
1395
    gen_load_gpr(t0, rs);
1396
    switch (opc) {
1397
    case OPC_SLL:
1398
        tcg_gen_shli_tl(t0, t0, uimm);
1399
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1400
        opn = "sll";
1401
        break;
1402
    case OPC_SRA:
1403
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1404
        opn = "sra";
1405
        break;
1406
    case OPC_SRL:
1407
        if (uimm != 0) {
1408
            tcg_gen_ext32u_tl(t0, t0);
1409
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1410
        } else {
1411
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1412
        }
1413
        opn = "srl";
1414
        break;
1415
    case OPC_ROTR:
1416
        if (uimm != 0) {
1417
            TCGv_i32 t1 = tcg_temp_new_i32();
1418

    
1419
            tcg_gen_trunc_tl_i32(t1, t0);
1420
            tcg_gen_rotri_i32(t1, t1, uimm);
1421
            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1422
            tcg_temp_free_i32(t1);
1423
        } else {
1424
            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1425
        }
1426
        opn = "rotr";
1427
        break;
1428
#if defined(TARGET_MIPS64)
1429
    case OPC_DSLL:
1430
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1431
        opn = "dsll";
1432
        break;
1433
    case OPC_DSRA:
1434
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1435
        opn = "dsra";
1436
        break;
1437
    case OPC_DSRL:
1438
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1439
        opn = "dsrl";
1440
        break;
1441
    case OPC_DROTR:
1442
        if (uimm != 0) {
1443
            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1444
        } else {
1445
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
1446
        }
1447
        opn = "drotr";
1448
        break;
1449
    case OPC_DSLL32:
1450
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1451
        opn = "dsll32";
1452
        break;
1453
    case OPC_DSRA32:
1454
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1455
        opn = "dsra32";
1456
        break;
1457
    case OPC_DSRL32:
1458
        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1459
        opn = "dsrl32";
1460
        break;
1461
    case OPC_DROTR32:
1462
        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1463
        opn = "drotr32";
1464
        break;
1465
#endif
1466
    }
1467
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1468
    tcg_temp_free(t0);
1469
}
1470

    
1471
/* Arithmetic */
1472
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1473
                       int rd, int rs, int rt)
1474
{
1475
    const char *opn = "arith";
1476

    
1477
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1478
       && opc != OPC_DADD && opc != OPC_DSUB) {
1479
        /* If no destination, treat it as a NOP.
1480
           For add & sub, we must generate the overflow exception when needed. */
1481
        MIPS_DEBUG("NOP");
1482
        return;
1483
    }
1484

    
1485
    switch (opc) {
1486
    case OPC_ADD:
1487
        {
1488
            TCGv t0 = tcg_temp_local_new();
1489
            TCGv t1 = tcg_temp_new();
1490
            TCGv t2 = tcg_temp_new();
1491
            int l1 = gen_new_label();
1492

    
1493
            gen_load_gpr(t1, rs);
1494
            gen_load_gpr(t2, rt);
1495
            tcg_gen_add_tl(t0, t1, t2);
1496
            tcg_gen_ext32s_tl(t0, t0);
1497
            tcg_gen_xor_tl(t1, t1, t2);
1498
            tcg_gen_xor_tl(t2, t0, t2);
1499
            tcg_gen_andc_tl(t1, t2, t1);
1500
            tcg_temp_free(t2);
1501
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1502
            tcg_temp_free(t1);
1503
            /* operands of same sign, result different sign */
1504
            generate_exception(ctx, EXCP_OVERFLOW);
1505
            gen_set_label(l1);
1506
            gen_store_gpr(t0, rd);
1507
            tcg_temp_free(t0);
1508
        }
1509
        opn = "add";
1510
        break;
1511
    case OPC_ADDU:
1512
        if (rs != 0 && rt != 0) {
1513
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1514
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1515
        } else if (rs == 0 && rt != 0) {
1516
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1517
        } else if (rs != 0 && rt == 0) {
1518
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1519
        } else {
1520
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1521
        }
1522
        opn = "addu";
1523
        break;
1524
    case OPC_SUB:
1525
        {
1526
            TCGv t0 = tcg_temp_local_new();
1527
            TCGv t1 = tcg_temp_new();
1528
            TCGv t2 = tcg_temp_new();
1529
            int l1 = gen_new_label();
1530

    
1531
            gen_load_gpr(t1, rs);
1532
            gen_load_gpr(t2, rt);
1533
            tcg_gen_sub_tl(t0, t1, t2);
1534
            tcg_gen_ext32s_tl(t0, t0);
1535
            tcg_gen_xor_tl(t2, t1, t2);
1536
            tcg_gen_xor_tl(t1, t0, t1);
1537
            tcg_gen_and_tl(t1, t1, t2);
1538
            tcg_temp_free(t2);
1539
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1540
            tcg_temp_free(t1);
1541
            /* operands of different sign, first operand and result different sign */
1542
            generate_exception(ctx, EXCP_OVERFLOW);
1543
            gen_set_label(l1);
1544
            gen_store_gpr(t0, rd);
1545
            tcg_temp_free(t0);
1546
        }
1547
        opn = "sub";
1548
        break;
1549
    case OPC_SUBU:
1550
        if (rs != 0 && rt != 0) {
1551
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1552
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1553
        } else if (rs == 0 && rt != 0) {
1554
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1555
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1556
        } else if (rs != 0 && rt == 0) {
1557
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1558
        } else {
1559
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1560
        }
1561
        opn = "subu";
1562
        break;
1563
#if defined(TARGET_MIPS64)
1564
    case OPC_DADD:
1565
        {
1566
            TCGv t0 = tcg_temp_local_new();
1567
            TCGv t1 = tcg_temp_new();
1568
            TCGv t2 = tcg_temp_new();
1569
            int l1 = gen_new_label();
1570

    
1571
            gen_load_gpr(t1, rs);
1572
            gen_load_gpr(t2, rt);
1573
            tcg_gen_add_tl(t0, t1, t2);
1574
            tcg_gen_xor_tl(t1, t1, t2);
1575
            tcg_gen_xor_tl(t2, t0, t2);
1576
            tcg_gen_andc_tl(t1, t2, t1);
1577
            tcg_temp_free(t2);
1578
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1579
            tcg_temp_free(t1);
1580
            /* operands of same sign, result different sign */
1581
            generate_exception(ctx, EXCP_OVERFLOW);
1582
            gen_set_label(l1);
1583
            gen_store_gpr(t0, rd);
1584
            tcg_temp_free(t0);
1585
        }
1586
        opn = "dadd";
1587
        break;
1588
    case OPC_DADDU:
1589
        if (rs != 0 && rt != 0) {
1590
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1591
        } else if (rs == 0 && rt != 0) {
1592
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1593
        } else if (rs != 0 && rt == 0) {
1594
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1595
        } else {
1596
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1597
        }
1598
        opn = "daddu";
1599
        break;
1600
    case OPC_DSUB:
1601
        {
1602
            TCGv t0 = tcg_temp_local_new();
1603
            TCGv t1 = tcg_temp_new();
1604
            TCGv t2 = tcg_temp_new();
1605
            int l1 = gen_new_label();
1606

    
1607
            gen_load_gpr(t1, rs);
1608
            gen_load_gpr(t2, rt);
1609
            tcg_gen_sub_tl(t0, t1, t2);
1610
            tcg_gen_xor_tl(t2, t1, t2);
1611
            tcg_gen_xor_tl(t1, t0, t1);
1612
            tcg_gen_and_tl(t1, t1, t2);
1613
            tcg_temp_free(t2);
1614
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1615
            tcg_temp_free(t1);
1616
            /* operands of different sign, first operand and result different sign */
1617
            generate_exception(ctx, EXCP_OVERFLOW);
1618
            gen_set_label(l1);
1619
            gen_store_gpr(t0, rd);
1620
            tcg_temp_free(t0);
1621
        }
1622
        opn = "dsub";
1623
        break;
1624
    case OPC_DSUBU:
1625
        if (rs != 0 && rt != 0) {
1626
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1627
        } else if (rs == 0 && rt != 0) {
1628
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1629
        } else if (rs != 0 && rt == 0) {
1630
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1631
        } else {
1632
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1633
        }
1634
        opn = "dsubu";
1635
        break;
1636
#endif
1637
    case OPC_MUL:
1638
        if (likely(rs != 0 && rt != 0)) {
1639
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1640
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1641
        } else {
1642
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1643
        }
1644
        opn = "mul";
1645
        break;
1646
    }
1647
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1648
}
1649

    
1650
/* Conditional move */
1651
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1652
{
1653
    const char *opn = "cond move";
1654
    int l1;
1655

    
1656
    if (rd == 0) {
1657
        /* If no destination, treat it as a NOP.
1658
           For add & sub, we must generate the overflow exception when needed. */
1659
        MIPS_DEBUG("NOP");
1660
        return;
1661
    }
1662

    
1663
    l1 = gen_new_label();
1664
    switch (opc) {
1665
    case OPC_MOVN:
1666
        if (likely(rt != 0))
1667
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1668
        else
1669
            tcg_gen_br(l1);
1670
        opn = "movn";
1671
        break;
1672
    case OPC_MOVZ:
1673
        if (likely(rt != 0))
1674
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1675
        opn = "movz";
1676
        break;
1677
    }
1678
    if (rs != 0)
1679
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1680
    else
1681
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1682
    gen_set_label(l1);
1683

    
1684
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1685
}
1686

    
1687
/* Logic */
1688
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1689
{
1690
    const char *opn = "logic";
1691

    
1692
    if (rd == 0) {
1693
        /* If no destination, treat it as a NOP. */
1694
        MIPS_DEBUG("NOP");
1695
        return;
1696
    }
1697

    
1698
    switch (opc) {
1699
    case OPC_AND:
1700
        if (likely(rs != 0 && rt != 0)) {
1701
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1702
        } else {
1703
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1704
        }
1705
        opn = "and";
1706
        break;
1707
    case OPC_NOR:
1708
        if (rs != 0 && rt != 0) {
1709
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1710
        } else if (rs == 0 && rt != 0) {
1711
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1712
        } else if (rs != 0 && rt == 0) {
1713
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1714
        } else {
1715
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1716
        }
1717
        opn = "nor";
1718
        break;
1719
    case OPC_OR:
1720
        if (likely(rs != 0 && rt != 0)) {
1721
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1722
        } else if (rs == 0 && rt != 0) {
1723
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1724
        } else if (rs != 0 && rt == 0) {
1725
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1726
        } else {
1727
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1728
        }
1729
        opn = "or";
1730
        break;
1731
    case OPC_XOR:
1732
        if (likely(rs != 0 && rt != 0)) {
1733
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1734
        } else if (rs == 0 && rt != 0) {
1735
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1736
        } else if (rs != 0 && rt == 0) {
1737
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1738
        } else {
1739
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1740
        }
1741
        opn = "xor";
1742
        break;
1743
    }
1744
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1745
}
1746

    
1747
/* Set on lower than */
1748
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1749
{
1750
    const char *opn = "slt";
1751
    TCGv t0, t1;
1752

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

    
1759
    t0 = tcg_temp_new();
1760
    t1 = tcg_temp_new();
1761
    gen_load_gpr(t0, rs);
1762
    gen_load_gpr(t1, rt);
1763
    switch (opc) {
1764
    case OPC_SLT:
1765
        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1766
        opn = "slt";
1767
        break;
1768
    case OPC_SLTU:
1769
        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1770
        opn = "sltu";
1771
        break;
1772
    }
1773
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1774
    tcg_temp_free(t0);
1775
    tcg_temp_free(t1);
1776
}
1777

    
1778
/* Shifts */
1779
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1780
                       int rd, int rs, int rt)
1781
{
1782
    const char *opn = "shifts";
1783
    TCGv t0, t1;
1784

    
1785
    if (rd == 0) {
1786
        /* If no destination, treat it as a NOP.
1787
           For add & sub, we must generate the overflow exception when needed. */
1788
        MIPS_DEBUG("NOP");
1789
        return;
1790
    }
1791

    
1792
    t0 = tcg_temp_new();
1793
    t1 = tcg_temp_new();
1794
    gen_load_gpr(t0, rs);
1795
    gen_load_gpr(t1, rt);
1796
    switch (opc) {
1797
    case OPC_SLLV:
1798
        tcg_gen_andi_tl(t0, t0, 0x1f);
1799
        tcg_gen_shl_tl(t0, t1, t0);
1800
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1801
        opn = "sllv";
1802
        break;
1803
    case OPC_SRAV:
1804
        tcg_gen_andi_tl(t0, t0, 0x1f);
1805
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1806
        opn = "srav";
1807
        break;
1808
    case OPC_SRLV:
1809
        tcg_gen_ext32u_tl(t1, t1);
1810
        tcg_gen_andi_tl(t0, t0, 0x1f);
1811
        tcg_gen_shr_tl(t0, t1, t0);
1812
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1813
        opn = "srlv";
1814
        break;
1815
    case OPC_ROTRV:
1816
        {
1817
            TCGv_i32 t2 = tcg_temp_new_i32();
1818
            TCGv_i32 t3 = tcg_temp_new_i32();
1819

    
1820
            tcg_gen_trunc_tl_i32(t2, t0);
1821
            tcg_gen_trunc_tl_i32(t3, t1);
1822
            tcg_gen_andi_i32(t2, t2, 0x1f);
1823
            tcg_gen_rotr_i32(t2, t3, t2);
1824
            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1825
            tcg_temp_free_i32(t2);
1826
            tcg_temp_free_i32(t3);
1827
            opn = "rotrv";
1828
        }
1829
        break;
1830
#if defined(TARGET_MIPS64)
1831
    case OPC_DSLLV:
1832
        tcg_gen_andi_tl(t0, t0, 0x3f);
1833
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1834
        opn = "dsllv";
1835
        break;
1836
    case OPC_DSRAV:
1837
        tcg_gen_andi_tl(t0, t0, 0x3f);
1838
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1839
        opn = "dsrav";
1840
        break;
1841
    case OPC_DSRLV:
1842
        tcg_gen_andi_tl(t0, t0, 0x3f);
1843
        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1844
        opn = "dsrlv";
1845
        break;
1846
    case OPC_DROTRV:
1847
        tcg_gen_andi_tl(t0, t0, 0x3f);
1848
        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1849
        opn = "drotrv";
1850
        break;
1851
#endif
1852
    }
1853
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1854
    tcg_temp_free(t0);
1855
    tcg_temp_free(t1);
1856
}
1857

    
1858
/* Arithmetic on HI/LO registers */
1859
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1860
{
1861
    const char *opn = "hilo";
1862

    
1863
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1864
        /* Treat as NOP. */
1865
        MIPS_DEBUG("NOP");
1866
        return;
1867
    }
1868
    switch (opc) {
1869
    case OPC_MFHI:
1870
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1871
        opn = "mfhi";
1872
        break;
1873
    case OPC_MFLO:
1874
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1875
        opn = "mflo";
1876
        break;
1877
    case OPC_MTHI:
1878
        if (reg != 0)
1879
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1880
        else
1881
            tcg_gen_movi_tl(cpu_HI[0], 0);
1882
        opn = "mthi";
1883
        break;
1884
    case OPC_MTLO:
1885
        if (reg != 0)
1886
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1887
        else
1888
            tcg_gen_movi_tl(cpu_LO[0], 0);
1889
        opn = "mtlo";
1890
        break;
1891
    }
1892
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1893
}
1894

    
1895
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1896
                        int rs, int rt)
1897
{
1898
    const char *opn = "mul/div";
1899
    TCGv t0, t1;
1900

    
1901
    switch (opc) {
1902
    case OPC_DIV:
1903
    case OPC_DIVU:
1904
#if defined(TARGET_MIPS64)
1905
    case OPC_DDIV:
1906
    case OPC_DDIVU:
1907
#endif
1908
        t0 = tcg_temp_local_new();
1909
        t1 = tcg_temp_local_new();
1910
        break;
1911
    default:
1912
        t0 = tcg_temp_new();
1913
        t1 = tcg_temp_new();
1914
        break;
1915
    }
1916

    
1917
    gen_load_gpr(t0, rs);
1918
    gen_load_gpr(t1, rt);
1919
    switch (opc) {
1920
    case OPC_DIV:
1921
        {
1922
            int l1 = gen_new_label();
1923
            int l2 = gen_new_label();
1924

    
1925
            tcg_gen_ext32s_tl(t0, t0);
1926
            tcg_gen_ext32s_tl(t1, t1);
1927
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1928
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1929
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1930

    
1931
            tcg_gen_mov_tl(cpu_LO[0], t0);
1932
            tcg_gen_movi_tl(cpu_HI[0], 0);
1933
            tcg_gen_br(l1);
1934
            gen_set_label(l2);
1935
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1936
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1937
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1938
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1939
            gen_set_label(l1);
1940
        }
1941
        opn = "div";
1942
        break;
1943
    case OPC_DIVU:
1944
        {
1945
            int l1 = gen_new_label();
1946

    
1947
            tcg_gen_ext32u_tl(t0, t0);
1948
            tcg_gen_ext32u_tl(t1, t1);
1949
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1950
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1951
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1952
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1953
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1954
            gen_set_label(l1);
1955
        }
1956
        opn = "divu";
1957
        break;
1958
    case OPC_MULT:
1959
        {
1960
            TCGv_i64 t2 = tcg_temp_new_i64();
1961
            TCGv_i64 t3 = tcg_temp_new_i64();
1962

    
1963
            tcg_gen_ext_tl_i64(t2, t0);
1964
            tcg_gen_ext_tl_i64(t3, t1);
1965
            tcg_gen_mul_i64(t2, t2, t3);
1966
            tcg_temp_free_i64(t3);
1967
            tcg_gen_trunc_i64_tl(t0, t2);
1968
            tcg_gen_shri_i64(t2, t2, 32);
1969
            tcg_gen_trunc_i64_tl(t1, t2);
1970
            tcg_temp_free_i64(t2);
1971
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1972
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1973
        }
1974
        opn = "mult";
1975
        break;
1976
    case OPC_MULTU:
1977
        {
1978
            TCGv_i64 t2 = tcg_temp_new_i64();
1979
            TCGv_i64 t3 = tcg_temp_new_i64();
1980

    
1981
            tcg_gen_ext32u_tl(t0, t0);
1982
            tcg_gen_ext32u_tl(t1, t1);
1983
            tcg_gen_extu_tl_i64(t2, t0);
1984
            tcg_gen_extu_tl_i64(t3, t1);
1985
            tcg_gen_mul_i64(t2, t2, t3);
1986
            tcg_temp_free_i64(t3);
1987
            tcg_gen_trunc_i64_tl(t0, t2);
1988
            tcg_gen_shri_i64(t2, t2, 32);
1989
            tcg_gen_trunc_i64_tl(t1, t2);
1990
            tcg_temp_free_i64(t2);
1991
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1992
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1993
        }
1994
        opn = "multu";
1995
        break;
1996
#if defined(TARGET_MIPS64)
1997
    case OPC_DDIV:
1998
        {
1999
            int l1 = gen_new_label();
2000
            int l2 = gen_new_label();
2001

    
2002
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2003
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2004
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2005
            tcg_gen_mov_tl(cpu_LO[0], t0);
2006
            tcg_gen_movi_tl(cpu_HI[0], 0);
2007
            tcg_gen_br(l1);
2008
            gen_set_label(l2);
2009
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2010
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2011
            gen_set_label(l1);
2012
        }
2013
        opn = "ddiv";
2014
        break;
2015
    case OPC_DDIVU:
2016
        {
2017
            int l1 = gen_new_label();
2018

    
2019
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2020
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2021
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2022
            gen_set_label(l1);
2023
        }
2024
        opn = "ddivu";
2025
        break;
2026
    case OPC_DMULT:
2027
        gen_helper_dmult(t0, t1);
2028
        opn = "dmult";
2029
        break;
2030
    case OPC_DMULTU:
2031
        gen_helper_dmultu(t0, t1);
2032
        opn = "dmultu";
2033
        break;
2034
#endif
2035
    case OPC_MADD:
2036
        {
2037
            TCGv_i64 t2 = tcg_temp_new_i64();
2038
            TCGv_i64 t3 = tcg_temp_new_i64();
2039

    
2040
            tcg_gen_ext_tl_i64(t2, t0);
2041
            tcg_gen_ext_tl_i64(t3, t1);
2042
            tcg_gen_mul_i64(t2, t2, t3);
2043
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2044
            tcg_gen_add_i64(t2, t2, t3);
2045
            tcg_temp_free_i64(t3);
2046
            tcg_gen_trunc_i64_tl(t0, t2);
2047
            tcg_gen_shri_i64(t2, t2, 32);
2048
            tcg_gen_trunc_i64_tl(t1, t2);
2049
            tcg_temp_free_i64(t2);
2050
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2051
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2052
        }
2053
        opn = "madd";
2054
        break;
2055
    case OPC_MADDU:
2056
       {
2057
            TCGv_i64 t2 = tcg_temp_new_i64();
2058
            TCGv_i64 t3 = tcg_temp_new_i64();
2059

    
2060
            tcg_gen_ext32u_tl(t0, t0);
2061
            tcg_gen_ext32u_tl(t1, t1);
2062
            tcg_gen_extu_tl_i64(t2, t0);
2063
            tcg_gen_extu_tl_i64(t3, t1);
2064
            tcg_gen_mul_i64(t2, t2, t3);
2065
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2066
            tcg_gen_add_i64(t2, t2, t3);
2067
            tcg_temp_free_i64(t3);
2068
            tcg_gen_trunc_i64_tl(t0, t2);
2069
            tcg_gen_shri_i64(t2, t2, 32);
2070
            tcg_gen_trunc_i64_tl(t1, t2);
2071
            tcg_temp_free_i64(t2);
2072
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2073
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2074
        }
2075
        opn = "maddu";
2076
        break;
2077
    case OPC_MSUB:
2078
        {
2079
            TCGv_i64 t2 = tcg_temp_new_i64();
2080
            TCGv_i64 t3 = tcg_temp_new_i64();
2081

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

    
2102
            tcg_gen_ext32u_tl(t0, t0);
2103
            tcg_gen_ext32u_tl(t1, t1);
2104
            tcg_gen_extu_tl_i64(t2, t0);
2105
            tcg_gen_extu_tl_i64(t3, t1);
2106
            tcg_gen_mul_i64(t2, t2, t3);
2107
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2108
            tcg_gen_sub_i64(t2, t3, t2);
2109
            tcg_temp_free_i64(t3);
2110
            tcg_gen_trunc_i64_tl(t0, t2);
2111
            tcg_gen_shri_i64(t2, t2, 32);
2112
            tcg_gen_trunc_i64_tl(t1, t2);
2113
            tcg_temp_free_i64(t2);
2114
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2115
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2116
        }
2117
        opn = "msubu";
2118
        break;
2119
    default:
2120
        MIPS_INVAL(opn);
2121
        generate_exception(ctx, EXCP_RI);
2122
        goto out;
2123
    }
2124
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2125
 out:
2126
    tcg_temp_free(t0);
2127
    tcg_temp_free(t1);
2128
}
2129

    
2130
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2131
                            int rd, int rs, int rt)
2132
{
2133
    const char *opn = "mul vr54xx";
2134
    TCGv t0 = tcg_temp_new();
2135
    TCGv t1 = tcg_temp_new();
2136

    
2137
    gen_load_gpr(t0, rs);
2138
    gen_load_gpr(t1, rt);
2139

    
2140
    switch (opc) {
2141
    case OPC_VR54XX_MULS:
2142
        gen_helper_muls(t0, t0, t1);
2143
        opn = "muls";
2144
        break;
2145
    case OPC_VR54XX_MULSU:
2146
        gen_helper_mulsu(t0, t0, t1);
2147
        opn = "mulsu";
2148
        break;
2149
    case OPC_VR54XX_MACC:
2150
        gen_helper_macc(t0, t0, t1);
2151
        opn = "macc";
2152
        break;
2153
    case OPC_VR54XX_MACCU:
2154
        gen_helper_maccu(t0, t0, t1);
2155
        opn = "maccu";
2156
        break;
2157
    case OPC_VR54XX_MSAC:
2158
        gen_helper_msac(t0, t0, t1);
2159
        opn = "msac";
2160
        break;
2161
    case OPC_VR54XX_MSACU:
2162
        gen_helper_msacu(t0, t0, t1);
2163
        opn = "msacu";
2164
        break;
2165
    case OPC_VR54XX_MULHI:
2166
        gen_helper_mulhi(t0, t0, t1);
2167
        opn = "mulhi";
2168
        break;
2169
    case OPC_VR54XX_MULHIU:
2170
        gen_helper_mulhiu(t0, t0, t1);
2171
        opn = "mulhiu";
2172
        break;
2173
    case OPC_VR54XX_MULSHI:
2174
        gen_helper_mulshi(t0, t0, t1);
2175
        opn = "mulshi";
2176
        break;
2177
    case OPC_VR54XX_MULSHIU:
2178
        gen_helper_mulshiu(t0, t0, t1);
2179
        opn = "mulshiu";
2180
        break;
2181
    case OPC_VR54XX_MACCHI:
2182
        gen_helper_macchi(t0, t0, t1);
2183
        opn = "macchi";
2184
        break;
2185
    case OPC_VR54XX_MACCHIU:
2186
        gen_helper_macchiu(t0, t0, t1);
2187
        opn = "macchiu";
2188
        break;
2189
    case OPC_VR54XX_MSACHI:
2190
        gen_helper_msachi(t0, t0, t1);
2191
        opn = "msachi";
2192
        break;
2193
    case OPC_VR54XX_MSACHIU:
2194
        gen_helper_msachiu(t0, t0, t1);
2195
        opn = "msachiu";
2196
        break;
2197
    default:
2198
        MIPS_INVAL("mul vr54xx");
2199
        generate_exception(ctx, EXCP_RI);
2200
        goto out;
2201
    }
2202
    gen_store_gpr(t0, rd);
2203
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2204

    
2205
 out:
2206
    tcg_temp_free(t0);
2207
    tcg_temp_free(t1);
2208
}
2209

    
2210
static void gen_cl (DisasContext *ctx, uint32_t opc,
2211
                    int rd, int rs)
2212
{
2213
    const char *opn = "CLx";
2214
    TCGv t0;
2215

    
2216
    if (rd == 0) {
2217
        /* Treat as NOP. */
2218
        MIPS_DEBUG("NOP");
2219
        return;
2220
    }
2221
    t0 = tcg_temp_new();
2222
    gen_load_gpr(t0, rs);
2223
    switch (opc) {
2224
    case OPC_CLO:
2225
        gen_helper_clo(cpu_gpr[rd], t0);
2226
        opn = "clo";
2227
        break;
2228
    case OPC_CLZ:
2229
        gen_helper_clz(cpu_gpr[rd], t0);
2230
        opn = "clz";
2231
        break;
2232
#if defined(TARGET_MIPS64)
2233
    case OPC_DCLO:
2234
        gen_helper_dclo(cpu_gpr[rd], t0);
2235
        opn = "dclo";
2236
        break;
2237
    case OPC_DCLZ:
2238
        gen_helper_dclz(cpu_gpr[rd], t0);
2239
        opn = "dclz";
2240
        break;
2241
#endif
2242
    }
2243
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2244
    tcg_temp_free(t0);
2245
}
2246

    
2247
/* Traps */
2248
static void gen_trap (DisasContext *ctx, uint32_t opc,
2249
                      int rs, int rt, int16_t imm)
2250
{
2251
    int cond;
2252
    TCGv t0 = tcg_temp_new();
2253
    TCGv t1 = tcg_temp_new();
2254

    
2255
    cond = 0;
2256
    /* Load needed operands */
2257
    switch (opc) {
2258
    case OPC_TEQ:
2259
    case OPC_TGE:
2260
    case OPC_TGEU:
2261
    case OPC_TLT:
2262
    case OPC_TLTU:
2263
    case OPC_TNE:
2264
        /* Compare two registers */
2265
        if (rs != rt) {
2266
            gen_load_gpr(t0, rs);
2267
            gen_load_gpr(t1, rt);
2268
            cond = 1;
2269
        }
2270
        break;
2271
    case OPC_TEQI:
2272
    case OPC_TGEI:
2273
    case OPC_TGEIU:
2274
    case OPC_TLTI:
2275
    case OPC_TLTIU:
2276
    case OPC_TNEI:
2277
        /* Compare register to immediate */
2278
        if (rs != 0 || imm != 0) {
2279
            gen_load_gpr(t0, rs);
2280
            tcg_gen_movi_tl(t1, (int32_t)imm);
2281
            cond = 1;
2282
        }
2283
        break;
2284
    }
2285
    if (cond == 0) {
2286
        switch (opc) {
2287
        case OPC_TEQ:   /* rs == rs */
2288
        case OPC_TEQI:  /* r0 == 0  */
2289
        case OPC_TGE:   /* rs >= rs */
2290
        case OPC_TGEI:  /* r0 >= 0  */
2291
        case OPC_TGEU:  /* rs >= rs unsigned */
2292
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2293
            /* Always trap */
2294
            generate_exception(ctx, EXCP_TRAP);
2295
            break;
2296
        case OPC_TLT:   /* rs < rs           */
2297
        case OPC_TLTI:  /* r0 < 0            */
2298
        case OPC_TLTU:  /* rs < rs unsigned  */
2299
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2300
        case OPC_TNE:   /* rs != rs          */
2301
        case OPC_TNEI:  /* r0 != 0           */
2302
            /* Never trap: treat as NOP. */
2303
            break;
2304
        }
2305
    } else {
2306
        int l1 = gen_new_label();
2307

    
2308
        switch (opc) {
2309
        case OPC_TEQ:
2310
        case OPC_TEQI:
2311
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2312
            break;
2313
        case OPC_TGE:
2314
        case OPC_TGEI:
2315
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2316
            break;
2317
        case OPC_TGEU:
2318
        case OPC_TGEIU:
2319
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2320
            break;
2321
        case OPC_TLT:
2322
        case OPC_TLTI:
2323
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2324
            break;
2325
        case OPC_TLTU:
2326
        case OPC_TLTIU:
2327
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2328
            break;
2329
        case OPC_TNE:
2330
        case OPC_TNEI:
2331
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2332
            break;
2333
        }
2334
        generate_exception(ctx, EXCP_TRAP);
2335
        gen_set_label(l1);
2336
    }
2337
    tcg_temp_free(t0);
2338
    tcg_temp_free(t1);
2339
}
2340

    
2341
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2342
{
2343
    TranslationBlock *tb;
2344
    tb = ctx->tb;
2345
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2346
        likely(!ctx->singlestep_enabled)) {
2347
        tcg_gen_goto_tb(n);
2348
        gen_save_pc(dest);
2349
        tcg_gen_exit_tb((long)tb + n);
2350
    } else {
2351
        gen_save_pc(dest);
2352
        if (ctx->singlestep_enabled) {
2353
            save_cpu_state(ctx, 0);
2354
            gen_helper_0i(raise_exception, EXCP_DEBUG);
2355
        }
2356
        tcg_gen_exit_tb(0);
2357
    }
2358
}
2359

    
2360
/* Branches (before delay slot) */
2361
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2362
                                int insn_bytes,
2363
                                int rs, int rt, int32_t offset)
2364
{
2365
    target_ulong btgt = -1;
2366
    int blink = 0;
2367
    int bcond_compute = 0;
2368
    TCGv t0 = tcg_temp_new();
2369
    TCGv t1 = tcg_temp_new();
2370

    
2371
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2372
#ifdef MIPS_DEBUG_DISAS
2373
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2374
#endif
2375
        generate_exception(ctx, EXCP_RI);
2376
        goto out;
2377
    }
2378

    
2379
    /* Load needed operands */
2380
    switch (opc) {
2381
    case OPC_BEQ:
2382
    case OPC_BEQL:
2383
    case OPC_BNE:
2384
    case OPC_BNEL:
2385
        /* Compare two registers */
2386
        if (rs != rt) {
2387
            gen_load_gpr(t0, rs);
2388
            gen_load_gpr(t1, rt);
2389
            bcond_compute = 1;
2390
        }
2391
        btgt = ctx->pc + insn_bytes + offset;
2392
        break;
2393
    case OPC_BGEZ:
2394
    case OPC_BGEZAL:
2395
    case OPC_BGEZALL:
2396
    case OPC_BGEZL:
2397
    case OPC_BGTZ:
2398
    case OPC_BGTZL:
2399
    case OPC_BLEZ:
2400
    case OPC_BLEZL:
2401
    case OPC_BLTZ:
2402
    case OPC_BLTZAL:
2403
    case OPC_BLTZALL:
2404
    case OPC_BLTZL:
2405
        /* Compare to zero */
2406
        if (rs != 0) {
2407
            gen_load_gpr(t0, rs);
2408
            bcond_compute = 1;
2409
        }
2410
        btgt = ctx->pc + insn_bytes + offset;
2411
        break;
2412
    case OPC_J:
2413
    case OPC_JAL:
2414
    case OPC_JALX:
2415
        /* Jump to immediate */
2416
        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2417
        break;
2418
    case OPC_JR:
2419
    case OPC_JALR:
2420
    case OPC_JALRC:
2421
        /* Jump to register */
2422
        if (offset != 0 && offset != 16) {
2423
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2424
               others are reserved. */
2425
            MIPS_INVAL("jump hint");
2426
            generate_exception(ctx, EXCP_RI);
2427
            goto out;
2428
        }
2429
        gen_load_gpr(btarget, rs);
2430
        break;
2431
    default:
2432
        MIPS_INVAL("branch/jump");
2433
        generate_exception(ctx, EXCP_RI);
2434
        goto out;
2435
    }
2436
    if (bcond_compute == 0) {
2437
        /* No condition to be computed */
2438
        switch (opc) {
2439
        case OPC_BEQ:     /* rx == rx        */
2440
        case OPC_BEQL:    /* rx == rx likely */
2441
        case OPC_BGEZ:    /* 0 >= 0          */
2442
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2443
        case OPC_BLEZ:    /* 0 <= 0          */
2444
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2445
            /* Always take */
2446
            ctx->hflags |= MIPS_HFLAG_B;
2447
            MIPS_DEBUG("balways");
2448
            break;
2449
        case OPC_BGEZAL:  /* 0 >= 0          */
2450
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2451
            /* Always take and link */
2452
            blink = 31;
2453
            ctx->hflags |= MIPS_HFLAG_B;
2454
            MIPS_DEBUG("balways and link");
2455
            break;
2456
        case OPC_BNE:     /* rx != rx        */
2457
        case OPC_BGTZ:    /* 0 > 0           */
2458
        case OPC_BLTZ:    /* 0 < 0           */
2459
            /* Treat as NOP. */
2460
            MIPS_DEBUG("bnever (NOP)");
2461
            goto out;
2462
        case OPC_BLTZAL:  /* 0 < 0           */
2463
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2464
            MIPS_DEBUG("bnever and link");
2465
            goto out;
2466
        case OPC_BLTZALL: /* 0 < 0 likely */
2467
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2468
            /* Skip the instruction in the delay slot */
2469
            MIPS_DEBUG("bnever, link and skip");
2470
            ctx->pc += 4;
2471
            goto out;
2472
        case OPC_BNEL:    /* rx != rx likely */
2473
        case OPC_BGTZL:   /* 0 > 0 likely */
2474
        case OPC_BLTZL:   /* 0 < 0 likely */
2475
            /* Skip the instruction in the delay slot */
2476
            MIPS_DEBUG("bnever and skip");
2477
            ctx->pc += 4;
2478
            goto out;
2479
        case OPC_J:
2480
            ctx->hflags |= MIPS_HFLAG_B;
2481
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2482
            break;
2483
        case OPC_JALX:
2484
            ctx->hflags |= MIPS_HFLAG_BX;
2485
            /* Fallthrough */
2486
        case OPC_JAL:
2487
            blink = 31;
2488
            ctx->hflags |= MIPS_HFLAG_B;
2489
            ctx->hflags |= (ctx->hflags & MIPS_HFLAG_M16
2490
                            ? MIPS_HFLAG_BDS16
2491
                            : MIPS_HFLAG_BDS32);
2492
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2493
            break;
2494
        case OPC_JR:
2495
            ctx->hflags |= MIPS_HFLAG_BR;
2496
            if (ctx->hflags & MIPS_HFLAG_M16)
2497
                ctx->hflags |= MIPS_HFLAG_BDS16;
2498
            MIPS_DEBUG("jr %s", regnames[rs]);
2499
            break;
2500
        case OPC_JALR:
2501
        case OPC_JALRC:
2502
            blink = rt;
2503
            ctx->hflags |= MIPS_HFLAG_BR;
2504
            if (ctx->hflags & MIPS_HFLAG_M16)
2505
                ctx->hflags |= MIPS_HFLAG_BDS16;
2506
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2507
            break;
2508
        default:
2509
            MIPS_INVAL("branch/jump");
2510
            generate_exception(ctx, EXCP_RI);
2511
            goto out;
2512
        }
2513
    } else {
2514
        switch (opc) {
2515
        case OPC_BEQ:
2516
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2517
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2518
                       regnames[rs], regnames[rt], btgt);
2519
            goto not_likely;
2520
        case OPC_BEQL:
2521
            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2522
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2523
                       regnames[rs], regnames[rt], btgt);
2524
            goto likely;
2525
        case OPC_BNE:
2526
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2527
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2528
                       regnames[rs], regnames[rt], btgt);
2529
            goto not_likely;
2530
        case OPC_BNEL:
2531
            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2532
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2533
                       regnames[rs], regnames[rt], btgt);
2534
            goto likely;
2535
        case OPC_BGEZ:
2536
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2537
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2538
            goto not_likely;
2539
        case OPC_BGEZL:
2540
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2541
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2542
            goto likely;
2543
        case OPC_BGEZAL:
2544
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2545
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2546
            blink = 31;
2547
            goto not_likely;
2548
        case OPC_BGEZALL:
2549
            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2550
            blink = 31;
2551
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2552
            goto likely;
2553
        case OPC_BGTZ:
2554
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2555
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2556
            goto not_likely;
2557
        case OPC_BGTZL:
2558
            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2559
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2560
            goto likely;
2561
        case OPC_BLEZ:
2562
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2563
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2564
            goto not_likely;
2565
        case OPC_BLEZL:
2566
            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2567
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2568
            goto likely;
2569
        case OPC_BLTZ:
2570
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2571
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2572
            goto not_likely;
2573
        case OPC_BLTZL:
2574
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2575
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2576
            goto likely;
2577
        case OPC_BLTZAL:
2578
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2579
            blink = 31;
2580
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2581
        not_likely:
2582
            ctx->hflags |= MIPS_HFLAG_BC;
2583
            break;
2584
        case OPC_BLTZALL:
2585
            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2586
            blink = 31;
2587
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2588
        likely:
2589
            ctx->hflags |= MIPS_HFLAG_BL;
2590
            break;
2591
        default:
2592
            MIPS_INVAL("conditional branch/jump");
2593
            generate_exception(ctx, EXCP_RI);
2594
            goto out;
2595
        }
2596
    }
2597
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2598
               blink, ctx->hflags, btgt);
2599

    
2600
    ctx->btarget = btgt;
2601
    if (blink > 0) {
2602
        int post_delay = insn_bytes;
2603
        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2604

    
2605
        if (opc != OPC_JALRC)
2606
            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2607

    
2608
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2609
    }
2610

    
2611
 out:
2612
    if (insn_bytes == 2)
2613
        ctx->hflags |= MIPS_HFLAG_B16;
2614
    tcg_temp_free(t0);
2615
    tcg_temp_free(t1);
2616
}
2617

    
2618
/* special3 bitfield operations */
2619
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2620
                        int rs, int lsb, int msb)
2621
{
2622
    TCGv t0 = tcg_temp_new();
2623
    TCGv t1 = tcg_temp_new();
2624
    target_ulong mask;
2625

    
2626
    gen_load_gpr(t1, rs);
2627
    switch (opc) {
2628
    case OPC_EXT:
2629
        if (lsb + msb > 31)
2630
            goto fail;
2631
        tcg_gen_shri_tl(t0, t1, lsb);
2632
        if (msb != 31) {
2633
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2634
        } else {
2635
            tcg_gen_ext32s_tl(t0, t0);
2636
        }
2637
        break;
2638
#if defined(TARGET_MIPS64)
2639
    case OPC_DEXTM:
2640
        tcg_gen_shri_tl(t0, t1, lsb);
2641
        if (msb != 31) {
2642
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2643
        }
2644
        break;
2645
    case OPC_DEXTU:
2646
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2647
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2648
        break;
2649
    case OPC_DEXT:
2650
        tcg_gen_shri_tl(t0, t1, lsb);
2651
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2652
        break;
2653
#endif
2654
    case OPC_INS:
2655
        if (lsb > msb)
2656
            goto fail;
2657
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2658
        gen_load_gpr(t0, rt);
2659
        tcg_gen_andi_tl(t0, t0, ~mask);
2660
        tcg_gen_shli_tl(t1, t1, lsb);
2661
        tcg_gen_andi_tl(t1, t1, mask);
2662
        tcg_gen_or_tl(t0, t0, t1);
2663
        tcg_gen_ext32s_tl(t0, t0);
2664
        break;
2665
#if defined(TARGET_MIPS64)
2666
    case OPC_DINSM:
2667
        if (lsb > msb)
2668
            goto fail;
2669
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2670
        gen_load_gpr(t0, rt);
2671
        tcg_gen_andi_tl(t0, t0, ~mask);
2672
        tcg_gen_shli_tl(t1, t1, lsb);
2673
        tcg_gen_andi_tl(t1, t1, mask);
2674
        tcg_gen_or_tl(t0, t0, t1);
2675
        break;
2676
    case OPC_DINSU:
2677
        if (lsb > msb)
2678
            goto fail;
2679
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2680
        gen_load_gpr(t0, rt);
2681
        tcg_gen_andi_tl(t0, t0, ~mask);
2682
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2683
        tcg_gen_andi_tl(t1, t1, mask);
2684
        tcg_gen_or_tl(t0, t0, t1);
2685
        break;
2686
    case OPC_DINS:
2687
        if (lsb > msb)
2688
            goto fail;
2689
        gen_load_gpr(t0, rt);
2690
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2691
        gen_load_gpr(t0, rt);
2692
        tcg_gen_andi_tl(t0, t0, ~mask);
2693
        tcg_gen_shli_tl(t1, t1, lsb);
2694
        tcg_gen_andi_tl(t1, t1, mask);
2695
        tcg_gen_or_tl(t0, t0, t1);
2696
        break;
2697
#endif
2698
    default:
2699
fail:
2700
        MIPS_INVAL("bitops");
2701
        generate_exception(ctx, EXCP_RI);
2702
        tcg_temp_free(t0);
2703
        tcg_temp_free(t1);
2704
        return;
2705
    }
2706
    gen_store_gpr(t0, rt);
2707
    tcg_temp_free(t0);
2708
    tcg_temp_free(t1);
2709
}
2710

    
2711
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2712
{
2713
    TCGv t0;
2714

    
2715
    if (rd == 0) {
2716
        /* If no destination, treat it as a NOP. */
2717
        MIPS_DEBUG("NOP");
2718
        return;
2719
    }
2720

    
2721
    t0 = tcg_temp_new();
2722
    gen_load_gpr(t0, rt);
2723
    switch (op2) {
2724
    case OPC_WSBH:
2725
        {
2726
            TCGv t1 = tcg_temp_new();
2727

    
2728
            tcg_gen_shri_tl(t1, t0, 8);
2729
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2730
            tcg_gen_shli_tl(t0, t0, 8);
2731
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2732
            tcg_gen_or_tl(t0, t0, t1);
2733
            tcg_temp_free(t1);
2734
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2735
        }
2736
        break;
2737
    case OPC_SEB:
2738
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2739
        break;
2740
    case OPC_SEH:
2741
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2742
        break;
2743
#if defined(TARGET_MIPS64)
2744
    case OPC_DSBH:
2745
        {
2746
            TCGv t1 = tcg_temp_new();
2747

    
2748
            tcg_gen_shri_tl(t1, t0, 8);
2749
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2750
            tcg_gen_shli_tl(t0, t0, 8);
2751
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2752
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2753
            tcg_temp_free(t1);
2754
        }
2755
        break;
2756
    case OPC_DSHD:
2757
        {
2758
            TCGv t1 = tcg_temp_new();
2759

    
2760
            tcg_gen_shri_tl(t1, t0, 16);
2761
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2762
            tcg_gen_shli_tl(t0, t0, 16);
2763
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2764
            tcg_gen_or_tl(t0, t0, t1);
2765
            tcg_gen_shri_tl(t1, t0, 32);
2766
            tcg_gen_shli_tl(t0, t0, 32);
2767
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2768
            tcg_temp_free(t1);
2769
        }
2770
        break;
2771
#endif
2772
    default:
2773
        MIPS_INVAL("bsfhl");
2774
        generate_exception(ctx, EXCP_RI);
2775
        tcg_temp_free(t0);
2776
        return;
2777
    }
2778
    tcg_temp_free(t0);
2779
}
2780

    
2781
#ifndef CONFIG_USER_ONLY
2782
/* CP0 (MMU and control) */
2783
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2784
{
2785
    TCGv_i32 t0 = tcg_temp_new_i32();
2786

    
2787
    tcg_gen_ld_i32(t0, cpu_env, off);
2788
    tcg_gen_ext_i32_tl(arg, t0);
2789
    tcg_temp_free_i32(t0);
2790
}
2791

    
2792
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2793
{
2794
    tcg_gen_ld_tl(arg, cpu_env, off);
2795
    tcg_gen_ext32s_tl(arg, arg);
2796
}
2797

    
2798
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2799
{
2800
    TCGv_i32 t0 = tcg_temp_new_i32();
2801

    
2802
    tcg_gen_trunc_tl_i32(t0, arg);
2803
    tcg_gen_st_i32(t0, cpu_env, off);
2804
    tcg_temp_free_i32(t0);
2805
}
2806

    
2807
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2808
{
2809
    tcg_gen_ext32s_tl(arg, arg);
2810
    tcg_gen_st_tl(arg, cpu_env, off);
2811
}
2812

    
2813
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2814
{
2815
    const char *rn = "invalid";
2816

    
2817
    if (sel != 0)
2818
        check_insn(env, ctx, ISA_MIPS32);
2819

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

    
3385
die:
3386
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3387
    generate_exception(ctx, EXCP_RI);
3388
}
3389

    
3390
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3391
{
3392
    const char *rn = "invalid";
3393

    
3394
    if (sel != 0)
3395
        check_insn(env, ctx, ISA_MIPS32);
3396

    
3397
    if (use_icount)
3398
        gen_io_start();
3399

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

    
3980
die:
3981
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3982
    generate_exception(ctx, EXCP_RI);
3983
}
3984

    
3985
#if defined(TARGET_MIPS64)
3986
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3987
{
3988
    const char *rn = "invalid";
3989

    
3990
    if (sel != 0)
3991
        check_insn(env, ctx, ISA_MIPS64);
3992

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

    
4547
die:
4548
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4549
    generate_exception(ctx, EXCP_RI);
4550
}
4551

    
4552
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4553
{
4554
    const char *rn = "invalid";
4555

    
4556
    if (sel != 0)
4557
        check_insn(env, ctx, ISA_MIPS64);
4558

    
4559
    if (use_icount)
4560
        gen_io_start();
4561

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

    
5133
die:
5134
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5135
    generate_exception(ctx, EXCP_RI);
5136
}
5137
#endif /* TARGET_MIPS64 */
5138

    
5139
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5140
                     int u, int sel, int h)
5141
{
5142
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5143
    TCGv t0 = tcg_temp_local_new();
5144

    
5145
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5146
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5147
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5148
        tcg_gen_movi_tl(t0, -1);
5149
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5150
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5151
        tcg_gen_movi_tl(t0, -1);
5152
    else if (u == 0) {
5153
        switch (rt) {
5154
        case 2:
5155
            switch (sel) {
5156
            case 1:
5157
                gen_helper_mftc0_tcstatus(t0);
5158
                break;
5159
            case 2:
5160
                gen_helper_mftc0_tcbind(t0);
5161
                break;
5162
            case 3:
5163
                gen_helper_mftc0_tcrestart(t0);
5164
                break;
5165
            case 4:
5166
                gen_helper_mftc0_tchalt(t0);
5167
                break;
5168
            case 5:
5169
                gen_helper_mftc0_tccontext(t0);
5170
                break;
5171
            case 6:
5172
                gen_helper_mftc0_tcschedule(t0);
5173
                break;
5174
            case 7:
5175
                gen_helper_mftc0_tcschefback(t0);
5176
                break;
5177
            default:
5178
                gen_mfc0(env, ctx, t0, rt, sel);
5179
                break;
5180
            }
5181
            break;
5182
        case 10:
5183
            switch (sel) {
5184
            case 0:
5185
                gen_helper_mftc0_entryhi(t0);
5186
                break;
5187
            default:
5188
                gen_mfc0(env, ctx, t0, rt, sel);
5189
                break;
5190
            }
5191
        case 12:
5192
            switch (sel) {
5193
            case 0:
5194
                gen_helper_mftc0_status(t0);
5195
                break;
5196
            default:
5197
                gen_mfc0(env, ctx, t0, rt, sel);
5198
                break;
5199
            }
5200
        case 23:
5201
            switch (sel) {
5202
            case 0:
5203
                gen_helper_mftc0_debug(t0);
5204
                break;
5205
            default:
5206
                gen_mfc0(env, ctx, t0, rt, sel);
5207
                break;
5208
            }
5209
            break;
5210
        default:
5211
            gen_mfc0(env, ctx, t0, rt, sel);
5212
        }
5213
    } else switch (sel) {
5214
    /* GPR registers. */
5215
    case 0:
5216
        gen_helper_1i(mftgpr, t0, rt);
5217
        break;
5218
    /* Auxiliary CPU registers */
5219
    case 1:
5220
        switch (rt) {
5221
        case 0:
5222
            gen_helper_1i(mftlo, t0, 0);
5223
            break;
5224
        case 1:
5225
            gen_helper_1i(mfthi, t0, 0);
5226
            break;
5227
        case 2:
5228
            gen_helper_1i(mftacx, t0, 0);
5229
            break;
5230
        case 4:
5231
            gen_helper_1i(mftlo, t0, 1);
5232
            break;
5233
        case 5:
5234
            gen_helper_1i(mfthi, t0, 1);
5235
            break;
5236
        case 6:
5237
            gen_helper_1i(mftacx, t0, 1);
5238
            break;
5239
        case 8:
5240
            gen_helper_1i(mftlo, t0, 2);
5241
            break;
5242
        case 9:
5243
            gen_helper_1i(mfthi, t0, 2);
5244
            break;
5245
        case 10:
5246
            gen_helper_1i(mftacx, t0, 2);
5247
            break;
5248
        case 12:
5249
            gen_helper_1i(mftlo, t0, 3);
5250
            break;
5251
        case 13:
5252
            gen_helper_1i(mfthi, t0, 3);
5253
            break;
5254
        case 14:
5255
            gen_helper_1i(mftacx, t0, 3);
5256
            break;
5257
        case 16:
5258
            gen_helper_mftdsp(t0);
5259
            break;
5260
        default:
5261
            goto die;
5262
        }
5263
        break;
5264
    /* Floating point (COP1). */
5265
    case 2:
5266
        /* XXX: For now we support only a single FPU context. */
5267
        if (h == 0) {
5268
            TCGv_i32 fp0 = tcg_temp_new_i32();
5269

    
5270
            gen_load_fpr32(fp0, rt);
5271
            tcg_gen_ext_i32_tl(t0, fp0);
5272
            tcg_temp_free_i32(fp0);
5273
        } else {
5274
            TCGv_i32 fp0 = tcg_temp_new_i32();
5275

    
5276
            gen_load_fpr32h(fp0, rt);
5277
            tcg_gen_ext_i32_tl(t0, fp0);
5278
            tcg_temp_free_i32(fp0);
5279
        }
5280
        break;
5281
    case 3:
5282
        /* XXX: For now we support only a single FPU context. */
5283
        gen_helper_1i(cfc1, t0, rt);
5284
        break;
5285
    /* COP2: Not implemented. */
5286
    case 4:
5287
    case 5:
5288
        /* fall through */
5289
    default:
5290
        goto die;
5291
    }
5292
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5293
    gen_store_gpr(t0, rd);
5294
    tcg_temp_free(t0);
5295
    return;
5296

    
5297
die:
5298
    tcg_temp_free(t0);
5299
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5300
    generate_exception(ctx, EXCP_RI);
5301
}
5302

    
5303
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5304
                     int u, int sel, int h)
5305
{
5306
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5307
    TCGv t0 = tcg_temp_local_new();
5308

    
5309
    gen_load_gpr(t0, rt);
5310
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5311
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5312
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5313
        /* NOP */ ;
5314
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5315
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5316
        /* NOP */ ;
5317
    else if (u == 0) {
5318
        switch (rd) {
5319
        case 2:
5320
            switch (sel) {
5321
            case 1:
5322
                gen_helper_mttc0_tcstatus(t0);
5323
                break;
5324
            case 2:
5325
                gen_helper_mttc0_tcbind(t0);
5326
                break;
5327
            case 3:
5328
                gen_helper_mttc0_tcrestart(t0);
5329
                break;
5330
            case 4:
5331
                gen_helper_mttc0_tchalt(t0);
5332
                break;
5333
            case 5:
5334
                gen_helper_mttc0_tccontext(t0);
5335
                break;
5336
            case 6:
5337
                gen_helper_mttc0_tcschedule(t0);
5338
                break;
5339
            case 7:
5340
                gen_helper_mttc0_tcschefback(t0);
5341
                break;
5342
            default:
5343
                gen_mtc0(env, ctx, t0, rd, sel);
5344
                break;
5345
            }
5346
            break;
5347
        case 10:
5348
            switch (sel) {
5349
            case 0:
5350
                gen_helper_mttc0_entryhi(t0);
5351
                break;
5352
            default:
5353
                gen_mtc0(env, ctx, t0, rd, sel);
5354
                break;
5355
            }
5356
        case 12:
5357
            switch (sel) {
5358
            case 0:
5359
                gen_helper_mttc0_status(t0);
5360
                break;
5361
            default:
5362
                gen_mtc0(env, ctx, t0, rd, sel);
5363
                break;
5364
            }
5365
        case 23:
5366
            switch (sel) {
5367
            case 0:
5368
                gen_helper_mttc0_debug(t0);
5369
                break;
5370
            default:
5371
                gen_mtc0(env, ctx, t0, rd, sel);
5372
                break;
5373
            }
5374
            break;
5375
        default:
5376
            gen_mtc0(env, ctx, t0, rd, sel);
5377
        }
5378
    } else switch (sel) {
5379
    /* GPR registers. */
5380
    case 0:
5381
        gen_helper_1i(mttgpr, t0, rd);
5382
        break;
5383
    /* Auxiliary CPU registers */
5384
    case 1:
5385
        switch (rd) {
5386
        case 0:
5387
            gen_helper_1i(mttlo, t0, 0);
5388
            break;
5389
        case 1:
5390
            gen_helper_1i(mtthi, t0, 0);
5391
            break;
5392
        case 2:
5393
            gen_helper_1i(mttacx, t0, 0);
5394
            break;
5395
        case 4:
5396
            gen_helper_1i(mttlo, t0, 1);
5397
            break;
5398
        case 5:
5399
            gen_helper_1i(mtthi, t0, 1);
5400
            break;
5401
        case 6:
5402
            gen_helper_1i(mttacx, t0, 1);
5403
            break;
5404
        case 8:
5405
            gen_helper_1i(mttlo, t0, 2);
5406
            break;
5407
        case 9:
5408
            gen_helper_1i(mtthi, t0, 2);
5409
            break;
5410
        case 10:
5411
            gen_helper_1i(mttacx, t0, 2);
5412
            break;
5413
        case 12:
5414
            gen_helper_1i(mttlo, t0, 3);
5415
            break;
5416
        case 13:
5417
            gen_helper_1i(mtthi, t0, 3);
5418
            break;
5419
        case 14:
5420
            gen_helper_1i(mttacx, t0, 3);
5421
            break;
5422
        case 16:
5423
            gen_helper_mttdsp(t0);
5424
            break;
5425
        default:
5426
            goto die;
5427
        }
5428
        break;
5429
    /* Floating point (COP1). */
5430
    case 2:
5431
        /* XXX: For now we support only a single FPU context. */
5432
        if (h == 0) {
5433
            TCGv_i32 fp0 = tcg_temp_new_i32();
5434

    
5435
            tcg_gen_trunc_tl_i32(fp0, t0);
5436
            gen_store_fpr32(fp0, rd);
5437
            tcg_temp_free_i32(fp0);
5438
        } else {
5439
            TCGv_i32 fp0 = tcg_temp_new_i32();
5440

    
5441
            tcg_gen_trunc_tl_i32(fp0, t0);
5442
            gen_store_fpr32h(fp0, rd);
5443
            tcg_temp_free_i32(fp0);
5444
        }
5445
        break;
5446
    case 3:
5447
        /* XXX: For now we support only a single FPU context. */
5448
        gen_helper_1i(ctc1, t0, rd);
5449
        break;
5450
    /* COP2: Not implemented. */
5451
    case 4:
5452
    case 5:
5453
        /* fall through */
5454
    default:
5455
        goto die;
5456
    }
5457
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5458
    tcg_temp_free(t0);
5459
    return;
5460

    
5461
die:
5462
    tcg_temp_free(t0);
5463
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5464
    generate_exception(ctx, EXCP_RI);
5465
}
5466

    
5467
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5468
{
5469
    const char *opn = "ldst";
5470

    
5471
    switch (opc) {
5472
    case OPC_MFC0:
5473
        if (rt == 0) {
5474
            /* Treat as NOP. */
5475
            return;
5476
        }
5477
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5478
        opn = "mfc0";
5479
        break;
5480
    case OPC_MTC0:
5481
        {
5482
            TCGv t0 = tcg_temp_new();
5483

    
5484
            gen_load_gpr(t0, rt);
5485
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5486
            tcg_temp_free(t0);
5487
        }
5488
        opn = "mtc0";
5489
        break;
5490
#if defined(TARGET_MIPS64)
5491
    case OPC_DMFC0:
5492
        check_insn(env, ctx, ISA_MIPS3);
5493
        if (rt == 0) {
5494
            /* Treat as NOP. */
5495
            return;
5496
        }
5497
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5498
        opn = "dmfc0";
5499
        break;
5500
    case OPC_DMTC0:
5501
        check_insn(env, ctx, ISA_MIPS3);
5502
        {
5503
            TCGv t0 = tcg_temp_new();
5504

    
5505
            gen_load_gpr(t0, rt);
5506
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5507
            tcg_temp_free(t0);
5508
        }
5509
        opn = "dmtc0";
5510
        break;
5511
#endif
5512
    case OPC_MFTR:
5513
        check_insn(env, ctx, ASE_MT);
5514
        if (rd == 0) {
5515
            /* Treat as NOP. */
5516
            return;
5517
        }
5518
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5519
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5520
        opn = "mftr";
5521
        break;
5522
    case OPC_MTTR:
5523
        check_insn(env, ctx, ASE_MT);
5524
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5525
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5526
        opn = "mttr";
5527
        break;
5528
    case OPC_TLBWI:
5529
        opn = "tlbwi";
5530
        if (!env->tlb->helper_tlbwi)
5531
            goto die;
5532
        gen_helper_tlbwi();
5533
        break;
5534
    case OPC_TLBWR:
5535
        opn = "tlbwr";
5536
        if (!env->tlb->helper_tlbwr)
5537
            goto die;
5538
        gen_helper_tlbwr();
5539
        break;
5540
    case OPC_TLBP:
5541
        opn = "tlbp";
5542
        if (!env->tlb->helper_tlbp)
5543
            goto die;
5544
        gen_helper_tlbp();
5545
        break;
5546
    case OPC_TLBR:
5547
        opn = "tlbr";
5548
        if (!env->tlb->helper_tlbr)
5549
            goto die;
5550
        gen_helper_tlbr();
5551
        break;
5552
    case OPC_ERET:
5553
        opn = "eret";
5554
        check_insn(env, ctx, ISA_MIPS2);
5555
        gen_helper_eret();
5556
        ctx->bstate = BS_EXCP;
5557
        break;
5558
    case OPC_DERET:
5559
        opn = "deret";
5560
        check_insn(env, ctx, ISA_MIPS32);
5561
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5562
            MIPS_INVAL(opn);
5563
            generate_exception(ctx, EXCP_RI);
5564
        } else {
5565
            gen_helper_deret();
5566
            ctx->bstate = BS_EXCP;
5567
        }
5568
        break;
5569
    case OPC_WAIT:
5570
        opn = "wait";
5571
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5572
        /* If we get an exception, we want to restart at next instruction */
5573
        ctx->pc += 4;
5574
        save_cpu_state(ctx, 1);
5575
        ctx->pc -= 4;
5576
        gen_helper_wait();
5577
        ctx->bstate = BS_EXCP;
5578
        break;
5579
    default:
5580
 die:
5581
        MIPS_INVAL(opn);
5582
        generate_exception(ctx, EXCP_RI);
5583
        return;
5584
    }
5585
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5586
}
5587
#endif /* !CONFIG_USER_ONLY */
5588

    
5589
/* CP1 Branches (before delay slot) */
5590
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5591
                                 int32_t cc, int32_t offset)
5592
{
5593
    target_ulong btarget;
5594
    const char *opn = "cp1 cond branch";
5595
    TCGv_i32 t0 = tcg_temp_new_i32();
5596

    
5597
    if (cc != 0)
5598
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5599

    
5600
    btarget = ctx->pc + 4 + offset;
5601

    
5602
    switch (op) {
5603
    case OPC_BC1F:
5604
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5605
        tcg_gen_not_i32(t0, t0);
5606
        tcg_gen_andi_i32(t0, t0, 1);
5607
        tcg_gen_extu_i32_tl(bcond, t0);
5608
        opn = "bc1f";
5609
        goto not_likely;
5610
    case OPC_BC1FL:
5611
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5612
        tcg_gen_not_i32(t0, t0);
5613
        tcg_gen_andi_i32(t0, t0, 1);
5614
        tcg_gen_extu_i32_tl(bcond, t0);
5615
        opn = "bc1fl";
5616
        goto likely;
5617
    case OPC_BC1T:
5618
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5619
        tcg_gen_andi_i32(t0, t0, 1);
5620
        tcg_gen_extu_i32_tl(bcond, t0);
5621
        opn = "bc1t";
5622
        goto not_likely;
5623
    case OPC_BC1TL:
5624
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5625
        tcg_gen_andi_i32(t0, t0, 1);
5626
        tcg_gen_extu_i32_tl(bcond, t0);
5627
        opn = "bc1tl";
5628
    likely:
5629
        ctx->hflags |= MIPS_HFLAG_BL;
5630
        break;
5631
    case OPC_BC1FANY2:
5632
        {
5633
            TCGv_i32 t1 = tcg_temp_new_i32();
5634
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5635
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5636
            tcg_gen_nor_i32(t0, t0, t1);
5637
            tcg_temp_free_i32(t1);
5638
            tcg_gen_andi_i32(t0, t0, 1);
5639
            tcg_gen_extu_i32_tl(bcond, t0);
5640
        }
5641
        opn = "bc1any2f";
5642
        goto not_likely;
5643
    case OPC_BC1TANY2:
5644
        {
5645
            TCGv_i32 t1 = tcg_temp_new_i32();
5646
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5647
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5648
            tcg_gen_or_i32(t0, t0, t1);
5649
            tcg_temp_free_i32(t1);
5650
            tcg_gen_andi_i32(t0, t0, 1);
5651
            tcg_gen_extu_i32_tl(bcond, t0);
5652
        }
5653
        opn = "bc1any2t";
5654
        goto not_likely;
5655
    case OPC_BC1FANY4:
5656
        {
5657
            TCGv_i32 t1 = tcg_temp_new_i32();
5658
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5659
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5660
            tcg_gen_or_i32(t0, t0, t1);
5661
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5662
            tcg_gen_or_i32(t0, t0, t1);
5663
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5664
            tcg_gen_nor_i32(t0, t0, t1);
5665
            tcg_temp_free_i32(t1);
5666
            tcg_gen_andi_i32(t0, t0, 1);
5667
            tcg_gen_extu_i32_tl(bcond, t0);
5668
        }
5669
        opn = "bc1any4f";
5670
        goto not_likely;
5671
    case OPC_BC1TANY4:
5672
        {
5673
            TCGv_i32 t1 = tcg_temp_new_i32();
5674
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5675
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5676
            tcg_gen_or_i32(t0, t0, t1);
5677
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5678
            tcg_gen_or_i32(t0, t0, t1);
5679
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5680
            tcg_gen_or_i32(t0, t0, t1);
5681
            tcg_temp_free_i32(t1);
5682
            tcg_gen_andi_i32(t0, t0, 1);
5683
            tcg_gen_extu_i32_tl(bcond, t0);
5684
        }
5685
        opn = "bc1any4t";
5686
    not_likely:
5687
        ctx->hflags |= MIPS_HFLAG_BC;
5688
        break;
5689
    default:
5690
        MIPS_INVAL(opn);
5691
        generate_exception (ctx, EXCP_RI);
5692
        goto out;
5693
    }
5694
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5695
               ctx->hflags, btarget);
5696
    ctx->btarget = btarget;
5697

    
5698
 out:
5699
    tcg_temp_free_i32(t0);
5700
}
5701

    
5702
/* Coprocessor 1 (FPU) */
5703

    
5704
#define FOP(func, fmt) (((fmt) << 21) | (func))
5705

    
5706
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5707
{
5708
    const char *opn = "cp1 move";
5709
    TCGv t0 = tcg_temp_new();
5710

    
5711
    switch (opc) {
5712
    case OPC_MFC1:
5713
        {
5714
            TCGv_i32 fp0 = tcg_temp_new_i32();
5715

    
5716
            gen_load_fpr32(fp0, fs);
5717
            tcg_gen_ext_i32_tl(t0, fp0);
5718
            tcg_temp_free_i32(fp0);
5719
        }
5720
        gen_store_gpr(t0, rt);
5721
        opn = "mfc1";
5722
        break;
5723
    case OPC_MTC1:
5724
        gen_load_gpr(t0, rt);
5725
        {
5726
            TCGv_i32 fp0 = tcg_temp_new_i32();
5727

    
5728
            tcg_gen_trunc_tl_i32(fp0, t0);
5729
            gen_store_fpr32(fp0, fs);
5730
            tcg_temp_free_i32(fp0);
5731
        }
5732
        opn = "mtc1";
5733
        break;
5734
    case OPC_CFC1:
5735
        gen_helper_1i(cfc1, t0, fs);
5736
        gen_store_gpr(t0, rt);
5737
        opn = "cfc1";
5738
        break;
5739
    case OPC_CTC1:
5740
        gen_load_gpr(t0, rt);
5741
        gen_helper_1i(ctc1, t0, fs);
5742
        opn = "ctc1";
5743
        break;
5744
#if defined(TARGET_MIPS64)
5745
    case OPC_DMFC1:
5746
        gen_load_fpr64(ctx, t0, fs);
5747
        gen_store_gpr(t0, rt);
5748
        opn = "dmfc1";
5749
        break;
5750
    case OPC_DMTC1:
5751
        gen_load_gpr(t0, rt);
5752
        gen_store_fpr64(ctx, t0, fs);
5753
        opn = "dmtc1";
5754
        break;
5755
#endif
5756
    case OPC_MFHC1:
5757
        {
5758
            TCGv_i32 fp0 = tcg_temp_new_i32();
5759

    
5760
            gen_load_fpr32h(fp0, fs);
5761
            tcg_gen_ext_i32_tl(t0, fp0);
5762
            tcg_temp_free_i32(fp0);
5763
        }
5764
        gen_store_gpr(t0, rt);
5765
        opn = "mfhc1";
5766
        break;
5767
    case OPC_MTHC1:
5768
        gen_load_gpr(t0, rt);
5769
        {
5770
            TCGv_i32 fp0 = tcg_temp_new_i32();
5771

    
5772
            tcg_gen_trunc_tl_i32(fp0, t0);
5773
            gen_store_fpr32h(fp0, fs);
5774
            tcg_temp_free_i32(fp0);
5775
        }
5776
        opn = "mthc1";
5777
        break;
5778
    default:
5779
        MIPS_INVAL(opn);
5780
        generate_exception (ctx, EXCP_RI);
5781
        goto out;
5782
    }
5783
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5784

    
5785
 out:
5786
    tcg_temp_free(t0);
5787
}
5788

    
5789
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5790
{
5791
    int l1;
5792
    TCGCond cond;
5793
    TCGv_i32 t0;
5794

    
5795
    if (rd == 0) {
5796
        /* Treat as NOP. */
5797
        return;
5798
    }
5799

    
5800
    if (tf)
5801
        cond = TCG_COND_EQ;
5802
    else
5803
        cond = TCG_COND_NE;
5804

    
5805
    l1 = gen_new_label();
5806
    t0 = tcg_temp_new_i32();
5807
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5808
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5809
    tcg_temp_free_i32(t0);
5810
    if (rs == 0) {
5811
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5812
    } else {
5813
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5814
    }
5815
    gen_set_label(l1);
5816
}
5817

    
5818
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5819
{
5820
    int cond;
5821
    TCGv_i32 t0 = tcg_temp_new_i32();
5822
    int l1 = gen_new_label();
5823

    
5824
    if (tf)
5825
        cond = TCG_COND_EQ;
5826
    else
5827
        cond = TCG_COND_NE;
5828

    
5829
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5830
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5831
    gen_load_fpr32(t0, fs);
5832
    gen_store_fpr32(t0, fd);
5833
    gen_set_label(l1);
5834
    tcg_temp_free_i32(t0);
5835
}
5836

    
5837
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5838
{
5839
    int cond;
5840
    TCGv_i32 t0 = tcg_temp_new_i32();
5841
    TCGv_i64 fp0;
5842
    int l1 = gen_new_label();
5843

    
5844
    if (tf)
5845
        cond = TCG_COND_EQ;
5846
    else
5847
        cond = TCG_COND_NE;
5848

    
5849
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5850
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5851
    tcg_temp_free_i32(t0);
5852
    fp0 = tcg_temp_new_i64();
5853
    gen_load_fpr64(ctx, fp0, fs);
5854
    gen_store_fpr64(ctx, fp0, fd);
5855
    tcg_temp_free_i64(fp0);
5856
    gen_set_label(l1);
5857
}
5858

    
5859
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5860
{
5861
    int cond;
5862
    TCGv_i32 t0 = tcg_temp_new_i32();
5863
    int l1 = gen_new_label();
5864
    int l2 = gen_new_label();
5865

    
5866
    if (tf)
5867
        cond = TCG_COND_EQ;
5868
    else
5869
        cond = TCG_COND_NE;
5870

    
5871
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5872
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5873
    gen_load_fpr32(t0, fs);
5874
    gen_store_fpr32(t0, fd);
5875
    gen_set_label(l1);
5876

    
5877
    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
5878
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5879
    gen_load_fpr32h(t0, fs);
5880
    gen_store_fpr32h(t0, fd);
5881
    tcg_temp_free_i32(t0);
5882
    gen_set_label(l2);
5883
}
5884

    
5885

    
5886
static void gen_farith (DisasContext *ctx, uint32_t op1,
5887
                        int ft, int fs, int fd, int cc)
5888
{
5889
    const char *opn = "farith";
5890
    const char *condnames[] = {
5891
            "c.f",
5892
            "c.un",
5893
            "c.eq",
5894
            "c.ueq",
5895
            "c.olt",
5896
            "c.ult",
5897
            "c.ole",
5898
            "c.ule",
5899
            "c.sf",
5900
            "c.ngle",
5901
            "c.seq",
5902
            "c.ngl",
5903
            "c.lt",
5904
            "c.nge",
5905
            "c.le",
5906
            "c.ngt",
5907
    };
5908
    const char *condnames_abs[] = {
5909
            "cabs.f",
5910
            "cabs.un",
5911
            "cabs.eq",
5912
            "cabs.ueq",
5913
            "cabs.olt",
5914
            "cabs.ult",
5915
            "cabs.ole",
5916
            "cabs.ule",
5917
            "cabs.sf",
5918
            "cabs.ngle",
5919
            "cabs.seq",
5920
            "cabs.ngl",
5921
            "cabs.lt",
5922
            "cabs.nge",
5923
            "cabs.le",
5924
            "cabs.ngt",
5925
    };
5926
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5927
    uint32_t func = ctx->opcode & 0x3f;
5928

    
5929
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5930
    case FOP(0, 16):
5931
        {
5932
            TCGv_i32 fp0 = tcg_temp_new_i32();
5933
            TCGv_i32 fp1 = tcg_temp_new_i32();
5934

    
5935
            gen_load_fpr32(fp0, fs);
5936
            gen_load_fpr32(fp1, ft);
5937
            gen_helper_float_add_s(fp0, fp0, fp1);
5938
            tcg_temp_free_i32(fp1);
5939
            gen_store_fpr32(fp0, fd);
5940
            tcg_temp_free_i32(fp0);
5941
        }
5942
        opn = "add.s";
5943
        optype = BINOP;
5944
        break;
5945
    case FOP(1, 16):
5946
        {
5947
            TCGv_i32 fp0 = tcg_temp_new_i32();
5948
            TCGv_i32 fp1 = tcg_temp_new_i32();
5949

    
5950
            gen_load_fpr32(fp0, fs);
5951
            gen_load_fpr32(fp1, ft);
5952
            gen_helper_float_sub_s(fp0, fp0, fp1);
5953
            tcg_temp_free_i32(fp1);
5954
            gen_store_fpr32(fp0, fd);
5955
            tcg_temp_free_i32(fp0);
5956
        }
5957
        opn = "sub.s";
5958
        optype = BINOP;
5959
        break;
5960
    case FOP(2, 16):
5961
        {
5962
            TCGv_i32 fp0 = tcg_temp_new_i32();
5963
            TCGv_i32 fp1 = tcg_temp_new_i32();
5964

    
5965
            gen_load_fpr32(fp0, fs);
5966
            gen_load_fpr32(fp1, ft);
5967
            gen_helper_float_mul_s(fp0, fp0, fp1);
5968
            tcg_temp_free_i32(fp1);
5969
            gen_store_fpr32(fp0, fd);
5970
            tcg_temp_free_i32(fp0);
5971
        }
5972
        opn = "mul.s";
5973
        optype = BINOP;
5974
        break;
5975
    case FOP(3, 16):
5976
        {
5977
            TCGv_i32 fp0 = tcg_temp_new_i32();
5978
            TCGv_i32 fp1 = tcg_temp_new_i32();
5979

    
5980
            gen_load_fpr32(fp0, fs);
5981
            gen_load_fpr32(fp1, ft);
5982
            gen_helper_float_div_s(fp0, fp0, fp1);
5983
            tcg_temp_free_i32(fp1);
5984
            gen_store_fpr32(fp0, fd);
5985
            tcg_temp_free_i32(fp0);
5986
        }
5987
        opn = "div.s";
5988
        optype = BINOP;
5989
        break;
5990
    case FOP(4, 16):
5991
        {
5992
            TCGv_i32 fp0 = tcg_temp_new_i32();
5993

    
5994
            gen_load_fpr32(fp0, fs);
5995
            gen_helper_float_sqrt_s(fp0, fp0);
5996
            gen_store_fpr32(fp0, fd);
5997
            tcg_temp_free_i32(fp0);
5998
        }
5999
        opn = "sqrt.s";
6000
        break;
6001
    case FOP(5, 16):
6002
        {
6003
            TCGv_i32 fp0 = tcg_temp_new_i32();
6004

    
6005
            gen_load_fpr32(fp0, fs);
6006
            gen_helper_float_abs_s(fp0, fp0);
6007
            gen_store_fpr32(fp0, fd);
6008
            tcg_temp_free_i32(fp0);
6009
        }
6010
        opn = "abs.s";
6011
        break;
6012
    case FOP(6, 16):
6013
        {
6014
            TCGv_i32 fp0 = tcg_temp_new_i32();
6015

    
6016
            gen_load_fpr32(fp0, fs);
6017
            gen_store_fpr32(fp0, fd);
6018
            tcg_temp_free_i32(fp0);
6019
        }
6020
        opn = "mov.s";
6021
        break;
6022
    case FOP(7, 16):
6023
        {
6024
            TCGv_i32 fp0 = tcg_temp_new_i32();
6025

    
6026
            gen_load_fpr32(fp0, fs);
6027
            gen_helper_float_chs_s(fp0, fp0);
6028
            gen_store_fpr32(fp0, fd);
6029
            tcg_temp_free_i32(fp0);
6030
        }
6031
        opn = "neg.s";
6032
        break;
6033
    case FOP(8, 16):
6034
        check_cp1_64bitmode(ctx);
6035
        {
6036
            TCGv_i32 fp32 = tcg_temp_new_i32();
6037
            TCGv_i64 fp64 = tcg_temp_new_i64();
6038

    
6039
            gen_load_fpr32(fp32, fs);
6040
            gen_helper_float_roundl_s(fp64, fp32);
6041
            tcg_temp_free_i32(fp32);
6042
            gen_store_fpr64(ctx, fp64, fd);
6043
            tcg_temp_free_i64(fp64);
6044
        }
6045
        opn = "round.l.s";
6046
        break;
6047
    case FOP(9, 16):
6048
        check_cp1_64bitmode(ctx);
6049
        {
6050
            TCGv_i32 fp32 = tcg_temp_new_i32();
6051
            TCGv_i64 fp64 = tcg_temp_new_i64();
6052

    
6053
            gen_load_fpr32(fp32, fs);
6054
            gen_helper_float_truncl_s(fp64, fp32);
6055
            tcg_temp_free_i32(fp32);
6056
            gen_store_fpr64(ctx, fp64, fd);
6057
            tcg_temp_free_i64(fp64);
6058
        }
6059
        opn = "trunc.l.s";
6060
        break;
6061
    case FOP(10, 16):
6062
        check_cp1_64bitmode(ctx);
6063
        {
6064
            TCGv_i32 fp32 = tcg_temp_new_i32();
6065
            TCGv_i64 fp64 = tcg_temp_new_i64();
6066

    
6067
            gen_load_fpr32(fp32, fs);
6068
            gen_helper_float_ceill_s(fp64, fp32);
6069
            tcg_temp_free_i32(fp32);
6070
            gen_store_fpr64(ctx, fp64, fd);
6071
            tcg_temp_free_i64(fp64);
6072
        }
6073
        opn = "ceil.l.s";
6074
        break;
6075
    case FOP(11, 16):
6076
        check_cp1_64bitmode(ctx);
6077
        {
6078
            TCGv_i32 fp32 = tcg_temp_new_i32();
6079
            TCGv_i64 fp64 = tcg_temp_new_i64();
6080

    
6081
            gen_load_fpr32(fp32, fs);
6082
            gen_helper_float_floorl_s(fp64, fp32);
6083
            tcg_temp_free_i32(fp32);
6084
            gen_store_fpr64(ctx, fp64, fd);
6085
            tcg_temp_free_i64(fp64);
6086
        }
6087
        opn = "floor.l.s";
6088
        break;
6089
    case FOP(12, 16):
6090
        {
6091
            TCGv_i32 fp0 = tcg_temp_new_i32();
6092

    
6093
            gen_load_fpr32(fp0, fs);
6094
            gen_helper_float_roundw_s(fp0, fp0);
6095
            gen_store_fpr32(fp0, fd);
6096
            tcg_temp_free_i32(fp0);
6097
        }
6098
        opn = "round.w.s";
6099
        break;
6100
    case FOP(13, 16):
6101
        {
6102
            TCGv_i32 fp0 = tcg_temp_new_i32();
6103

    
6104
            gen_load_fpr32(fp0, fs);
6105
            gen_helper_float_truncw_s(fp0, fp0);
6106
            gen_store_fpr32(fp0, fd);
6107
            tcg_temp_free_i32(fp0);
6108
        }
6109
        opn = "trunc.w.s";
6110
        break;
6111
    case FOP(14, 16):
6112
        {
6113
            TCGv_i32 fp0 = tcg_temp_new_i32();
6114

    
6115
            gen_load_fpr32(fp0, fs);
6116
            gen_helper_float_ceilw_s(fp0, fp0);
6117
            gen_store_fpr32(fp0, fd);
6118
            tcg_temp_free_i32(fp0);
6119
        }
6120
        opn = "ceil.w.s";
6121
        break;
6122
    case FOP(15, 16):
6123
        {
6124
            TCGv_i32 fp0 = tcg_temp_new_i32();
6125

    
6126
            gen_load_fpr32(fp0, fs);
6127
            gen_helper_float_floorw_s(fp0, fp0);
6128
            gen_store_fpr32(fp0, fd);
6129
            tcg_temp_free_i32(fp0);
6130
        }
6131
        opn = "floor.w.s";
6132
        break;
6133
    case FOP(17, 16):
6134
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6135
        opn = "movcf.s";
6136
        break;
6137
    case FOP(18, 16):
6138
        {
6139
            int l1 = gen_new_label();
6140
            TCGv_i32 fp0;
6141

    
6142
            if (ft != 0) {
6143
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6144
            }
6145
            fp0 = tcg_temp_new_i32();
6146
            gen_load_fpr32(fp0, fs);
6147
            gen_store_fpr32(fp0, fd);
6148
            tcg_temp_free_i32(fp0);
6149
            gen_set_label(l1);
6150
        }
6151
        opn = "movz.s";
6152
        break;
6153
    case FOP(19, 16):
6154
        {
6155
            int l1 = gen_new_label();
6156
            TCGv_i32 fp0;
6157

    
6158
            if (ft != 0) {
6159
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6160
                fp0 = tcg_temp_new_i32();
6161
                gen_load_fpr32(fp0, fs);
6162
                gen_store_fpr32(fp0, fd);
6163
                tcg_temp_free_i32(fp0);
6164
                gen_set_label(l1);
6165
            }
6166
        }
6167
        opn = "movn.s";
6168
        break;
6169
    case FOP(21, 16):
6170
        check_cop1x(ctx);
6171
        {
6172
            TCGv_i32 fp0 = tcg_temp_new_i32();
6173

    
6174
            gen_load_fpr32(fp0, fs);
6175
            gen_helper_float_recip_s(fp0, fp0);
6176
            gen_store_fpr32(fp0, fd);
6177
            tcg_temp_free_i32(fp0);
6178
        }
6179
        opn = "recip.s";
6180
        break;
6181
    case FOP(22, 16):
6182
        check_cop1x(ctx);
6183
        {
6184
            TCGv_i32 fp0 = tcg_temp_new_i32();
6185

    
6186
            gen_load_fpr32(fp0, fs);
6187
            gen_helper_float_rsqrt_s(fp0, fp0);
6188
            gen_store_fpr32(fp0, fd);
6189
            tcg_temp_free_i32(fp0);
6190
        }
6191
        opn = "rsqrt.s";
6192
        break;
6193
    case FOP(28, 16):
6194
        check_cp1_64bitmode(ctx);
6195
        {
6196
            TCGv_i32 fp0 = tcg_temp_new_i32();
6197
            TCGv_i32 fp1 = tcg_temp_new_i32();
6198

    
6199
            gen_load_fpr32(fp0, fs);
6200
            gen_load_fpr32(fp1, fd);
6201
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6202
            tcg_temp_free_i32(fp1);
6203
            gen_store_fpr32(fp0, fd);
6204
            tcg_temp_free_i32(fp0);
6205
        }
6206
        opn = "recip2.s";
6207
        break;
6208
    case FOP(29, 16):
6209
        check_cp1_64bitmode(ctx);
6210
        {
6211
            TCGv_i32 fp0 = tcg_temp_new_i32();
6212

    
6213
            gen_load_fpr32(fp0, fs);
6214
            gen_helper_float_recip1_s(fp0, fp0);
6215
            gen_store_fpr32(fp0, fd);
6216
            tcg_temp_free_i32(fp0);
6217
        }
6218
        opn = "recip1.s";
6219
        break;
6220
    case FOP(30, 16):
6221
        check_cp1_64bitmode(ctx);
6222
        {
6223
            TCGv_i32 fp0 = tcg_temp_new_i32();
6224

    
6225
            gen_load_fpr32(fp0, fs);
6226
            gen_helper_float_rsqrt1_s(fp0, fp0);
6227
            gen_store_fpr32(fp0, fd);
6228
            tcg_temp_free_i32(fp0);
6229
        }
6230
        opn = "rsqrt1.s";
6231
        break;
6232
    case FOP(31, 16):
6233
        check_cp1_64bitmode(ctx);
6234
        {
6235
            TCGv_i32 fp0 = tcg_temp_new_i32();
6236
            TCGv_i32 fp1 = tcg_temp_new_i32();
6237

    
6238
            gen_load_fpr32(fp0, fs);
6239
            gen_load_fpr32(fp1, ft);
6240
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6241
            tcg_temp_free_i32(fp1);
6242
            gen_store_fpr32(fp0, fd);
6243
            tcg_temp_free_i32(fp0);
6244
        }
6245
        opn = "rsqrt2.s";
6246
        break;
6247
    case FOP(33, 16):
6248
        check_cp1_registers(ctx, fd);
6249
        {
6250
            TCGv_i32 fp32 = tcg_temp_new_i32();
6251
            TCGv_i64 fp64 = tcg_temp_new_i64();
6252

    
6253
            gen_load_fpr32(fp32, fs);
6254
            gen_helper_float_cvtd_s(fp64, fp32);
6255
            tcg_temp_free_i32(fp32);
6256
            gen_store_fpr64(ctx, fp64, fd);
6257
            tcg_temp_free_i64(fp64);
6258
        }
6259
        opn = "cvt.d.s";
6260
        break;
6261
    case FOP(36, 16):
6262
        {
6263
            TCGv_i32 fp0 = tcg_temp_new_i32();
6264

    
6265
            gen_load_fpr32(fp0, fs);
6266
            gen_helper_float_cvtw_s(fp0, fp0);
6267
            gen_store_fpr32(fp0, fd);
6268
            tcg_temp_free_i32(fp0);
6269
        }
6270
        opn = "cvt.w.s";
6271
        break;
6272
    case FOP(37, 16):
6273
        check_cp1_64bitmode(ctx);
6274
        {
6275
            TCGv_i32 fp32 = tcg_temp_new_i32();
6276
            TCGv_i64 fp64 = tcg_temp_new_i64();
6277

    
6278
            gen_load_fpr32(fp32, fs);
6279
            gen_helper_float_cvtl_s(fp64, fp32);
6280
            tcg_temp_free_i32(fp32);
6281
            gen_store_fpr64(ctx, fp64, fd);
6282
            tcg_temp_free_i64(fp64);
6283
        }
6284
        opn = "cvt.l.s";
6285
        break;
6286
    case FOP(38, 16):
6287
        check_cp1_64bitmode(ctx);
6288
        {
6289
            TCGv_i64 fp64 = tcg_temp_new_i64();
6290
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6291
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6292

    
6293
            gen_load_fpr32(fp32_0, fs);
6294
            gen_load_fpr32(fp32_1, ft);
6295
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6296
            tcg_temp_free_i32(fp32_1);
6297
            tcg_temp_free_i32(fp32_0);
6298
            gen_store_fpr64(ctx, fp64, fd);
6299
            tcg_temp_free_i64(fp64);
6300
        }
6301
        opn = "cvt.ps.s";
6302
        break;
6303
    case FOP(48, 16):
6304
    case FOP(49, 16):
6305
    case FOP(50, 16):
6306
    case FOP(51, 16):
6307
    case FOP(52, 16):
6308
    case FOP(53, 16):
6309
    case FOP(54, 16):
6310
    case FOP(55, 16):
6311
    case FOP(56, 16):
6312
    case FOP(57, 16):
6313
    case FOP(58, 16):
6314
    case FOP(59, 16):
6315
    case FOP(60, 16):
6316
    case FOP(61, 16):
6317
    case FOP(62, 16):
6318
    case FOP(63, 16):
6319
        {
6320
            TCGv_i32 fp0 = tcg_temp_new_i32();
6321
            TCGv_i32 fp1 = tcg_temp_new_i32();
6322

    
6323
            gen_load_fpr32(fp0, fs);
6324
            gen_load_fpr32(fp1, ft);
6325
            if (ctx->opcode & (1 << 6)) {
6326
                check_cop1x(ctx);
6327
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6328
                opn = condnames_abs[func-48];
6329
            } else {
6330
                gen_cmp_s(func-48, fp0, fp1, cc);
6331
                opn = condnames[func-48];
6332
            }
6333
            tcg_temp_free_i32(fp0);
6334
            tcg_temp_free_i32(fp1);
6335
        }
6336
        break;
6337
    case FOP(0, 17):
6338
        check_cp1_registers(ctx, fs | ft | fd);
6339
        {
6340
            TCGv_i64 fp0 = tcg_temp_new_i64();
6341
            TCGv_i64 fp1 = tcg_temp_new_i64();
6342

    
6343
            gen_load_fpr64(ctx, fp0, fs);
6344
            gen_load_fpr64(ctx, fp1, ft);
6345
            gen_helper_float_add_d(fp0, fp0, fp1);
6346
            tcg_temp_free_i64(fp1);
6347
            gen_store_fpr64(ctx, fp0, fd);
6348
            tcg_temp_free_i64(fp0);
6349
        }
6350
        opn = "add.d";
6351
        optype = BINOP;
6352
        break;
6353
    case FOP(1, 17):
6354
        check_cp1_registers(ctx, fs | ft | fd);
6355
        {
6356
            TCGv_i64 fp0 = tcg_temp_new_i64();
6357
            TCGv_i64 fp1 = tcg_temp_new_i64();
6358

    
6359
            gen_load_fpr64(ctx, fp0, fs);
6360
            gen_load_fpr64(ctx, fp1, ft);
6361
            gen_helper_float_sub_d(fp0, fp0, fp1);
6362
            tcg_temp_free_i64(fp1);
6363
            gen_store_fpr64(ctx, fp0, fd);
6364
            tcg_temp_free_i64(fp0);
6365
        }
6366
        opn = "sub.d";
6367
        optype = BINOP;
6368
        break;
6369
    case FOP(2, 17):
6370
        check_cp1_registers(ctx, fs | ft | fd);
6371
        {
6372
            TCGv_i64 fp0 = tcg_temp_new_i64();
6373
            TCGv_i64 fp1 = tcg_temp_new_i64();
6374

    
6375
            gen_load_fpr64(ctx, fp0, fs);
6376
            gen_load_fpr64(ctx, fp1, ft);
6377
            gen_helper_float_mul_d(fp0, fp0, fp1);
6378
            tcg_temp_free_i64(fp1);
6379
            gen_store_fpr64(ctx, fp0, fd);
6380
            tcg_temp_free_i64(fp0);
6381
        }
6382
        opn = "mul.d";
6383
        optype = BINOP;
6384
        break;
6385
    case FOP(3, 17):
6386
        check_cp1_registers(ctx, fs | ft | fd);
6387
        {
6388
            TCGv_i64 fp0 = tcg_temp_new_i64();
6389
            TCGv_i64 fp1 = tcg_temp_new_i64();
6390

    
6391
            gen_load_fpr64(ctx, fp0, fs);
6392
            gen_load_fpr64(ctx, fp1, ft);
6393
            gen_helper_float_div_d(fp0, fp0, fp1);
6394
            tcg_temp_free_i64(fp1);
6395
            gen_store_fpr64(ctx, fp0, fd);
6396
            tcg_temp_free_i64(fp0);
6397
        }
6398
        opn = "div.d";
6399
        optype = BINOP;
6400
        break;
6401
    case FOP(4, 17):
6402
        check_cp1_registers(ctx, fs | fd);
6403
        {
6404
            TCGv_i64 fp0 = tcg_temp_new_i64();
6405

    
6406
            gen_load_fpr64(ctx, fp0, fs);
6407
            gen_helper_float_sqrt_d(fp0, fp0);
6408
            gen_store_fpr64(ctx, fp0, fd);
6409
            tcg_temp_free_i64(fp0);
6410
        }
6411
        opn = "sqrt.d";
6412
        break;
6413
    case FOP(5, 17):
6414
        check_cp1_registers(ctx, fs | fd);
6415
        {
6416
            TCGv_i64 fp0 = tcg_temp_new_i64();
6417

    
6418
            gen_load_fpr64(ctx, fp0, fs);
6419
            gen_helper_float_abs_d(fp0, fp0);
6420
            gen_store_fpr64(ctx, fp0, fd);
6421
            tcg_temp_free_i64(fp0);
6422
        }
6423
        opn = "abs.d";
6424
        break;
6425
    case FOP(6, 17):
6426
        check_cp1_registers(ctx, fs | fd);
6427
        {
6428
            TCGv_i64 fp0 = tcg_temp_new_i64();
6429

    
6430
            gen_load_fpr64(ctx, fp0, fs);
6431
            gen_store_fpr64(ctx, fp0, fd);
6432
            tcg_temp_free_i64(fp0);
6433
        }
6434
        opn = "mov.d";
6435
        break;
6436
    case FOP(7, 17):
6437
        check_cp1_registers(ctx, fs | fd);
6438
        {
6439
            TCGv_i64 fp0 = tcg_temp_new_i64();
6440

    
6441
            gen_load_fpr64(ctx, fp0, fs);
6442
            gen_helper_float_chs_d(fp0, fp0);
6443
            gen_store_fpr64(ctx, fp0, fd);
6444
            tcg_temp_free_i64(fp0);
6445
        }
6446
        opn = "neg.d";
6447
        break;
6448
    case FOP(8, 17):
6449
        check_cp1_64bitmode(ctx);
6450
        {
6451
            TCGv_i64 fp0 = tcg_temp_new_i64();
6452

    
6453
            gen_load_fpr64(ctx, fp0, fs);
6454
            gen_helper_float_roundl_d(fp0, fp0);
6455
            gen_store_fpr64(ctx, fp0, fd);
6456
            tcg_temp_free_i64(fp0);
6457
        }
6458
        opn = "round.l.d";
6459
        break;
6460
    case FOP(9, 17):
6461
        check_cp1_64bitmode(ctx);
6462
        {
6463
            TCGv_i64 fp0 = tcg_temp_new_i64();
6464

    
6465
            gen_load_fpr64(ctx, fp0, fs);
6466
            gen_helper_float_truncl_d(fp0, fp0);
6467
            gen_store_fpr64(ctx, fp0, fd);
6468
            tcg_temp_free_i64(fp0);
6469
        }
6470
        opn = "trunc.l.d";
6471
        break;
6472
    case FOP(10, 17):
6473
        check_cp1_64bitmode(ctx);
6474
        {
6475
            TCGv_i64 fp0 = tcg_temp_new_i64();
6476

    
6477
            gen_load_fpr64(ctx, fp0, fs);
6478
            gen_helper_float_ceill_d(fp0, fp0);
6479
            gen_store_fpr64(ctx, fp0, fd);
6480
            tcg_temp_free_i64(fp0);
6481
        }
6482
        opn = "ceil.l.d";
6483
        break;
6484
    case FOP(11, 17):
6485
        check_cp1_64bitmode(ctx);
6486
        {
6487
            TCGv_i64 fp0 = tcg_temp_new_i64();
6488

    
6489
            gen_load_fpr64(ctx, fp0, fs);
6490
            gen_helper_float_floorl_d(fp0, fp0);
6491
            gen_store_fpr64(ctx, fp0, fd);
6492
            tcg_temp_free_i64(fp0);
6493
        }
6494
        opn = "floor.l.d";
6495
        break;
6496
    case FOP(12, 17):
6497
        check_cp1_registers(ctx, fs);
6498
        {
6499
            TCGv_i32 fp32 = tcg_temp_new_i32();
6500
            TCGv_i64 fp64 = tcg_temp_new_i64();
6501

    
6502
            gen_load_fpr64(ctx, fp64, fs);
6503
            gen_helper_float_roundw_d(fp32, fp64);
6504
            tcg_temp_free_i64(fp64);
6505
            gen_store_fpr32(fp32, fd);
6506
            tcg_temp_free_i32(fp32);
6507
        }
6508
        opn = "round.w.d";
6509
        break;
6510
    case FOP(13, 17):
6511
        check_cp1_registers(ctx, fs);
6512
        {
6513
            TCGv_i32 fp32 = tcg_temp_new_i32();
6514
            TCGv_i64 fp64 = tcg_temp_new_i64();
6515

    
6516
            gen_load_fpr64(ctx, fp64, fs);
6517
            gen_helper_float_truncw_d(fp32, fp64);
6518
            tcg_temp_free_i64(fp64);
6519
            gen_store_fpr32(fp32, fd);
6520
            tcg_temp_free_i32(fp32);
6521
        }
6522
        opn = "trunc.w.d";
6523
        break;
6524
    case FOP(14, 17):
6525
        check_cp1_registers(ctx, fs);
6526
        {
6527
            TCGv_i32 fp32 = tcg_temp_new_i32();
6528
            TCGv_i64 fp64 = tcg_temp_new_i64();
6529

    
6530
            gen_load_fpr64(ctx, fp64, fs);
6531
            gen_helper_float_ceilw_d(fp32, fp64);
6532
            tcg_temp_free_i64(fp64);
6533
            gen_store_fpr32(fp32, fd);
6534
            tcg_temp_free_i32(fp32);
6535
        }
6536
        opn = "ceil.w.d";
6537
        break;
6538
    case FOP(15, 17):
6539
        check_cp1_registers(ctx, fs);
6540
        {
6541
            TCGv_i32 fp32 = tcg_temp_new_i32();
6542
            TCGv_i64 fp64 = tcg_temp_new_i64();
6543

    
6544
            gen_load_fpr64(ctx, fp64, fs);
6545
            gen_helper_float_floorw_d(fp32, fp64);
6546
            tcg_temp_free_i64(fp64);
6547
            gen_store_fpr32(fp32, fd);
6548
            tcg_temp_free_i32(fp32);
6549
        }
6550
        opn = "floor.w.d";
6551
        break;
6552
    case FOP(17, 17):
6553
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6554
        opn = "movcf.d";
6555
        break;
6556
    case FOP(18, 17):
6557
        {
6558
            int l1 = gen_new_label();
6559
            TCGv_i64 fp0;
6560

    
6561
            if (ft != 0) {
6562
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6563
            }
6564
            fp0 = tcg_temp_new_i64();
6565
            gen_load_fpr64(ctx, fp0, fs);
6566
            gen_store_fpr64(ctx, fp0, fd);
6567
            tcg_temp_free_i64(fp0);
6568
            gen_set_label(l1);
6569
        }
6570
        opn = "movz.d";
6571
        break;
6572
    case FOP(19, 17):
6573
        {
6574
            int l1 = gen_new_label();
6575
            TCGv_i64 fp0;
6576

    
6577
            if (ft != 0) {
6578
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6579
                fp0 = tcg_temp_new_i64();
6580
                gen_load_fpr64(ctx, fp0, fs);
6581
                gen_store_fpr64(ctx, fp0, fd);
6582
                tcg_temp_free_i64(fp0);
6583
                gen_set_label(l1);
6584
            }
6585
        }
6586
        opn = "movn.d";
6587
        break;
6588
    case FOP(21, 17):
6589
        check_cp1_64bitmode(ctx);
6590
        {
6591
            TCGv_i64 fp0 = tcg_temp_new_i64();
6592

    
6593
            gen_load_fpr64(ctx, fp0, fs);
6594
            gen_helper_float_recip_d(fp0, fp0);
6595
            gen_store_fpr64(ctx, fp0, fd);
6596
            tcg_temp_free_i64(fp0);
6597
        }
6598
        opn = "recip.d";
6599
        break;
6600
    case FOP(22, 17):
6601
        check_cp1_64bitmode(ctx);
6602
        {
6603
            TCGv_i64 fp0 = tcg_temp_new_i64();
6604

    
6605
            gen_load_fpr64(ctx, fp0, fs);
6606
            gen_helper_float_rsqrt_d(fp0, fp0);
6607
            gen_store_fpr64(ctx, fp0, fd);
6608
            tcg_temp_free_i64(fp0);
6609
        }
6610
        opn = "rsqrt.d";
6611
        break;
6612
    case FOP(28, 17):
6613
        check_cp1_64bitmode(ctx);
6614
        {
6615
            TCGv_i64 fp0 = tcg_temp_new_i64();
6616
            TCGv_i64 fp1 = tcg_temp_new_i64();
6617

    
6618
            gen_load_fpr64(ctx, fp0, fs);
6619
            gen_load_fpr64(ctx, fp1, ft);
6620
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6621
            tcg_temp_free_i64(fp1);
6622
            gen_store_fpr64(ctx, fp0, fd);
6623
            tcg_temp_free_i64(fp0);
6624
        }
6625
        opn = "recip2.d";
6626
        break;
6627
    case FOP(29, 17):
6628
        check_cp1_64bitmode(ctx);
6629
        {
6630
            TCGv_i64 fp0 = tcg_temp_new_i64();
6631

    
6632
            gen_load_fpr64(ctx, fp0, fs);
6633
            gen_helper_float_recip1_d(fp0, fp0);
6634
            gen_store_fpr64(ctx, fp0, fd);
6635
            tcg_temp_free_i64(fp0);
6636
        }
6637
        opn = "recip1.d";
6638
        break;
6639
    case FOP(30, 17):
6640
        check_cp1_64bitmode(ctx);
6641
        {
6642
            TCGv_i64 fp0 = tcg_temp_new_i64();
6643

    
6644
            gen_load_fpr64(ctx, fp0, fs);
6645
            gen_helper_float_rsqrt1_d(fp0, fp0);
6646
            gen_store_fpr64(ctx, fp0, fd);
6647
            tcg_temp_free_i64(fp0);
6648
        }
6649
        opn = "rsqrt1.d";
6650
        break;
6651
    case FOP(31, 17):
6652
        check_cp1_64bitmode(ctx);
6653
        {
6654
            TCGv_i64 fp0 = tcg_temp_new_i64();
6655
            TCGv_i64 fp1 = tcg_temp_new_i64();
6656

    
6657
            gen_load_fpr64(ctx, fp0, fs);
6658
            gen_load_fpr64(ctx, fp1, ft);
6659
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6660
            tcg_temp_free_i64(fp1);
6661
            gen_store_fpr64(ctx, fp0, fd);
6662
            tcg_temp_free_i64(fp0);
6663
        }
6664
        opn = "rsqrt2.d";
6665
        break;
6666
    case FOP(48, 17):
6667
    case FOP(49, 17):
6668
    case FOP(50, 17):
6669
    case FOP(51, 17):
6670
    case FOP(52, 17):
6671
    case FOP(53, 17):
6672
    case FOP(54, 17):
6673
    case FOP(55, 17):
6674
    case FOP(56, 17):
6675
    case FOP(57, 17):
6676
    case FOP(58, 17):
6677
    case FOP(59, 17):
6678
    case FOP(60, 17):
6679
    case FOP(61, 17):
6680
    case FOP(62, 17):
6681
    case FOP(63, 17):
6682
        {
6683
            TCGv_i64 fp0 = tcg_temp_new_i64();
6684
            TCGv_i64 fp1 = tcg_temp_new_i64();
6685

    
6686
            gen_load_fpr64(ctx, fp0, fs);
6687
            gen_load_fpr64(ctx, fp1, ft);
6688
            if (ctx->opcode & (1 << 6)) {
6689
                check_cop1x(ctx);
6690
                check_cp1_registers(ctx, fs | ft);
6691
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6692
                opn = condnames_abs[func-48];
6693
            } else {
6694
                check_cp1_registers(ctx, fs | ft);
6695
                gen_cmp_d(func-48, fp0, fp1, cc);
6696
                opn = condnames[func-48];
6697
            }
6698
            tcg_temp_free_i64(fp0);
6699
            tcg_temp_free_i64(fp1);
6700
        }
6701
        break;
6702
    case FOP(32, 17):
6703
        check_cp1_registers(ctx, fs);
6704
        {
6705
            TCGv_i32 fp32 = tcg_temp_new_i32();
6706
            TCGv_i64 fp64 = tcg_temp_new_i64();
6707

    
6708
            gen_load_fpr64(ctx, fp64, fs);
6709
            gen_helper_float_cvts_d(fp32, fp64);
6710
            tcg_temp_free_i64(fp64);
6711
            gen_store_fpr32(fp32, fd);
6712
            tcg_temp_free_i32(fp32);
6713
        }
6714
        opn = "cvt.s.d";
6715
        break;
6716
    case FOP(36, 17):
6717
        check_cp1_registers(ctx, fs);
6718
        {
6719
            TCGv_i32 fp32 = tcg_temp_new_i32();
6720
            TCGv_i64 fp64 = tcg_temp_new_i64();
6721

    
6722
            gen_load_fpr64(ctx, fp64, fs);
6723
            gen_helper_float_cvtw_d(fp32, fp64);
6724
            tcg_temp_free_i64(fp64);
6725
            gen_store_fpr32(fp32, fd);
6726
            tcg_temp_free_i32(fp32);
6727
        }
6728
        opn = "cvt.w.d";
6729
        break;
6730
    case FOP(37, 17):
6731
        check_cp1_64bitmode(ctx);
6732
        {
6733
            TCGv_i64 fp0 = tcg_temp_new_i64();
6734

    
6735
            gen_load_fpr64(ctx, fp0, fs);
6736
            gen_helper_float_cvtl_d(fp0, fp0);
6737
            gen_store_fpr64(ctx, fp0, fd);
6738
            tcg_temp_free_i64(fp0);
6739
        }
6740
        opn = "cvt.l.d";
6741
        break;
6742
    case FOP(32, 20):
6743
        {
6744
            TCGv_i32 fp0 = tcg_temp_new_i32();
6745

    
6746
            gen_load_fpr32(fp0, fs);
6747
            gen_helper_float_cvts_w(fp0, fp0);
6748
            gen_store_fpr32(fp0, fd);
6749
            tcg_temp_free_i32(fp0);
6750
        }
6751
        opn = "cvt.s.w";
6752
        break;
6753
    case FOP(33, 20):
6754
        check_cp1_registers(ctx, fd);
6755
        {
6756
            TCGv_i32 fp32 = tcg_temp_new_i32();
6757
            TCGv_i64 fp64 = tcg_temp_new_i64();
6758

    
6759
            gen_load_fpr32(fp32, fs);
6760
            gen_helper_float_cvtd_w(fp64, fp32);
6761
            tcg_temp_free_i32(fp32);
6762
            gen_store_fpr64(ctx, fp64, fd);
6763
            tcg_temp_free_i64(fp64);
6764
        }
6765
        opn = "cvt.d.w";
6766
        break;
6767
    case FOP(32, 21):
6768
        check_cp1_64bitmode(ctx);
6769
        {
6770
            TCGv_i32 fp32 = tcg_temp_new_i32();
6771
            TCGv_i64 fp64 = tcg_temp_new_i64();
6772

    
6773
            gen_load_fpr64(ctx, fp64, fs);
6774
            gen_helper_float_cvts_l(fp32, fp64);
6775
            tcg_temp_free_i64(fp64);
6776
            gen_store_fpr32(fp32, fd);
6777
            tcg_temp_free_i32(fp32);
6778
        }
6779
        opn = "cvt.s.l";
6780
        break;
6781
    case FOP(33, 21):
6782
        check_cp1_64bitmode(ctx);
6783
        {
6784
            TCGv_i64 fp0 = tcg_temp_new_i64();
6785

    
6786
            gen_load_fpr64(ctx, fp0, fs);
6787
            gen_helper_float_cvtd_l(fp0, fp0);
6788
            gen_store_fpr64(ctx, fp0, fd);
6789
            tcg_temp_free_i64(fp0);
6790
        }
6791
        opn = "cvt.d.l";
6792
        break;
6793
    case FOP(38, 20):
6794
        check_cp1_64bitmode(ctx);
6795
        {
6796
            TCGv_i64 fp0 = tcg_temp_new_i64();
6797

    
6798
            gen_load_fpr64(ctx, fp0, fs);
6799
            gen_helper_float_cvtps_pw(fp0, fp0);
6800
            gen_store_fpr64(ctx, fp0, fd);
6801
            tcg_temp_free_i64(fp0);
6802
        }
6803
        opn = "cvt.ps.pw";
6804
        break;
6805
    case FOP(0, 22):
6806
        check_cp1_64bitmode(ctx);
6807
        {
6808
            TCGv_i64 fp0 = tcg_temp_new_i64();
6809
            TCGv_i64 fp1 = tcg_temp_new_i64();
6810

    
6811
            gen_load_fpr64(ctx, fp0, fs);
6812
            gen_load_fpr64(ctx, fp1, ft);
6813
            gen_helper_float_add_ps(fp0, fp0, fp1);
6814
            tcg_temp_free_i64(fp1);
6815
            gen_store_fpr64(ctx, fp0, fd);
6816
            tcg_temp_free_i64(fp0);
6817
        }
6818
        opn = "add.ps";
6819
        break;
6820
    case FOP(1, 22):
6821
        check_cp1_64bitmode(ctx);
6822
        {
6823
            TCGv_i64 fp0 = tcg_temp_new_i64();
6824
            TCGv_i64 fp1 = tcg_temp_new_i64();
6825

    
6826
            gen_load_fpr64(ctx, fp0, fs);
6827
            gen_load_fpr64(ctx, fp1, ft);
6828
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6829
            tcg_temp_free_i64(fp1);
6830
            gen_store_fpr64(ctx, fp0, fd);
6831
            tcg_temp_free_i64(fp0);
6832
        }
6833
        opn = "sub.ps";
6834
        break;
6835
    case FOP(2, 22):
6836
        check_cp1_64bitmode(ctx);
6837
        {
6838
            TCGv_i64 fp0 = tcg_temp_new_i64();
6839
            TCGv_i64 fp1 = tcg_temp_new_i64();
6840

    
6841
            gen_load_fpr64(ctx, fp0, fs);
6842
            gen_load_fpr64(ctx, fp1, ft);
6843
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6844
            tcg_temp_free_i64(fp1);
6845
            gen_store_fpr64(ctx, fp0, fd);
6846
            tcg_temp_free_i64(fp0);
6847
        }
6848
        opn = "mul.ps";
6849
        break;
6850
    case FOP(5, 22):
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_abs_ps(fp0, fp0);
6857
            gen_store_fpr64(ctx, fp0, fd);
6858
            tcg_temp_free_i64(fp0);
6859
        }
6860
        opn = "abs.ps";
6861
        break;
6862
    case FOP(6, 22):
6863
        check_cp1_64bitmode(ctx);
6864
        {
6865
            TCGv_i64 fp0 = tcg_temp_new_i64();
6866

    
6867
            gen_load_fpr64(ctx, fp0, fs);
6868
            gen_store_fpr64(ctx, fp0, fd);
6869
            tcg_temp_free_i64(fp0);
6870
        }
6871
        opn = "mov.ps";
6872
        break;
6873
    case FOP(7, 22):
6874
        check_cp1_64bitmode(ctx);
6875
        {
6876
            TCGv_i64 fp0 = tcg_temp_new_i64();
6877

    
6878
            gen_load_fpr64(ctx, fp0, fs);
6879
            gen_helper_float_chs_ps(fp0, fp0);
6880
            gen_store_fpr64(ctx, fp0, fd);
6881
            tcg_temp_free_i64(fp0);
6882
        }
6883
        opn = "neg.ps";
6884
        break;
6885
    case FOP(17, 22):
6886
        check_cp1_64bitmode(ctx);
6887
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6888
        opn = "movcf.ps";
6889
        break;
6890
    case FOP(18, 22):
6891
        check_cp1_64bitmode(ctx);
6892
        {
6893
            int l1 = gen_new_label();
6894
            TCGv_i64 fp0;
6895

    
6896
            if (ft != 0)
6897
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6898
            fp0 = tcg_temp_new_i64();
6899
            gen_load_fpr64(ctx, fp0, fs);
6900
            gen_store_fpr64(ctx, fp0, fd);
6901
            tcg_temp_free_i64(fp0);
6902
            gen_set_label(l1);
6903
        }
6904
        opn = "movz.ps";
6905
        break;
6906
    case FOP(19, 22):
6907
        check_cp1_64bitmode(ctx);
6908
        {
6909
            int l1 = gen_new_label();
6910
            TCGv_i64 fp0;
6911

    
6912
            if (ft != 0) {
6913
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6914
                fp0 = tcg_temp_new_i64();
6915
                gen_load_fpr64(ctx, fp0, fs);
6916
                gen_store_fpr64(ctx, fp0, fd);
6917
                tcg_temp_free_i64(fp0);
6918
                gen_set_label(l1);
6919
            }
6920
        }
6921
        opn = "movn.ps";
6922
        break;
6923
    case FOP(24, 22):
6924
        check_cp1_64bitmode(ctx);
6925
        {
6926
            TCGv_i64 fp0 = tcg_temp_new_i64();
6927
            TCGv_i64 fp1 = tcg_temp_new_i64();
6928

    
6929
            gen_load_fpr64(ctx, fp0, ft);
6930
            gen_load_fpr64(ctx, fp1, fs);
6931
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6932
            tcg_temp_free_i64(fp1);
6933
            gen_store_fpr64(ctx, fp0, fd);
6934
            tcg_temp_free_i64(fp0);
6935
        }
6936
        opn = "addr.ps";
6937
        break;
6938
    case FOP(26, 22):
6939
        check_cp1_64bitmode(ctx);
6940
        {
6941
            TCGv_i64 fp0 = tcg_temp_new_i64();
6942
            TCGv_i64 fp1 = tcg_temp_new_i64();
6943

    
6944
            gen_load_fpr64(ctx, fp0, ft);
6945
            gen_load_fpr64(ctx, fp1, fs);
6946
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
6947
            tcg_temp_free_i64(fp1);
6948
            gen_store_fpr64(ctx, fp0, fd);
6949
            tcg_temp_free_i64(fp0);
6950
        }
6951
        opn = "mulr.ps";
6952
        break;
6953
    case FOP(28, 22):
6954
        check_cp1_64bitmode(ctx);
6955
        {
6956
            TCGv_i64 fp0 = tcg_temp_new_i64();
6957
            TCGv_i64 fp1 = tcg_temp_new_i64();
6958

    
6959
            gen_load_fpr64(ctx, fp0, fs);
6960
            gen_load_fpr64(ctx, fp1, fd);
6961
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6962
            tcg_temp_free_i64(fp1);
6963
            gen_store_fpr64(ctx, fp0, fd);
6964
            tcg_temp_free_i64(fp0);
6965
        }
6966
        opn = "recip2.ps";
6967
        break;
6968
    case FOP(29, 22):
6969
        check_cp1_64bitmode(ctx);
6970
        {
6971
            TCGv_i64 fp0 = tcg_temp_new_i64();
6972

    
6973
            gen_load_fpr64(ctx, fp0, fs);
6974
            gen_helper_float_recip1_ps(fp0, fp0);
6975
            gen_store_fpr64(ctx, fp0, fd);
6976
            tcg_temp_free_i64(fp0);
6977
        }
6978
        opn = "recip1.ps";
6979
        break;
6980
    case FOP(30, 22):
6981
        check_cp1_64bitmode(ctx);
6982
        {
6983
            TCGv_i64 fp0 = tcg_temp_new_i64();
6984

    
6985
            gen_load_fpr64(ctx, fp0, fs);
6986
            gen_helper_float_rsqrt1_ps(fp0, fp0);
6987
            gen_store_fpr64(ctx, fp0, fd);
6988
            tcg_temp_free_i64(fp0);
6989
        }
6990
        opn = "rsqrt1.ps";
6991
        break;
6992
    case FOP(31, 22):
6993
        check_cp1_64bitmode(ctx);
6994
        {
6995
            TCGv_i64 fp0 = tcg_temp_new_i64();
6996
            TCGv_i64 fp1 = tcg_temp_new_i64();
6997

    
6998
            gen_load_fpr64(ctx, fp0, fs);
6999
            gen_load_fpr64(ctx, fp1, ft);
7000
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7001
            tcg_temp_free_i64(fp1);
7002
            gen_store_fpr64(ctx, fp0, fd);
7003
            tcg_temp_free_i64(fp0);
7004
        }
7005
        opn = "rsqrt2.ps";
7006
        break;
7007
    case FOP(32, 22):
7008
        check_cp1_64bitmode(ctx);
7009
        {
7010
            TCGv_i32 fp0 = tcg_temp_new_i32();
7011

    
7012
            gen_load_fpr32h(fp0, fs);
7013
            gen_helper_float_cvts_pu(fp0, fp0);
7014
            gen_store_fpr32(fp0, fd);
7015
            tcg_temp_free_i32(fp0);
7016
        }
7017
        opn = "cvt.s.pu";
7018
        break;
7019
    case FOP(36, 22):
7020
        check_cp1_64bitmode(ctx);
7021
        {
7022
            TCGv_i64 fp0 = tcg_temp_new_i64();
7023

    
7024
            gen_load_fpr64(ctx, fp0, fs);
7025
            gen_helper_float_cvtpw_ps(fp0, fp0);
7026
            gen_store_fpr64(ctx, fp0, fd);
7027
            tcg_temp_free_i64(fp0);
7028
        }
7029
        opn = "cvt.pw.ps";
7030
        break;
7031
    case FOP(40, 22):
7032
        check_cp1_64bitmode(ctx);
7033
        {
7034
            TCGv_i32 fp0 = tcg_temp_new_i32();
7035

    
7036
            gen_load_fpr32(fp0, fs);
7037
            gen_helper_float_cvts_pl(fp0, fp0);
7038
            gen_store_fpr32(fp0, fd);
7039
            tcg_temp_free_i32(fp0);
7040
        }
7041
        opn = "cvt.s.pl";
7042
        break;
7043
    case FOP(44, 22):
7044
        check_cp1_64bitmode(ctx);
7045
        {
7046
            TCGv_i32 fp0 = tcg_temp_new_i32();
7047
            TCGv_i32 fp1 = tcg_temp_new_i32();
7048

    
7049
            gen_load_fpr32(fp0, fs);
7050
            gen_load_fpr32(fp1, ft);
7051
            gen_store_fpr32h(fp0, fd);
7052
            gen_store_fpr32(fp1, fd);
7053
            tcg_temp_free_i32(fp0);
7054
            tcg_temp_free_i32(fp1);
7055
        }
7056
        opn = "pll.ps";
7057
        break;
7058
    case FOP(45, 22):
7059
        check_cp1_64bitmode(ctx);
7060
        {
7061
            TCGv_i32 fp0 = tcg_temp_new_i32();
7062
            TCGv_i32 fp1 = tcg_temp_new_i32();
7063

    
7064
            gen_load_fpr32(fp0, fs);
7065
            gen_load_fpr32h(fp1, ft);
7066
            gen_store_fpr32(fp1, fd);
7067
            gen_store_fpr32h(fp0, fd);
7068
            tcg_temp_free_i32(fp0);
7069
            tcg_temp_free_i32(fp1);
7070
        }
7071
        opn = "plu.ps";
7072
        break;
7073
    case FOP(46, 22):
7074
        check_cp1_64bitmode(ctx);
7075
        {
7076
            TCGv_i32 fp0 = tcg_temp_new_i32();
7077
            TCGv_i32 fp1 = tcg_temp_new_i32();
7078

    
7079
            gen_load_fpr32h(fp0, fs);
7080
            gen_load_fpr32(fp1, ft);
7081
            gen_store_fpr32(fp1, fd);
7082
            gen_store_fpr32h(fp0, fd);
7083
            tcg_temp_free_i32(fp0);
7084
            tcg_temp_free_i32(fp1);
7085
        }
7086
        opn = "pul.ps";
7087
        break;
7088
    case FOP(47, 22):
7089
        check_cp1_64bitmode(ctx);
7090
        {
7091
            TCGv_i32 fp0 = tcg_temp_new_i32();
7092
            TCGv_i32 fp1 = tcg_temp_new_i32();
7093

    
7094
            gen_load_fpr32h(fp0, fs);
7095
            gen_load_fpr32h(fp1, ft);
7096
            gen_store_fpr32(fp1, fd);
7097
            gen_store_fpr32h(fp0, fd);
7098
            tcg_temp_free_i32(fp0);
7099
            tcg_temp_free_i32(fp1);
7100
        }
7101
        opn = "puu.ps";
7102
        break;
7103
    case FOP(48, 22):
7104
    case FOP(49, 22):
7105
    case FOP(50, 22):
7106
    case FOP(51, 22):
7107
    case FOP(52, 22):
7108
    case FOP(53, 22):
7109
    case FOP(54, 22):
7110
    case FOP(55, 22):
7111
    case FOP(56, 22):
7112
    case FOP(57, 22):
7113
    case FOP(58, 22):
7114
    case FOP(59, 22):
7115
    case FOP(60, 22):
7116
    case FOP(61, 22):
7117
    case FOP(62, 22):
7118
    case FOP(63, 22):
7119
        check_cp1_64bitmode(ctx);
7120
        {
7121
            TCGv_i64 fp0 = tcg_temp_new_i64();
7122
            TCGv_i64 fp1 = tcg_temp_new_i64();
7123

    
7124
            gen_load_fpr64(ctx, fp0, fs);
7125
            gen_load_fpr64(ctx, fp1, ft);
7126
            if (ctx->opcode & (1 << 6)) {
7127
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7128
                opn = condnames_abs[func-48];
7129
            } else {
7130
                gen_cmp_ps(func-48, fp0, fp1, cc);
7131
                opn = condnames[func-48];
7132
            }
7133
            tcg_temp_free_i64(fp0);
7134
            tcg_temp_free_i64(fp1);
7135
        }
7136
        break;
7137
    default:
7138
        MIPS_INVAL(opn);
7139
        generate_exception (ctx, EXCP_RI);
7140
        return;
7141
    }
7142
    switch (optype) {
7143
    case BINOP:
7144
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7145
        break;
7146
    case CMPOP:
7147
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7148
        break;
7149
    default:
7150
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7151
        break;
7152
    }
7153
}
7154

    
7155
/* Coprocessor 3 (FPU) */
7156
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7157
                           int fd, int fs, int base, int index)
7158
{
7159
    const char *opn = "extended float load/store";
7160
    int store = 0;
7161
    TCGv t0 = tcg_temp_new();
7162

    
7163
    if (base == 0) {
7164
        gen_load_gpr(t0, index);
7165
    } else if (index == 0) {
7166
        gen_load_gpr(t0, base);
7167
    } else {
7168
        gen_load_gpr(t0, index);
7169
        gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7170
    }
7171
    /* Don't do NOP if destination is zero: we must perform the actual
7172
       memory access. */
7173
    save_cpu_state(ctx, 0);
7174
    switch (opc) {
7175
    case OPC_LWXC1:
7176
        check_cop1x(ctx);
7177
        {
7178
            TCGv_i32 fp0 = tcg_temp_new_i32();
7179

    
7180
            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7181
            tcg_gen_trunc_tl_i32(fp0, t0);
7182
            gen_store_fpr32(fp0, fd);
7183
            tcg_temp_free_i32(fp0);
7184
        }
7185
        opn = "lwxc1";
7186
        break;
7187
    case OPC_LDXC1:
7188
        check_cop1x(ctx);
7189
        check_cp1_registers(ctx, fd);
7190
        {
7191
            TCGv_i64 fp0 = tcg_temp_new_i64();
7192

    
7193
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7194
            gen_store_fpr64(ctx, fp0, fd);
7195
            tcg_temp_free_i64(fp0);
7196
        }
7197
        opn = "ldxc1";
7198
        break;
7199
    case OPC_LUXC1:
7200
        check_cp1_64bitmode(ctx);
7201
        tcg_gen_andi_tl(t0, t0, ~0x7);
7202
        {
7203
            TCGv_i64 fp0 = tcg_temp_new_i64();
7204

    
7205
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7206
            gen_store_fpr64(ctx, fp0, fd);
7207
            tcg_temp_free_i64(fp0);
7208
        }
7209
        opn = "luxc1";
7210
        break;
7211
    case OPC_SWXC1:
7212
        check_cop1x(ctx);
7213
        {
7214
            TCGv_i32 fp0 = tcg_temp_new_i32();
7215
            TCGv t1 = tcg_temp_new();
7216

    
7217
            gen_load_fpr32(fp0, fs);
7218
            tcg_gen_extu_i32_tl(t1, fp0);
7219
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7220
            tcg_temp_free_i32(fp0);
7221
            tcg_temp_free(t1);
7222
        }
7223
        opn = "swxc1";
7224
        store = 1;
7225
        break;
7226
    case OPC_SDXC1:
7227
        check_cop1x(ctx);
7228
        check_cp1_registers(ctx, fs);
7229
        {
7230
            TCGv_i64 fp0 = tcg_temp_new_i64();
7231

    
7232
            gen_load_fpr64(ctx, fp0, fs);
7233
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7234
            tcg_temp_free_i64(fp0);
7235
        }
7236
        opn = "sdxc1";
7237
        store = 1;
7238
        break;
7239
    case OPC_SUXC1:
7240
        check_cp1_64bitmode(ctx);
7241
        tcg_gen_andi_tl(t0, t0, ~0x7);
7242
        {
7243
            TCGv_i64 fp0 = tcg_temp_new_i64();
7244

    
7245
            gen_load_fpr64(ctx, fp0, fs);
7246
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7247
            tcg_temp_free_i64(fp0);
7248
        }
7249
        opn = "suxc1";
7250
        store = 1;
7251
        break;
7252
    }
7253
    tcg_temp_free(t0);
7254
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7255
               regnames[index], regnames[base]);
7256
}
7257

    
7258
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7259
                            int fd, int fr, int fs, int ft)
7260
{
7261
    const char *opn = "flt3_arith";
7262

    
7263
    switch (opc) {
7264
    case OPC_ALNV_PS:
7265
        check_cp1_64bitmode(ctx);
7266
        {
7267
            TCGv t0 = tcg_temp_local_new();
7268
            TCGv_i32 fp = tcg_temp_new_i32();
7269
            TCGv_i32 fph = tcg_temp_new_i32();
7270
            int l1 = gen_new_label();
7271
            int l2 = gen_new_label();
7272

    
7273
            gen_load_gpr(t0, fr);
7274
            tcg_gen_andi_tl(t0, t0, 0x7);
7275

    
7276
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7277
            gen_load_fpr32(fp, fs);
7278
            gen_load_fpr32h(fph, fs);
7279
            gen_store_fpr32(fp, fd);
7280
            gen_store_fpr32h(fph, fd);
7281
            tcg_gen_br(l2);
7282
            gen_set_label(l1);
7283
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7284
            tcg_temp_free(t0);
7285
#ifdef TARGET_WORDS_BIGENDIAN
7286
            gen_load_fpr32(fp, fs);
7287
            gen_load_fpr32h(fph, ft);
7288
            gen_store_fpr32h(fp, fd);
7289
            gen_store_fpr32(fph, fd);
7290
#else
7291
            gen_load_fpr32h(fph, fs);
7292
            gen_load_fpr32(fp, ft);
7293
            gen_store_fpr32(fph, fd);
7294
            gen_store_fpr32h(fp, fd);
7295
#endif
7296
            gen_set_label(l2);
7297
            tcg_temp_free_i32(fp);
7298
            tcg_temp_free_i32(fph);
7299
        }
7300
        opn = "alnv.ps";
7301
        break;
7302
    case OPC_MADD_S:
7303
        check_cop1x(ctx);
7304
        {
7305
            TCGv_i32 fp0 = tcg_temp_new_i32();
7306
            TCGv_i32 fp1 = tcg_temp_new_i32();
7307
            TCGv_i32 fp2 = tcg_temp_new_i32();
7308

    
7309
            gen_load_fpr32(fp0, fs);
7310
            gen_load_fpr32(fp1, ft);
7311
            gen_load_fpr32(fp2, fr);
7312
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7313
            tcg_temp_free_i32(fp0);
7314
            tcg_temp_free_i32(fp1);
7315
            gen_store_fpr32(fp2, fd);
7316
            tcg_temp_free_i32(fp2);
7317
        }
7318
        opn = "madd.s";
7319
        break;
7320
    case OPC_MADD_D:
7321
        check_cop1x(ctx);
7322
        check_cp1_registers(ctx, fd | fs | ft | fr);
7323
        {
7324
            TCGv_i64 fp0 = tcg_temp_new_i64();
7325
            TCGv_i64 fp1 = tcg_temp_new_i64();
7326
            TCGv_i64 fp2 = tcg_temp_new_i64();
7327

    
7328
            gen_load_fpr64(ctx, fp0, fs);
7329
            gen_load_fpr64(ctx, fp1, ft);
7330
            gen_load_fpr64(ctx, fp2, fr);
7331
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7332
            tcg_temp_free_i64(fp0);
7333
            tcg_temp_free_i64(fp1);
7334
            gen_store_fpr64(ctx, fp2, fd);
7335
            tcg_temp_free_i64(fp2);
7336
        }
7337
        opn = "madd.d";
7338
        break;
7339
    case OPC_MADD_PS:
7340
        check_cp1_64bitmode(ctx);
7341
        {
7342
            TCGv_i64 fp0 = tcg_temp_new_i64();
7343
            TCGv_i64 fp1 = tcg_temp_new_i64();
7344
            TCGv_i64 fp2 = tcg_temp_new_i64();
7345

    
7346
            gen_load_fpr64(ctx, fp0, fs);
7347
            gen_load_fpr64(ctx, fp1, ft);
7348
            gen_load_fpr64(ctx, fp2, fr);
7349
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7350
            tcg_temp_free_i64(fp0);
7351
            tcg_temp_free_i64(fp1);
7352
            gen_store_fpr64(ctx, fp2, fd);
7353
            tcg_temp_free_i64(fp2);
7354
        }
7355
        opn = "madd.ps";
7356
        break;
7357
    case OPC_MSUB_S:
7358
        check_cop1x(ctx);
7359
        {
7360
            TCGv_i32 fp0 = tcg_temp_new_i32();
7361
            TCGv_i32 fp1 = tcg_temp_new_i32();
7362
            TCGv_i32 fp2 = tcg_temp_new_i32();
7363

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

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

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

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

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

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

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

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

    
7511
            gen_load_fpr64(ctx, fp0, fs);
7512
            gen_load_fpr64(ctx, fp1, ft);
7513
            gen_load_fpr64(ctx, fp2, fr);
7514
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7515
            tcg_temp_free_i64(fp0);
7516
            tcg_temp_free_i64(fp1);
7517
            gen_store_fpr64(ctx, fp2, fd);
7518
            tcg_temp_free_i64(fp2);
7519
        }
7520
        opn = "nmsub.ps";
7521
        break;
7522
    default:
7523
        MIPS_INVAL(opn);
7524
        generate_exception (ctx, EXCP_RI);
7525
        return;
7526
    }
7527
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7528
               fregnames[fs], fregnames[ft]);
7529
}
7530

    
7531
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
7532
                               int insn_bytes)
7533
{
7534
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7535
        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7536
        /* Branches completion */
7537
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7538
        ctx->bstate = BS_BRANCH;
7539
        save_cpu_state(ctx, 0);
7540
        /* FIXME: Need to clear can_do_io.  */
7541
        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
7542
        case MIPS_HFLAG_B:
7543
            /* unconditional branch */
7544
            MIPS_DEBUG("unconditional branch");
7545
            if (proc_hflags & MIPS_HFLAG_BX) {
7546
                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
7547
            }
7548
            gen_goto_tb(ctx, 0, ctx->btarget);
7549
            break;
7550
        case MIPS_HFLAG_BL:
7551
            /* blikely taken case */
7552
            MIPS_DEBUG("blikely branch taken");
7553
            gen_goto_tb(ctx, 0, ctx->btarget);
7554
            break;
7555
        case MIPS_HFLAG_BC:
7556
            /* Conditional branch */
7557
            MIPS_DEBUG("conditional branch");
7558
            {
7559
                int l1 = gen_new_label();
7560

    
7561
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7562
                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
7563
                gen_set_label(l1);
7564
                gen_goto_tb(ctx, 0, ctx->btarget);
7565
            }
7566
            break;
7567
        case MIPS_HFLAG_BR:
7568
            /* unconditional branch to register */
7569
            MIPS_DEBUG("branch to register");
7570
            if (env->insn_flags & ASE_MIPS16) {
7571
                TCGv t0 = tcg_temp_new();
7572
                TCGv_i32 t1 = tcg_temp_new_i32();
7573

    
7574
                tcg_gen_andi_tl(t0, btarget, 0x1);
7575
                tcg_gen_trunc_tl_i32(t1, t0);
7576
                tcg_temp_free(t0);
7577
                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
7578
                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
7579
                tcg_gen_or_i32(hflags, hflags, t1);
7580
                tcg_temp_free_i32(t1);
7581

    
7582
                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
7583
            } else {
7584
                tcg_gen_mov_tl(cpu_PC, btarget);
7585
            }
7586
            if (ctx->singlestep_enabled) {
7587
                save_cpu_state(ctx, 0);
7588
                gen_helper_0i(raise_exception, EXCP_DEBUG);
7589
            }
7590
            tcg_gen_exit_tb(0);
7591
            break;
7592
        default:
7593
            MIPS_DEBUG("unknown branch");
7594
            break;
7595
        }
7596
    }
7597
}
7598

    
7599
/* ISA extensions (ASEs) */
7600
/* MIPS16 extension to MIPS32 */
7601

    
7602
/* MIPS16 major opcodes */
7603
enum {
7604
  M16_OPC_ADDIUSP = 0x00,
7605
  M16_OPC_ADDIUPC = 0x01,
7606
  M16_OPC_B = 0x02,
7607
  M16_OPC_JAL = 0x03,
7608
  M16_OPC_BEQZ = 0x04,
7609
  M16_OPC_BNEQZ = 0x05,
7610
  M16_OPC_SHIFT = 0x06,
7611
  M16_OPC_LD = 0x07,
7612
  M16_OPC_RRIA = 0x08,
7613
  M16_OPC_ADDIU8 = 0x09,
7614
  M16_OPC_SLTI = 0x0a,
7615
  M16_OPC_SLTIU = 0x0b,
7616
  M16_OPC_I8 = 0x0c,
7617
  M16_OPC_LI = 0x0d,
7618
  M16_OPC_CMPI = 0x0e,
7619
  M16_OPC_SD = 0x0f,
7620
  M16_OPC_LB = 0x10,
7621
  M16_OPC_LH = 0x11,
7622
  M16_OPC_LWSP = 0x12,
7623
  M16_OPC_LW = 0x13,
7624
  M16_OPC_LBU = 0x14,
7625
  M16_OPC_LHU = 0x15,
7626
  M16_OPC_LWPC = 0x16,
7627
  M16_OPC_LWU = 0x17,
7628
  M16_OPC_SB = 0x18,
7629
  M16_OPC_SH = 0x19,
7630
  M16_OPC_SWSP = 0x1a,
7631
  M16_OPC_SW = 0x1b,
7632
  M16_OPC_RRR = 0x1c,
7633
  M16_OPC_RR = 0x1d,
7634
  M16_OPC_EXTEND = 0x1e,
7635
  M16_OPC_I64 = 0x1f
7636
};
7637

    
7638
/* I8 funct field */
7639
enum {
7640
  I8_BTEQZ = 0x0,
7641
  I8_BTNEZ = 0x1,
7642
  I8_SWRASP = 0x2,
7643
  I8_ADJSP = 0x3,
7644
  I8_SVRS = 0x4,
7645
  I8_MOV32R = 0x5,
7646
  I8_MOVR32 = 0x7
7647
};
7648

    
7649
/* RRR f field */
7650
enum {
7651
  RRR_DADDU = 0x0,
7652
  RRR_ADDU = 0x1,
7653
  RRR_DSUBU = 0x2,
7654
  RRR_SUBU = 0x3
7655
};
7656

    
7657
/* RR funct field */
7658
enum {
7659
  RR_JR = 0x00,
7660
  RR_SDBBP = 0x01,
7661
  RR_SLT = 0x02,
7662
  RR_SLTU = 0x03,
7663
  RR_SLLV = 0x04,
7664
  RR_BREAK = 0x05,
7665
  RR_SRLV = 0x06,
7666
  RR_SRAV = 0x07,
7667
  RR_DSRL = 0x08,
7668
  RR_CMP = 0x0a,
7669
  RR_NEG = 0x0b,
7670
  RR_AND = 0x0c,
7671
  RR_OR = 0x0d,
7672
  RR_XOR = 0x0e,
7673
  RR_NOT = 0x0f,
7674
  RR_MFHI = 0x10,
7675
  RR_CNVT = 0x11,
7676
  RR_MFLO = 0x12,
7677
  RR_DSRA = 0x13,
7678
  RR_DSLLV = 0x14,
7679
  RR_DSRLV = 0x16,
7680
  RR_DSRAV = 0x17,
7681
  RR_MULT = 0x18,
7682
  RR_MULTU = 0x19,
7683
  RR_DIV = 0x1a,
7684
  RR_DIVU = 0x1b,
7685
  RR_DMULT = 0x1c,
7686
  RR_DMULTU = 0x1d,
7687
  RR_DDIV = 0x1e,
7688
  RR_DDIVU = 0x1f
7689
};
7690

    
7691
/* I64 funct field */
7692
enum {
7693
  I64_LDSP = 0x0,
7694
  I64_SDSP = 0x1,
7695
  I64_SDRASP = 0x2,
7696
  I64_DADJSP = 0x3,
7697
  I64_LDPC = 0x4,
7698
  I64_DADDIU5 = 0x5,
7699
  I64_DADDIUPC = 0x6,
7700
  I64_DADDIUSP = 0x7
7701
};
7702

    
7703
/* RR ry field for CNVT */
7704
enum {
7705
  RR_RY_CNVT_ZEB = 0x0,
7706
  RR_RY_CNVT_ZEH = 0x1,
7707
  RR_RY_CNVT_ZEW = 0x2,
7708
  RR_RY_CNVT_SEB = 0x4,
7709
  RR_RY_CNVT_SEH = 0x5,
7710
  RR_RY_CNVT_SEW = 0x6,
7711
};
7712

    
7713
static int xlat (int r)
7714
{
7715
  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
7716

    
7717
  return map[r];
7718
}
7719

    
7720
static void gen_mips16_save (DisasContext *ctx,
7721
                             int xsregs, int aregs,
7722
                             int do_ra, int do_s0, int do_s1,
7723
                             int framesize)
7724
{
7725
    TCGv t0 = tcg_temp_new();
7726
    TCGv t1 = tcg_temp_new();
7727
    int args, astatic;
7728

    
7729
    switch (aregs) {
7730
    case 0:
7731
    case 1:
7732
    case 2:
7733
    case 3:
7734
    case 11:
7735
        args = 0;
7736
        break;
7737
    case 4:
7738
    case 5:
7739
    case 6:
7740
    case 7:
7741
        args = 1;
7742
        break;
7743
    case 8:
7744
    case 9:
7745
    case 10:
7746
        args = 2;
7747
        break;
7748
    case 12:
7749
    case 13:
7750
        args = 3;
7751
        break;
7752
    case 14:
7753
        args = 4;
7754
        break;
7755
    default:
7756
        generate_exception(ctx, EXCP_RI);
7757
        return;
7758
    }
7759

    
7760
    switch (args) {
7761
    case 4:
7762
        gen_base_offset_addr(ctx, t0, 29, 12);
7763
        gen_load_gpr(t1, 7);
7764
        op_ldst_sw(t1, t0, ctx);
7765
        /* Fall through */
7766
    case 3:
7767
        gen_base_offset_addr(ctx, t0, 29, 8);
7768
        gen_load_gpr(t1, 6);
7769
        op_ldst_sw(t1, t0, ctx);
7770
        /* Fall through */
7771
    case 2:
7772
        gen_base_offset_addr(ctx, t0, 29, 4);
7773
        gen_load_gpr(t1, 5);
7774
        op_ldst_sw(t1, t0, ctx);
7775
        /* Fall through */
7776
    case 1:
7777
        gen_base_offset_addr(ctx, t0, 29, 0);
7778
        gen_load_gpr(t1, 4);
7779
        op_ldst_sw(t1, t0, ctx);
7780
    }
7781

    
7782
    gen_load_gpr(t0, 29);
7783

    
7784
#define DECR_AND_STORE(reg) do {                \
7785
        tcg_gen_subi_tl(t0, t0, 4);             \
7786
        gen_load_gpr(t1, reg);                  \
7787
        op_ldst_sw(t1, t0, ctx);                \
7788
    } while (0)
7789

    
7790
    if (do_ra) {
7791
        DECR_AND_STORE(31);
7792
    }
7793

    
7794
    switch (xsregs) {
7795
    case 7:
7796
        DECR_AND_STORE(30);
7797
        /* Fall through */
7798
    case 6:
7799
        DECR_AND_STORE(23);
7800
        /* Fall through */
7801
    case 5:
7802
        DECR_AND_STORE(22);
7803
        /* Fall through */
7804
    case 4:
7805
        DECR_AND_STORE(21);
7806
        /* Fall through */
7807
    case 3:
7808
        DECR_AND_STORE(20);
7809
        /* Fall through */
7810
    case 2:
7811
        DECR_AND_STORE(19);
7812
        /* Fall through */
7813
    case 1:
7814
        DECR_AND_STORE(18);
7815
    }
7816

    
7817
    if (do_s1) {
7818
        DECR_AND_STORE(17);
7819
    }
7820
    if (do_s0) {
7821
        DECR_AND_STORE(16);
7822
    }
7823

    
7824
    switch (aregs) {
7825
    case 0:
7826
    case 4:
7827
    case 8:
7828
    case 12:
7829
    case 14:
7830
        astatic = 0;
7831
        break;
7832
    case 1:
7833
    case 5:
7834
    case 9:
7835
    case 13:
7836
        astatic = 1;
7837
        break;
7838
    case 2:
7839
    case 6:
7840
    case 10:
7841
        astatic = 2;
7842
        break;
7843
    case 3:
7844
    case 7:
7845
        astatic = 3;
7846
        break;
7847
    case 11:
7848
        astatic = 4;
7849
        break;
7850
    default:
7851
        generate_exception(ctx, EXCP_RI);
7852
        return;
7853
    }
7854

    
7855
    if (astatic > 0) {
7856
        DECR_AND_STORE(7);
7857
        if (astatic > 1) {
7858
            DECR_AND_STORE(6);
7859
            if (astatic > 2) {
7860
                DECR_AND_STORE(5);
7861
                if (astatic > 3) {
7862
                    DECR_AND_STORE(4);
7863
                }
7864
            }
7865
        }
7866
    }
7867
#undef DECR_AND_STORE
7868

    
7869
    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
7870
    tcg_temp_free(t0);
7871
    tcg_temp_free(t1);
7872
}
7873

    
7874
static void gen_mips16_restore (DisasContext *ctx,
7875
                                int xsregs, int aregs,
7876
                                int do_ra, int do_s0, int do_s1,
7877
                                int framesize)
7878
{
7879
    int astatic;
7880
    TCGv t0 = tcg_temp_new();
7881
    TCGv t1 = tcg_temp_new();
7882

    
7883
    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
7884

    
7885
#define DECR_AND_LOAD(reg) do {                 \
7886
        tcg_gen_subi_tl(t0, t0, 4);             \
7887
        op_ldst_lw(t1, t0, ctx);                \
7888
        gen_store_gpr(t1, reg);                 \
7889
    } while (0)
7890

    
7891
    if (do_ra) {
7892
        DECR_AND_LOAD(31);
7893
    }
7894

    
7895
    switch (xsregs) {
7896
    case 7:
7897
        DECR_AND_LOAD(30);
7898
        /* Fall through */
7899
    case 6:
7900
        DECR_AND_LOAD(23);
7901
        /* Fall through */
7902
    case 5:
7903
        DECR_AND_LOAD(22);
7904
        /* Fall through */
7905
    case 4:
7906
        DECR_AND_LOAD(21);
7907
        /* Fall through */
7908
    case 3:
7909
        DECR_AND_LOAD(20);
7910
        /* Fall through */
7911
    case 2:
7912
        DECR_AND_LOAD(19);
7913
        /* Fall through */
7914
    case 1:
7915
        DECR_AND_LOAD(18);
7916
    }
7917

    
7918
    if (do_s1) {
7919
        DECR_AND_LOAD(17);
7920
    }
7921
    if (do_s0) {
7922
        DECR_AND_LOAD(16);
7923
    }
7924

    
7925
    switch (aregs) {
7926
    case 0:
7927
    case 4:
7928
    case 8:
7929
    case 12:
7930
    case 14:
7931
        astatic = 0;
7932
        break;
7933
    case 1:
7934
    case 5:
7935
    case 9:
7936
    case 13:
7937
        astatic = 1;
7938
        break;
7939
    case 2:
7940
    case 6:
7941
    case 10:
7942
        astatic = 2;
7943
        break;
7944
    case 3:
7945
    case 7:
7946
        astatic = 3;
7947
        break;
7948
    case 11:
7949
        astatic = 4;
7950
        break;
7951
    default:
7952
        generate_exception(ctx, EXCP_RI);
7953
        return;
7954
    }
7955

    
7956
    if (astatic > 0) {
7957
        DECR_AND_LOAD(7);
7958
        if (astatic > 1) {
7959
            DECR_AND_LOAD(6);
7960
            if (astatic > 2) {
7961
                DECR_AND_LOAD(5);
7962
                if (astatic > 3) {
7963
                    DECR_AND_LOAD(4);
7964
                }
7965
            }
7966
        }
7967
    }
7968
#undef DECR_AND_LOAD
7969

    
7970
    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
7971
    tcg_temp_free(t0);
7972
    tcg_temp_free(t1);
7973
}
7974

    
7975
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
7976
                         int is_64_bit, int extended)
7977
{
7978
    TCGv t0;
7979

    
7980
    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
7981
        generate_exception(ctx, EXCP_RI);
7982
        return;
7983
    }
7984

    
7985
    t0 = tcg_temp_new();
7986

    
7987
    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
7988
    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
7989
    if (!is_64_bit) {
7990
        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
7991
    }
7992

    
7993
    tcg_temp_free(t0);
7994
}
7995

    
7996
#if defined(TARGET_MIPS64)
7997
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
7998
                               int ry, int funct, int16_t offset,
7999
                               int extended)
8000
{
8001
    switch (funct) {
8002
    case I64_LDSP:
8003
        check_mips_64(ctx);
8004
        offset = extended ? offset : offset << 3;
8005
        gen_ldst(ctx, OPC_LD, ry, 29, offset);
8006
        break;
8007
    case I64_SDSP:
8008
        check_mips_64(ctx);
8009
        offset = extended ? offset : offset << 3;
8010
        gen_ldst(ctx, OPC_SD, ry, 29, offset);
8011
        break;
8012
    case I64_SDRASP:
8013
        check_mips_64(ctx);
8014
        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8015
        gen_ldst(ctx, OPC_SD, 31, 29, offset);
8016
        break;
8017
    case I64_DADJSP:
8018
        check_mips_64(ctx);
8019
        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8020
        gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8021
        break;
8022
    case I64_LDPC:
8023
        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8024
            generate_exception(ctx, EXCP_RI);
8025
        } else {
8026
            offset = extended ? offset : offset << 3;
8027
            gen_ldst(ctx, OPC_LDPC, ry, 0, offset);
8028
        }
8029
        break;
8030
    case I64_DADDIU5:
8031
        check_mips_64(ctx);
8032
        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8033
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8034
        break;
8035
    case I64_DADDIUPC:
8036
        check_mips_64(ctx);
8037
        offset = extended ? offset : offset << 2;
8038
        gen_addiupc(ctx, ry, offset, 1, extended);
8039
        break;
8040
    case I64_DADDIUSP:
8041
        check_mips_64(ctx);
8042
        offset = extended ? offset : offset << 2;
8043
        gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8044
        break;
8045
    }
8046
}
8047
#endif
8048

    
8049
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8050
                                       int *is_branch)
8051
{
8052
    int extend = lduw_code(ctx->pc + 2);
8053
    int op, rx, ry, funct, sa;
8054
    int16_t imm, offset;
8055

    
8056
    ctx->opcode = (ctx->opcode << 16) | extend;
8057
    op = (ctx->opcode >> 11) & 0x1f;
8058
    sa = (ctx->opcode >> 22) & 0x1f;
8059
    funct = (ctx->opcode >> 8) & 0x7;
8060
    rx = xlat((ctx->opcode >> 8) & 0x7);
8061
    ry = xlat((ctx->opcode >> 5) & 0x7);
8062
    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8063
                              | ((ctx->opcode >> 21) & 0x3f) << 5
8064
                              | (ctx->opcode & 0x1f));
8065

    
8066
    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
8067
       counterparts.  */
8068
    switch (op) {
8069
    case M16_OPC_ADDIUSP:
8070
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8071
        break;
8072
    case M16_OPC_ADDIUPC:
8073
        gen_addiupc(ctx, rx, imm, 0, 1);
8074
        break;
8075
    case M16_OPC_B:
8076
        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8077
        /* No delay slot, so just process as a normal instruction */
8078
        break;
8079
    case M16_OPC_BEQZ:
8080
        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8081
        /* No delay slot, so just process as a normal instruction */
8082
        break;
8083
    case M16_OPC_BNEQZ:
8084
        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8085
        /* No delay slot, so just process as a normal instruction */
8086
        break;
8087
    case M16_OPC_SHIFT:
8088
        switch (ctx->opcode & 0x3) {
8089
        case 0x0:
8090
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8091
            break;
8092
        case 0x1:
8093
#if defined(TARGET_MIPS64)
8094
            check_mips_64(ctx);
8095
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8096
#else
8097
            generate_exception(ctx, EXCP_RI);
8098
#endif
8099
            break;
8100
        case 0x2:
8101
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8102
            break;
8103
        case 0x3:
8104
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8105
            break;
8106
        }
8107
        break;
8108
#if defined(TARGET_MIPS64)
8109
    case M16_OPC_LD:
8110
            check_mips_64(ctx);
8111
        gen_ldst(ctx, OPC_LD, ry, rx, offset);
8112
        break;
8113
#endif
8114
    case M16_OPC_RRIA:
8115
        imm = ctx->opcode & 0xf;
8116
        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8117
        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8118
        imm = (int16_t) (imm << 1) >> 1;
8119
        if ((ctx->opcode >> 4) & 0x1) {
8120
#if defined(TARGET_MIPS64)
8121
            check_mips_64(ctx);
8122
            gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8123
#else
8124
            generate_exception(ctx, EXCP_RI);
8125
#endif
8126
        } else {
8127
            gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8128
        }
8129
        break;
8130
    case M16_OPC_ADDIU8:
8131
        gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8132
        break;
8133
    case M16_OPC_SLTI:
8134
        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8135
        break;
8136
    case M16_OPC_SLTIU:
8137
        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8138
        break;
8139
    case M16_OPC_I8:
8140
        switch (funct) {
8141
        case I8_BTEQZ:
8142
            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8143
            break;
8144
        case I8_BTNEZ:
8145
            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8146
            break;
8147
        case I8_SWRASP:
8148
            gen_ldst(ctx, OPC_SW, 31, 29, imm);
8149
            break;
8150
        case I8_ADJSP:
8151
            gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8152
            break;
8153
        case I8_SVRS:
8154
            {
8155
                int xsregs = (ctx->opcode >> 24) & 0x7;
8156
                int aregs = (ctx->opcode >> 16) & 0xf;
8157
                int do_ra = (ctx->opcode >> 6) & 0x1;
8158
                int do_s0 = (ctx->opcode >> 5) & 0x1;
8159
                int do_s1 = (ctx->opcode >> 4) & 0x1;
8160
                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8161
                                 | (ctx->opcode & 0xf)) << 3;
8162

    
8163
                if (ctx->opcode & (1 << 7)) {
8164
                    gen_mips16_save(ctx, xsregs, aregs,
8165
                                    do_ra, do_s0, do_s1,
8166
                                    framesize);
8167
                } else {
8168
                    gen_mips16_restore(ctx, xsregs, aregs,
8169
                                       do_ra, do_s0, do_s1,
8170
                                       framesize);
8171
                }
8172
            }
8173
            break;
8174
        default:
8175
            generate_exception(ctx, EXCP_RI);
8176
            break;
8177
        }
8178
        break;
8179
    case M16_OPC_LI:
8180
        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8181
        break;
8182
    case M16_OPC_CMPI:
8183
        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8184
        break;
8185
#if defined(TARGET_MIPS64)
8186
    case M16_OPC_SD:
8187
        gen_ldst(ctx, OPC_SD, ry, rx, offset);
8188
        break;
8189
#endif
8190
    case M16_OPC_LB:
8191
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8192
        break;
8193
    case M16_OPC_LH:
8194
        gen_ldst(ctx, OPC_LH, ry, rx, offset);
8195
        break;
8196
    case M16_OPC_LWSP:
8197
        gen_ldst(ctx, OPC_LW, rx, 29, offset);
8198
        break;
8199
    case M16_OPC_LW:
8200
        gen_ldst(ctx, OPC_LW, ry, rx, offset);
8201
        break;
8202
    case M16_OPC_LBU:
8203
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8204
        break;
8205
    case M16_OPC_LHU:
8206
        gen_ldst(ctx, OPC_LHU, ry, rx, offset);
8207
        break;
8208
    case M16_OPC_LWPC:
8209
        gen_ldst(ctx, OPC_LWPC, rx, 0, offset);
8210
        break;
8211
#if defined(TARGET_MIPS64)
8212
    case M16_OPC_LWU:
8213
        gen_ldst(ctx, OPC_LWU, ry, rx, offset);
8214
        break;
8215
#endif
8216
    case M16_OPC_SB:
8217
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8218
        break;
8219
    case M16_OPC_SH:
8220
        gen_ldst(ctx, OPC_SH, ry, rx, offset);
8221
        break;
8222
    case M16_OPC_SWSP:
8223
        gen_ldst(ctx, OPC_SW, rx, 29, offset);
8224
        break;
8225
    case M16_OPC_SW:
8226
        gen_ldst(ctx, OPC_SW, ry, rx, offset);
8227
        break;
8228
#if defined(TARGET_MIPS64)
8229
    case M16_OPC_I64:
8230
        decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8231
        break;
8232
#endif
8233
    default:
8234
        generate_exception(ctx, EXCP_RI);
8235
        break;
8236
    }
8237

    
8238
    return 4;
8239
}
8240

    
8241
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8242
                              int *is_branch)
8243
{
8244
    int rx, ry;
8245
    int sa;
8246
    int op, cnvt_op, op1, offset;
8247
    int funct;
8248
    int n_bytes;
8249

    
8250
    op = (ctx->opcode >> 11) & 0x1f;
8251
    sa = (ctx->opcode >> 2) & 0x7;
8252
    sa = sa == 0 ? 8 : sa;
8253
    rx = xlat((ctx->opcode >> 8) & 0x7);
8254
    cnvt_op = (ctx->opcode >> 5) & 0x7;
8255
    ry = xlat((ctx->opcode >> 5) & 0x7);
8256
    op1 = offset = ctx->opcode & 0x1f;
8257

    
8258
    n_bytes = 2;
8259

    
8260
    switch (op) {
8261
    case M16_OPC_ADDIUSP:
8262
        {
8263
            int16_t imm = ((uint8_t) ctx->opcode) << 2;
8264

    
8265
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8266
        }
8267
        break;
8268
    case M16_OPC_ADDIUPC:
8269
        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8270
        break;
8271
    case M16_OPC_B:
8272
        offset = (ctx->opcode & 0x7ff) << 1;
8273
        offset = (int16_t)(offset << 4) >> 4;
8274
        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8275
        /* No delay slot, so just process as a normal instruction */
8276
        break;
8277
    case M16_OPC_JAL:
8278
        offset = lduw_code(ctx->pc + 2);
8279
        offset = (((ctx->opcode & 0x1f) << 21)
8280
                  | ((ctx->opcode >> 5) & 0x1f) << 16
8281
                  | offset) << 2;
8282
        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
8283
        gen_compute_branch(ctx, op, 4, rx, ry, offset);
8284
        n_bytes = 4;
8285
        *is_branch = 1;
8286
        break;
8287
    case M16_OPC_BEQZ:
8288
        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8289
        /* No delay slot, so just process as a normal instruction */
8290
        break;
8291
    case M16_OPC_BNEQZ:
8292
        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8293
        /* No delay slot, so just process as a normal instruction */
8294
        break;
8295
    case M16_OPC_SHIFT:
8296
        switch (ctx->opcode & 0x3) {
8297
        case 0x0:
8298
            gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8299
            break;
8300
        case 0x1:
8301
#if defined(TARGET_MIPS64)
8302
            check_mips_64(ctx);
8303
            gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8304
#else
8305
            generate_exception(ctx, EXCP_RI);
8306
#endif
8307
            break;
8308
        case 0x2:
8309
            gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8310
            break;
8311
        case 0x3:
8312
            gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8313
            break;
8314
        }
8315
        break;
8316
#if defined(TARGET_MIPS64)
8317
    case M16_OPC_LD:
8318
        check_mips_64(ctx);
8319
        gen_ldst(ctx, OPC_LD, ry, rx, offset << 3);
8320
        break;
8321
#endif
8322
    case M16_OPC_RRIA:
8323
        {
8324
            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8325

    
8326
            if ((ctx->opcode >> 4) & 1) {
8327
#if defined(TARGET_MIPS64)
8328
                check_mips_64(ctx);
8329
                gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8330
#else
8331
                generate_exception(ctx, EXCP_RI);
8332
#endif
8333
            } else {
8334
                gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8335
            }
8336
        }
8337
        break;
8338
    case M16_OPC_ADDIU8:
8339
        {
8340
            int16_t imm = (int8_t) ctx->opcode;
8341

    
8342
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8343
        }
8344
        break;
8345
    case M16_OPC_SLTI:
8346
        {
8347
            int16_t imm = (uint8_t) ctx->opcode;
8348

    
8349
            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8350
        }
8351
        break;
8352
    case M16_OPC_SLTIU:
8353
        {
8354
            int16_t imm = (uint8_t) ctx->opcode;
8355

    
8356
            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8357
        }
8358
        break;
8359
    case M16_OPC_I8:
8360
        {
8361
            int reg32;
8362

    
8363
            funct = (ctx->opcode >> 8) & 0x7;
8364
            switch (funct) {
8365
            case I8_BTEQZ:
8366
                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8367
                                   ((int8_t)ctx->opcode) << 1);
8368
                break;
8369
            case I8_BTNEZ:
8370
                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8371
                                   ((int8_t)ctx->opcode) << 1);
8372
                break;
8373
            case I8_SWRASP:
8374
                gen_ldst(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8375
                break;
8376
            case I8_ADJSP:
8377
                gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8378
                              ((int8_t)ctx->opcode) << 3);
8379
                break;
8380
            case I8_SVRS:
8381
                {
8382
                    int do_ra = ctx->opcode & (1 << 6);
8383
                    int do_s0 = ctx->opcode & (1 << 5);
8384
                    int do_s1 = ctx->opcode & (1 << 4);
8385
                    int framesize = ctx->opcode & 0xf;
8386

    
8387
                    if (framesize == 0) {
8388
                        framesize = 128;
8389
                    } else {
8390
                        framesize = framesize << 3;
8391
                    }
8392

    
8393
                    if (ctx->opcode & (1 << 7)) {
8394
                        gen_mips16_save(ctx, 0, 0,
8395
                                        do_ra, do_s0, do_s1, framesize);
8396
                    } else {
8397
                        gen_mips16_restore(ctx, 0, 0,
8398
                                           do_ra, do_s0, do_s1, framesize);
8399
                    }
8400
                }
8401
                break;
8402
            case I8_MOV32R:
8403
                {
8404
                    int rz = xlat(ctx->opcode & 0x7);
8405

    
8406
                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8407
                        ((ctx->opcode >> 5) & 0x7);
8408
                    gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8409
                }
8410
                break;
8411
            case I8_MOVR32:
8412
                reg32 = ctx->opcode & 0x1f;
8413
                gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8414
                break;
8415
            default:
8416
                generate_exception(ctx, EXCP_RI);
8417
                break;
8418
            }
8419
        }
8420
        break;
8421
    case M16_OPC_LI:
8422
        {
8423
            int16_t imm = (uint8_t) ctx->opcode;
8424

    
8425
            gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8426
        }
8427
        break;
8428
    case M16_OPC_CMPI:
8429
        {
8430
            int16_t imm = (uint8_t) ctx->opcode;
8431

    
8432
            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8433
        }
8434
        break;
8435
#if defined(TARGET_MIPS64)
8436
    case M16_OPC_SD:
8437
        check_mips_64(ctx);
8438
        gen_ldst(ctx, OPC_SD, ry, rx, offset << 3);
8439
        break;
8440
#endif
8441
    case M16_OPC_LB:
8442
        gen_ldst(ctx, OPC_LB, ry, rx, offset);
8443
        break;
8444
    case M16_OPC_LH:
8445
        gen_ldst(ctx, OPC_LH, ry, rx, offset << 1);
8446
        break;
8447
    case M16_OPC_LWSP:
8448
        gen_ldst(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8449
        break;
8450
    case M16_OPC_LW:
8451
        gen_ldst(ctx, OPC_LW, ry, rx, offset << 2);
8452
        break;
8453
    case M16_OPC_LBU:
8454
        gen_ldst(ctx, OPC_LBU, ry, rx, offset);
8455
        break;
8456
    case M16_OPC_LHU:
8457
        gen_ldst(ctx, OPC_LHU, ry, rx, offset << 1);
8458
        break;
8459
    case M16_OPC_LWPC:
8460
        gen_ldst(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
8461
        break;
8462
#if defined (TARGET_MIPS64)
8463
    case M16_OPC_LWU:
8464
        check_mips_64(ctx);
8465
        gen_ldst(ctx, OPC_LWU, ry, rx, offset << 2);
8466
        break;
8467
#endif
8468
    case M16_OPC_SB:
8469
        gen_ldst(ctx, OPC_SB, ry, rx, offset);
8470
        break;
8471
    case M16_OPC_SH:
8472
        gen_ldst(ctx, OPC_SH, ry, rx, offset << 1);
8473
        break;
8474
    case M16_OPC_SWSP:
8475
        gen_ldst(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8476
        break;
8477
    case M16_OPC_SW:
8478
        gen_ldst(ctx, OPC_SW, ry, rx, offset << 2);
8479
        break;
8480
    case M16_OPC_RRR:
8481
        {
8482
            int rz = xlat((ctx->opcode >> 2) & 0x7);
8483
            int mips32_op;
8484

    
8485
            switch (ctx->opcode & 0x3) {
8486
            case RRR_ADDU:
8487
                mips32_op = OPC_ADDU;
8488
                break;
8489
            case RRR_SUBU:
8490
                mips32_op = OPC_SUBU;
8491
                break;
8492
#if defined(TARGET_MIPS64)
8493
            case RRR_DADDU:
8494
                mips32_op = OPC_DADDU;
8495
                check_mips_64(ctx);
8496
                break;
8497
            case RRR_DSUBU:
8498
                mips32_op = OPC_DSUBU;
8499
                check_mips_64(ctx);
8500
                break;
8501
#endif
8502
            default:
8503
                generate_exception(ctx, EXCP_RI);
8504
                goto done;
8505
            }
8506

    
8507
            gen_arith(env, ctx, mips32_op, rz, rx, ry);
8508
        done:
8509
            ;
8510
        }
8511
        break;
8512
    case M16_OPC_RR:
8513
        switch (op1) {
8514
        case RR_JR:
8515
            {
8516
                int nd = (ctx->opcode >> 7) & 0x1;
8517
                int link = (ctx->opcode >> 6) & 0x1;
8518
                int ra = (ctx->opcode >> 5) & 0x1;
8519

    
8520
                if (link) {
8521
                    op = nd ? OPC_JALRC : OPC_JALR;
8522
                } else {
8523
                    op = OPC_JR;
8524
                }
8525

    
8526
                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
8527
                if (!nd) {
8528
                    *is_branch = 1;
8529
                }
8530
            }
8531
            break;
8532
        case RR_SDBBP:
8533
            /* XXX: not clear which exception should be raised
8534
             *      when in debug mode...
8535
             */
8536
            check_insn(env, ctx, ISA_MIPS32);
8537
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8538
                generate_exception(ctx, EXCP_DBp);
8539
            } else {
8540
                generate_exception(ctx, EXCP_DBp);
8541
            }
8542
            break;
8543
        case RR_SLT:
8544
            gen_slt(env, OPC_SLT, 24, rx, ry);
8545
            break;
8546
        case RR_SLTU:
8547
            gen_slt(env, OPC_SLTU, 24, rx, ry);
8548
            break;
8549
        case RR_BREAK:
8550
            generate_exception(ctx, EXCP_BREAK);
8551
            break;
8552
        case RR_SLLV:
8553
            gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
8554
            break;
8555
        case RR_SRLV:
8556
            gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
8557
            break;
8558
        case RR_SRAV:
8559
            gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
8560
            break;
8561
#if defined (TARGET_MIPS64)
8562
        case RR_DSRL:
8563
            check_mips_64(ctx);
8564
            gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
8565
            break;
8566
#endif
8567
        case RR_CMP:
8568
            gen_logic(env, OPC_XOR, 24, rx, ry);
8569
            break;
8570
        case RR_NEG:
8571
            gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
8572
            break;
8573
        case RR_AND:
8574
            gen_logic(env, OPC_AND, rx, rx, ry);
8575
            break;
8576
        case RR_OR:
8577
            gen_logic(env, OPC_OR, rx, rx, ry);
8578
            break;
8579
        case RR_XOR:
8580
            gen_logic(env, OPC_XOR, rx, rx, ry);
8581
            break;
8582
        case RR_NOT:
8583
            gen_logic(env, OPC_NOR, rx, ry, 0);
8584
            break;
8585
        case RR_MFHI:
8586
            gen_HILO(ctx, OPC_MFHI, rx);
8587
            break;
8588
        case RR_CNVT:
8589
            switch (cnvt_op) {
8590
            case RR_RY_CNVT_ZEB:
8591
                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8592
                break;
8593
            case RR_RY_CNVT_ZEH:
8594
                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8595
                break;
8596
            case RR_RY_CNVT_SEB:
8597
                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8598
                break;
8599
            case RR_RY_CNVT_SEH:
8600
                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8601
                break;
8602
#if defined (TARGET_MIPS64)
8603
            case RR_RY_CNVT_ZEW:
8604
                check_mips_64(ctx);
8605
                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
8606
                break;
8607
            case RR_RY_CNVT_SEW:
8608
                check_mips_64(ctx);
8609
                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8610
                break;
8611
#endif
8612
            default:
8613
                generate_exception(ctx, EXCP_RI);
8614
                break;
8615
            }
8616
            break;
8617
        case RR_MFLO:
8618
            gen_HILO(ctx, OPC_MFLO, rx);
8619
            break;
8620
#if defined (TARGET_MIPS64)
8621
        case RR_DSRA:
8622
            check_mips_64(ctx);
8623
            gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
8624
            break;
8625
        case RR_DSLLV:
8626
            check_mips_64(ctx);
8627
            gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
8628
            break;
8629
        case RR_DSRLV:
8630
            check_mips_64(ctx);
8631
            gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
8632
            break;
8633
        case RR_DSRAV:
8634
            check_mips_64(ctx);
8635
            gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
8636
            break;
8637
#endif
8638
        case RR_MULT:
8639
            gen_muldiv(ctx, OPC_MULT, rx, ry);
8640
            break;
8641
        case RR_MULTU:
8642
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
8643
            break;
8644
        case RR_DIV:
8645
            gen_muldiv(ctx, OPC_DIV, rx, ry);
8646
            break;
8647
        case RR_DIVU:
8648
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
8649
            break;
8650
#if defined (TARGET_MIPS64)
8651
        case RR_DMULT:
8652
            check_mips_64(ctx);
8653
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
8654
            break;
8655
        case RR_DMULTU:
8656
            check_mips_64(ctx);
8657
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
8658
            break;
8659
        case RR_DDIV:
8660
            check_mips_64(ctx);
8661
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
8662
            break;
8663
        case RR_DDIVU:
8664
            check_mips_64(ctx);
8665
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
8666
            break;
8667
#endif
8668
        default:
8669
            generate_exception(ctx, EXCP_RI);
8670
            break;
8671
        }
8672
        break;
8673
    case M16_OPC_EXTEND:
8674
        decode_extended_mips16_opc(env, ctx, is_branch);
8675
        n_bytes = 4;
8676
        break;
8677
#if defined(TARGET_MIPS64)
8678
    case M16_OPC_I64:
8679
        funct = (ctx->opcode >> 8) & 0x7;
8680
        decode_i64_mips16(env, ctx, ry, funct, offset, 0);
8681
        break;
8682
#endif
8683
    default:
8684
        generate_exception(ctx, EXCP_RI);
8685
        break;
8686
    }
8687

    
8688
    return n_bytes;
8689
}
8690

    
8691
/* SmartMIPS extension to MIPS32 */
8692

    
8693
#if defined(TARGET_MIPS64)
8694

    
8695
/* MDMX extension to MIPS64 */
8696

    
8697
#endif
8698

    
8699
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
8700
{
8701
    int32_t offset;
8702
    int rs, rt, rd, sa;
8703
    uint32_t op, op1, op2;
8704
    int16_t imm;
8705

    
8706
    /* make sure instructions are on a word boundary */
8707
    if (ctx->pc & 0x3) {
8708
        env->CP0_BadVAddr = ctx->pc;
8709
        generate_exception(ctx, EXCP_AdEL);
8710
        return;
8711
    }
8712

    
8713
    /* Handle blikely not taken case */
8714
    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
8715
        int l1 = gen_new_label();
8716

    
8717
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
8718
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8719
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
8720
        gen_goto_tb(ctx, 1, ctx->pc + 4);
8721
        gen_set_label(l1);
8722
    }
8723

    
8724
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
8725
        tcg_gen_debug_insn_start(ctx->pc);
8726

    
8727
    op = MASK_OP_MAJOR(ctx->opcode);
8728
    rs = (ctx->opcode >> 21) & 0x1f;
8729
    rt = (ctx->opcode >> 16) & 0x1f;
8730
    rd = (ctx->opcode >> 11) & 0x1f;
8731
    sa = (ctx->opcode >> 6) & 0x1f;
8732
    imm = (int16_t)ctx->opcode;
8733
    switch (op) {
8734
    case OPC_SPECIAL:
8735
        op1 = MASK_SPECIAL(ctx->opcode);
8736
        switch (op1) {
8737
        case OPC_SLL:          /* Shift with immediate */
8738
        case OPC_SRA:
8739
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
8740
            break;
8741
        case OPC_SRL:
8742
            switch ((ctx->opcode >> 21) & 0x1f) {
8743
            case 1:
8744
                /* rotr is decoded as srl on non-R2 CPUs */
8745
                if (env->insn_flags & ISA_MIPS32R2) {
8746
                    op1 = OPC_ROTR;
8747
                }
8748
                /* Fallthrough */
8749
            case 0:
8750
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8751
                break;
8752
            default:
8753
                generate_exception(ctx, EXCP_RI);
8754
                break;
8755
            }
8756
            break;
8757
        case OPC_MOVN:         /* Conditional move */
8758
        case OPC_MOVZ:
8759
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8760
            gen_cond_move(env, op1, rd, rs, rt);
8761
            break;
8762
        case OPC_ADD ... OPC_SUBU:
8763
            gen_arith(env, ctx, op1, rd, rs, rt);
8764
            break;
8765
        case OPC_SLLV:         /* Shifts */
8766
        case OPC_SRAV:
8767
            gen_shift(env, ctx, op1, rd, rs, rt);
8768
            break;
8769
        case OPC_SRLV:
8770
            switch ((ctx->opcode >> 6) & 0x1f) {
8771
            case 1:
8772
                /* rotrv is decoded as srlv on non-R2 CPUs */
8773
                if (env->insn_flags & ISA_MIPS32R2) {
8774
                    op1 = OPC_ROTRV;
8775
                }
8776
                /* Fallthrough */
8777
            case 0:
8778
                gen_shift(env, ctx, op1, rd, rs, rt);
8779
                break;
8780
            default:
8781
                generate_exception(ctx, EXCP_RI);
8782
                break;
8783
            }
8784
            break;
8785
        case OPC_SLT:          /* Set on less than */
8786
        case OPC_SLTU:
8787
            gen_slt(env, op1, rd, rs, rt);
8788
            break;
8789
        case OPC_AND:          /* Logic*/
8790
        case OPC_OR:
8791
        case OPC_NOR:
8792
        case OPC_XOR:
8793
            gen_logic(env, op1, rd, rs, rt);
8794
            break;
8795
        case OPC_MULT ... OPC_DIVU:
8796
            if (sa) {
8797
                check_insn(env, ctx, INSN_VR54XX);
8798
                op1 = MASK_MUL_VR54XX(ctx->opcode);
8799
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
8800
            } else
8801
                gen_muldiv(ctx, op1, rs, rt);
8802
            break;
8803
        case OPC_JR ... OPC_JALR:
8804
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
8805
            *is_branch = 1;
8806
            break;
8807
        case OPC_TGE ... OPC_TEQ: /* Traps */
8808
        case OPC_TNE:
8809
            gen_trap(ctx, op1, rs, rt, -1);
8810
            break;
8811
        case OPC_MFHI:          /* Move from HI/LO */
8812
        case OPC_MFLO:
8813
            gen_HILO(ctx, op1, rd);
8814
            break;
8815
        case OPC_MTHI:
8816
        case OPC_MTLO:          /* Move to HI/LO */
8817
            gen_HILO(ctx, op1, rs);
8818
            break;
8819
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
8820
#ifdef MIPS_STRICT_STANDARD
8821
            MIPS_INVAL("PMON / selsl");
8822
            generate_exception(ctx, EXCP_RI);
8823
#else
8824
            gen_helper_0i(pmon, sa);
8825
#endif
8826
            break;
8827
        case OPC_SYSCALL:
8828
            generate_exception(ctx, EXCP_SYSCALL);
8829
            ctx->bstate = BS_STOP;
8830
            break;
8831
        case OPC_BREAK:
8832
            generate_exception(ctx, EXCP_BREAK);
8833
            break;
8834
        case OPC_SPIM:
8835
#ifdef MIPS_STRICT_STANDARD
8836
            MIPS_INVAL("SPIM");
8837
            generate_exception(ctx, EXCP_RI);
8838
#else
8839
           /* Implemented as RI exception for now. */
8840
            MIPS_INVAL("spim (unofficial)");
8841
            generate_exception(ctx, EXCP_RI);
8842
#endif
8843
            break;
8844
        case OPC_SYNC:
8845
            /* Treat as NOP. */
8846
            break;
8847

    
8848
        case OPC_MOVCI:
8849
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8850
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8851
                check_cp1_enabled(ctx);
8852
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
8853
                          (ctx->opcode >> 16) & 1);
8854
            } else {
8855
                generate_exception_err(ctx, EXCP_CpU, 1);
8856
            }
8857
            break;
8858

    
8859
#if defined(TARGET_MIPS64)
8860
       /* MIPS64 specific opcodes */
8861
        case OPC_DSLL:
8862
        case OPC_DSRA:
8863
        case OPC_DSLL32:
8864
        case OPC_DSRA32:
8865
            check_insn(env, ctx, ISA_MIPS3);
8866
            check_mips_64(ctx);
8867
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
8868
            break;
8869
        case OPC_DSRL:
8870
            switch ((ctx->opcode >> 21) & 0x1f) {
8871
            case 1:
8872
                /* drotr is decoded as dsrl on non-R2 CPUs */
8873
                if (env->insn_flags & ISA_MIPS32R2) {
8874
                    op1 = OPC_DROTR;
8875
                }
8876
                /* Fallthrough */
8877
            case 0:
8878
                check_insn(env, ctx, ISA_MIPS3);
8879
                check_mips_64(ctx);
8880
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8881
                break;
8882
            default:
8883
                generate_exception(ctx, EXCP_RI);
8884
                break;
8885
            }
8886
            break;
8887
        case OPC_DSRL32:
8888
            switch ((ctx->opcode >> 21) & 0x1f) {
8889
            case 1:
8890
                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
8891
                if (env->insn_flags & ISA_MIPS32R2) {
8892
                    op1 = OPC_DROTR32;
8893
                }
8894
                /* Fallthrough */
8895
            case 0:
8896
                check_insn(env, ctx, ISA_MIPS3);
8897
                check_mips_64(ctx);
8898
                gen_shift_imm(env, ctx, op1, rd, rt, sa);
8899
                break;
8900
            default:
8901
                generate_exception(ctx, EXCP_RI);
8902
                break;
8903
            }
8904
            break;
8905
        case OPC_DADD ... OPC_DSUBU:
8906
            check_insn(env, ctx, ISA_MIPS3);
8907
            check_mips_64(ctx);
8908
            gen_arith(env, ctx, op1, rd, rs, rt);
8909
            break;
8910
        case OPC_DSLLV:
8911
        case OPC_DSRAV:
8912
            check_insn(env, ctx, ISA_MIPS3);
8913
            check_mips_64(ctx);
8914
            gen_shift(env, ctx, op1, rd, rs, rt);
8915
            break;
8916
        case OPC_DSRLV:
8917
            switch ((ctx->opcode >> 6) & 0x1f) {
8918
            case 1:
8919
                /* drotrv is decoded as dsrlv on non-R2 CPUs */
8920
                if (env->insn_flags & ISA_MIPS32R2) {
8921
                    op1 = OPC_DROTRV;
8922
                }
8923
                /* Fallthrough */
8924
            case 0:
8925
                check_insn(env, ctx, ISA_MIPS3);
8926
                check_mips_64(ctx);
8927
                gen_shift(env, ctx, op1, rd, rs, rt);
8928
                break;
8929
            default:
8930
                generate_exception(ctx, EXCP_RI);
8931
                break;
8932
            }
8933
            break;
8934
        case OPC_DMULT ... OPC_DDIVU:
8935
            check_insn(env, ctx, ISA_MIPS3);
8936
            check_mips_64(ctx);
8937
            gen_muldiv(ctx, op1, rs, rt);
8938
            break;
8939
#endif
8940
        default:            /* Invalid */
8941
            MIPS_INVAL("special");
8942
            generate_exception(ctx, EXCP_RI);
8943
            break;
8944
        }
8945
        break;
8946
    case OPC_SPECIAL2:
8947
        op1 = MASK_SPECIAL2(ctx->opcode);
8948
        switch (op1) {
8949
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
8950
        case OPC_MSUB ... OPC_MSUBU:
8951
            check_insn(env, ctx, ISA_MIPS32);
8952
            gen_muldiv(ctx, op1, rs, rt);
8953
            break;
8954
        case OPC_MUL:
8955
            gen_arith(env, ctx, op1, rd, rs, rt);
8956
            break;
8957
        case OPC_CLO:
8958
        case OPC_CLZ:
8959
            check_insn(env, ctx, ISA_MIPS32);
8960
            gen_cl(ctx, op1, rd, rs);
8961
            break;
8962
        case OPC_SDBBP:
8963
            /* XXX: not clear which exception should be raised
8964
             *      when in debug mode...
8965
             */
8966
            check_insn(env, ctx, ISA_MIPS32);
8967
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8968
                generate_exception(ctx, EXCP_DBp);
8969
            } else {
8970
                generate_exception(ctx, EXCP_DBp);
8971
            }
8972
            /* Treat as NOP. */
8973
            break;
8974
#if defined(TARGET_MIPS64)
8975
        case OPC_DCLO:
8976
        case OPC_DCLZ:
8977
            check_insn(env, ctx, ISA_MIPS64);
8978
            check_mips_64(ctx);
8979
            gen_cl(ctx, op1, rd, rs);
8980
            break;
8981
#endif
8982
        default:            /* Invalid */
8983
            MIPS_INVAL("special2");
8984
            generate_exception(ctx, EXCP_RI);
8985
            break;
8986
        }
8987
        break;
8988
    case OPC_SPECIAL3:
8989
        op1 = MASK_SPECIAL3(ctx->opcode);
8990
        switch (op1) {
8991
        case OPC_EXT:
8992
        case OPC_INS:
8993
            check_insn(env, ctx, ISA_MIPS32R2);
8994
            gen_bitops(ctx, op1, rt, rs, sa, rd);
8995
            break;
8996
        case OPC_BSHFL:
8997
            check_insn(env, ctx, ISA_MIPS32R2);
8998
            op2 = MASK_BSHFL(ctx->opcode);
8999
            gen_bshfl(ctx, op2, rt, rd);
9000
            break;
9001
        case OPC_RDHWR:
9002
            check_insn(env, ctx, ISA_MIPS32R2);
9003
            {
9004
                TCGv t0 = tcg_temp_new();
9005

    
9006
                switch (rd) {
9007
                case 0:
9008
                    save_cpu_state(ctx, 1);
9009
                    gen_helper_rdhwr_cpunum(t0);
9010
                    gen_store_gpr(t0, rt);
9011
                    break;
9012
                case 1:
9013
                    save_cpu_state(ctx, 1);
9014
                    gen_helper_rdhwr_synci_step(t0);
9015
                    gen_store_gpr(t0, rt);
9016
                    break;
9017
                case 2:
9018
                    save_cpu_state(ctx, 1);
9019
                    gen_helper_rdhwr_cc(t0);
9020
                    gen_store_gpr(t0, rt);
9021
                    break;
9022
                case 3:
9023
                    save_cpu_state(ctx, 1);
9024
                    gen_helper_rdhwr_ccres(t0);
9025
                    gen_store_gpr(t0, rt);
9026
                    break;
9027
                case 29:
9028
#if defined(CONFIG_USER_ONLY)
9029
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
9030
                    gen_store_gpr(t0, rt);
9031
                    break;
9032
#else
9033
                    /* XXX: Some CPUs implement this in hardware.
9034
                       Not supported yet. */
9035
#endif
9036
                default:            /* Invalid */
9037
                    MIPS_INVAL("rdhwr");
9038
                    generate_exception(ctx, EXCP_RI);
9039
                    break;
9040
                }
9041
                tcg_temp_free(t0);
9042
            }
9043
            break;
9044
        case OPC_FORK:
9045
            check_insn(env, ctx, ASE_MT);
9046
            {
9047
                TCGv t0 = tcg_temp_new();
9048
                TCGv t1 = tcg_temp_new();
9049

    
9050
                gen_load_gpr(t0, rt);
9051
                gen_load_gpr(t1, rs);
9052
                gen_helper_fork(t0, t1);
9053
                tcg_temp_free(t0);
9054
                tcg_temp_free(t1);
9055
            }
9056
            break;
9057
        case OPC_YIELD:
9058
            check_insn(env, ctx, ASE_MT);
9059
            {
9060
                TCGv t0 = tcg_temp_new();
9061

    
9062
                save_cpu_state(ctx, 1);
9063
                gen_load_gpr(t0, rs);
9064
                gen_helper_yield(t0, t0);
9065
                gen_store_gpr(t0, rd);
9066
                tcg_temp_free(t0);
9067
            }
9068
            break;
9069
#if defined(TARGET_MIPS64)
9070
        case OPC_DEXTM ... OPC_DEXT:
9071
        case OPC_DINSM ... OPC_DINS:
9072
            check_insn(env, ctx, ISA_MIPS64R2);
9073
            check_mips_64(ctx);
9074
            gen_bitops(ctx, op1, rt, rs, sa, rd);
9075
            break;
9076
        case OPC_DBSHFL:
9077
            check_insn(env, ctx, ISA_MIPS64R2);
9078
            check_mips_64(ctx);
9079
            op2 = MASK_DBSHFL(ctx->opcode);
9080
            gen_bshfl(ctx, op2, rt, rd);
9081
            break;
9082
#endif
9083
        default:            /* Invalid */
9084
            MIPS_INVAL("special3");
9085
            generate_exception(ctx, EXCP_RI);
9086
            break;
9087
        }
9088
        break;
9089
    case OPC_REGIMM:
9090
        op1 = MASK_REGIMM(ctx->opcode);
9091
        switch (op1) {
9092
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
9093
        case OPC_BLTZAL ... OPC_BGEZALL:
9094
            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
9095
            *is_branch = 1;
9096
            break;
9097
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
9098
        case OPC_TNEI:
9099
            gen_trap(ctx, op1, rs, -1, imm);
9100
            break;
9101
        case OPC_SYNCI:
9102
            check_insn(env, ctx, ISA_MIPS32R2);
9103
            /* Treat as NOP. */
9104
            break;
9105
        default:            /* Invalid */
9106
            MIPS_INVAL("regimm");
9107
            generate_exception(ctx, EXCP_RI);
9108
            break;
9109
        }
9110
        break;
9111
    case OPC_CP0:
9112
        check_cp0_enabled(ctx);
9113
        op1 = MASK_CP0(ctx->opcode);
9114
        switch (op1) {
9115
        case OPC_MFC0:
9116
        case OPC_MTC0:
9117
        case OPC_MFTR:
9118
        case OPC_MTTR:
9119
#if defined(TARGET_MIPS64)
9120
        case OPC_DMFC0:
9121
        case OPC_DMTC0:
9122
#endif
9123
#ifndef CONFIG_USER_ONLY
9124
            gen_cp0(env, ctx, op1, rt, rd);
9125
#endif /* !CONFIG_USER_ONLY */
9126
            break;
9127
        case OPC_C0_FIRST ... OPC_C0_LAST:
9128
#ifndef CONFIG_USER_ONLY
9129
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
9130
#endif /* !CONFIG_USER_ONLY */
9131
            break;
9132
        case OPC_MFMC0:
9133
#ifndef CONFIG_USER_ONLY
9134
            {
9135
                TCGv t0 = tcg_temp_new();
9136

    
9137
                op2 = MASK_MFMC0(ctx->opcode);
9138
                switch (op2) {
9139
                case OPC_DMT:
9140
                    check_insn(env, ctx, ASE_MT);
9141
                    gen_helper_dmt(t0, t0);
9142
                    gen_store_gpr(t0, rt);
9143
                    break;
9144
                case OPC_EMT:
9145
                    check_insn(env, ctx, ASE_MT);
9146
                    gen_helper_emt(t0, t0);
9147
                    gen_store_gpr(t0, rt);
9148
                    break;
9149
                case OPC_DVPE:
9150
                    check_insn(env, ctx, ASE_MT);
9151
                    gen_helper_dvpe(t0, t0);
9152
                    gen_store_gpr(t0, rt);
9153
                    break;
9154
                case OPC_EVPE:
9155
                    check_insn(env, ctx, ASE_MT);
9156
                    gen_helper_evpe(t0, t0);
9157
                    gen_store_gpr(t0, rt);
9158
                    break;
9159
                case OPC_DI:
9160
                    check_insn(env, ctx, ISA_MIPS32R2);
9161
                    save_cpu_state(ctx, 1);
9162
                    gen_helper_di(t0);
9163
                    gen_store_gpr(t0, rt);
9164
                    /* Stop translation as we may have switched the execution mode */
9165
                    ctx->bstate = BS_STOP;
9166
                    break;
9167
                case OPC_EI:
9168
                    check_insn(env, ctx, ISA_MIPS32R2);
9169
                    save_cpu_state(ctx, 1);
9170
                    gen_helper_ei(t0);
9171
                    gen_store_gpr(t0, rt);
9172
                    /* Stop translation as we may have switched the execution mode */
9173
                    ctx->bstate = BS_STOP;
9174
                    break;
9175
                default:            /* Invalid */
9176
                    MIPS_INVAL("mfmc0");
9177
                    generate_exception(ctx, EXCP_RI);
9178
                    break;
9179
                }
9180
                tcg_temp_free(t0);
9181
            }
9182
#endif /* !CONFIG_USER_ONLY */
9183
            break;
9184
        case OPC_RDPGPR:
9185
            check_insn(env, ctx, ISA_MIPS32R2);
9186
            gen_load_srsgpr(rt, rd);
9187
            break;
9188
        case OPC_WRPGPR:
9189
            check_insn(env, ctx, ISA_MIPS32R2);
9190
            gen_store_srsgpr(rt, rd);
9191
            break;
9192
        default:
9193
            MIPS_INVAL("cp0");
9194
            generate_exception(ctx, EXCP_RI);
9195
            break;
9196
        }
9197
        break;
9198
    case OPC_ADDI: /* Arithmetic with immediate opcode */
9199
    case OPC_ADDIU:
9200
         gen_arith_imm(env, ctx, op, rt, rs, imm);
9201
         break;
9202
    case OPC_SLTI: /* Set on less than with immediate opcode */
9203
    case OPC_SLTIU:
9204
         gen_slt_imm(env, op, rt, rs, imm);
9205
         break;
9206
    case OPC_ANDI: /* Arithmetic with immediate opcode */
9207
    case OPC_LUI:
9208
    case OPC_ORI:
9209
    case OPC_XORI:
9210
         gen_logic_imm(env, op, rt, rs, imm);
9211
         break;
9212
    case OPC_J ... OPC_JAL: /* Jump */
9213
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
9214
         gen_compute_branch(ctx, op, 4, rs, rt, offset);
9215
         *is_branch = 1;
9216
         break;
9217
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
9218
    case OPC_BEQL ... OPC_BGTZL:
9219
         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
9220
         *is_branch = 1;
9221
         break;
9222
    case OPC_LB ... OPC_LWR: /* Load and stores */
9223
    case OPC_SB ... OPC_SW:
9224
    case OPC_SWR:
9225
    case OPC_LL:
9226
         gen_ldst(ctx, op, rt, rs, imm);
9227
         break;
9228
    case OPC_SC:
9229
         gen_st_cond(ctx, op, rt, rs, imm);
9230
         break;
9231
    case OPC_CACHE:
9232
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
9233
        /* Treat as NOP. */
9234
        break;
9235
    case OPC_PREF:
9236
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
9237
        /* Treat as NOP. */
9238
        break;
9239

    
9240
    /* Floating point (COP1). */
9241
    case OPC_LWC1:
9242
    case OPC_LDC1:
9243
    case OPC_SWC1:
9244
    case OPC_SDC1:
9245
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9246
            check_cp1_enabled(ctx);
9247
            gen_flt_ldst(ctx, op, rt, rs, imm);
9248
        } else {
9249
            generate_exception_err(ctx, EXCP_CpU, 1);
9250
        }
9251
        break;
9252

    
9253
    case OPC_CP1:
9254
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9255
            check_cp1_enabled(ctx);
9256
            op1 = MASK_CP1(ctx->opcode);
9257
            switch (op1) {
9258
            case OPC_MFHC1:
9259
            case OPC_MTHC1:
9260
                check_insn(env, ctx, ISA_MIPS32R2);
9261
            case OPC_MFC1:
9262
            case OPC_CFC1:
9263
            case OPC_MTC1:
9264
            case OPC_CTC1:
9265
                gen_cp1(ctx, op1, rt, rd);
9266
                break;
9267
#if defined(TARGET_MIPS64)
9268
            case OPC_DMFC1:
9269
            case OPC_DMTC1:
9270
                check_insn(env, ctx, ISA_MIPS3);
9271
                gen_cp1(ctx, op1, rt, rd);
9272
                break;
9273
#endif
9274
            case OPC_BC1ANY2:
9275
            case OPC_BC1ANY4:
9276
                check_cop1x(ctx);
9277
                check_insn(env, ctx, ASE_MIPS3D);
9278
                /* fall through */
9279
            case OPC_BC1:
9280
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
9281
                                    (rt >> 2) & 0x7, imm << 2);
9282
                *is_branch = 1;
9283
                break;
9284
            case OPC_S_FMT:
9285
            case OPC_D_FMT:
9286
            case OPC_W_FMT:
9287
            case OPC_L_FMT:
9288
            case OPC_PS_FMT:
9289
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
9290
                           (imm >> 8) & 0x7);
9291
                break;
9292
            default:
9293
                MIPS_INVAL("cp1");
9294
                generate_exception (ctx, EXCP_RI);
9295
                break;
9296
            }
9297
        } else {
9298
            generate_exception_err(ctx, EXCP_CpU, 1);
9299
        }
9300
        break;
9301

    
9302
    /* COP2.  */
9303
    case OPC_LWC2:
9304
    case OPC_LDC2:
9305
    case OPC_SWC2:
9306
    case OPC_SDC2:
9307
    case OPC_CP2:
9308
        /* COP2: Not implemented. */
9309
        generate_exception_err(ctx, EXCP_CpU, 2);
9310
        break;
9311

    
9312
    case OPC_CP3:
9313
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9314
            check_cp1_enabled(ctx);
9315
            op1 = MASK_CP3(ctx->opcode);
9316
            switch (op1) {
9317
            case OPC_LWXC1:
9318
            case OPC_LDXC1:
9319
            case OPC_LUXC1:
9320
            case OPC_SWXC1:
9321
            case OPC_SDXC1:
9322
            case OPC_SUXC1:
9323
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
9324
                break;
9325
            case OPC_PREFX:
9326
                /* Treat as NOP. */
9327
                break;
9328
            case OPC_ALNV_PS:
9329
            case OPC_MADD_S:
9330
            case OPC_MADD_D:
9331
            case OPC_MADD_PS:
9332
            case OPC_MSUB_S:
9333
            case OPC_MSUB_D:
9334
            case OPC_MSUB_PS:
9335
            case OPC_NMADD_S:
9336
            case OPC_NMADD_D:
9337
            case OPC_NMADD_PS:
9338
            case OPC_NMSUB_S:
9339
            case OPC_NMSUB_D:
9340
            case OPC_NMSUB_PS:
9341
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
9342
                break;
9343
            default:
9344
                MIPS_INVAL("cp3");
9345
                generate_exception (ctx, EXCP_RI);
9346
                break;
9347
            }
9348
        } else {
9349
            generate_exception_err(ctx, EXCP_CpU, 1);
9350
        }
9351
        break;
9352

    
9353
#if defined(TARGET_MIPS64)
9354
    /* MIPS64 opcodes */
9355
    case OPC_LWU:
9356
    case OPC_LDL ... OPC_LDR:
9357
    case OPC_SDL ... OPC_SDR:
9358
    case OPC_LLD:
9359
    case OPC_LD:
9360
    case OPC_SD:
9361
        check_insn(env, ctx, ISA_MIPS3);
9362
        check_mips_64(ctx);
9363
        gen_ldst(ctx, op, rt, rs, imm);
9364
        break;
9365
    case OPC_SCD:
9366
        check_insn(env, ctx, ISA_MIPS3);
9367
        check_mips_64(ctx);
9368
        gen_st_cond(ctx, op, rt, rs, imm);
9369
        break;
9370
    case OPC_DADDI:
9371
    case OPC_DADDIU:
9372
        check_insn(env, ctx, ISA_MIPS3);
9373
        check_mips_64(ctx);
9374
        gen_arith_imm(env, ctx, op, rt, rs, imm);
9375
        break;
9376
#endif
9377
    case OPC_JALX:
9378
        check_insn(env, ctx, ASE_MIPS16);
9379
        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
9380
        gen_compute_branch(ctx, op, 4, rs, rt, offset);
9381
        *is_branch = 1;
9382
        break;
9383
    case OPC_MDMX:
9384
        check_insn(env, ctx, ASE_MDMX);
9385
        /* MDMX: Not implemented. */
9386
    default:            /* Invalid */
9387
        MIPS_INVAL("major opcode");
9388
        generate_exception(ctx, EXCP_RI);
9389
        break;
9390
    }
9391
}
9392

    
9393
static inline void
9394
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
9395
                                int search_pc)
9396
{
9397
    DisasContext ctx;
9398
    target_ulong pc_start;
9399
    uint16_t *gen_opc_end;
9400
    CPUBreakpoint *bp;
9401
    int j, lj = -1;
9402
    int num_insns;
9403
    int max_insns;
9404
    int insn_bytes;
9405
    int is_branch;
9406

    
9407
    if (search_pc)
9408
        qemu_log("search pc %d\n", search_pc);
9409

    
9410
    pc_start = tb->pc;
9411
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9412
    ctx.pc = pc_start;
9413
    ctx.saved_pc = -1;
9414
    ctx.singlestep_enabled = env->singlestep_enabled;
9415
    ctx.tb = tb;
9416
    ctx.bstate = BS_NONE;
9417
    /* Restore delay slot state from the tb context.  */
9418
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
9419
    restore_cpu_state(env, &ctx);
9420
#ifdef CONFIG_USER_ONLY
9421
        ctx.mem_idx = MIPS_HFLAG_UM;
9422
#else
9423
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
9424
#endif
9425
    num_insns = 0;
9426
    max_insns = tb->cflags & CF_COUNT_MASK;
9427
    if (max_insns == 0)
9428
        max_insns = CF_COUNT_MASK;
9429
#ifdef DEBUG_DISAS
9430
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
9431
    /* FIXME: This may print out stale hflags from env... */
9432
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
9433
#endif
9434
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
9435
    gen_icount_start();
9436
    while (ctx.bstate == BS_NONE) {
9437
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9438
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9439
                if (bp->pc == ctx.pc) {
9440
                    save_cpu_state(&ctx, 1);
9441
                    ctx.bstate = BS_BRANCH;
9442
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
9443
                    /* Include the breakpoint location or the tb won't
9444
                     * be flushed when it must be.  */
9445
                    ctx.pc += 4;
9446
                    goto done_generating;
9447
                }
9448
            }
9449
        }
9450

    
9451
        if (search_pc) {
9452
            j = gen_opc_ptr - gen_opc_buf;
9453
            if (lj < j) {
9454
                lj++;
9455
                while (lj < j)
9456
                    gen_opc_instr_start[lj++] = 0;
9457
            }
9458
            gen_opc_pc[lj] = ctx.pc;
9459
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
9460
            gen_opc_instr_start[lj] = 1;
9461
            gen_opc_icount[lj] = num_insns;
9462
        }
9463
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9464
            gen_io_start();
9465

    
9466
        is_branch = 0;
9467
        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
9468
            ctx.opcode = ldl_code(ctx.pc);
9469
            insn_bytes = 4;
9470
            decode_opc(env, &ctx, &is_branch);
9471
        } else if (env->insn_flags & ASE_MIPS16) {
9472
            ctx.opcode = lduw_code(ctx.pc);
9473
            insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
9474
        } else {
9475
            generate_exception(&ctx, EXCP_RI);
9476
            break;
9477
        }
9478
        if (!is_branch) {
9479
            handle_delay_slot(env, &ctx, insn_bytes);
9480
        }
9481
        ctx.pc += insn_bytes;
9482

    
9483
        num_insns++;
9484

    
9485
        /* Execute a branch and its delay slot as a single instruction.
9486
           This is what GDB expects and is consistent with what the
9487
           hardware does (e.g. if a delay slot instruction faults, the
9488
           reported PC is the PC of the branch).  */
9489
        if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
9490
            break;
9491

    
9492
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
9493
            break;
9494

    
9495
        if (gen_opc_ptr >= gen_opc_end)
9496
            break;
9497

    
9498
        if (num_insns >= max_insns)
9499
            break;
9500

    
9501
        if (singlestep)
9502
            break;
9503
    }
9504
    if (tb->cflags & CF_LAST_IO)
9505
        gen_io_end();
9506
    if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
9507
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
9508
        gen_helper_0i(raise_exception, EXCP_DEBUG);
9509
    } else {
9510
        switch (ctx.bstate) {
9511
        case BS_STOP:
9512
            gen_helper_interrupt_restart();
9513
            gen_goto_tb(&ctx, 0, ctx.pc);
9514
            break;
9515
        case BS_NONE:
9516
            save_cpu_state(&ctx, 0);
9517
            gen_goto_tb(&ctx, 0, ctx.pc);
9518
            break;
9519
        case BS_EXCP:
9520
            gen_helper_interrupt_restart();
9521
            tcg_gen_exit_tb(0);
9522
            break;
9523
        case BS_BRANCH:
9524
        default:
9525
            break;
9526
        }
9527
    }
9528
done_generating:
9529
    gen_icount_end(tb, num_insns);
9530
    *gen_opc_ptr = INDEX_op_end;
9531
    if (search_pc) {
9532
        j = gen_opc_ptr - gen_opc_buf;
9533
        lj++;
9534
        while (lj <= j)
9535
            gen_opc_instr_start[lj++] = 0;
9536
    } else {
9537
        tb->size = ctx.pc - pc_start;
9538
        tb->icount = num_insns;
9539
    }
9540
#ifdef DEBUG_DISAS
9541
    LOG_DISAS("\n");
9542
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9543
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9544
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
9545
        qemu_log("\n");
9546
    }
9547
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
9548
#endif
9549
}
9550

    
9551
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9552
{
9553
    gen_intermediate_code_internal(env, tb, 0);
9554
}
9555

    
9556
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9557
{
9558
    gen_intermediate_code_internal(env, tb, 1);
9559
}
9560

    
9561
static void fpu_dump_state(CPUState *env, FILE *f,
9562
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
9563
                           int flags)
9564
{
9565
    int i;
9566
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
9567

    
9568
#define printfpr(fp)                                                        \
9569
    do {                                                                    \
9570
        if (is_fpu64)                                                       \
9571
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
9572
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
9573
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
9574
        else {                                                              \
9575
            fpr_t tmp;                                                      \
9576
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
9577
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
9578
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
9579
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
9580
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
9581
        }                                                                   \
9582
    } while(0)
9583

    
9584

    
9585
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
9586
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
9587
                get_float_exception_flags(&env->active_fpu.fp_status));
9588
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
9589
        fpu_fprintf(f, "%3s: ", fregnames[i]);
9590
        printfpr(&env->active_fpu.fpr[i]);
9591
    }
9592

    
9593
#undef printfpr
9594
}
9595

    
9596
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
9597
/* Debug help: The architecture requires 32bit code to maintain proper
9598
   sign-extended values on 64bit machines.  */
9599

    
9600
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
9601

    
9602
static void
9603
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
9604
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9605
                                int flags)
9606
{
9607
    int i;
9608

    
9609
    if (!SIGN_EXT_P(env->active_tc.PC))
9610
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
9611
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
9612
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
9613
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
9614
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
9615
    if (!SIGN_EXT_P(env->btarget))
9616
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
9617

    
9618
    for (i = 0; i < 32; i++) {
9619
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
9620
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
9621
    }
9622

    
9623
    if (!SIGN_EXT_P(env->CP0_EPC))
9624
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
9625
    if (!SIGN_EXT_P(env->lladdr))
9626
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
9627
}
9628
#endif
9629

    
9630
void cpu_dump_state (CPUState *env, FILE *f,
9631
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
9632
                     int flags)
9633
{
9634
    int i;
9635

    
9636
    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",
9637
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
9638
                env->hflags, env->btarget, env->bcond);
9639
    for (i = 0; i < 32; i++) {
9640
        if ((i & 3) == 0)
9641
            cpu_fprintf(f, "GPR%02d:", i);
9642
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
9643
        if ((i & 3) == 3)
9644
            cpu_fprintf(f, "\n");
9645
    }
9646

    
9647
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
9648
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
9649
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
9650
                env->CP0_Config0, env->CP0_Config1, env->lladdr);
9651
    if (env->hflags & MIPS_HFLAG_FPU)
9652
        fpu_dump_state(env, f, cpu_fprintf, flags);
9653
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
9654
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
9655
#endif
9656
}
9657

    
9658
static void mips_tcg_init(void)
9659
{
9660
    int i;
9661
    static int inited;
9662

    
9663
    /* Initialize various static tables. */
9664
    if (inited)
9665
        return;
9666

    
9667
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
9668
    TCGV_UNUSED(cpu_gpr[0]);
9669
    for (i = 1; i < 32; i++)
9670
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
9671
                                        offsetof(CPUState, active_tc.gpr[i]),
9672
                                        regnames[i]);
9673
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
9674
                                offsetof(CPUState, active_tc.PC), "PC");
9675
    for (i = 0; i < MIPS_DSP_ACC; i++) {
9676
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
9677
                                       offsetof(CPUState, active_tc.HI[i]),
9678
                                       regnames_HI[i]);
9679
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
9680
                                       offsetof(CPUState, active_tc.LO[i]),
9681
                                       regnames_LO[i]);
9682
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
9683
                                        offsetof(CPUState, active_tc.ACX[i]),
9684
                                        regnames_ACX[i]);
9685
    }
9686
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
9687
                                     offsetof(CPUState, active_tc.DSPControl),
9688
                                     "DSPControl");
9689
    bcond = tcg_global_mem_new(TCG_AREG0,
9690
                               offsetof(CPUState, bcond), "bcond");
9691
    btarget = tcg_global_mem_new(TCG_AREG0,
9692
                                 offsetof(CPUState, btarget), "btarget");
9693
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
9694
                                    offsetof(CPUState, hflags), "hflags");
9695

    
9696
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
9697
                                      offsetof(CPUState, active_fpu.fcr0),
9698
                                      "fcr0");
9699
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
9700
                                       offsetof(CPUState, active_fpu.fcr31),
9701
                                       "fcr31");
9702

    
9703
    /* register helpers */
9704
#define GEN_HELPER 2
9705
#include "helper.h"
9706

    
9707
    inited = 1;
9708
}
9709

    
9710
#include "translate_init.c"
9711

    
9712
CPUMIPSState *cpu_mips_init (const char *cpu_model)
9713
{
9714
    CPUMIPSState *env;
9715
    const mips_def_t *def;
9716

    
9717
    def = cpu_mips_find_by_name(cpu_model);
9718
    if (!def)
9719
        return NULL;
9720
    env = qemu_mallocz(sizeof(CPUMIPSState));
9721
    env->cpu_model = def;
9722
    env->cpu_model_str = cpu_model;
9723

    
9724
    cpu_exec_init(env);
9725
#ifndef CONFIG_USER_ONLY
9726
    mmu_init(env, def);
9727
#endif
9728
    fpu_init(env, def);
9729
    mvp_init(env, def);
9730
    mips_tcg_init();
9731
    cpu_reset(env);
9732
    qemu_init_vcpu(env);
9733
    return env;
9734
}
9735

    
9736
void cpu_reset (CPUMIPSState *env)
9737
{
9738
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
9739
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
9740
        log_cpu_state(env, 0);
9741
    }
9742

    
9743
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
9744
    tlb_flush(env, 1);
9745

    
9746
    /* Reset registers to their default values */
9747
    env->CP0_PRid = env->cpu_model->CP0_PRid;
9748
    env->CP0_Config0 = env->cpu_model->CP0_Config0;
9749
#ifdef TARGET_WORDS_BIGENDIAN
9750
    env->CP0_Config0 |= (1 << CP0C0_BE);
9751
#endif
9752
    env->CP0_Config1 = env->cpu_model->CP0_Config1;
9753
    env->CP0_Config2 = env->cpu_model->CP0_Config2;
9754
    env->CP0_Config3 = env->cpu_model->CP0_Config3;
9755
    env->CP0_Config6 = env->cpu_model->CP0_Config6;
9756
    env->CP0_Config7 = env->cpu_model->CP0_Config7;
9757
    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
9758
                                 << env->cpu_model->CP0_LLAddr_shift;
9759
    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
9760
    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
9761
    env->CCRes = env->cpu_model->CCRes;
9762
    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
9763
    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
9764
    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
9765
    env->current_tc = 0;
9766
    env->SEGBITS = env->cpu_model->SEGBITS;
9767
    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
9768
#if defined(TARGET_MIPS64)
9769
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
9770
        env->SEGMask |= 3ULL << 62;
9771
    }
9772
#endif
9773
    env->PABITS = env->cpu_model->PABITS;
9774
    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
9775
    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
9776
    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
9777
    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
9778
    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
9779
    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
9780
    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
9781
    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
9782
    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
9783
    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
9784
    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
9785
    env->insn_flags = env->cpu_model->insn_flags;
9786

    
9787
#if defined(CONFIG_USER_ONLY)
9788
    env->hflags = MIPS_HFLAG_UM;
9789
    /* Enable access to the SYNCI_Step register.  */
9790
    env->CP0_HWREna |= (1 << 1);
9791
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9792
        env->hflags |= MIPS_HFLAG_FPU;
9793
    }
9794
#ifdef TARGET_MIPS64
9795
    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
9796
        env->hflags |= MIPS_HFLAG_F64;
9797
    }
9798
#endif
9799
#else
9800
    if (env->hflags & MIPS_HFLAG_BMASK) {
9801
        /* If the exception was raised from a delay slot,
9802
           come back to the jump.  */
9803
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
9804
    } else {
9805
        env->CP0_ErrorEPC = env->active_tc.PC;
9806
    }
9807
    env->active_tc.PC = (int32_t)0xBFC00000;
9808
    env->CP0_Random = env->tlb->nb_tlb - 1;
9809
    env->tlb->tlb_in_use = env->tlb->nb_tlb;
9810
    env->CP0_Wired = 0;
9811
    /* SMP not implemented */
9812
    env->CP0_EBase = 0x80000000;
9813
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
9814
    /* vectored interrupts not implemented, timer on int 7,
9815
       no performance counters. */
9816
    env->CP0_IntCtl = 0xe0000000;
9817
    {
9818
        int i;
9819

    
9820
        for (i = 0; i < 7; i++) {
9821
            env->CP0_WatchLo[i] = 0;
9822
            env->CP0_WatchHi[i] = 0x80000000;
9823
        }
9824
        env->CP0_WatchLo[7] = 0;
9825
        env->CP0_WatchHi[7] = 0;
9826
    }
9827
    /* Count register increments in debug mode, EJTAG version 1 */
9828
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9829
    env->hflags = MIPS_HFLAG_CP0;
9830
#endif
9831
#if defined(TARGET_MIPS64)
9832
    if (env->cpu_model->insn_flags & ISA_MIPS3) {
9833
        env->hflags |= MIPS_HFLAG_64;
9834
    }
9835
#endif
9836
    env->exception_index = EXCP_NONE;
9837
}
9838

    
9839
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9840
                unsigned long searched_pc, int pc_pos, void *puc)
9841
{
9842
    env->active_tc.PC = gen_opc_pc[pc_pos];
9843
    env->hflags &= ~MIPS_HFLAG_BMASK;
9844
    env->hflags |= gen_opc_hflags[pc_pos];
9845
}