Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (360.9 kB)

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

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

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

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

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

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

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

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

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

    
199
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
200

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
490
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
491

    
492
#include "gen-icount.h"
493

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1028
        pc -= branch_bytes;
1029
    }
1030

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

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

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

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

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

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

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

    
1222

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

    
1230
    t0 = tcg_temp_local_new();
1231

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3767
    if (use_icount)
3768
        gen_io_start();
3769

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

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

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

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

    
4364
    switch (reg) {
4365
    case 0:
4366
        switch (sel) {
4367
        case 0:
4368
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4369
            rn = "Index";
4370
            break;
4371
        case 1:
4372
            check_insn(env, ctx, ASE_MT);
4373
            gen_helper_mfc0_mvpcontrol(arg);
4374
            rn = "MVPControl";
4375
            break;
4376
        case 2:
4377
            check_insn(env, ctx, ASE_MT);
4378
            gen_helper_mfc0_mvpconf0(arg);
4379
            rn = "MVPConf0";
4380
            break;
4381
        case 3:
4382
            check_insn(env, ctx, ASE_MT);
4383
            gen_helper_mfc0_mvpconf1(arg);
4384
            rn = "MVPConf1";
4385
            break;
4386
        default:
4387
            goto die;
4388
        }
4389
        break;
4390
    case 1:
4391
        switch (sel) {
4392
        case 0:
4393
            gen_helper_mfc0_random(arg);
4394
            rn = "Random";
4395
            break;
4396
        case 1:
4397
            check_insn(env, ctx, ASE_MT);
4398
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4399
            rn = "VPEControl";
4400
            break;
4401
        case 2:
4402
            check_insn(env, ctx, ASE_MT);
4403
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4404
            rn = "VPEConf0";
4405
            break;
4406
        case 3:
4407
            check_insn(env, ctx, ASE_MT);
4408
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4409
            rn = "VPEConf1";
4410
            break;
4411
        case 4:
4412
            check_insn(env, ctx, ASE_MT);
4413
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4414
            rn = "YQMask";
4415
            break;
4416
        case 5:
4417
            check_insn(env, ctx, ASE_MT);
4418
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4419
            rn = "VPESchedule";
4420
            break;
4421
        case 6:
4422
            check_insn(env, ctx, ASE_MT);
4423
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4424
            rn = "VPEScheFBack";
4425
            break;
4426
        case 7:
4427
            check_insn(env, ctx, ASE_MT);
4428
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4429
            rn = "VPEOpt";
4430
            break;
4431
        default:
4432
            goto die;
4433
        }
4434
        break;
4435
    case 2:
4436
        switch (sel) {
4437
        case 0:
4438
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4439
            rn = "EntryLo0";
4440
            break;
4441
        case 1:
4442
            check_insn(env, ctx, ASE_MT);
4443
            gen_helper_mfc0_tcstatus(arg);
4444
            rn = "TCStatus";
4445
            break;
4446
        case 2:
4447
            check_insn(env, ctx, ASE_MT);
4448
            gen_helper_mfc0_tcbind(arg);
4449
            rn = "TCBind";
4450
            break;
4451
        case 3:
4452
            check_insn(env, ctx, ASE_MT);
4453
            gen_helper_dmfc0_tcrestart(arg);
4454
            rn = "TCRestart";
4455
            break;
4456
        case 4:
4457
            check_insn(env, ctx, ASE_MT);
4458
            gen_helper_dmfc0_tchalt(arg);
4459
            rn = "TCHalt";
4460
            break;
4461
        case 5:
4462
            check_insn(env, ctx, ASE_MT);
4463
            gen_helper_dmfc0_tccontext(arg);
4464
            rn = "TCContext";
4465
            break;
4466
        case 6:
4467
            check_insn(env, ctx, ASE_MT);
4468
            gen_helper_dmfc0_tcschedule(arg);
4469
            rn = "TCSchedule";
4470
            break;
4471
        case 7:
4472
            check_insn(env, ctx, ASE_MT);
4473
            gen_helper_dmfc0_tcschefback(arg);
4474
            rn = "TCScheFBack";
4475
            break;
4476
        default:
4477
            goto die;
4478
        }
4479
        break;
4480
    case 3:
4481
        switch (sel) {
4482
        case 0:
4483
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4484
            rn = "EntryLo1";
4485
            break;
4486
        default:
4487
            goto die;
4488
        }
4489
        break;
4490
    case 4:
4491
        switch (sel) {
4492
        case 0:
4493
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4494
            rn = "Context";
4495
            break;
4496
        case 1:
4497
//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4498
            rn = "ContextConfig";
4499
//            break;
4500
        default:
4501
            goto die;
4502
        }
4503
        break;
4504
    case 5:
4505
        switch (sel) {
4506
        case 0:
4507
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4508
            rn = "PageMask";
4509
            break;
4510
        case 1:
4511
            check_insn(env, ctx, ISA_MIPS32R2);
4512
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4513
            rn = "PageGrain";
4514
            break;
4515
        default:
4516
            goto die;
4517
        }
4518
        break;
4519
    case 6:
4520
        switch (sel) {
4521
        case 0:
4522
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4523
            rn = "Wired";
4524
            break;
4525
        case 1:
4526
            check_insn(env, ctx, ISA_MIPS32R2);
4527
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4528
            rn = "SRSConf0";
4529
            break;
4530
        case 2:
4531
            check_insn(env, ctx, ISA_MIPS32R2);
4532
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4533
            rn = "SRSConf1";
4534
            break;
4535
        case 3:
4536
            check_insn(env, ctx, ISA_MIPS32R2);
4537
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4538
            rn = "SRSConf2";
4539
            break;
4540
        case 4:
4541
            check_insn(env, ctx, ISA_MIPS32R2);
4542
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4543
            rn = "SRSConf3";
4544
            break;
4545
        case 5:
4546
            check_insn(env, ctx, ISA_MIPS32R2);
4547
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4548
            rn = "SRSConf4";
4549
            break;
4550
        default:
4551
            goto die;
4552
        }
4553
        break;
4554
    case 7:
4555
        switch (sel) {
4556
        case 0:
4557
            check_insn(env, ctx, ISA_MIPS32R2);
4558
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4559
            rn = "HWREna";
4560
            break;
4561
        default:
4562
            goto die;
4563
        }
4564
        break;
4565
    case 8:
4566
        switch (sel) {
4567
        case 0:
4568
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4569
            rn = "BadVAddr";
4570
            break;
4571
        default:
4572
            goto die;
4573
        }
4574
        break;
4575
    case 9:
4576
        switch (sel) {
4577
        case 0:
4578
            /* Mark as an IO operation because we read the time.  */
4579
            if (use_icount)
4580
                gen_io_start();
4581
            gen_helper_mfc0_count(arg);
4582
            if (use_icount) {
4583
                gen_io_end();
4584
                ctx->bstate = BS_STOP;
4585
            }
4586
            rn = "Count";
4587
            break;
4588
        /* 6,7 are implementation dependent */
4589
        default:
4590
            goto die;
4591
        }
4592
        break;
4593
    case 10:
4594
        switch (sel) {
4595
        case 0:
4596
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4597
            rn = "EntryHi";
4598
            break;
4599
        default:
4600
            goto die;
4601
        }
4602
        break;
4603
    case 11:
4604
        switch (sel) {
4605
        case 0:
4606
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4607
            rn = "Compare";
4608
            break;
4609
        /* 6,7 are implementation dependent */
4610
        default:
4611
            goto die;
4612
        }
4613
        break;
4614
    case 12:
4615
        switch (sel) {
4616
        case 0:
4617
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4618
            rn = "Status";
4619
            break;
4620
        case 1:
4621
            check_insn(env, ctx, ISA_MIPS32R2);
4622
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4623
            rn = "IntCtl";
4624
            break;
4625
        case 2:
4626
            check_insn(env, ctx, ISA_MIPS32R2);
4627
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4628
            rn = "SRSCtl";
4629
            break;
4630
        case 3:
4631
            check_insn(env, ctx, ISA_MIPS32R2);
4632
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4633
            rn = "SRSMap";
4634
            break;
4635
        default:
4636
            goto die;
4637
        }
4638
        break;
4639
    case 13:
4640
        switch (sel) {
4641
        case 0:
4642
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4643
            rn = "Cause";
4644
            break;
4645
        default:
4646
            goto die;
4647
        }
4648
        break;
4649
    case 14:
4650
        switch (sel) {
4651
        case 0:
4652
            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4653
            rn = "EPC";
4654
            break;
4655
        default:
4656
            goto die;
4657
        }
4658
        break;
4659
    case 15:
4660
        switch (sel) {
4661
        case 0:
4662
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4663
            rn = "PRid";
4664
            break;
4665
        case 1:
4666
            check_insn(env, ctx, ISA_MIPS32R2);
4667
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4668
            rn = "EBase";
4669
            break;
4670
        default:
4671
            goto die;
4672
        }
4673
        break;
4674
    case 16:
4675
        switch (sel) {
4676
        case 0:
4677
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4678
            rn = "Config";
4679
            break;
4680
        case 1:
4681
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4682
            rn = "Config1";
4683
            break;
4684
        case 2:
4685
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4686
            rn = "Config2";
4687
            break;
4688
        case 3:
4689
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4690
            rn = "Config3";
4691
            break;
4692
       /* 6,7 are implementation dependent */
4693
        case 6:
4694
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4695
            rn = "Config6";
4696
            break;
4697
        case 7:
4698
            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4699
            rn = "Config7";
4700
            break;
4701
        default:
4702
            goto die;
4703
        }
4704
        break;
4705
    case 17:
4706
        switch (sel) {
4707
        case 0:
4708
            gen_helper_dmfc0_lladdr(arg);
4709
            rn = "LLAddr";
4710
            break;
4711
        default:
4712
            goto die;
4713
        }
4714
        break;
4715
    case 18:
4716
        switch (sel) {
4717
        case 0 ... 7:
4718
            gen_helper_1i(dmfc0_watchlo, arg, sel);
4719
            rn = "WatchLo";
4720
            break;
4721
        default:
4722
            goto die;
4723
        }
4