Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c239529e

History | View | Annotate | Download (217.3 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
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

    
36
//#define MIPS_DEBUG_DISAS
37
//#define MIPS_DEBUG_SIGN_EXTENSIONS
38
//#define MIPS_SINGLE_STEP
39

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

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

    
118
/* MIPS special opcodes */
119
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
120

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

    
186
    /* Special */
187
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
188
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
189
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
190
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
191
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
192

    
193
    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
194
    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
195
    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
196
    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
197
    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
198
    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
199
    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
200
};
201

    
202
/* Multiplication variants of the vr54xx. */
203
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
204

    
205
enum {
206
    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
207
    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
208
    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
209
    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
210
    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
211
    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
212
    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
213
    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
214
    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
215
    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
216
    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
217
    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
218
    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
219
    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
220
};
221

    
222
/* REGIMM (rt field) opcodes */
223
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
224

    
225
enum {
226
    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
227
    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
228
    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
229
    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
230
    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
231
    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
232
    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
233
    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
234
    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
235
    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
236
    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
237
    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
238
    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
239
    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
240
    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
241
};
242

    
243
/* Special2 opcodes */
244
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
245

    
246
enum {
247
    /* Multiply & xxx operations */
248
    OPC_MADD     = 0x00 | OPC_SPECIAL2,
249
    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
250
    OPC_MUL      = 0x02 | OPC_SPECIAL2,
251
    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
252
    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
253
    /* Misc */
254
    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
255
    OPC_CLO      = 0x21 | OPC_SPECIAL2,
256
    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
257
    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
258
    /* Special */
259
    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
260
};
261

    
262
/* Special3 opcodes */
263
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
264

    
265
enum {
266
    OPC_EXT      = 0x00 | OPC_SPECIAL3,
267
    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
268
    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
269
    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
270
    OPC_INS      = 0x04 | OPC_SPECIAL3,
271
    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
272
    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
273
    OPC_DINS     = 0x07 | OPC_SPECIAL3,
274
    OPC_FORK     = 0x08 | OPC_SPECIAL3,
275
    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
276
    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
277
    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
278
    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
279
};
280

    
281
/* BSHFL opcodes */
282
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
283

    
284
enum {
285
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
286
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
287
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
288
};
289

    
290
/* DBSHFL opcodes */
291
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
292

    
293
enum {
294
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
295
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
296
};
297

    
298
/* Coprocessor 0 (rs field) */
299
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
300

    
301
enum {
302
    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
303
    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
304
    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
305
    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
306
    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
307
    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
308
    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
309
    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
310
    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
311
    OPC_C0       = (0x10 << 21) | OPC_CP0,
312
    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
313
    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
314
};
315

    
316
/* MFMC0 opcodes */
317
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
318

    
319
enum {
320
    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
321
    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
322
    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
323
    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
324
    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
325
    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
326
};
327

    
328
/* Coprocessor 0 (with rs == C0) */
329
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
330

    
331
enum {
332
    OPC_TLBR     = 0x01 | OPC_C0,
333
    OPC_TLBWI    = 0x02 | OPC_C0,
334
    OPC_TLBWR    = 0x06 | OPC_C0,
335
    OPC_TLBP     = 0x08 | OPC_C0,
336
    OPC_RFE      = 0x10 | OPC_C0,
337
    OPC_ERET     = 0x18 | OPC_C0,
338
    OPC_DERET    = 0x1F | OPC_C0,
339
    OPC_WAIT     = 0x20 | OPC_C0,
340
};
341

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

    
345
enum {
346
    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
347
    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
348
    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
349
    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
350
    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
351
    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
352
    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
353
    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
354
    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
355
    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
356
    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
357
    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
358
    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
359
    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
360
    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
361
    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
362
    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
363
    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
364
};
365

    
366
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
367
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
368

    
369
enum {
370
    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
371
    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
372
    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
373
    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
374
};
375

    
376
enum {
377
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
378
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
379
};
380

    
381
enum {
382
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
383
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
384
};
385

    
386
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387

    
388
enum {
389
    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
390
    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
391
    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
392
    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
393
    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
394
    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
395
    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
396
    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
397
    OPC_BC2     = (0x08 << 21) | OPC_CP2,
398
};
399

    
400
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
401

    
402
enum {
403
    OPC_LWXC1   = 0x00 | OPC_CP3,
404
    OPC_LDXC1   = 0x01 | OPC_CP3,
405
    OPC_LUXC1   = 0x05 | OPC_CP3,
406
    OPC_SWXC1   = 0x08 | OPC_CP3,
407
    OPC_SDXC1   = 0x09 | OPC_CP3,
408
    OPC_SUXC1   = 0x0D | OPC_CP3,
409
    OPC_PREFX   = 0x0F | OPC_CP3,
410
    OPC_ALNV_PS = 0x1E | OPC_CP3,
411
    OPC_MADD_S  = 0x20 | OPC_CP3,
412
    OPC_MADD_D  = 0x21 | OPC_CP3,
413
    OPC_MADD_PS = 0x26 | OPC_CP3,
414
    OPC_MSUB_S  = 0x28 | OPC_CP3,
415
    OPC_MSUB_D  = 0x29 | OPC_CP3,
416
    OPC_MSUB_PS = 0x2E | OPC_CP3,
417
    OPC_NMADD_S = 0x30 | OPC_CP3,
418
    OPC_NMADD_D = 0x31 | OPC_CP3,
419
    OPC_NMADD_PS= 0x36 | OPC_CP3,
420
    OPC_NMSUB_S = 0x38 | OPC_CP3,
421
    OPC_NMSUB_D = 0x39 | OPC_CP3,
422
    OPC_NMSUB_PS= 0x3E | OPC_CP3,
423
};
424

    
425
/* global register indices */
426
static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2];
427

    
428
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg)
429
{
430
    TCGv t = tcg_const_i32(arg);
431

    
432
    tcg_gen_helper_0_1(func, t);
433
    tcg_temp_free(t);
434
}
435

    
436
static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2)
437
{
438
    TCGv t1 = tcg_const_i32(arg1);
439
    TCGv t2 = tcg_const_i32(arg2);
440

    
441
    tcg_gen_helper_0_2(func, t1, t2);
442
    tcg_temp_free(t1);
443
    tcg_temp_free(t2);
444
}
445

    
446
typedef struct DisasContext {
447
    struct TranslationBlock *tb;
448
    target_ulong pc, saved_pc;
449
    uint32_t opcode;
450
    uint32_t fp_status;
451
    /* Routine used to access memory */
452
    int mem_idx;
453
    uint32_t hflags, saved_hflags;
454
    int bstate;
455
    target_ulong btarget;
456
} DisasContext;
457

    
458
enum {
459
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
460
                      * exception condition
461
                      */
462
    BS_STOP     = 1, /* We want to stop translation for any reason */
463
    BS_BRANCH   = 2, /* We reached a branch condition     */
464
    BS_EXCP     = 3, /* We reached an exception condition */
465
};
466

    
467
static const char *regnames[] =
468
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
469
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
470
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
471
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
472

    
473
static const char *fregnames[] =
474
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
475
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
476
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
477
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
478

    
479
#ifdef MIPS_DEBUG_DISAS
480
#define MIPS_DEBUG(fmt, args...)                                              \
481
do {                                                                          \
482
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
483
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
484
                ctx->pc, ctx->opcode , ##args);                               \
485
    }                                                                         \
486
} while (0)
487
#else
488
#define MIPS_DEBUG(fmt, args...) do { } while(0)
489
#endif
490

    
491
#define MIPS_INVAL(op)                                                        \
492
do {                                                                          \
493
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
494
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
495
} while (0)
496

    
497
/* General purpose registers moves. */
498
static inline void gen_load_gpr (TCGv t, int reg)
499
{
500
    if (reg == 0)
501
        tcg_gen_movi_tl(t, 0);
502
    else
503
        tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
504
}
505

    
506
static inline void gen_store_gpr (TCGv t, int reg)
507
{
508
    if (reg != 0)
509
        tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
510
}
511

    
512
/* Moves to/from HI and LO registers.  */
513
static inline void gen_load_LO (TCGv t, int reg)
514
{
515
    tcg_gen_ld_tl(t, current_tc_hi,
516
                  offsetof(CPUState, LO)
517
                  - offsetof(CPUState, HI)
518
                  + sizeof(target_ulong) * reg);
519
}
520

    
521
static inline void gen_store_LO (TCGv t, int reg)
522
{
523
    tcg_gen_st_tl(t, current_tc_hi,
524
                  offsetof(CPUState, LO)
525
                  - offsetof(CPUState, HI)
526
                  + sizeof(target_ulong) * reg);
527
}
528

    
529
static inline void gen_load_HI (TCGv t, int reg)
530
{
531
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
532
}
533

    
534
static inline void gen_store_HI (TCGv t, int reg)
535
{
536
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
537
}
538

    
539
/* Moves to/from shadow registers. */
540
static inline void gen_load_srsgpr (TCGv t, int reg)
541
{
542
    if (reg == 0)
543
        tcg_gen_movi_tl(t, 0);
544
    else {
545
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
546

    
547
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
548
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
549
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
550
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
551
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
552

    
553
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
554
        tcg_temp_free(r_tmp);
555
    }
556
}
557

    
558
static inline void gen_store_srsgpr (TCGv t, int reg)
559
{
560
    if (reg != 0) {
561
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
562

    
563
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
564
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
565
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
566
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
567
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
568

    
569
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
570
        tcg_temp_free(r_tmp);
571
    }
572
}
573

    
574
/* Floating point register moves. */
575
#define FGEN32(func, NAME)                       \
576
static GenOpFunc *NAME ## _table [32] = {        \
577
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
578
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
579
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
580
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
581
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
582
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
583
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
584
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
585
};                                               \
586
static always_inline void func(int n)            \
587
{                                                \
588
    NAME ## _table[n]();                         \
589
}
590

    
591
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
592
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
593

    
594
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
595
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
596

    
597
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
598
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
599

    
600
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
601
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
602

    
603
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
604
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
605

    
606
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
607
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
608

    
609
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
610
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
611

    
612
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
613
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
614

    
615
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
616
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
617

    
618
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
619
do {                                                                          \
620
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
621
} while (0)
622

    
623
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
624
do {                                                                          \
625
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
626
} while (0)
627

    
628
#define FOP_CONDS(type, fmt)                                            \
629
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
630
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
631
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
632
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
633
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
634
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
635
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
636
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
637
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
638
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
639
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
640
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
641
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
642
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
643
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
644
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
645
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
646
};                                                                      \
647
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
648
{                                                                       \
649
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
650
}
651

    
652
FOP_CONDS(, d)
653
FOP_CONDS(abs, d)
654
FOP_CONDS(, s)
655
FOP_CONDS(abs, s)
656
FOP_CONDS(, ps)
657
FOP_CONDS(abs, ps)
658

    
659
/* Tests */
660
#define OP_COND(name, cond)                                   \
661
void glue(gen_op_, name) (void)                               \
662
{                                                             \
663
    int l1 = gen_new_label();                                 \
664
    int l2 = gen_new_label();                                 \
665
                                                              \
666
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
667
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
668
    tcg_gen_br(l2);                                           \
669
    gen_set_label(l1);                                        \
670
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
671
    gen_set_label(l2);                                        \
672
}
673
OP_COND(eq, TCG_COND_EQ);
674
OP_COND(ne, TCG_COND_NE);
675
OP_COND(ge, TCG_COND_GE);
676
OP_COND(geu, TCG_COND_GEU);
677
OP_COND(lt, TCG_COND_LT);
678
OP_COND(ltu, TCG_COND_LTU);
679
#undef OP_COND
680

    
681
#define OP_CONDI(name, cond)                                  \
682
void glue(gen_op_, name) (target_ulong val)                   \
683
{                                                             \
684
    int l1 = gen_new_label();                                 \
685
    int l2 = gen_new_label();                                 \
686
                                                              \
687
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
688
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
689
    tcg_gen_br(l2);                                           \
690
    gen_set_label(l1);                                        \
691
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
692
    gen_set_label(l2);                                        \
693
}
694
OP_CONDI(lti, TCG_COND_LT);
695
OP_CONDI(ltiu, TCG_COND_LTU);
696
#undef OP_CONDI
697

    
698
#define OP_CONDZ(name, cond)                                  \
699
void glue(gen_op_, name) (void)                               \
700
{                                                             \
701
    int l1 = gen_new_label();                                 \
702
    int l2 = gen_new_label();                                 \
703
                                                              \
704
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1);                \
705
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
706
    tcg_gen_br(l2);                                           \
707
    gen_set_label(l1);                                        \
708
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
709
    gen_set_label(l2);                                        \
710
}
711
OP_CONDZ(gez, TCG_COND_GE);
712
OP_CONDZ(gtz, TCG_COND_GT);
713
OP_CONDZ(lez, TCG_COND_LE);
714
OP_CONDZ(ltz, TCG_COND_LT);
715
#undef OP_CONDZ
716

    
717
static inline void gen_save_pc(target_ulong pc)
718
{
719
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
720
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
721
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
722
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
723

    
724
    tcg_gen_movi_tl(r_tmp, pc);
725
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
726
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
727
    tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
728
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
729
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
730
    tcg_temp_free(r_tc_off);
731
    tcg_temp_free(r_tc_off_ptr);
732
    tcg_temp_free(r_ptr);
733
    tcg_temp_free(r_tmp);
734
}
735

    
736
static inline void gen_breg_pc(void)
737
{
738
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
739
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
740
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
741
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
742

    
743
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
744
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
745
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
746
    tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
747
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
748
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
749
    tcg_temp_free(r_tc_off);
750
    tcg_temp_free(r_tc_off_ptr);
751
    tcg_temp_free(r_ptr);
752
    tcg_temp_free(r_tmp);
753
}
754

    
755
static inline void gen_save_btarget(target_ulong btarget)
756
{
757
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
758

    
759
    tcg_gen_movi_tl(r_tmp, btarget);
760
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
761
    tcg_temp_free(r_tmp);
762
}
763

    
764
static always_inline void gen_save_breg_target(int reg)
765
{
766
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
767

    
768
    gen_load_gpr(r_tmp, reg);
769
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
770
    tcg_temp_free(r_tmp);
771
}
772

    
773
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
774
{
775
#if defined MIPS_DEBUG_DISAS
776
    if (loglevel & CPU_LOG_TB_IN_ASM) {
777
            fprintf(logfile, "hflags %08x saved %08x\n",
778
                    ctx->hflags, ctx->saved_hflags);
779
    }
780
#endif
781
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
782
        gen_save_pc(ctx->pc);
783
        ctx->saved_pc = ctx->pc;
784
    }
785
    if (ctx->hflags != ctx->saved_hflags) {
786
        gen_op_save_state(ctx->hflags);
787
        ctx->saved_hflags = ctx->hflags;
788
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
789
        case MIPS_HFLAG_BR:
790
            break;
791
        case MIPS_HFLAG_BC:
792
        case MIPS_HFLAG_BL:
793
        case MIPS_HFLAG_B:
794
            gen_save_btarget(ctx->btarget);
795
            break;
796
        }
797
    }
798
}
799

    
800
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
801
{
802
    ctx->saved_hflags = ctx->hflags;
803
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
804
    case MIPS_HFLAG_BR:
805
        break;
806
    case MIPS_HFLAG_BC:
807
    case MIPS_HFLAG_BL:
808
    case MIPS_HFLAG_B:
809
        ctx->btarget = env->btarget;
810
        break;
811
    }
812
}
813

    
814
static always_inline void
815
generate_exception_err (DisasContext *ctx, int excp, int err)
816
{
817
    save_cpu_state(ctx, 1);
818
    tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err);
819
    tcg_gen_helper_0_0(do_interrupt_restart);
820
    tcg_gen_exit_tb(0);
821
}
822

    
823
static always_inline void
824
generate_exception (DisasContext *ctx, int excp)
825
{
826
    save_cpu_state(ctx, 1);
827
    tcg_gen_helper_0_1i(do_raise_exception, excp);
828
    tcg_gen_helper_0_0(do_interrupt_restart);
829
    tcg_gen_exit_tb(0);
830
}
831

    
832
/* Addresses computation */
833
static inline void gen_op_addr_add (void)
834
{
835
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
836

    
837
#if defined(TARGET_MIPS64)
838
    /* For compatibility with 32-bit code, data reference in user mode
839
       with Status_UX = 0 should be casted to 32-bit and sign extended.
840
       See the MIPS64 PRA manual, section 4.10. */
841
    {
842
        int l1 = gen_new_label();
843

    
844
        {
845
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
846

    
847
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
848
            tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
849
            tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
850
        }
851
        {
852
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
853

    
854
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
855
            tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
856
            tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
857
        }
858
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
859
        gen_set_label(l1);
860
    }
861
#endif
862
}
863

    
864
static always_inline void check_cp0_enabled(DisasContext *ctx)
865
{
866
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
867
        generate_exception_err(ctx, EXCP_CpU, 1);
868
}
869

    
870
static always_inline void check_cp1_enabled(DisasContext *ctx)
871
{
872
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
873
        generate_exception_err(ctx, EXCP_CpU, 1);
874
}
875

    
876
/* Verify that the processor is running with COP1X instructions enabled.
877
   This is associated with the nabla symbol in the MIPS32 and MIPS64
878
   opcode tables.  */
879

    
880
static always_inline void check_cop1x(DisasContext *ctx)
881
{
882
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
883
        generate_exception(ctx, EXCP_RI);
884
}
885

    
886
/* Verify that the processor is running with 64-bit floating-point
887
   operations enabled.  */
888

    
889
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
890
{
891
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
892
        generate_exception(ctx, EXCP_RI);
893
}
894

    
895
/*
896
 * Verify if floating point register is valid; an operation is not defined
897
 * if bit 0 of any register specification is set and the FR bit in the
898
 * Status register equals zero, since the register numbers specify an
899
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
900
 * in the Status register equals one, both even and odd register numbers
901
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
902
 *
903
 * Multiple 64 bit wide registers can be checked by calling
904
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
905
 */
906
void check_cp1_registers(DisasContext *ctx, int regs)
907
{
908
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
909
        generate_exception(ctx, EXCP_RI);
910
}
911

    
912
/* This code generates a "reserved instruction" exception if the
913
   CPU does not support the instruction set corresponding to flags. */
914
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
915
{
916
    if (unlikely(!(env->insn_flags & flags)))
917
        generate_exception(ctx, EXCP_RI);
918
}
919

    
920
/* This code generates a "reserved instruction" exception if 64-bit
921
   instructions are not enabled. */
922
static always_inline void check_mips_64(DisasContext *ctx)
923
{
924
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
925
        generate_exception(ctx, EXCP_RI);
926
}
927

    
928
/* load/store instructions. */
929
#if defined(CONFIG_USER_ONLY)
930
#define op_ldst(name)        gen_op_##name##_raw()
931
#define OP_LD_TABLE(width)
932
#define OP_ST_TABLE(width)
933
#else
934
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
935
#define OP_LD_TABLE(width)                                                    \
936
static GenOpFunc *gen_op_l##width[] = {                                       \
937
    &gen_op_l##width##_kernel,                                                \
938
    &gen_op_l##width##_super,                                                 \
939
    &gen_op_l##width##_user,                                                  \
940
}
941
#define OP_ST_TABLE(width)                                                    \
942
static GenOpFunc *gen_op_s##width[] = {                                       \
943
    &gen_op_s##width##_kernel,                                                \
944
    &gen_op_s##width##_super,                                                 \
945
    &gen_op_s##width##_user,                                                  \
946
}
947
#endif
948

    
949
#if defined(TARGET_MIPS64)
950
OP_LD_TABLE(dl);
951
OP_LD_TABLE(dr);
952
OP_ST_TABLE(dl);
953
OP_ST_TABLE(dr);
954
#endif
955
OP_LD_TABLE(wl);
956
OP_LD_TABLE(wr);
957
OP_ST_TABLE(wl);
958
OP_ST_TABLE(wr);
959
OP_LD_TABLE(wc1);
960
OP_ST_TABLE(wc1);
961
OP_LD_TABLE(dc1);
962
OP_ST_TABLE(dc1);
963
OP_LD_TABLE(uxc1);
964
OP_ST_TABLE(uxc1);
965

    
966
#define OP_LD(insn,fname)                                        \
967
void inline op_ldst_##insn(DisasContext *ctx)                    \
968
{                                                                \
969
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
970
}
971
OP_LD(lb,ld8s);
972
OP_LD(lbu,ld8u);
973
OP_LD(lh,ld16s);
974
OP_LD(lhu,ld16u);
975
OP_LD(lw,ld32s);
976
#if defined(TARGET_MIPS64)
977
OP_LD(lwu,ld32u);
978
OP_LD(ld,ld64);
979
#endif
980
#undef OP_LD
981

    
982
#define OP_ST(insn,fname)                                        \
983
void inline op_ldst_##insn(DisasContext *ctx)                    \
984
{                                                                \
985
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
986
}
987
OP_ST(sb,st8);
988
OP_ST(sh,st16);
989
OP_ST(sw,st32);
990
#if defined(TARGET_MIPS64)
991
OP_ST(sd,st64);
992
#endif
993
#undef OP_ST
994

    
995
#define OP_LD_ATOMIC(insn,fname)                                        \
996
void inline op_ldst_##insn(DisasContext *ctx)                           \
997
{                                                                       \
998
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
999
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1000
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1001
}
1002
OP_LD_ATOMIC(ll,ld32s);
1003
#if defined(TARGET_MIPS64)
1004
OP_LD_ATOMIC(lld,ld64);
1005
#endif
1006
#undef OP_LD_ATOMIC
1007

    
1008
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1009
void inline op_ldst_##insn(DisasContext *ctx)                           \
1010
{                                                                       \
1011
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1012
    int l1 = gen_new_label();                                           \
1013
    int l2 = gen_new_label();                                           \
1014
    int l3 = gen_new_label();                                           \
1015
                                                                        \
1016
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1017
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1018
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1019
    generate_exception(ctx, EXCP_AdES);                                 \
1020
    gen_set_label(l1);                                                  \
1021
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1022
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1023
    tcg_temp_free(r_tmp);                                               \
1024
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1025
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1026
    tcg_gen_br(l3);                                                     \
1027
    gen_set_label(l2);                                                  \
1028
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1029
    gen_set_label(l3);                                                  \
1030
}
1031
OP_ST_ATOMIC(sc,st32,0x3);
1032
#if defined(TARGET_MIPS64)
1033
OP_ST_ATOMIC(scd,st64,0x7);
1034
#endif
1035
#undef OP_ST_ATOMIC
1036

    
1037
void inline op_ldst_lwc1(DisasContext *ctx)
1038
{
1039
    op_ldst(lwc1);
1040
}
1041

    
1042
void inline op_ldst_ldc1(DisasContext *ctx)
1043
{
1044
    op_ldst(ldc1);
1045
}
1046

    
1047
void inline op_ldst_swc1(DisasContext *ctx)
1048
{
1049
    op_ldst(swc1);
1050
}
1051

    
1052
void inline op_ldst_sdc1(DisasContext *ctx)
1053
{
1054
    op_ldst(sdc1);
1055
}
1056

    
1057
/* Load and store */
1058
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1059
                      int base, int16_t offset)
1060
{
1061
    const char *opn = "ldst";
1062

    
1063
    if (base == 0) {
1064
        tcg_gen_movi_tl(cpu_T[0], offset);
1065
    } else if (offset == 0) {
1066
        gen_load_gpr(cpu_T[0], base);
1067
    } else {
1068
        gen_load_gpr(cpu_T[0], base);
1069
        tcg_gen_movi_tl(cpu_T[1], offset);
1070
        gen_op_addr_add();
1071
    }
1072
    /* Don't do NOP if destination is zero: we must perform the actual
1073
       memory access. */
1074
    switch (opc) {
1075
#if defined(TARGET_MIPS64)
1076
    case OPC_LWU:
1077
        op_ldst_lwu(ctx);
1078
        gen_store_gpr(cpu_T[0], rt);
1079
        opn = "lwu";
1080
        break;
1081
    case OPC_LD:
1082
        op_ldst_ld(ctx);
1083
        gen_store_gpr(cpu_T[0], rt);
1084
        opn = "ld";
1085
        break;
1086
    case OPC_LLD:
1087
        op_ldst_lld(ctx);
1088
        gen_store_gpr(cpu_T[0], rt);
1089
        opn = "lld";
1090
        break;
1091
    case OPC_SD:
1092
        gen_load_gpr(cpu_T[1], rt);
1093
        op_ldst_sd(ctx);
1094
        opn = "sd";
1095
        break;
1096
    case OPC_SCD:
1097
        save_cpu_state(ctx, 1);
1098
        gen_load_gpr(cpu_T[1], rt);
1099
        op_ldst_scd(ctx);
1100
        gen_store_gpr(cpu_T[0], rt);
1101
        opn = "scd";
1102
        break;
1103
    case OPC_LDL:
1104
        gen_load_gpr(cpu_T[1], rt);
1105
        op_ldst(ldl);
1106
        gen_store_gpr(cpu_T[1], rt);
1107
        opn = "ldl";
1108
        break;
1109
    case OPC_SDL:
1110
        gen_load_gpr(cpu_T[1], rt);
1111
        op_ldst(sdl);
1112
        opn = "sdl";
1113
        break;
1114
    case OPC_LDR:
1115
        gen_load_gpr(cpu_T[1], rt);
1116
        op_ldst(ldr);
1117
        gen_store_gpr(cpu_T[1], rt);
1118
        opn = "ldr";
1119
        break;
1120
    case OPC_SDR:
1121
        gen_load_gpr(cpu_T[1], rt);
1122
        op_ldst(sdr);
1123
        opn = "sdr";
1124
        break;
1125
#endif
1126
    case OPC_LW:
1127
        op_ldst_lw(ctx);
1128
        gen_store_gpr(cpu_T[0], rt);
1129
        opn = "lw";
1130
        break;
1131
    case OPC_SW:
1132
        gen_load_gpr(cpu_T[1], rt);
1133
        op_ldst_sw(ctx);
1134
        opn = "sw";
1135
        break;
1136
    case OPC_LH:
1137
        op_ldst_lh(ctx);
1138
        gen_store_gpr(cpu_T[0], rt);
1139
        opn = "lh";
1140
        break;
1141
    case OPC_SH:
1142
        gen_load_gpr(cpu_T[1], rt);
1143
        op_ldst_sh(ctx);
1144
        opn = "sh";
1145
        break;
1146
    case OPC_LHU:
1147
        op_ldst_lhu(ctx);
1148
        gen_store_gpr(cpu_T[0], rt);
1149
        opn = "lhu";
1150
        break;
1151
    case OPC_LB:
1152
        op_ldst_lb(ctx);
1153
        gen_store_gpr(cpu_T[0], rt);
1154
        opn = "lb";
1155
        break;
1156
    case OPC_SB:
1157
        gen_load_gpr(cpu_T[1], rt);
1158
        op_ldst_sb(ctx);
1159
        opn = "sb";
1160
        break;
1161
    case OPC_LBU:
1162
        op_ldst_lbu(ctx);
1163
        gen_store_gpr(cpu_T[0], rt);
1164
        opn = "lbu";
1165
        break;
1166
    case OPC_LWL:
1167
        gen_load_gpr(cpu_T[1], rt);
1168
        op_ldst(lwl);
1169
        gen_store_gpr(cpu_T[1], rt);
1170
        opn = "lwl";
1171
        break;
1172
    case OPC_SWL:
1173
        gen_load_gpr(cpu_T[1], rt);
1174
        op_ldst(swl);
1175
        opn = "swr";
1176
        break;
1177
    case OPC_LWR:
1178
        gen_load_gpr(cpu_T[1], rt);
1179
        op_ldst(lwr);
1180
        gen_store_gpr(cpu_T[1], rt);
1181
        opn = "lwr";
1182
        break;
1183
    case OPC_SWR:
1184
        gen_load_gpr(cpu_T[1], rt);
1185
        op_ldst(swr);
1186
        opn = "swr";
1187
        break;
1188
    case OPC_LL:
1189
        op_ldst_ll(ctx);
1190
        gen_store_gpr(cpu_T[0], rt);
1191
        opn = "ll";
1192
        break;
1193
    case OPC_SC:
1194
        save_cpu_state(ctx, 1);
1195
        gen_load_gpr(cpu_T[1], rt);
1196
        op_ldst_sc(ctx);
1197
        gen_store_gpr(cpu_T[0], rt);
1198
        opn = "sc";
1199
        break;
1200
    default:
1201
        MIPS_INVAL(opn);
1202
        generate_exception(ctx, EXCP_RI);
1203
        return;
1204
    }
1205
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1206
}
1207

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

    
1214
    if (base == 0) {
1215
        tcg_gen_movi_tl(cpu_T[0], offset);
1216
    } else if (offset == 0) {
1217
        gen_load_gpr(cpu_T[0], base);
1218
    } else {
1219
        gen_load_gpr(cpu_T[0], base);
1220
        tcg_gen_movi_tl(cpu_T[1], offset);
1221
        gen_op_addr_add();
1222
    }
1223
    /* Don't do NOP if destination is zero: we must perform the actual
1224
       memory access. */
1225
    switch (opc) {
1226
    case OPC_LWC1:
1227
        op_ldst_lwc1(ctx);
1228
        GEN_STORE_FTN_FREG(ft, WT0);
1229
        opn = "lwc1";
1230
        break;
1231
    case OPC_SWC1:
1232
        GEN_LOAD_FREG_FTN(WT0, ft);
1233
        op_ldst_swc1(ctx);
1234
        opn = "swc1";
1235
        break;
1236
    case OPC_LDC1:
1237
        op_ldst_ldc1(ctx);
1238
        GEN_STORE_FTN_FREG(ft, DT0);
1239
        opn = "ldc1";
1240
        break;
1241
    case OPC_SDC1:
1242
        GEN_LOAD_FREG_FTN(DT0, ft);
1243
        op_ldst_sdc1(ctx);
1244
        opn = "sdc1";
1245
        break;
1246
    default:
1247
        MIPS_INVAL(opn);
1248
        generate_exception(ctx, EXCP_RI);
1249
        return;
1250
    }
1251
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1252
}
1253

    
1254
/* Arithmetic with immediate operand */
1255
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1256
                           int rt, int rs, int16_t imm)
1257
{
1258
    target_ulong uimm;
1259
    const char *opn = "imm arith";
1260

    
1261
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1262
        /* If no destination, treat it as a NOP.
1263
           For addi, we must generate the overflow exception when needed. */
1264
        MIPS_DEBUG("NOP");
1265
        return;
1266
    }
1267
    uimm = (uint16_t)imm;
1268
    switch (opc) {
1269
    case OPC_ADDI:
1270
    case OPC_ADDIU:
1271
#if defined(TARGET_MIPS64)
1272
    case OPC_DADDI:
1273
    case OPC_DADDIU:
1274
#endif
1275
    case OPC_SLTI:
1276
    case OPC_SLTIU:
1277
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1278
        tcg_gen_movi_tl(cpu_T[1], uimm);
1279
        /* Fall through. */
1280
    case OPC_ANDI:
1281
    case OPC_ORI:
1282
    case OPC_XORI:
1283
        gen_load_gpr(cpu_T[0], rs);
1284
        break;
1285
    case OPC_LUI:
1286
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1287
        break;
1288
    case OPC_SLL:
1289
    case OPC_SRA:
1290
    case OPC_SRL:
1291
#if defined(TARGET_MIPS64)
1292
    case OPC_DSLL:
1293
    case OPC_DSRA:
1294
    case OPC_DSRL:
1295
    case OPC_DSLL32:
1296
    case OPC_DSRA32:
1297
    case OPC_DSRL32:
1298
#endif
1299
        uimm &= 0x1f;
1300
        gen_load_gpr(cpu_T[0], rs);
1301
        break;
1302
    }
1303
    switch (opc) {
1304
    case OPC_ADDI:
1305
        {
1306
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1307
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1308
            int l1 = gen_new_label();
1309

    
1310
            save_cpu_state(ctx, 1);
1311
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1312
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1313

    
1314
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1315
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1316
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1317
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1318
            tcg_temp_free(r_tmp2);
1319
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1320
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1321
            tcg_temp_free(r_tmp1);
1322
            /* operands of same sign, result different sign */
1323
            generate_exception(ctx, EXCP_OVERFLOW);
1324
            gen_set_label(l1);
1325

    
1326
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1327
        }
1328
        opn = "addi";
1329
        break;
1330
    case OPC_ADDIU:
1331
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1332
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1333
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1334
        opn = "addiu";
1335
        break;
1336
#if defined(TARGET_MIPS64)
1337
    case OPC_DADDI:
1338
        {
1339
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1340
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1341
            int l1 = gen_new_label();
1342

    
1343
            save_cpu_state(ctx, 1);
1344
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1345
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1346

    
1347
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1348
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1349
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1350
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1351
            tcg_temp_free(r_tmp2);
1352
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1353
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1354
            tcg_temp_free(r_tmp1);
1355
            /* operands of same sign, result different sign */
1356
            generate_exception(ctx, EXCP_OVERFLOW);
1357
            gen_set_label(l1);
1358
        }
1359
        opn = "daddi";
1360
        break;
1361
    case OPC_DADDIU:
1362
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1363
        opn = "daddiu";
1364
        break;
1365
#endif
1366
    case OPC_SLTI:
1367
        gen_op_lti(uimm);
1368
        opn = "slti";
1369
        break;
1370
    case OPC_SLTIU:
1371
        gen_op_ltiu(uimm);
1372
        opn = "sltiu";
1373
        break;
1374
    case OPC_ANDI:
1375
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1376
        opn = "andi";
1377
        break;
1378
    case OPC_ORI:
1379
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1380
        opn = "ori";
1381
        break;
1382
    case OPC_XORI:
1383
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1384
        opn = "xori";
1385
        break;
1386
    case OPC_LUI:
1387
        opn = "lui";
1388
        break;
1389
    case OPC_SLL:
1390
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1391
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1392
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1393
        opn = "sll";
1394
        break;
1395
    case OPC_SRA:
1396
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1397
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1398
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1399
        opn = "sra";
1400
        break;
1401
    case OPC_SRL:
1402
        switch ((ctx->opcode >> 21) & 0x1f) {
1403
        case 0:
1404
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1405
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1406
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1407
            opn = "srl";
1408
            break;
1409
        case 1:
1410
            /* rotr is decoded as srl on non-R2 CPUs */
1411
            if (env->insn_flags & ISA_MIPS32R2) {
1412
                if (uimm != 0) {
1413
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1414
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1415

    
1416
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1417
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1418
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1419
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1420
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1421
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1422
                    tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1);
1423
                    tcg_temp_free(r_tmp1);
1424
                    tcg_temp_free(r_tmp2);
1425
                }
1426
                opn = "rotr";
1427
            } else {
1428
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1429
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1430
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1431
                opn = "srl";
1432
            }
1433
            break;
1434
        default:
1435
            MIPS_INVAL("invalid srl flag");
1436
            generate_exception(ctx, EXCP_RI);
1437
            break;
1438
        }
1439
        break;
1440
#if defined(TARGET_MIPS64)
1441
    case OPC_DSLL:
1442
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1443
        opn = "dsll";
1444
        break;
1445
    case OPC_DSRA:
1446
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1447
        opn = "dsra";
1448
        break;
1449
    case OPC_DSRL:
1450
        switch ((ctx->opcode >> 21) & 0x1f) {
1451
        case 0:
1452
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1453
            opn = "dsrl";
1454
            break;
1455
        case 1:
1456
            /* drotr is decoded as dsrl on non-R2 CPUs */
1457
            if (env->insn_flags & ISA_MIPS32R2) {
1458
                if (uimm != 0) {
1459
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1460

    
1461
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1462
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1463
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1464
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1465
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1466
                    tcg_temp_free(r_tmp1);
1467
                }
1468
                opn = "drotr";
1469
            } else {
1470
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1471
                opn = "dsrl";
1472
            }
1473
            break;
1474
        default:
1475
            MIPS_INVAL("invalid dsrl flag");
1476
            generate_exception(ctx, EXCP_RI);
1477
            break;
1478
        }
1479
        break;
1480
    case OPC_DSLL32:
1481
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1482
        opn = "dsll32";
1483
        break;
1484
    case OPC_DSRA32:
1485
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1486
        opn = "dsra32";
1487
        break;
1488
    case OPC_DSRL32:
1489
        switch ((ctx->opcode >> 21) & 0x1f) {
1490
        case 0:
1491
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1492
            opn = "dsrl32";
1493
            break;
1494
        case 1:
1495
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1496
            if (env->insn_flags & ISA_MIPS32R2) {
1497
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1498
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1499

    
1500
                tcg_gen_movi_tl(r_tmp1, 0x40);
1501
                tcg_gen_movi_tl(r_tmp2, 32);
1502
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1503
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1504
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1505
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1506
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1507
                tcg_temp_free(r_tmp1);
1508
                tcg_temp_free(r_tmp2);
1509
                opn = "drotr32";
1510
            } else {
1511
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1512
                opn = "dsrl32";
1513
            }
1514
            break;
1515
        default:
1516
            MIPS_INVAL("invalid dsrl32 flag");
1517
            generate_exception(ctx, EXCP_RI);
1518
            break;
1519
        }
1520
        break;
1521
#endif
1522
    default:
1523
        MIPS_INVAL(opn);
1524
        generate_exception(ctx, EXCP_RI);
1525
        return;
1526
    }
1527
    gen_store_gpr(cpu_T[0], rt);
1528
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1529
}
1530

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

    
1537
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1538
       && opc != OPC_DADD && opc != OPC_DSUB) {
1539
        /* If no destination, treat it as a NOP.
1540
           For add & sub, we must generate the overflow exception when needed. */
1541
        MIPS_DEBUG("NOP");
1542
        return;
1543
    }
1544
    gen_load_gpr(cpu_T[0], rs);
1545
    /* Specialcase the conventional move operation. */
1546
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1547
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1548
        gen_store_gpr(cpu_T[0], rd);
1549
        return;
1550
    }
1551
    gen_load_gpr(cpu_T[1], rt);
1552
    switch (opc) {
1553
    case OPC_ADD:
1554
        {
1555
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1556
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1557
            int l1 = gen_new_label();
1558

    
1559
            save_cpu_state(ctx, 1);
1560
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1561
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1562
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1563

    
1564
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1565
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1566
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1567
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1568
            tcg_temp_free(r_tmp2);
1569
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1570
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1571
            tcg_temp_free(r_tmp1);
1572
            /* operands of same sign, result different sign */
1573
            generate_exception(ctx, EXCP_OVERFLOW);
1574
            gen_set_label(l1);
1575

    
1576
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1577
        }
1578
        opn = "add";
1579
        break;
1580
    case OPC_ADDU:
1581
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1582
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1583
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1584
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1585
        opn = "addu";
1586
        break;
1587
    case OPC_SUB:
1588
        {
1589
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1590
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1591
            int l1 = gen_new_label();
1592

    
1593
            save_cpu_state(ctx, 1);
1594
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1595
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1596
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1597

    
1598
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1599
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1600
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1601
            tcg_temp_free(r_tmp2);
1602
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1603
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1604
            tcg_temp_free(r_tmp1);
1605
            /* operands of different sign, first operand and result different sign */
1606
            generate_exception(ctx, EXCP_OVERFLOW);
1607
            gen_set_label(l1);
1608

    
1609
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1610
        }
1611
        opn = "sub";
1612
        break;
1613
    case OPC_SUBU:
1614
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1615
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1616
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1617
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1618
        opn = "subu";
1619
        break;
1620
#if defined(TARGET_MIPS64)
1621
    case OPC_DADD:
1622
        {
1623
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1624
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1625
            int l1 = gen_new_label();
1626

    
1627
            save_cpu_state(ctx, 1);
1628
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1629
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1630

    
1631
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1632
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1633
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1634
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1635
            tcg_temp_free(r_tmp2);
1636
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1637
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1638
            tcg_temp_free(r_tmp1);
1639
            /* operands of same sign, result different sign */
1640
            generate_exception(ctx, EXCP_OVERFLOW);
1641
            gen_set_label(l1);
1642
        }
1643
        opn = "dadd";
1644
        break;
1645
    case OPC_DADDU:
1646
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1647
        opn = "daddu";
1648
        break;
1649
    case OPC_DSUB:
1650
        {
1651
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1652
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1653
            int l1 = gen_new_label();
1654

    
1655
            save_cpu_state(ctx, 1);
1656
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1657
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1658

    
1659
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1660
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1661
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1662
            tcg_temp_free(r_tmp2);
1663
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1664
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1665
            tcg_temp_free(r_tmp1);
1666
            /* operands of different sign, first operand and result different sign */
1667
            generate_exception(ctx, EXCP_OVERFLOW);
1668
            gen_set_label(l1);
1669
        }
1670
        opn = "dsub";
1671
        break;
1672
    case OPC_DSUBU:
1673
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1674
        opn = "dsubu";
1675
        break;
1676
#endif
1677
    case OPC_SLT:
1678
        gen_op_lt();
1679
        opn = "slt";
1680
        break;
1681
    case OPC_SLTU:
1682
        gen_op_ltu();
1683
        opn = "sltu";
1684
        break;
1685
    case OPC_AND:
1686
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1687
        opn = "and";
1688
        break;
1689
    case OPC_NOR:
1690
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1691
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1692
        opn = "nor";
1693
        break;
1694
    case OPC_OR:
1695
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1696
        opn = "or";
1697
        break;
1698
    case OPC_XOR:
1699
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1700
        opn = "xor";
1701
        break;
1702
    case OPC_MUL:
1703
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1704
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1705
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1706
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1707
        opn = "mul";
1708
        break;
1709
    case OPC_MOVN:
1710
        {
1711
            int l1 = gen_new_label();
1712

    
1713
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1714
            gen_store_gpr(cpu_T[0], rd);
1715
            gen_set_label(l1);
1716
        }
1717
        opn = "movn";
1718
        goto print;
1719
    case OPC_MOVZ:
1720
        {
1721
            int l1 = gen_new_label();
1722

    
1723
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1724
            gen_store_gpr(cpu_T[0], rd);
1725
            gen_set_label(l1);
1726
        }
1727
        opn = "movz";
1728
        goto print;
1729
    case OPC_SLLV:
1730
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1731
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1732
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1733
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1734
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1735
        opn = "sllv";
1736
        break;
1737
    case OPC_SRAV:
1738
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1739
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1740
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1741
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1742
        opn = "srav";
1743
        break;
1744
    case OPC_SRLV:
1745
        switch ((ctx->opcode >> 6) & 0x1f) {
1746
        case 0:
1747
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1748
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1749
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1750
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1751
            opn = "srlv";
1752
            break;
1753
        case 1:
1754
            /* rotrv is decoded as srlv on non-R2 CPUs */
1755
            if (env->insn_flags & ISA_MIPS32R2) {
1756
                int l1 = gen_new_label();
1757
                int l2 = gen_new_label();
1758

    
1759
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1760
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1761
                {
1762
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1763
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1764
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1765

    
1766
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1767
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1768
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1769
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1770
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1771
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1772
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1773
                    tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1);
1774
                    tcg_temp_free(r_tmp1);
1775
                    tcg_temp_free(r_tmp2);
1776
                    tcg_temp_free(r_tmp3);
1777
                    tcg_gen_br(l2);
1778
                }
1779
                gen_set_label(l1);
1780
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1781
                gen_set_label(l2);
1782
                opn = "rotrv";
1783
            } else {
1784
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1785
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1786
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1787
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1788
                opn = "srlv";
1789
            }
1790
            break;
1791
        default:
1792
            MIPS_INVAL("invalid srlv flag");
1793
            generate_exception(ctx, EXCP_RI);
1794
            break;
1795
        }
1796
        break;
1797
#if defined(TARGET_MIPS64)
1798
    case OPC_DSLLV:
1799
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1800
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1801
        opn = "dsllv";
1802
        break;
1803
    case OPC_DSRAV:
1804
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1805
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1806
        opn = "dsrav";
1807
        break;
1808
    case OPC_DSRLV:
1809
        switch ((ctx->opcode >> 6) & 0x1f) {
1810
        case 0:
1811
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1812
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1813
            opn = "dsrlv";
1814
            break;
1815
        case 1:
1816
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1817
            if (env->insn_flags & ISA_MIPS32R2) {
1818
                int l1 = gen_new_label();
1819
                int l2 = gen_new_label();
1820

    
1821
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1822
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1823
                {
1824
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1825

    
1826
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1827
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1828
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1829
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1830
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1831
                    tcg_temp_free(r_tmp1);
1832
                    tcg_gen_br(l2);
1833
                }
1834
                gen_set_label(l1);
1835
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1836
                gen_set_label(l2);
1837
                opn = "drotrv";
1838
            } else {
1839
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1840
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1841
                opn = "dsrlv";
1842
            }
1843
            break;
1844
        default:
1845
            MIPS_INVAL("invalid dsrlv flag");
1846
            generate_exception(ctx, EXCP_RI);
1847
            break;
1848
        }
1849
        break;
1850
#endif
1851
    default:
1852
        MIPS_INVAL(opn);
1853
        generate_exception(ctx, EXCP_RI);
1854
        return;
1855
    }
1856
    gen_store_gpr(cpu_T[0], rd);
1857
 print:
1858
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1859
}
1860

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

    
1866
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1867
        /* Treat as NOP. */
1868
        MIPS_DEBUG("NOP");
1869
        return;
1870
    }
1871
    switch (opc) {
1872
    case OPC_MFHI:
1873
        gen_load_HI(cpu_T[0], 0);
1874
        gen_store_gpr(cpu_T[0], reg);
1875
        opn = "mfhi";
1876
        break;
1877
    case OPC_MFLO:
1878
        gen_load_LO(cpu_T[0], 0);
1879
        gen_store_gpr(cpu_T[0], reg);
1880
        opn = "mflo";
1881
        break;
1882
    case OPC_MTHI:
1883
        gen_load_gpr(cpu_T[0], reg);
1884
        gen_store_HI(cpu_T[0], 0);
1885
        opn = "mthi";
1886
        break;
1887
    case OPC_MTLO:
1888
        gen_load_gpr(cpu_T[0], reg);
1889
        gen_store_LO(cpu_T[0], 0);
1890
        opn = "mtlo";
1891
        break;
1892
    default:
1893
        MIPS_INVAL(opn);
1894
        generate_exception(ctx, EXCP_RI);
1895
        return;
1896
    }
1897
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1898
}
1899

    
1900
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1901
                        int rs, int rt)
1902
{
1903
    const char *opn = "mul/div";
1904

    
1905
    gen_load_gpr(cpu_T[0], rs);
1906
    gen_load_gpr(cpu_T[1], rt);
1907
    switch (opc) {
1908
    case OPC_DIV:
1909
        {
1910
            int l1 = gen_new_label();
1911

    
1912
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1913
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1914
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1915
            {
1916
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1917
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1918
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1919

    
1920
                tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1921
                tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1922
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1923
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1924
                tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1925
                tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1926
                tcg_temp_free(r_tmp1);
1927
                tcg_temp_free(r_tmp2);
1928
                tcg_temp_free(r_tmp3);
1929
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1930
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1931
                gen_store_LO(cpu_T[0], 0);
1932
                gen_store_HI(cpu_T[1], 0);
1933
            }
1934
            gen_set_label(l1);
1935
        }
1936
        opn = "div";
1937
        break;
1938
    case OPC_DIVU:
1939
        {
1940
            int l1 = gen_new_label();
1941

    
1942
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1943
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1944
            {
1945
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1946
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1947
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1948

    
1949
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1950
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1951
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1952
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1953
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1954
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1955
                tcg_temp_free(r_tmp1);
1956
                tcg_temp_free(r_tmp2);
1957
                tcg_temp_free(r_tmp3);
1958
                gen_store_LO(cpu_T[0], 0);
1959
                gen_store_HI(cpu_T[1], 0);
1960
            }
1961
            gen_set_label(l1);
1962
        }
1963
        opn = "divu";
1964
        break;
1965
    case OPC_MULT:
1966
        gen_op_mult();
1967
        opn = "mult";
1968
        break;
1969
    case OPC_MULTU:
1970
        gen_op_multu();
1971
        opn = "multu";
1972
        break;
1973
#if defined(TARGET_MIPS64)
1974
    case OPC_DDIV:
1975
        {
1976
            int l1 = gen_new_label();
1977

    
1978
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1979
            {
1980
                int l2 = gen_new_label();
1981

    
1982
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2);
1983
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2);
1984
                {
1985
                    tcg_gen_movi_tl(cpu_T[1], 0);
1986
                    gen_store_LO(cpu_T[0], 0);
1987
                    gen_store_HI(cpu_T[1], 0);
1988
                    tcg_gen_br(l1);
1989
                }
1990
                gen_set_label(l2);
1991
                {
1992
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1993
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1994

    
1995
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1996
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1997
                    gen_store_LO(r_tmp1, 0);
1998
                    gen_store_HI(r_tmp2, 0);
1999
                    tcg_temp_free(r_tmp1);
2000
                    tcg_temp_free(r_tmp2);
2001
                }
2002
            }
2003
            gen_set_label(l1);
2004
        }
2005
        opn = "ddiv";
2006
        break;
2007
    case OPC_DDIVU:
2008
        {
2009
            int l1 = gen_new_label();
2010

    
2011
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
2012
            {
2013
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2014
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2015

    
2016
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
2017
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
2018
                tcg_temp_free(r_tmp1);
2019
                tcg_temp_free(r_tmp2);
2020
                gen_store_LO(r_tmp1, 0);
2021
                gen_store_HI(r_tmp2, 0);
2022
            }
2023
            gen_set_label(l1);
2024
        }
2025
        opn = "ddivu";
2026
        break;
2027
    case OPC_DMULT:
2028
        gen_op_dmult();
2029
        opn = "dmult";
2030
        break;
2031
    case OPC_DMULTU:
2032
        gen_op_dmultu();
2033
        opn = "dmultu";
2034
        break;
2035
#endif
2036
    case OPC_MADD:
2037
        gen_op_madd();
2038
        opn = "madd";
2039
        break;
2040
    case OPC_MADDU:
2041
        gen_op_maddu();
2042
        opn = "maddu";
2043
        break;
2044
    case OPC_MSUB:
2045
        gen_op_msub();
2046
        opn = "msub";
2047
        break;
2048
    case OPC_MSUBU:
2049
        gen_op_msubu();
2050
        opn = "msubu";
2051
        break;
2052
    default:
2053
        MIPS_INVAL(opn);
2054
        generate_exception(ctx, EXCP_RI);
2055
        return;
2056
    }
2057
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2058
}
2059

    
2060
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2061
                            int rd, int rs, int rt)
2062
{
2063
    const char *opn = "mul vr54xx";
2064

    
2065
    gen_load_gpr(cpu_T[0], rs);
2066
    gen_load_gpr(cpu_T[1], rt);
2067

    
2068
    switch (opc) {
2069
    case OPC_VR54XX_MULS:
2070
        gen_op_muls();
2071
        opn = "muls";
2072
        break;
2073
    case OPC_VR54XX_MULSU:
2074
        gen_op_mulsu();
2075
        opn = "mulsu";
2076
        break;
2077
    case OPC_VR54XX_MACC:
2078
        gen_op_macc();
2079
        opn = "macc";
2080
        break;
2081
    case OPC_VR54XX_MACCU:
2082
        gen_op_maccu();
2083
        opn = "maccu";
2084
        break;
2085
    case OPC_VR54XX_MSAC:
2086
        gen_op_msac();
2087
        opn = "msac";
2088
        break;
2089
    case OPC_VR54XX_MSACU:
2090
        gen_op_msacu();
2091
        opn = "msacu";
2092
        break;
2093
    case OPC_VR54XX_MULHI:
2094
        gen_op_mulhi();
2095
        opn = "mulhi";
2096
        break;
2097
    case OPC_VR54XX_MULHIU:
2098
        gen_op_mulhiu();
2099
        opn = "mulhiu";
2100
        break;
2101
    case OPC_VR54XX_MULSHI:
2102
        gen_op_mulshi();
2103
        opn = "mulshi";
2104
        break;
2105
    case OPC_VR54XX_MULSHIU:
2106
        gen_op_mulshiu();
2107
        opn = "mulshiu";
2108
        break;
2109
    case OPC_VR54XX_MACCHI:
2110
        gen_op_macchi();
2111
        opn = "macchi";
2112
        break;
2113
    case OPC_VR54XX_MACCHIU:
2114
        gen_op_macchiu();
2115
        opn = "macchiu";
2116
        break;
2117
    case OPC_VR54XX_MSACHI:
2118
        gen_op_msachi();
2119
        opn = "msachi";
2120
        break;
2121
    case OPC_VR54XX_MSACHIU:
2122
        gen_op_msachiu();
2123
        opn = "msachiu";
2124
        break;
2125
    default:
2126
        MIPS_INVAL("mul vr54xx");
2127
        generate_exception(ctx, EXCP_RI);
2128
        return;
2129
    }
2130
    gen_store_gpr(cpu_T[0], rd);
2131
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2132
}
2133

    
2134
static void gen_cl (DisasContext *ctx, uint32_t opc,
2135
                    int rd, int rs)
2136
{
2137
    const char *opn = "CLx";
2138
    if (rd == 0) {
2139
        /* Treat as NOP. */
2140
        MIPS_DEBUG("NOP");
2141
        return;
2142
    }
2143
    gen_load_gpr(cpu_T[0], rs);
2144
    switch (opc) {
2145
    case OPC_CLO:
2146
        tcg_gen_helper_0_0(do_clo);
2147
        opn = "clo";
2148
        break;
2149
    case OPC_CLZ:
2150
        tcg_gen_helper_0_0(do_clz);
2151
        opn = "clz";
2152
        break;
2153
#if defined(TARGET_MIPS64)
2154
    case OPC_DCLO:
2155
        tcg_gen_helper_0_0(do_dclo);
2156
        opn = "dclo";
2157
        break;
2158
    case OPC_DCLZ:
2159
        tcg_gen_helper_0_0(do_dclz);
2160
        opn = "dclz";
2161
        break;
2162
#endif
2163
    default:
2164
        MIPS_INVAL(opn);
2165
        generate_exception(ctx, EXCP_RI);
2166
        return;
2167
    }
2168
    gen_store_gpr(cpu_T[0], rd);
2169
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2170
}
2171

    
2172
/* Traps */
2173
static void gen_trap (DisasContext *ctx, uint32_t opc,
2174
                      int rs, int rt, int16_t imm)
2175
{
2176
    int cond;
2177

    
2178
    cond = 0;
2179
    /* Load needed operands */
2180
    switch (opc) {
2181
    case OPC_TEQ:
2182
    case OPC_TGE:
2183
    case OPC_TGEU:
2184
    case OPC_TLT:
2185
    case OPC_TLTU:
2186
    case OPC_TNE:
2187
        /* Compare two registers */
2188
        if (rs != rt) {
2189
            gen_load_gpr(cpu_T[0], rs);
2190
            gen_load_gpr(cpu_T[1], rt);
2191
            cond = 1;
2192
        }
2193
        break;
2194
    case OPC_TEQI:
2195
    case OPC_TGEI:
2196
    case OPC_TGEIU:
2197
    case OPC_TLTI:
2198
    case OPC_TLTIU:
2199
    case OPC_TNEI:
2200
        /* Compare register to immediate */
2201
        if (rs != 0 || imm != 0) {
2202
            gen_load_gpr(cpu_T[0], rs);
2203
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2204
            cond = 1;
2205
        }
2206
        break;
2207
    }
2208
    if (cond == 0) {
2209
        switch (opc) {
2210
        case OPC_TEQ:   /* rs == rs */
2211
        case OPC_TEQI:  /* r0 == 0  */
2212
        case OPC_TGE:   /* rs >= rs */
2213
        case OPC_TGEI:  /* r0 >= 0  */
2214
        case OPC_TGEU:  /* rs >= rs unsigned */
2215
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2216
            /* Always trap */
2217
            tcg_gen_movi_tl(cpu_T[0], 1);
2218
            break;
2219
        case OPC_TLT:   /* rs < rs           */
2220
        case OPC_TLTI:  /* r0 < 0            */
2221
        case OPC_TLTU:  /* rs < rs unsigned  */
2222
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2223
        case OPC_TNE:   /* rs != rs          */
2224
        case OPC_TNEI:  /* r0 != 0           */
2225
            /* Never trap: treat as NOP. */
2226
            return;
2227
        default:
2228
            MIPS_INVAL("trap");
2229
            generate_exception(ctx, EXCP_RI);
2230
            return;
2231
        }
2232
    } else {
2233
        switch (opc) {
2234
        case OPC_TEQ:
2235
        case OPC_TEQI:
2236
            gen_op_eq();
2237
            break;
2238
        case OPC_TGE:
2239
        case OPC_TGEI:
2240
            gen_op_ge();
2241
            break;
2242
        case OPC_TGEU:
2243
        case OPC_TGEIU:
2244
            gen_op_geu();
2245
            break;
2246
        case OPC_TLT:
2247
        case OPC_TLTI:
2248
            gen_op_lt();
2249
            break;
2250
        case OPC_TLTU:
2251
        case OPC_TLTIU:
2252
            gen_op_ltu();
2253
            break;
2254
        case OPC_TNE:
2255
        case OPC_TNEI:
2256
            gen_op_ne();
2257
            break;
2258
        default:
2259
            MIPS_INVAL("trap");
2260
            generate_exception(ctx, EXCP_RI);
2261
            return;
2262
        }
2263
    }
2264
    save_cpu_state(ctx, 1);
2265
    gen_op_trap();
2266
    ctx->bstate = BS_STOP;
2267
}
2268

    
2269
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2270
{
2271
    TranslationBlock *tb;
2272
    tb = ctx->tb;
2273
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2274
        tcg_gen_goto_tb(n);
2275
        gen_save_pc(dest);
2276
        tcg_gen_exit_tb((long)tb + n);
2277
    } else {
2278
        gen_save_pc(dest);
2279
        tcg_gen_exit_tb(0);
2280
    }
2281
}
2282

    
2283
/* Branches (before delay slot) */
2284
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2285
                                int rs, int rt, int32_t offset)
2286
{
2287
    target_ulong btarget = -1;
2288
    int blink = 0;
2289
    int bcond = 0;
2290

    
2291
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2292
#ifdef MIPS_DEBUG_DISAS
2293
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2294
            fprintf(logfile,
2295
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2296
                    ctx->pc);
2297
        }
2298
#endif
2299
        generate_exception(ctx, EXCP_RI);
2300
        return;
2301
    }
2302

    
2303
    /* Load needed operands */
2304
    switch (opc) {
2305
    case OPC_BEQ:
2306
    case OPC_BEQL:
2307
    case OPC_BNE:
2308
    case OPC_BNEL:
2309
        /* Compare two registers */
2310
        if (rs != rt) {
2311
            gen_load_gpr(cpu_T[0], rs);
2312
            gen_load_gpr(cpu_T[1], rt);
2313
            bcond = 1;
2314
        }
2315
        btarget = ctx->pc + 4 + offset;
2316
        break;
2317
    case OPC_BGEZ:
2318
    case OPC_BGEZAL:
2319
    case OPC_BGEZALL:
2320
    case OPC_BGEZL:
2321
    case OPC_BGTZ:
2322
    case OPC_BGTZL:
2323
    case OPC_BLEZ:
2324
    case OPC_BLEZL:
2325
    case OPC_BLTZ:
2326
    case OPC_BLTZAL:
2327
    case OPC_BLTZALL:
2328
    case OPC_BLTZL:
2329
        /* Compare to zero */
2330
        if (rs != 0) {
2331
            gen_load_gpr(cpu_T[0], rs);
2332
            bcond = 1;
2333
        }
2334
        btarget = ctx->pc + 4 + offset;
2335
        break;
2336
    case OPC_J:
2337
    case OPC_JAL:
2338
        /* Jump to immediate */
2339
        btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2340
        break;
2341
    case OPC_JR:
2342
    case OPC_JALR:
2343
        /* Jump to register */
2344
        if (offset != 0 && offset != 16) {
2345
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2346
               others are reserved. */
2347
            MIPS_INVAL("jump hint");
2348
            generate_exception(ctx, EXCP_RI);
2349
            return;
2350
        }
2351
        gen_save_breg_target(rs);
2352
        break;
2353
    default:
2354
        MIPS_INVAL("branch/jump");
2355
        generate_exception(ctx, EXCP_RI);
2356
        return;
2357
    }
2358
    if (bcond == 0) {
2359
        /* No condition to be computed */
2360
        switch (opc) {
2361
        case OPC_BEQ:     /* rx == rx        */
2362
        case OPC_BEQL:    /* rx == rx likely */
2363
        case OPC_BGEZ:    /* 0 >= 0          */
2364
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2365
        case OPC_BLEZ:    /* 0 <= 0          */
2366
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2367
            /* Always take */
2368
            ctx->hflags |= MIPS_HFLAG_B;
2369
            MIPS_DEBUG("balways");
2370
            break;
2371
        case OPC_BGEZAL:  /* 0 >= 0          */
2372
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2373
            /* Always take and link */
2374
            blink = 31;
2375
            ctx->hflags |= MIPS_HFLAG_B;
2376
            MIPS_DEBUG("balways and link");
2377
            break;
2378
        case OPC_BNE:     /* rx != rx        */
2379
        case OPC_BGTZ:    /* 0 > 0           */
2380
        case OPC_BLTZ:    /* 0 < 0           */
2381
            /* Treat as NOP. */
2382
            MIPS_DEBUG("bnever (NOP)");
2383
            return;
2384
        case OPC_BLTZAL:  /* 0 < 0           */
2385
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2386
            gen_store_gpr(cpu_T[0], 31);
2387
            MIPS_DEBUG("bnever and link");
2388
            return;
2389
        case OPC_BLTZALL: /* 0 < 0 likely */
2390
            tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2391
            gen_store_gpr(cpu_T[0], 31);
2392
            /* Skip the instruction in the delay slot */
2393
            MIPS_DEBUG("bnever, link and skip");
2394
            ctx->pc += 4;
2395
            return;
2396
        case OPC_BNEL:    /* rx != rx likely */
2397
        case OPC_BGTZL:   /* 0 > 0 likely */
2398
        case OPC_BLTZL:   /* 0 < 0 likely */
2399
            /* Skip the instruction in the delay slot */
2400
            MIPS_DEBUG("bnever and skip");
2401
            ctx->pc += 4;
2402
            return;
2403
        case OPC_J:
2404
            ctx->hflags |= MIPS_HFLAG_B;
2405
            MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
2406
            break;
2407
        case OPC_JAL:
2408
            blink = 31;
2409
            ctx->hflags |= MIPS_HFLAG_B;
2410
            MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
2411
            break;
2412
        case OPC_JR:
2413
            ctx->hflags |= MIPS_HFLAG_BR;
2414
            MIPS_DEBUG("jr %s", regnames[rs]);
2415
            break;
2416
        case OPC_JALR:
2417
            blink = rt;
2418
            ctx->hflags |= MIPS_HFLAG_BR;
2419
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2420
            break;
2421
        default:
2422
            MIPS_INVAL("branch/jump");
2423
            generate_exception(ctx, EXCP_RI);
2424
            return;
2425
        }
2426
    } else {
2427
        switch (opc) {
2428
        case OPC_BEQ:
2429
            gen_op_eq();
2430
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2431
                       regnames[rs], regnames[rt], btarget);
2432
            goto not_likely;
2433
        case OPC_BEQL:
2434
            gen_op_eq();
2435
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2436
                       regnames[rs], regnames[rt], btarget);
2437
            goto likely;
2438
        case OPC_BNE:
2439
            gen_op_ne();
2440
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2441
                       regnames[rs], regnames[rt], btarget);
2442
            goto not_likely;
2443
        case OPC_BNEL:
2444
            gen_op_ne();
2445
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2446
                       regnames[rs], regnames[rt], btarget);
2447
            goto likely;
2448
        case OPC_BGEZ:
2449
            gen_op_gez();
2450
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2451
            goto not_likely;
2452
        case OPC_BGEZL:
2453
            gen_op_gez();
2454
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2455
            goto likely;
2456
        case OPC_BGEZAL:
2457
            gen_op_gez();
2458
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2459
            blink = 31;
2460
            goto not_likely;
2461
        case OPC_BGEZALL:
2462
            gen_op_gez();
2463
            blink = 31;
2464
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2465
            goto likely;
2466
        case OPC_BGTZ:
2467
            gen_op_gtz();
2468
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2469
            goto not_likely;
2470
        case OPC_BGTZL:
2471
            gen_op_gtz();
2472
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2473
            goto likely;
2474
        case OPC_BLEZ:
2475
            gen_op_lez();
2476
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
2477
            goto not_likely;
2478
        case OPC_BLEZL:
2479
            gen_op_lez();
2480
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2481
            goto likely;
2482
        case OPC_BLTZ:
2483
            gen_op_ltz();
2484
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
2485
            goto not_likely;
2486
        case OPC_BLTZL:
2487
            gen_op_ltz();
2488
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
2489
            goto likely;
2490
        case OPC_BLTZAL:
2491
            gen_op_ltz();
2492
            blink = 31;
2493
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
2494
        not_likely:
2495
            ctx->hflags |= MIPS_HFLAG_BC;
2496
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2497
            break;
2498
        case OPC_BLTZALL:
2499
            gen_op_ltz();
2500
            blink = 31;
2501
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
2502
        likely:
2503
            ctx->hflags |= MIPS_HFLAG_BL;
2504
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
2505
            break;
2506
        default:
2507
            MIPS_INVAL("conditional branch/jump");
2508
            generate_exception(ctx, EXCP_RI);
2509
            return;
2510
        }
2511
    }
2512
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2513
               blink, ctx->hflags, btarget);
2514

    
2515
    ctx->btarget = btarget;
2516
    if (blink > 0) {
2517
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2518
        gen_store_gpr(cpu_T[0], blink);
2519
    }
2520
}
2521

    
2522
/* special3 bitfield operations */
2523
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2524
                       int rs, int lsb, int msb)
2525
{
2526
    gen_load_gpr(cpu_T[1], rs);
2527
    switch (opc) {
2528
    case OPC_EXT:
2529
        if (lsb + msb > 31)
2530
            goto fail;
2531
        gen_op_ext(lsb, msb + 1);
2532
        break;
2533
#if defined(TARGET_MIPS64)
2534
    case OPC_DEXTM:
2535
        if (lsb + msb > 63)
2536
            goto fail;
2537
        gen_op_dext(lsb, msb + 1 + 32);
2538
        break;
2539
    case OPC_DEXTU:
2540
        if (lsb + msb > 63)
2541
            goto fail;
2542
        gen_op_dext(lsb + 32, msb + 1);
2543
        break;
2544
    case OPC_DEXT:
2545
        if (lsb + msb > 63)
2546
            goto fail;
2547
        gen_op_dext(lsb, msb + 1);
2548
        break;
2549
#endif
2550
    case OPC_INS:
2551
        if (lsb > msb)
2552
            goto fail;
2553
        gen_load_gpr(cpu_T[0], rt);
2554
        gen_op_ins(lsb, msb - lsb + 1);
2555
        break;
2556
#if defined(TARGET_MIPS64)
2557
    case OPC_DINSM:
2558
        if (lsb > msb)
2559
            goto fail;
2560
        gen_load_gpr(cpu_T[0], rt);
2561
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2562
        break;
2563
    case OPC_DINSU:
2564
        if (lsb > msb)
2565
            goto fail;
2566
        gen_load_gpr(cpu_T[0], rt);
2567
        gen_op_dins(lsb + 32, msb - lsb + 1);
2568
        break;
2569
    case OPC_DINS:
2570
        if (lsb > msb)
2571
            goto fail;
2572
        gen_load_gpr(cpu_T[0], rt);
2573
        gen_op_dins(lsb, msb - lsb + 1);
2574
        break;
2575
#endif
2576
    default:
2577
fail:
2578
        MIPS_INVAL("bitops");
2579
        generate_exception(ctx, EXCP_RI);
2580
        return;
2581
    }
2582
    gen_store_gpr(cpu_T[0], rt);
2583
}
2584

    
2585
/* CP0 (MMU and control) */
2586
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2587
{
2588
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2589

    
2590
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2591
    tcg_gen_ext_i32_tl(t, r_tmp);
2592
    tcg_temp_free(r_tmp);
2593
}
2594

    
2595
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2596
{
2597
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I64);
2598

    
2599
    tcg_gen_ld_i64(r_tmp, cpu_env, off);
2600
    tcg_gen_trunc_i64_tl(t, r_tmp);
2601
    tcg_temp_free(r_tmp);
2602
}
2603

    
2604
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2605
{
2606
    const char *rn = "invalid";
2607

    
2608
    if (sel != 0)
2609
        check_insn(env, ctx, ISA_MIPS32);
2610

    
2611
    switch (reg) {
2612
    case 0:
2613
        switch (sel) {
2614
        case 0:
2615
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
2616
            rn = "Index";
2617
            break;
2618
        case 1:
2619
            check_insn(env, ctx, ASE_MT);
2620
            gen_op_mfc0_mvpcontrol();
2621
            rn = "MVPControl";
2622
            break;
2623
        case 2:
2624
            check_insn(env, ctx, ASE_MT);
2625
            gen_op_mfc0_mvpconf0();
2626
            rn = "MVPConf0";
2627
            break;
2628
        case 3:
2629
            check_insn(env, ctx, ASE_MT);
2630
            gen_op_mfc0_mvpconf1();
2631
            rn = "MVPConf1";
2632
            break;
2633
        default:
2634
            goto die;
2635
        }
2636
        break;
2637
    case 1:
2638
        switch (sel) {
2639
        case 0:
2640
            gen_op_mfc0_random();
2641
            rn = "Random";
2642
            break;
2643
        case 1:
2644
            check_insn(env, ctx, ASE_MT);
2645
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
2646
            rn = "VPEControl";
2647
            break;
2648
        case 2:
2649
            check_insn(env, ctx, ASE_MT);
2650
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
2651
            rn = "VPEConf0";
2652
            break;
2653
        case 3:
2654
            check_insn(env, ctx, ASE_MT);
2655
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
2656
            rn = "VPEConf1";
2657
            break;
2658
        case 4:
2659
            check_insn(env, ctx, ASE_MT);
2660
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_YQMask));
2661
            rn = "YQMask";
2662
            break;
2663
        case 5:
2664
            check_insn(env, ctx, ASE_MT);
2665
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule));
2666
            rn = "VPESchedule";
2667
            break;
2668
        case 6:
2669
            check_insn(env, ctx, ASE_MT);
2670
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack));
2671
            rn = "VPEScheFBack";
2672
            break;
2673
        case 7:
2674
            check_insn(env, ctx, ASE_MT);
2675
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
2676
            rn = "VPEOpt";
2677
            break;
2678
        default:
2679
            goto die;
2680
        }
2681
        break;
2682
    case 2:
2683
        switch (sel) {
2684
        case 0:
2685
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2686
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2687
            rn = "EntryLo0";
2688
            break;
2689
        case 1:
2690
            check_insn(env, ctx, ASE_MT);
2691
            gen_op_mfc0_tcstatus();
2692
            rn = "TCStatus";
2693
            break;
2694
        case 2:
2695
            check_insn(env, ctx, ASE_MT);
2696
            gen_op_mfc0_tcbind();
2697
            rn = "TCBind";
2698
            break;
2699
        case 3:
2700
            check_insn(env, ctx, ASE_MT);
2701
            gen_op_mfc0_tcrestart();
2702
            rn = "TCRestart";
2703
            break;
2704
        case 4:
2705
            check_insn(env, ctx, ASE_MT);
2706
            gen_op_mfc0_tchalt();
2707
            rn = "TCHalt";
2708
            break;
2709
        case 5:
2710
            check_insn(env, ctx, ASE_MT);
2711
            gen_op_mfc0_tccontext();
2712
            rn = "TCContext";
2713
            break;
2714
        case 6:
2715
            check_insn(env, ctx, ASE_MT);
2716
            gen_op_mfc0_tcschedule();
2717
            rn = "TCSchedule";
2718
            break;
2719
        case 7:
2720
            check_insn(env, ctx, ASE_MT);
2721
            gen_op_mfc0_tcschefback();
2722
            rn = "TCScheFBack";
2723
            break;
2724
        default:
2725
            goto die;
2726
        }
2727
        break;
2728
    case 3:
2729
        switch (sel) {
2730
        case 0:
2731
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2732
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2733
            rn = "EntryLo1";
2734
            break;
2735
        default:
2736
            goto die;
2737
        }
2738
        break;
2739
    case 4:
2740
        switch (sel) {
2741
        case 0:
2742
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2743
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2744
            rn = "Context";
2745
            break;
2746
        case 1:
2747
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2748
            rn = "ContextConfig";
2749
//            break;
2750
        default:
2751
            goto die;
2752
        }
2753
        break;
2754
    case 5:
2755
        switch (sel) {
2756
        case 0:
2757
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
2758
            rn = "PageMask";
2759
            break;
2760
        case 1:
2761
            check_insn(env, ctx, ISA_MIPS32R2);
2762
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
2763
            rn = "PageGrain";
2764
            break;
2765
        default:
2766
            goto die;
2767
        }
2768
        break;
2769
    case 6:
2770
        switch (sel) {
2771
        case 0:
2772
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
2773
            rn = "Wired";
2774
            break;
2775
        case 1:
2776
            check_insn(env, ctx, ISA_MIPS32R2);
2777
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
2778
            rn = "SRSConf0";
2779
            break;
2780
        case 2:
2781
            check_insn(env, ctx, ISA_MIPS32R2);
2782
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
2783
            rn = "SRSConf1";
2784
            break;
2785
        case 3:
2786
            check_insn(env, ctx, ISA_MIPS32R2);
2787
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
2788
            rn = "SRSConf2";
2789
            break;
2790
        case 4:
2791
            check_insn(env, ctx, ISA_MIPS32R2);
2792
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
2793
            rn = "SRSConf3";
2794
            break;
2795
        case 5:
2796
            check_insn(env, ctx, ISA_MIPS32R2);
2797
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
2798
            rn = "SRSConf4";
2799
            break;
2800
        default:
2801
            goto die;
2802
        }
2803
        break;
2804
    case 7:
2805
        switch (sel) {
2806
        case 0:
2807
            check_insn(env, ctx, ISA_MIPS32R2);
2808
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
2809
            rn = "HWREna";
2810
            break;
2811
        default:
2812
            goto die;
2813
        }
2814
        break;
2815
    case 8:
2816
        switch (sel) {
2817
        case 0:
2818
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2819
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2820
            rn = "BadVAddr";
2821
            break;
2822
        default:
2823
            goto die;
2824
       }
2825
        break;
2826
    case 9:
2827
        switch (sel) {
2828
        case 0:
2829
            gen_op_mfc0_count();
2830
            rn = "Count";
2831
            break;
2832
        /* 6,7 are implementation dependent */
2833
        default:
2834
            goto die;
2835
        }
2836
        break;
2837
    case 10:
2838
        switch (sel) {
2839
        case 0:
2840
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2841
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2842
            rn = "EntryHi";
2843
            break;
2844
        default:
2845
            goto die;
2846
        }
2847
        break;
2848
    case 11:
2849
        switch (sel) {
2850
        case 0:
2851
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
2852
            rn = "Compare";
2853
            break;
2854
        /* 6,7 are implementation dependent */
2855
        default:
2856
            goto die;
2857
        }
2858
        break;
2859
    case 12:
2860
        switch (sel) {
2861
        case 0:
2862
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
2863
            rn = "Status";
2864
            break;
2865
        case 1:
2866
            check_insn(env, ctx, ISA_MIPS32R2);
2867
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
2868
            rn = "IntCtl";
2869
            break;
2870
        case 2:
2871
            check_insn(env, ctx, ISA_MIPS32R2);
2872
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
2873
            rn = "SRSCtl";
2874
            break;
2875
        case 3:
2876
            check_insn(env, ctx, ISA_MIPS32R2);
2877
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
2878
            rn = "SRSMap";
2879
            break;
2880
        default:
2881
            goto die;
2882
       }
2883
        break;
2884
    case 13:
2885
        switch (sel) {
2886
        case 0:
2887
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
2888
            rn = "Cause";
2889
            break;
2890
        default:
2891
            goto die;
2892
       }
2893
        break;
2894
    case 14:
2895
        switch (sel) {
2896
        case 0:
2897
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2898
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2899
            rn = "EPC";
2900
            break;
2901
        default:
2902
            goto die;
2903
        }
2904
        break;
2905
    case 15:
2906
        switch (sel) {
2907
        case 0:
2908
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
2909
            rn = "PRid";
2910
            break;
2911
        case 1:
2912
            check_insn(env, ctx, ISA_MIPS32R2);
2913
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
2914
            rn = "EBase";
2915
            break;
2916
        default:
2917
            goto die;
2918
       }
2919
        break;
2920
    case 16:
2921
        switch (sel) {
2922
        case 0:
2923
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
2924
            rn = "Config";
2925
            break;
2926
        case 1:
2927
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
2928
            rn = "Config1";
2929
            break;
2930
        case 2:
2931
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
2932
            rn = "Config2";
2933
            break;
2934
        case 3:
2935
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
2936
            rn = "Config3";
2937
            break;
2938
        /* 4,5 are reserved */
2939
        /* 6,7 are implementation dependent */
2940
        case 6:
2941
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
2942
            rn = "Config6";
2943
            break;
2944
        case 7:
2945
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
2946
            rn = "Config7";
2947
            break;
2948
        default:
2949
            goto die;
2950
        }
2951
        break;
2952
    case 17:
2953
        switch (sel) {
2954
        case 0:
2955
            gen_op_mfc0_lladdr();
2956
            rn = "LLAddr";
2957
            break;
2958
        default:
2959
            goto die;
2960
        }
2961
        break;
2962
    case 18:
2963
        switch (sel) {
2964
        case 0 ... 7:
2965
            gen_op_mfc0_watchlo(sel);
2966
            rn = "WatchLo";
2967
            break;
2968
        default:
2969
            goto die;
2970
        }
2971
        break;
2972
    case 19:
2973
        switch (sel) {
2974
        case 0 ...7:
2975
            gen_op_mfc0_watchhi(sel);
2976
            rn = "WatchHi";
2977
            break;
2978
        default:
2979
            goto die;
2980
        }
2981
        break;
2982
    case 20:
2983
        switch (sel) {
2984
        case 0:
2985
#if defined(TARGET_MIPS64)
2986
            check_insn(env, ctx, ISA_MIPS3);
2987
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2988
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2989
            rn = "XContext";
2990
            break;
2991
#endif
2992
        default:
2993
            goto die;
2994
        }
2995
        break;
2996
    case 21:
2997
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2998
        switch (sel) {
2999
        case 0:
3000
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
3001
            rn = "Framemask";
3002
            break;
3003
        default:
3004
            goto die;
3005
        }
3006
        break;
3007
    case 22:
3008
        /* ignored */
3009
        rn = "'Diagnostic"; /* implementation dependent */
3010
        break;
3011
    case 23:
3012
        switch (sel) {
3013
        case 0:
3014
            gen_op_mfc0_debug(); /* EJTAG support */
3015
            rn = "Debug";
3016
            break;
3017
        case 1:
3018
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3019
            rn = "TraceControl";
3020
//            break;
3021
        case 2:
3022
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3023
            rn = "TraceControl2";
3024
//            break;
3025
        case 3:
3026
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3027
            rn = "UserTraceData";
3028
//            break;
3029
        case 4:
3030
//            gen_op_mfc0_debug(); /* PDtrace support */
3031
            rn = "TraceBPC";
3032
//            break;
3033
        default:
3034
            goto die;
3035
        }
3036
        break;
3037
    case 24:
3038
        switch (sel) {
3039
        case 0:
3040
            /* EJTAG support */
3041
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3042
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3043
            rn = "DEPC";
3044
            break;
3045
        default:
3046
            goto die;
3047
        }
3048
        break;
3049
    case 25:
3050
        switch (sel) {
3051
        case 0:
3052
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
3053
            rn = "Performance0";
3054
            break;
3055
        case 1:
3056
//            gen_op_mfc0_performance1();
3057
            rn = "Performance1";
3058
//            break;
3059
        case 2:
3060
//            gen_op_mfc0_performance2();
3061
            rn = "Performance2";
3062
//            break;
3063
        case 3:
3064
//            gen_op_mfc0_performance3();
3065
            rn = "Performance3";
3066
//            break;
3067
        case 4:
3068
//            gen_op_mfc0_performance4();
3069
            rn = "Performance4";
3070
//            break;
3071
        case 5:
3072
//            gen_op_mfc0_performance5();
3073
            rn = "Performance5";
3074
//            break;
3075
        case 6:
3076
//            gen_op_mfc0_performance6();
3077
            rn = "Performance6";
3078
//            break;
3079
        case 7:
3080
//            gen_op_mfc0_performance7();
3081
            rn = "Performance7";
3082
//            break;
3083
        default:
3084
            goto die;
3085
        }
3086
        break;
3087
    case 26:
3088
       rn = "ECC";
3089
       break;
3090
    case 27:
3091
        switch (sel) {
3092
        /* ignored */
3093
        case 0 ... 3:
3094
            rn = "CacheErr";
3095
            break;
3096
        default:
3097
            goto die;
3098
        }
3099
        break;
3100
    case 28:
3101
        switch (sel) {
3102
        case 0:
3103
        case 2:
3104
        case 4:
3105
        case 6:
3106
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
3107
            rn = "TagLo";
3108
            break;
3109
        case 1:
3110
        case 3:
3111
        case 5:
3112
        case 7:
3113
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
3114
            rn = "DataLo";
3115
            break;
3116
        default:
3117
            goto die;
3118
        }
3119
        break;
3120
    case 29:
3121
        switch (sel) {
3122
        case 0:
3123
        case 2:
3124
        case 4:
3125
        case 6:
3126
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
3127
            rn = "TagHi";
3128
            break;
3129
        case 1:
3130
        case 3:
3131
        case 5:
3132
        case 7:
3133
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
3134
            rn = "DataHi";
3135
            break;
3136
        default:
3137
            goto die;
3138
        }
3139
        break;
3140
    case 30:
3141
        switch (sel) {
3142
        case 0:
3143
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3144
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3145
            rn = "ErrorEPC";
3146
            break;
3147
        default:
3148
            goto die;
3149
        }
3150
        break;
3151
    case 31:
3152
        switch (sel) {
3153
        case 0:
3154
            /* EJTAG support */
3155
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
3156
            rn = "DESAVE";
3157
            break;
3158
        default:
3159
            goto die;
3160
        }
3161
        break;
3162
    default:
3163
       goto die;
3164
    }
3165
#if defined MIPS_DEBUG_DISAS
3166
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3167
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3168
                rn, reg, sel);
3169
    }
3170
#endif
3171
    return;
3172

    
3173
die:
3174
#if defined MIPS_DEBUG_DISAS
3175
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3176
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3177
                rn, reg, sel);
3178
    }
3179
#endif
3180
    generate_exception(ctx, EXCP_RI);
3181
}
3182

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

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

    
3190
    switch (reg) {
3191
    case 0:
3192
        switch (sel) {
3193
        case 0:
3194
            gen_op_mtc0_index();
3195
            rn = "Index";
3196
            break;
3197
        case 1:
3198
            check_insn(env, ctx, ASE_MT);
3199
            gen_op_mtc0_mvpcontrol();
3200
            rn = "MVPControl";
3201
            break;
3202
        case 2:
3203
            check_insn(env, ctx, ASE_MT);
3204
            /* ignored */
3205
            rn = "MVPConf0";
3206
            break;
3207
        case 3:
3208
            check_insn(env, ctx, ASE_MT);
3209
            /* ignored */
3210
            rn = "MVPConf1";
3211
            break;
3212
        default:
3213
            goto die;
3214
        }
3215
        break;
3216
    case 1:
3217
        switch (sel) {
3218
        case 0:
3219
            /* ignored */
3220
            rn = "Random";
3221
            break;
3222
        case 1:
3223
            check_insn(env, ctx, ASE_MT);
3224
            gen_op_mtc0_vpecontrol();
3225
            rn = "VPEControl";
3226
            break;
3227
        case 2:
3228
            check_insn(env, ctx, ASE_MT);
3229
            gen_op_mtc0_vpeconf0();
3230
            rn = "VPEConf0";
3231
            break;
3232
        case 3:
3233
            check_insn(env, ctx, ASE_MT);
3234
            gen_op_mtc0_vpeconf1();
3235
            rn = "VPEConf1";
3236
            break;
3237
        case 4:
3238
            check_insn(env, ctx, ASE_MT);
3239
            gen_op_mtc0_yqmask();
3240
            rn = "YQMask";
3241
            break;
3242
        case 5:
3243
            check_insn(env, ctx, ASE_MT);
3244
            gen_op_mtc0_vpeschedule();
3245
            rn = "VPESchedule";
3246
            break;
3247
        case 6:
3248
            check_insn(env, ctx, ASE_MT);
3249
            gen_op_mtc0_vpeschefback();
3250
            rn = "VPEScheFBack";
3251
            break;
3252
        case 7:
3253
            check_insn(env, ctx, ASE_MT);
3254
            gen_op_mtc0_vpeopt();
3255
            rn = "VPEOpt";
3256
            break;
3257
        default:
3258
            goto die;
3259
        }
3260
        break;
3261
    case 2:
3262
        switch (sel) {
3263
        case 0:
3264
            gen_op_mtc0_entrylo0();
3265
            rn = "EntryLo0";
3266
            break;
3267
        case 1:
3268
            check_insn(env, ctx, ASE_MT);
3269
            gen_op_mtc0_tcstatus();
3270
            rn = "TCStatus";
3271
            break;
3272
        case 2:
3273
            check_insn(env, ctx, ASE_MT);
3274
            gen_op_mtc0_tcbind();
3275
            rn = "TCBind";
3276
            break;
3277
        case 3:
3278
            check_insn(env, ctx, ASE_MT);
3279
            gen_op_mtc0_tcrestart();
3280
            rn = "TCRestart";
3281
            break;
3282
        case 4:
3283
            check_insn(env, ctx, ASE_MT);
3284
            gen_op_mtc0_tchalt();
3285
            rn = "TCHalt";
3286
            break;
3287
        case 5:
3288
            check_insn(env, ctx, ASE_MT);
3289
            gen_op_mtc0_tccontext();
3290
            rn = "TCContext";
3291
            break;
3292
        case 6:
3293
            check_insn(env, ctx, ASE_MT);
3294
            gen_op_mtc0_tcschedule();
3295
            rn = "TCSchedule";
3296
            break;
3297
        case 7:
3298
            check_insn(env, ctx, ASE_MT);
3299
            gen_op_mtc0_tcschefback();
3300
            rn = "TCScheFBack";
3301
            break;
3302
        default:
3303
            goto die;
3304
        }
3305
        break;
3306
    case 3:
3307
        switch (sel) {
3308
        case 0:
3309
            gen_op_mtc0_entrylo1();
3310
            rn = "EntryLo1";
3311
            break;
3312
        default:
3313
            goto die;
3314
        }
3315
        break;
3316
    case 4:
3317
        switch (sel) {
3318
        case 0:
3319
            gen_op_mtc0_context();
3320
            rn = "Context";
3321
            break;
3322
        case 1:
3323
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3324
            rn = "ContextConfig";
3325
//            break;
3326
        default:
3327
            goto die;
3328
        }
3329
        break;
3330
    case 5:
3331
        switch (sel) {
3332
        case 0:
3333
            gen_op_mtc0_pagemask();
3334
            rn = "PageMask";
3335
            break;
3336
        case 1:
3337
            check_insn(env, ctx, ISA_MIPS32R2);
3338
            gen_op_mtc0_pagegrain();
3339
            rn = "PageGrain";
3340
            break;
3341
        default:
3342
            goto die;
3343
        }
3344
        break;
3345
    case 6:
3346
        switch (sel) {
3347
        case 0:
3348
            gen_op_mtc0_wired();
3349
            rn = "Wired";
3350
            break;
3351
        case 1:
3352
            check_insn(env, ctx, ISA_MIPS32R2);
3353
            gen_op_mtc0_srsconf0();
3354
            rn = "SRSConf0";
3355
            break;
3356
        case 2:
3357
            check_insn(env, ctx, ISA_MIPS32R2);
3358
            gen_op_mtc0_srsconf1();
3359
            rn = "SRSConf1";
3360
            break;
3361
        case 3:
3362
            check_insn(env, ctx, ISA_MIPS32R2);
3363
            gen_op_mtc0_srsconf2();
3364
            rn = "SRSConf2";
3365
            break;
3366
        case 4:
3367
            check_insn(env, ctx, ISA_MIPS32R2);
3368
            gen_op_mtc0_srsconf3();
3369
            rn = "SRSConf3";
3370
            break;
3371
        case 5:
3372
            check_insn(env, ctx, ISA_MIPS32R2);
3373
            gen_op_mtc0_srsconf4();
3374
            rn = "SRSConf4";
3375
            break;
3376
        default:
3377
            goto die;
3378
        }
3379
        break;
3380
    case 7:
3381
        switch (sel) {
3382
        case 0:
3383
            check_insn(env, ctx, ISA_MIPS32R2);
3384
            gen_op_mtc0_hwrena();
3385
            rn = "HWREna";
3386
            break;
3387
        default:
3388
            goto die;
3389
        }
3390
        break;
3391
    case 8:
3392
        /* ignored */
3393
        rn = "BadVAddr";
3394
        break;
3395
    case 9:
3396
        switch (sel) {
3397
        case 0:
3398
            gen_op_mtc0_count();
3399
            rn = "Count";
3400
            break;
3401
        /* 6,7 are implementation dependent */
3402
        default:
3403
            goto die;
3404
        }
3405
        /* Stop translation as we may have switched the execution mode */
3406
        ctx->bstate = BS_STOP;
3407
        break;
3408
    case 10:
3409
        switch (sel) {
3410
        case 0:
3411
            gen_op_mtc0_entryhi();
3412
            rn = "EntryHi";
3413
            break;
3414
        default:
3415
            goto die;
3416
        }
3417
        break;
3418
    case 11:
3419
        switch (sel) {
3420
        case 0:
3421
            gen_op_mtc0_compare();
3422
            rn = "Compare";
3423
            break;
3424
        /* 6,7 are implementation dependent */
3425
        default:
3426
            goto die;
3427
        }
3428
        /* Stop translation as we may have switched the execution mode */
3429
        ctx->bstate = BS_STOP;
3430
        break;
3431
    case 12:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_op_mtc0_status();
3435
            /* BS_STOP isn't good enough here, hflags may have changed. */
3436
            gen_save_pc(ctx->pc + 4);
3437
            ctx->bstate = BS_EXCP;
3438
            rn = "Status";
3439
            break;
3440
        case 1:
3441
            check_insn(env, ctx, ISA_MIPS32R2);
3442
            gen_op_mtc0_intctl();
3443
            /* Stop translation as we may have switched the execution mode */
3444
            ctx->bstate = BS_STOP;
3445
            rn = "IntCtl";
3446
            break;
3447
        case 2:
3448
            check_insn(env, ctx, ISA_MIPS32R2);
3449
            gen_op_mtc0_srsctl();
3450
            /* Stop translation as we may have switched the execution mode */
3451
            ctx->bstate = BS_STOP;
3452
            rn = "SRSCtl";
3453
            break;
3454
        case 3:
3455
            check_insn(env, ctx, ISA_MIPS32R2);
3456
            gen_op_mtc0_srsmap();
3457
            /* Stop translation as we may have switched the execution mode */
3458
            ctx->bstate = BS_STOP;
3459
            rn = "SRSMap";
3460
            break;
3461
        default:
3462
            goto die;
3463
        }
3464
        break;
3465
    case 13:
3466
        switch (sel) {
3467
        case 0:
3468
            gen_op_mtc0_cause();
3469
            rn = "Cause";
3470
            break;
3471
        default:
3472
            goto die;
3473
        }
3474
        /* Stop translation as we may have switched the execution mode */
3475
        ctx->bstate = BS_STOP;
3476
        break;
3477
    case 14:
3478
        switch (sel) {
3479
        case 0:
3480
            gen_op_mtc0_epc();
3481
            rn = "EPC";
3482
            break;
3483
        default:
3484
            goto die;
3485
        }
3486
        break;
3487
    case 15:
3488
        switch (sel) {
3489
        case 0:
3490
            /* ignored */
3491
            rn = "PRid";
3492
            break;
3493
        case 1:
3494
            check_insn(env, ctx, ISA_MIPS32R2);
3495
            gen_op_mtc0_ebase();
3496
            rn = "EBase";
3497
            break;
3498
        default:
3499
            goto die;
3500
        }
3501
        break;
3502
    case 16:
3503
        switch (sel) {
3504
        case 0:
3505
            gen_op_mtc0_config0();
3506
            rn = "Config";
3507
            /* Stop translation as we may have switched the execution mode */
3508
            ctx->bstate = BS_STOP;
3509
            break;
3510
        case 1:
3511
            /* ignored, read only */
3512
            rn = "Config1";
3513
            break;
3514
        case 2:
3515
            gen_op_mtc0_config2();
3516
            rn = "Config2";
3517
            /* Stop translation as we may have switched the execution mode */
3518
            ctx->bstate = BS_STOP;
3519
            break;
3520
        case 3:
3521
            /* ignored, read only */
3522
            rn = "Config3";
3523
            break;
3524
        /* 4,5 are reserved */
3525
        /* 6,7 are implementation dependent */
3526
        case 6:
3527
            /* ignored */
3528
            rn = "Config6";
3529
            break;
3530
        case 7:
3531
            /* ignored */
3532
            rn = "Config7";
3533
            break;
3534
        default:
3535
            rn = "Invalid config selector";
3536
            goto die;
3537
        }
3538
        break;
3539
    case 17:
3540
        switch (sel) {
3541
        case 0:
3542
            /* ignored */
3543
            rn = "LLAddr";
3544
            break;
3545
        default:
3546
            goto die;
3547
        }
3548
        break;
3549
    case 18:
3550
        switch (sel) {
3551
        case 0 ... 7:
3552
            gen_op_mtc0_watchlo(sel);
3553
            rn = "WatchLo";
3554
            break;
3555
        default:
3556
            goto die;
3557
        }
3558
        break;
3559
    case 19:
3560
        switch (sel) {
3561
        case 0 ... 7:
3562
            gen_op_mtc0_watchhi(sel);
3563
            rn = "WatchHi";
3564
            break;
3565
        default:
3566
            goto die;
3567
        }
3568
        break;
3569
    case 20:
3570
        switch (sel) {
3571
        case 0:
3572
#if defined(TARGET_MIPS64)
3573
            check_insn(env, ctx, ISA_MIPS3);
3574
            gen_op_mtc0_xcontext();
3575
            rn = "XContext";
3576
            break;
3577
#endif
3578
        default:
3579
            goto die;
3580
        }
3581
        break;
3582
    case 21:
3583
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3584
        switch (sel) {
3585
        case 0:
3586
            gen_op_mtc0_framemask();
3587
            rn = "Framemask";
3588
            break;
3589
        default:
3590
            goto die;
3591
        }
3592
        break;
3593
    case 22:
3594
        /* ignored */
3595
        rn = "Diagnostic"; /* implementation dependent */
3596
        break;
3597
    case 23:
3598
        switch (sel) {
3599
        case 0:
3600
            gen_op_mtc0_debug(); /* EJTAG support */
3601
            /* BS_STOP isn't good enough here, hflags may have changed. */
3602
            gen_save_pc(ctx->pc + 4);
3603
            ctx->bstate = BS_EXCP;
3604
            rn = "Debug";
3605
            break;
3606
        case 1:
3607
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3608
            rn = "TraceControl";
3609
            /* Stop translation as we may have switched the execution mode */
3610
            ctx->bstate = BS_STOP;
3611
//            break;
3612
        case 2:
3613
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3614
            rn = "TraceControl2";
3615
            /* Stop translation as we may have switched the execution mode */
3616
            ctx->bstate = BS_STOP;
3617
//            break;
3618
        case 3:
3619
            /* Stop translation as we may have switched the execution mode */
3620
            ctx->bstate = BS_STOP;
3621
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3622
            rn = "UserTraceData";
3623
            /* Stop translation as we may have switched the execution mode */
3624
            ctx->bstate = BS_STOP;
3625
//            break;
3626
        case 4:
3627
//            gen_op_mtc0_debug(); /* PDtrace support */
3628
            /* Stop translation as we may have switched the execution mode */
3629
            ctx->bstate = BS_STOP;
3630
            rn = "TraceBPC";
3631
//            break;
3632
        default:
3633
            goto die;
3634
        }
3635
        break;
3636
    case 24:
3637
        switch (sel) {
3638
        case 0:
3639
            gen_op_mtc0_depc(); /* EJTAG support */
3640
            rn = "DEPC";
3641
            break;
3642
        default:
3643
            goto die;
3644
        }
3645
        break;
3646
    case 25:
3647
        switch (sel) {
3648
        case 0:
3649
            gen_op_mtc0_performance0();
3650
            rn = "Performance0";
3651
            break;
3652
        case 1:
3653
//            gen_op_mtc0_performance1();
3654
            rn = "Performance1";
3655
//            break;
3656
        case 2:
3657
//            gen_op_mtc0_performance2();
3658
            rn = "Performance2";
3659
//            break;
3660
        case 3:
3661
//            gen_op_mtc0_performance3();
3662
            rn = "Performance3";
3663
//            break;
3664
        case 4:
3665
//            gen_op_mtc0_performance4();
3666
            rn = "Performance4";
3667
//            break;
3668
        case 5:
3669
//            gen_op_mtc0_performance5();
3670
            rn = "Performance5";
3671
//            break;
3672
        case 6:
3673
//            gen_op_mtc0_performance6();
3674
            rn = "Performance6";
3675
//            break;
3676
        case 7:
3677
//            gen_op_mtc0_performance7();
3678
            rn = "Performance7";
3679
//            break;
3680
        default:
3681
            goto die;
3682
        }
3683
       break;
3684
    case 26:
3685
        /* ignored */
3686
        rn = "ECC";
3687
        break;
3688
    case 27:
3689
        switch (sel) {
3690
        case 0 ... 3:
3691
            /* ignored */
3692
            rn = "CacheErr";
3693
            break;
3694
        default:
3695
            goto die;
3696
        }
3697
       break;
3698
    case 28:
3699
        switch (sel) {
3700
        case 0:
3701
        case 2:
3702
        case 4:
3703
        case 6:
3704
            gen_op_mtc0_taglo();
3705
            rn = "TagLo";
3706
            break;
3707
        case 1:
3708
        case 3:
3709
        case 5:
3710
        case 7:
3711
            gen_op_mtc0_datalo();
3712
            rn = "DataLo";
3713
            break;
3714
        default:
3715
            goto die;
3716
        }
3717
        break;
3718
    case 29:
3719
        switch (sel) {
3720
        case 0:
3721
        case 2:
3722
        case 4:
3723
        case 6:
3724
            gen_op_mtc0_taghi();
3725
            rn = "TagHi";
3726
            break;
3727
        case 1:
3728
        case 3:
3729
        case 5:
3730
        case 7:
3731
            gen_op_mtc0_datahi();
3732
            rn = "DataHi";
3733
            break;
3734
        default:
3735
            rn = "invalid sel";
3736
            goto die;
3737
        }
3738
       break;
3739
    case 30:
3740
        switch (sel) {
3741
        case 0:
3742
            gen_op_mtc0_errorepc();
3743
            rn = "ErrorEPC";
3744
            break;
3745
        default:
3746
            goto die;
3747
        }
3748
        break;
3749
    case 31:
3750
        switch (sel) {
3751
        case 0:
3752
            gen_op_mtc0_desave(); /* EJTAG support */
3753
            rn = "DESAVE";
3754
            break;
3755
        default:
3756
            goto die;
3757
        }
3758
        /* Stop translation as we may have switched the execution mode */
3759
        ctx->bstate = BS_STOP;
3760
        break;
3761
    default:
3762
       goto die;
3763
    }
3764
#if defined MIPS_DEBUG_DISAS
3765
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3766
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3767
                rn, reg, sel);
3768
    }
3769
#endif
3770
    return;
3771

    
3772
die:
3773
#if defined MIPS_DEBUG_DISAS
3774
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3775
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3776
                rn, reg, sel);
3777
    }
3778
#endif
3779
    generate_exception(ctx, EXCP_RI);
3780
}
3781

    
3782
#if defined(TARGET_MIPS64)
3783
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3784
{
3785
    const char *rn = "invalid";
3786

    
3787
    if (sel != 0)
3788
        check_insn(env, ctx, ISA_MIPS64);
3789

    
3790
    switch (reg) {
3791
    case 0:
3792
        switch (sel) {
3793
        case 0:
3794
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
3795
            rn = "Index";
3796
            break;
3797
        case 1:
3798
            check_insn(env, ctx, ASE_MT);
3799
            gen_op_mfc0_mvpcontrol();
3800
            rn = "MVPControl";
3801
            break;
3802
        case 2:
3803
            check_insn(env, ctx, ASE_MT);
3804
            gen_op_mfc0_mvpconf0();
3805
            rn = "MVPConf0";
3806
            break;
3807
        case 3:
3808
            check_insn(env, ctx, ASE_MT);
3809
            gen_op_mfc0_mvpconf1();
3810
            rn = "MVPConf1";
3811
            break;
3812
        default:
3813
            goto die;
3814
        }
3815
        break;
3816
    case 1:
3817
        switch (sel) {
3818
        case 0:
3819
            gen_op_mfc0_random();
3820
            rn = "Random";
3821
            break;
3822
        case 1:
3823
            check_insn(env, ctx, ASE_MT);
3824
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
3825
            rn = "VPEControl";
3826
            break;
3827
        case 2:
3828
            check_insn(env, ctx, ASE_MT);
3829
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
3830
            rn = "VPEConf0";
3831
            break;
3832
        case 3:
3833
            check_insn(env, ctx, ASE_MT);
3834
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
3835
            rn = "VPEConf1";
3836
            break;
3837
        case 4:
3838
            check_insn(env, ctx, ASE_MT);
3839
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3840
            rn = "YQMask";
3841
            break;
3842
        case 5:
3843
            check_insn(env, ctx, ASE_MT);
3844
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3845
            rn = "VPESchedule";
3846
            break;
3847
        case 6:
3848
            check_insn(env, ctx, ASE_MT);
3849
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3850
            rn = "VPEScheFBack";
3851
            break;
3852
        case 7:
3853
            check_insn(env, ctx, ASE_MT);
3854
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
3855
            rn = "VPEOpt";
3856
            break;
3857
        default:
3858
            goto die;
3859
        }
3860
        break;
3861
    case 2:
3862
        switch (sel) {
3863
        case 0:
3864
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3865
            rn = "EntryLo0";
3866
            break;
3867
        case 1:
3868
            check_insn(env, ctx, ASE_MT);
3869
            gen_op_mfc0_tcstatus();
3870
            rn = "TCStatus";
3871
            break;
3872
        case 2:
3873
            check_insn(env, ctx, ASE_MT);
3874
            gen_op_mfc0_tcbind();
3875
            rn = "TCBind";
3876
            break;
3877
        case 3:
3878
            check_insn(env, ctx, ASE_MT);
3879
            gen_op_dmfc0_tcrestart();
3880
            rn = "TCRestart";
3881
            break;
3882
        case 4:
3883
            check_insn(env, ctx, ASE_MT);
3884
            gen_op_dmfc0_tchalt();
3885
            rn = "TCHalt";
3886
            break;
3887
        case 5:
3888
            check_insn(env, ctx, ASE_MT);
3889
            gen_op_dmfc0_tccontext();
3890
            rn = "TCContext";
3891
            break;
3892
        case 6:
3893
            check_insn(env, ctx, ASE_MT);
3894
            gen_op_dmfc0_tcschedule();
3895
            rn = "TCSchedule";
3896
            break;
3897
        case 7:
3898
            check_insn(env, ctx, ASE_MT);
3899
            gen_op_dmfc0_tcschefback();
3900
            rn = "TCScheFBack";
3901
            break;
3902
        default:
3903
            goto die;
3904
        }
3905
        break;
3906
    case 3:
3907
        switch (sel) {
3908
        case 0:
3909
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3910
            rn = "EntryLo1";
3911
            break;
3912
        default:
3913
            goto die;
3914
        }
3915
        break;
3916
    case 4:
3917
        switch (sel) {
3918
        case 0:
3919
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3920
            rn = "Context";
3921
            break;
3922
        case 1:
3923
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3924
            rn = "ContextConfig";
3925
//            break;
3926
        default:
3927
            goto die;
3928
        }
3929
        break;
3930
    case 5:
3931
        switch (sel) {
3932
        case 0:
3933
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
3934
            rn = "PageMask";
3935
            break;
3936
        case 1:
3937
            check_insn(env, ctx, ISA_MIPS32R2);
3938
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
3939
            rn = "PageGrain";
3940
            break;
3941
        default:
3942
            goto die;
3943
        }
3944
        break;
3945
    case 6:
3946
        switch (sel) {
3947
        case 0:
3948
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
3949
            rn = "Wired";
3950
            break;
3951
        case 1:
3952
            check_insn(env, ctx, ISA_MIPS32R2);
3953
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
3954
            rn = "SRSConf0";
3955
            break;
3956
        case 2:
3957
            check_insn(env, ctx, ISA_MIPS32R2);
3958
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
3959
            rn = "SRSConf1";
3960
            break;
3961
        case 3:
3962
            check_insn(env, ctx, ISA_MIPS32R2);
3963
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
3964
            rn = "SRSConf2";
3965
            break;
3966
        case 4:
3967
            check_insn(env, ctx, ISA_MIPS32R2);
3968
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
3969
            rn = "SRSConf3";
3970
            break;
3971
        case 5:
3972
            check_insn(env, ctx, ISA_MIPS32R2);
3973
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
3974
            rn = "SRSConf4";
3975
            break;
3976
        default:
3977
            goto die;
3978
        }
3979
        break;
3980
    case 7:
3981
        switch (sel) {
3982
        case 0:
3983
            check_insn(env, ctx, ISA_MIPS32R2);
3984
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
3985
            rn = "HWREna";
3986
            break;
3987
        default:
3988
            goto die;
3989
        }
3990
        break;
3991
    case 8:
3992
        switch (sel) {
3993
        case 0:
3994
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
3995
            rn = "BadVAddr";
3996
            break;
3997
        default:
3998
            goto die;
3999
        }
4000
        break;
4001
    case 9:
4002
        switch (sel) {
4003
        case 0:
4004
            gen_op_mfc0_count();
4005
            rn = "Count";
4006
            break;
4007
        /* 6,7 are implementation dependent */
4008
        default:
4009
            goto die;
4010
        }
4011
        break;
4012
    case 10:
4013
        switch (sel) {
4014
        case 0:
4015
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4016
            rn = "EntryHi";
4017
            break;
4018
        default:
4019
            goto die;
4020
        }
4021
        break;
4022
    case 11:
4023
        switch (sel) {
4024
        case 0:
4025
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
4026
            rn = "Compare";
4027
            break;
4028
        /* 6,7 are implementation dependent */
4029
        default:
4030
            goto die;
4031
        }
4032
        break;
4033
    case 12:
4034
        switch (sel) {
4035
        case 0:
4036
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
4037
            rn = "Status";
4038
            break;
4039
        case 1:
4040
            check_insn(env, ctx, ISA_MIPS32R2);
4041
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
4042
            rn = "IntCtl";
4043
            break;
4044
        case 2:
4045
            check_insn(env, ctx, ISA_MIPS32R2);
4046
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
4047
            rn = "SRSCtl";
4048
            break;
4049
        case 3:
4050
            check_insn(env, ctx, ISA_MIPS32R2);
4051
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
4052
            rn = "SRSMap";
4053
            break;
4054
        default:
4055
            goto die;
4056
        }
4057
        break;
4058
    case 13:
4059
        switch (sel) {
4060
        case 0:
4061
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
4062
            rn = "Cause";
4063
            break;
4064
        default:
4065
            goto die;
4066
        }
4067
        break;
4068
    case 14:
4069
        switch (sel) {
4070
        case 0:
4071
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4072
            rn = "EPC";
4073
            break;
4074
        default:
4075
            goto die;
4076
        }
4077
        break;
4078
    case 15:
4079
        switch (sel) {
4080
        case 0:
4081
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
4082
            rn = "PRid";
4083
            break;
4084
        case 1:
4085
            check_insn(env, ctx, ISA_MIPS32R2);
4086
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
4087
            rn = "EBase";
4088
            break;
4089
        default:
4090
            goto die;
4091
        }
4092
        break;
4093
    case 16:
4094
        switch (sel) {
4095
        case 0:
4096
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
4097
            rn = "Config";
4098
            break;
4099
        case 1:
4100
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
4101
            rn = "Config1";
4102
            break;
4103
        case 2:
4104
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
4105
            rn = "Config2";
4106
            break;
4107
        case 3:
4108
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
4109
            rn = "Config3";
4110
            break;
4111
       /* 6,7 are implementation dependent */
4112
        case 6:
4113
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
4114
            rn = "Config6";
4115
            break;
4116
        case 7:
4117
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
4118
            rn = "Config7";
4119
            break;
4120
        default:
4121
            goto die;
4122
        }
4123
        break;
4124
    case 17:
4125
        switch (sel) {
4126
        case 0:
4127
            gen_op_dmfc0_lladdr();
4128
            rn = "LLAddr";
4129
            break;
4130
        default:
4131
            goto die;
4132
        }
4133
        break;
4134
    case 18:
4135
        switch (sel) {
4136
        case 0 ... 7:
4137
            gen_op_dmfc0_watchlo(sel);
4138
            rn = "WatchLo";
4139
            break;
4140
        default:
4141
            goto die;
4142
        }
4143
        break;
4144
    case 19:
4145
        switch (sel) {
4146
        case 0 ... 7:
4147
            gen_op_mfc0_watchhi(sel);
4148
            rn = "WatchHi";
4149
            break;
4150
        default:
4151
            goto die;
4152
        }
4153
        break;
4154
    case 20:
4155
        switch (sel) {
4156
        case 0:
4157
            check_insn(env, ctx, ISA_MIPS3);
4158
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4159
            rn = "XContext";
4160
            break;
4161
        default:
4162
            goto die;
4163
        }
4164
        break;
4165
    case 21:
4166
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4167
        switch (sel) {
4168
        case 0:
4169
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
4170
            rn = "Framemask";
4171
            break;
4172
        default:
4173
            goto die;
4174
        }
4175
        break;
4176
    case 22:
4177
        /* ignored */
4178
        rn = "'Diagnostic"; /* implementation dependent */
4179
        break;
4180
    case 23:
4181
        switch (sel) {
4182
        case 0:
4183
            gen_op_mfc0_debug(); /* EJTAG support */
4184
            rn = "Debug";
4185
            break;
4186
        case 1:
4187
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4188
            rn = "TraceControl";
4189
//            break;
4190
        case 2:
4191
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4192
            rn = "TraceControl2";
4193
//            break;
4194
        case 3:
4195
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4196
            rn = "UserTraceData";
4197
//            break;
4198
        case 4:
4199
//            gen_op_dmfc0_debug(); /* PDtrace support */
4200
            rn = "TraceBPC";
4201
//            break;
4202
        default:
4203
            goto die;
4204
        }
4205
        break;
4206
    case 24:
4207
        switch (sel) {
4208
        case 0:
4209
            /* EJTAG support */
4210
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4211
            rn = "DEPC";
4212
            break;
4213
        default:
4214
            goto die;
4215
        }
4216
        break;
4217
    case 25:
4218
        switch (sel) {
4219
        case 0:
4220
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
4221
            rn = "Performance0";
4222
            break;
4223
        case 1:
4224
//            gen_op_dmfc0_performance1();
4225
            rn = "Performance1";
4226
//            break;
4227
        case 2:
4228
//            gen_op_dmfc0_performance2();
4229
            rn = "Performance2";
4230
//            break;
4231
        case 3:
4232
//            gen_op_dmfc0_performance3();
4233
            rn = "Performance3";
4234
//            break;
4235
        case 4:
4236
//            gen_op_dmfc0_performance4();
4237
            rn = "Performance4";
4238
//            break;
4239
        case 5:
4240
//            gen_op_dmfc0_performance5();
4241
            rn = "Performance5";
4242
//            break;
4243
        case 6:
4244
//            gen_op_dmfc0_performance6();
4245
            rn = "Performance6";
4246
//            break;
4247
        case 7:
4248
//            gen_op_dmfc0_performance7();
4249
            rn = "Performance7";
4250
//            break;
4251
        default:
4252
            goto die;
4253
        }
4254
        break;
4255
    case 26:
4256
       rn = "ECC";
4257
       break;
4258
    case 27:
4259
        switch (sel) {
4260
        /* ignored */
4261
        case 0 ... 3:
4262
            rn = "CacheErr";
4263
            break;
4264
        default:
4265
            goto die;
4266
        }
4267
        break;
4268
    case 28:
4269
        switch (sel) {
4270
        case 0:
4271
        case 2:
4272
        case 4:
4273
        case 6:
4274
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
4275
            rn = "TagLo";
4276
            break;
4277
        case 1:
4278
        case 3:
4279
        case 5:
4280
        case 7:
4281
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
4282
            rn = "DataLo";
4283
            break;
4284
        default:
4285
            goto die;
4286
        }
4287
        break;
4288
    case 29:
4289
        switch (sel) {
4290
        case 0:
4291
        case 2:
4292
        case 4:
4293
        case 6:
4294
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
4295
            rn = "TagHi";
4296
            break;
4297
        case 1:
4298
        case 3:
4299
        case 5:
4300
        case 7:
4301
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
4302
            rn = "DataHi";
4303
            break;
4304
        default:
4305
            goto die;
4306
        }
4307
        break;
4308
    case 30:
4309
        switch (sel) {
4310
        case 0:
4311
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4312
            rn = "ErrorEPC";
4313
            break;
4314
        default:
4315
            goto die;
4316
        }
4317
        break;
4318
    case 31:
4319
        switch (sel) {
4320
        case 0:
4321
            /* EJTAG support */
4322
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
4323
            rn = "DESAVE";
4324
            break;
4325
        default:
4326
            goto die;
4327
        }
4328
        break;
4329
    default:
4330
        goto die;
4331
    }
4332
#if defined MIPS_DEBUG_DISAS
4333
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4334
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4335
                rn, reg, sel);
4336
    }
4337
#endif
4338
    return;
4339

    
4340
die:
4341
#if defined MIPS_DEBUG_DISAS
4342
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4343
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4344
                rn, reg, sel);
4345
    }
4346
#endif
4347
    generate_exception(ctx, EXCP_RI);
4348
}
4349

    
4350
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4351
{
4352
    const char *rn = "invalid";
4353

    
4354
    if (sel != 0)
4355
        check_insn(env, ctx, ISA_MIPS64);
4356

    
4357
    switch (reg) {
4358
    case 0:
4359
        switch (sel) {
4360
        case 0:
4361
            gen_op_mtc0_index();
4362
            rn = "Index";
4363
            break;
4364
        case 1:
4365
            check_insn(env, ctx, ASE_MT);
4366
            gen_op_mtc0_mvpcontrol();
4367
            rn = "MVPControl";
4368
            break;
4369
        case 2:
4370
            check_insn(env, ctx, ASE_MT);
4371
            /* ignored */
4372
            rn = "MVPConf0";
4373
            break;
4374
        case 3:
4375
            check_insn(env, ctx, ASE_MT);
4376
            /* ignored */
4377
            rn = "MVPConf1";
4378
            break;
4379
        default:
4380
            goto die;
4381
        }
4382
        break;
4383
    case 1:
4384
        switch (sel) {
4385
        case 0:
4386
            /* ignored */
4387
            rn = "Random";
4388
            break;
4389
        case 1:
4390
            check_insn(env, ctx, ASE_MT);
4391
            gen_op_mtc0_vpecontrol();
4392
            rn = "VPEControl";
4393
            break;
4394
        case 2:
4395
            check_insn(env, ctx, ASE_MT);
4396
            gen_op_mtc0_vpeconf0();
4397
            rn = "VPEConf0";
4398
            break;
4399
        case 3:
4400
            check_insn(env, ctx, ASE_MT);
4401
            gen_op_mtc0_vpeconf1();
4402
            rn = "VPEConf1";
4403
            break;
4404
        case 4:
4405
            check_insn(env, ctx, ASE_MT);
4406
            gen_op_mtc0_yqmask();
4407
            rn = "YQMask";
4408
            break;
4409
        case 5:
4410
            check_insn(env, ctx, ASE_MT);
4411
            gen_op_mtc0_vpeschedule();
4412
            rn = "VPESchedule";
4413
            break;
4414
        case 6:
4415
            check_insn(env, ctx, ASE_MT);
4416
            gen_op_mtc0_vpeschefback();
4417
            rn = "VPEScheFBack";
4418
            break;
4419
        case 7:
4420
            check_insn(env, ctx, ASE_MT);
4421
            gen_op_mtc0_vpeopt();
4422
            rn = "VPEOpt";
4423
            break;
4424
        default:
4425
            goto die;
4426
        }
4427
        break;
4428
    case 2:
4429
        switch (sel) {
4430
        case 0:
4431
            gen_op_mtc0_entrylo0();
4432
            rn = "EntryLo0";
4433
            break;
4434
        case 1:
4435
            check_insn(env, ctx, ASE_MT);
4436
            gen_op_mtc0_tcstatus();
4437
            rn = "TCStatus";
4438
            break;
4439
        case 2:
4440
            check_insn(env, ctx, ASE_MT);
4441
            gen_op_mtc0_tcbind();
4442
            rn = "TCBind";
4443
            break;
4444
        case 3:
4445
            check_insn(env, ctx, ASE_MT);
4446
            gen_op_mtc0_tcrestart();
4447
            rn = "TCRestart";
4448
            break;
4449
        case 4:
4450
            check_insn(env, ctx, ASE_MT);
4451
            gen_op_mtc0_tchalt();
4452
            rn = "TCHalt";
4453
            break;
4454
        case 5:
4455
            check_insn(env, ctx, ASE_MT);
4456
            gen_op_mtc0_tccontext();
4457
            rn = "TCContext";
4458
            break;
4459
        case 6:
4460
            check_insn(env, ctx, ASE_MT);
4461
            gen_op_mtc0_tcschedule();
4462
            rn = "TCSchedule";
4463
            break;
4464
        case 7:
4465
            check_insn(env, ctx, ASE_MT);
4466
            gen_op_mtc0_tcschefback();
4467
            rn = "TCScheFBack";
4468
            break;
4469
        default:
4470
            goto die;
4471
        }
4472
        break;
4473
    case 3:
4474
        switch (sel) {
4475
        case 0:
4476
            gen_op_mtc0_entrylo1();
4477
            rn = "EntryLo1";
4478
            break;
4479
        default:
4480
            goto die;
4481
        }
4482
        break;
4483
    case 4:
4484
        switch (sel) {
4485
        case 0:
4486
            gen_op_mtc0_context();
4487
            rn = "Context";
4488
            break;
4489
        case 1:
4490
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4491
            rn = "ContextConfig";
4492
//           break;
4493
        default:
4494
            goto die;
4495
        }
4496
        break;
4497
    case 5:
4498
        switch (sel) {
4499
        case 0:
4500
            gen_op_mtc0_pagemask();
4501
            rn = "PageMask";
4502
            break;
4503
        case 1:
4504
            check_insn(env, ctx, ISA_MIPS32R2);
4505
            gen_op_mtc0_pagegrain();
4506
            rn = "PageGrain";
4507
            break;
4508
        default:
4509
            goto die;
4510
        }
4511
        break;
4512
    case 6:
4513
        switch (sel) {
4514
        case 0:
4515
            gen_op_mtc0_wired();
4516
            rn = "Wired";
4517
            break;
4518
        case 1:
4519
            check_insn(env, ctx, ISA_MIPS32R2);
4520
            gen_op_mtc0_srsconf0();
4521
            rn = "SRSConf0";
4522
            break;
4523
        case 2:
4524
            check_insn(env, ctx, ISA_MIPS32R2);
4525
            gen_op_mtc0_srsconf1();
4526
            rn = "SRSConf1";
4527
            break;
4528
        case 3:
4529
            check_insn(env, ctx, ISA_MIPS32R2);
4530
            gen_op_mtc0_srsconf2();
4531
            rn = "SRSConf2";
4532
            break;
4533
        case 4:
4534
            check_insn(env, ctx, ISA_MIPS32R2);
4535
            gen_op_mtc0_srsconf3();
4536
            rn = "SRSConf3";
4537
            break;
4538
        case 5:
4539
            check_insn(env, ctx, ISA_MIPS32R2);
4540
            gen_op_mtc0_srsconf4();
4541
            rn = "SRSConf4";
4542
            break;
4543
        default:
4544
            goto die;
4545
        }
4546
        break;
4547
    case 7:
4548
        switch (sel) {
4549
        case 0:
4550
            check_insn(env, ctx, ISA_MIPS32R2);
4551
            gen_op_mtc0_hwrena();
4552
            rn = "HWREna";
4553
            break;
4554
        default:
4555
            goto die;
4556
        }
4557
        break;
4558
    case 8:
4559
        /* ignored */
4560
        rn = "BadVAddr";
4561
        break;
4562
    case 9:
4563
        switch (sel) {
4564
        case 0:
4565
            gen_op_mtc0_count();
4566
            rn = "Count";
4567
            break;
4568
        /* 6,7 are implementation dependent */
4569
        default:
4570
            goto die;
4571
        }
4572
        /* Stop translation as we may have switched the execution mode */
4573
        ctx->bstate = BS_STOP;
4574
        break;
4575
    case 10:
4576
        switch (sel) {
4577
        case 0:
4578
            gen_op_mtc0_entryhi();
4579
            rn = "EntryHi";
4580
            break;
4581
        default:
4582
            goto die;
4583
        }
4584
        break;
4585
    case 11:
4586
        switch (sel) {
4587
        case 0:
4588
            gen_op_mtc0_compare();
4589
            rn = "Compare";
4590
            break;
4591
        /* 6,7 are implementation dependent */
4592
        default:
4593
            goto die;
4594
        }
4595
        /* Stop translation as we may have switched the execution mode */
4596
        ctx->bstate = BS_STOP;
4597
        break;
4598
    case 12:
4599
        switch (sel) {
4600
        case 0:
4601
            gen_op_mtc0_status();
4602
            /* BS_STOP isn't good enough here, hflags may have changed. */
4603
            gen_save_pc(ctx->pc + 4);
4604
            ctx->bstate = BS_EXCP;
4605
            rn = "Status";
4606
            break;
4607
        case 1:
4608
            check_insn(env, ctx, ISA_MIPS32R2);
4609
            gen_op_mtc0_intctl();
4610
            /* Stop translation as we may have switched the execution mode */
4611
            ctx->bstate = BS_STOP;
4612
            rn = "IntCtl";
4613
            break;
4614
        case 2:
4615
            check_insn(env, ctx, ISA_MIPS32R2);
4616
            gen_op_mtc0_srsctl();
4617
            /* Stop translation as we may have switched the execution mode */
4618
            ctx->bstate = BS_STOP;
4619
            rn = "SRSCtl";
4620
            break;
4621
        case 3:
4622
            check_insn(env, ctx, ISA_MIPS32R2);
4623
            gen_op_mtc0_srsmap();
4624
            /* Stop translation as we may have switched the execution mode */
4625
            ctx->bstate = BS_STOP;
4626
            rn = "SRSMap";
4627
            break;
4628
        default:
4629
            goto die;
4630
        }
4631
        break;
4632
    case 13:
4633
        switch (sel) {
4634
        case 0:
4635
            gen_op_mtc0_cause();
4636
            rn = "Cause";
4637
            break;
4638
        default:
4639
            goto die;
4640
        }
4641
        /* Stop translation as we may have switched the execution mode */
4642
        ctx->bstate = BS_STOP;
4643
        break;
4644
    case 14:
4645
        switch (sel) {
4646
        case 0:
4647
            gen_op_mtc0_epc();
4648
            rn = "EPC";
4649
            break;
4650
        default:
4651
            goto die;
4652
        }
4653
        break;
4654
    case 15:
4655
        switch (sel) {
4656
        case 0:
4657
            /* ignored */
4658
            rn = "PRid