Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 92af06d2

History | View | Annotate | Download (241.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, current_fpu, cpu_T[2];
427

    
428
/* FPU TNs, global for now. */
429
static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3];
430

    
431
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg)
432
{
433
    TCGv t = tcg_const_i32(arg);
434

    
435
    tcg_gen_helper_0_1(func, t);
436
    tcg_temp_free(t);
437
}
438

    
439
static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2)
440
{
441
    TCGv t1 = tcg_const_i32(arg1);
442
    TCGv t2 = tcg_const_i32(arg2);
443

    
444
    tcg_gen_helper_0_2(func, t1, t2);
445
    tcg_temp_free(t1);
446
    tcg_temp_free(t2);
447
}
448

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

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

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

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

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

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

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

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

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

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

    
532
static inline void gen_load_HI (TCGv t, int reg)
533
{
534
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
535
}
536

    
537
static inline void gen_store_HI (TCGv t, int reg)
538
{
539
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
540
}
541

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

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

    
556
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
557
        tcg_temp_free(r_tmp);
558
    }
559
}
560

    
561
static inline void gen_store_srsgpr (TCGv t, int reg)
562
{
563
    if (reg != 0) {
564
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
565

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

    
572
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
573
        tcg_temp_free(r_tmp);
574
    }
575
}
576

    
577
/* Floating point register moves. */
578
static inline void gen_load_fpr32 (TCGv t, int reg)
579
{
580
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
581
}
582

    
583
static inline void gen_store_fpr32 (TCGv t, int reg)
584
{
585
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
586
}
587

    
588
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
589
{
590
    if (ctx->hflags & MIPS_HFLAG_F64) {
591
        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
592
    } else {
593
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
594
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
595

    
596
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
597
        tcg_gen_extu_i32_i64(t, r_tmp1);
598
        tcg_gen_shli_i64(t, t, 32);
599
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
600
        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
601
        tcg_gen_or_i64(t, t, r_tmp2);
602
        tcg_temp_free(r_tmp1);
603
        tcg_temp_free(r_tmp2);
604
    }
605
}
606

    
607
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
608
{
609
    if (ctx->hflags & MIPS_HFLAG_F64) {
610
        tcg_gen_st_i64(t, current_fpu, 8 * reg);
611
    } else {
612
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
613

    
614
        tcg_gen_trunc_i64_i32(r_tmp, t);
615
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
616
        tcg_gen_shri_i64(t, t, 32);
617
        tcg_gen_trunc_i64_i32(r_tmp, t);
618
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
619
        tcg_temp_free(r_tmp);
620
    }
621
}
622

    
623
static inline void gen_load_fpr32h (TCGv t, int reg)
624
{
625
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
626
}
627

    
628
static inline void gen_store_fpr32h (TCGv t, int reg)
629
{
630
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
631
}
632

    
633
static inline void get_fp_cond (TCGv t)
634
{
635
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
636
    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
637

    
638
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
639
    tcg_gen_shri_i32(r_tmp2, r_tmp1, 24);
640
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
641
    tcg_gen_shri_i32(r_tmp1, r_tmp1, 23);
642
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
643
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
644
    tcg_temp_free(r_tmp1);
645
    tcg_temp_free(r_tmp2);
646
}
647

    
648
#define FOP_CONDS(type, fmt)                                              \
649
static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = {            \
650
    do_cmp ## type ## _ ## fmt ## _f,                                     \
651
    do_cmp ## type ## _ ## fmt ## _un,                                    \
652
    do_cmp ## type ## _ ## fmt ## _eq,                                    \
653
    do_cmp ## type ## _ ## fmt ## _ueq,                                   \
654
    do_cmp ## type ## _ ## fmt ## _olt,                                   \
655
    do_cmp ## type ## _ ## fmt ## _ult,                                   \
656
    do_cmp ## type ## _ ## fmt ## _ole,                                   \
657
    do_cmp ## type ## _ ## fmt ## _ule,                                   \
658
    do_cmp ## type ## _ ## fmt ## _sf,                                    \
659
    do_cmp ## type ## _ ## fmt ## _ngle,                                  \
660
    do_cmp ## type ## _ ## fmt ## _seq,                                   \
661
    do_cmp ## type ## _ ## fmt ## _ngl,                                   \
662
    do_cmp ## type ## _ ## fmt ## _lt,                                    \
663
    do_cmp ## type ## _ ## fmt ## _nge,                                   \
664
    do_cmp ## type ## _ ## fmt ## _le,                                    \
665
    do_cmp ## type ## _ ## fmt ## _ngt,                                   \
666
};                                                                        \
667
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)            \
668
{                                                                         \
669
    tcg_gen_helper_0_1i(fcmp ## type ## _ ## fmt ## _table[n], cc);       \
670
}
671

    
672
FOP_CONDS(, d)
673
FOP_CONDS(abs, d)
674
FOP_CONDS(, s)
675
FOP_CONDS(abs, s)
676
FOP_CONDS(, ps)
677
FOP_CONDS(abs, ps)
678
#undef FOP_CONDS
679

    
680
/* Tests */
681
#define OP_COND(name, cond)                                   \
682
void glue(gen_op_, name) (void)                               \
683
{                                                             \
684
    int l1 = gen_new_label();                                 \
685
    int l2 = gen_new_label();                                 \
686
                                                              \
687
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], 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_COND(eq, TCG_COND_EQ);
695
OP_COND(ne, TCG_COND_NE);
696
OP_COND(ge, TCG_COND_GE);
697
OP_COND(geu, TCG_COND_GEU);
698
OP_COND(lt, TCG_COND_LT);
699
OP_COND(ltu, TCG_COND_LTU);
700
#undef OP_COND
701

    
702
#define OP_CONDI(name, cond)                                  \
703
void glue(gen_op_, name) (target_ulong val)                   \
704
{                                                             \
705
    int l1 = gen_new_label();                                 \
706
    int l2 = gen_new_label();                                 \
707
                                                              \
708
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
709
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
710
    tcg_gen_br(l2);                                           \
711
    gen_set_label(l1);                                        \
712
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
713
    gen_set_label(l2);                                        \
714
}
715
OP_CONDI(lti, TCG_COND_LT);
716
OP_CONDI(ltiu, TCG_COND_LTU);
717
#undef OP_CONDI
718

    
719
#define OP_CONDZ(name, cond)                                  \
720
void glue(gen_op_, name) (void)                               \
721
{                                                             \
722
    int l1 = gen_new_label();                                 \
723
    int l2 = gen_new_label();                                 \
724
                                                              \
725
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1);                \
726
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
727
    tcg_gen_br(l2);                                           \
728
    gen_set_label(l1);                                        \
729
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
730
    gen_set_label(l2);                                        \
731
}
732
OP_CONDZ(gez, TCG_COND_GE);
733
OP_CONDZ(gtz, TCG_COND_GT);
734
OP_CONDZ(lez, TCG_COND_LE);
735
OP_CONDZ(ltz, TCG_COND_LT);
736
#undef OP_CONDZ
737

    
738
static inline void gen_save_pc(target_ulong pc)
739
{
740
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
741
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
742
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
743
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
744

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

    
757
static inline void gen_breg_pc(void)
758
{
759
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
760
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
761
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
762
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
763

    
764
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
765
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
766
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
767
    tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
768
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
769
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
770
    tcg_temp_free(r_tc_off);
771
    tcg_temp_free(r_tc_off_ptr);
772
    tcg_temp_free(r_ptr);
773
    tcg_temp_free(r_tmp);
774
}
775

    
776
static inline void gen_save_btarget(target_ulong btarget)
777
{
778
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
779

    
780
    tcg_gen_movi_tl(r_tmp, btarget);
781
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
782
    tcg_temp_free(r_tmp);
783
}
784

    
785
static always_inline void gen_save_breg_target(int reg)
786
{
787
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
788

    
789
    gen_load_gpr(r_tmp, reg);
790
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
791
    tcg_temp_free(r_tmp);
792
}
793

    
794
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
795
{
796
#if defined MIPS_DEBUG_DISAS
797
    if (loglevel & CPU_LOG_TB_IN_ASM) {
798
            fprintf(logfile, "hflags %08x saved %08x\n",
799
                    ctx->hflags, ctx->saved_hflags);
800
    }
801
#endif
802
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
803
        gen_save_pc(ctx->pc);
804
        ctx->saved_pc = ctx->pc;
805
    }
806
    if (ctx->hflags != ctx->saved_hflags) {
807
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
808

    
809
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
810
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
811
        tcg_temp_free(r_tmp);
812
        ctx->saved_hflags = ctx->hflags;
813
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
814
        case MIPS_HFLAG_BR:
815
            break;
816
        case MIPS_HFLAG_BC:
817
        case MIPS_HFLAG_BL:
818
        case MIPS_HFLAG_B:
819
            gen_save_btarget(ctx->btarget);
820
            break;
821
        }
822
    }
823
}
824

    
825
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
826
{
827
    ctx->saved_hflags = ctx->hflags;
828
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
829
    case MIPS_HFLAG_BR:
830
        break;
831
    case MIPS_HFLAG_BC:
832
    case MIPS_HFLAG_BL:
833
    case MIPS_HFLAG_B:
834
        ctx->btarget = env->btarget;
835
        break;
836
    }
837
}
838

    
839
static always_inline void
840
generate_exception_err (DisasContext *ctx, int excp, int err)
841
{
842
    save_cpu_state(ctx, 1);
843
    tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err);
844
    tcg_gen_helper_0_0(do_interrupt_restart);
845
    tcg_gen_exit_tb(0);
846
}
847

    
848
static always_inline void
849
generate_exception (DisasContext *ctx, int excp)
850
{
851
    save_cpu_state(ctx, 1);
852
    tcg_gen_helper_0_1i(do_raise_exception, excp);
853
    tcg_gen_helper_0_0(do_interrupt_restart);
854
    tcg_gen_exit_tb(0);
855
}
856

    
857
/* Addresses computation */
858
static inline void gen_op_addr_add (void)
859
{
860
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
861

    
862
#if defined(TARGET_MIPS64)
863
    /* For compatibility with 32-bit code, data reference in user mode
864
       with Status_UX = 0 should be casted to 32-bit and sign extended.
865
       See the MIPS64 PRA manual, section 4.10. */
866
    {
867
        int l1 = gen_new_label();
868
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
869

    
870
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
871
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
872
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
873
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
874
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
875
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
876
        tcg_temp_free(r_tmp);
877
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
878
        gen_set_label(l1);
879
    }
880
#endif
881
}
882

    
883
static always_inline void check_cp0_enabled(DisasContext *ctx)
884
{
885
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
886
        generate_exception_err(ctx, EXCP_CpU, 1);
887
}
888

    
889
static always_inline void check_cp1_enabled(DisasContext *ctx)
890
{
891
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
892
        generate_exception_err(ctx, EXCP_CpU, 1);
893
}
894

    
895
/* Verify that the processor is running with COP1X instructions enabled.
896
   This is associated with the nabla symbol in the MIPS32 and MIPS64
897
   opcode tables.  */
898

    
899
static always_inline void check_cop1x(DisasContext *ctx)
900
{
901
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
902
        generate_exception(ctx, EXCP_RI);
903
}
904

    
905
/* Verify that the processor is running with 64-bit floating-point
906
   operations enabled.  */
907

    
908
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
909
{
910
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
911
        generate_exception(ctx, EXCP_RI);
912
}
913

    
914
/*
915
 * Verify if floating point register is valid; an operation is not defined
916
 * if bit 0 of any register specification is set and the FR bit in the
917
 * Status register equals zero, since the register numbers specify an
918
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
919
 * in the Status register equals one, both even and odd register numbers
920
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
921
 *
922
 * Multiple 64 bit wide registers can be checked by calling
923
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
924
 */
925
void check_cp1_registers(DisasContext *ctx, int regs)
926
{
927
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
928
        generate_exception(ctx, EXCP_RI);
929
}
930

    
931
/* This code generates a "reserved instruction" exception if the
932
   CPU does not support the instruction set corresponding to flags. */
933
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
934
{
935
    if (unlikely(!(env->insn_flags & flags)))
936
        generate_exception(ctx, EXCP_RI);
937
}
938

    
939
/* This code generates a "reserved instruction" exception if 64-bit
940
   instructions are not enabled. */
941
static always_inline void check_mips_64(DisasContext *ctx)
942
{
943
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
944
        generate_exception(ctx, EXCP_RI);
945
}
946

    
947
/* load/store instructions. */
948
#if defined(CONFIG_USER_ONLY)
949
#define op_ldst(name)        gen_op_##name##_raw()
950
#define OP_LD_TABLE(width)
951
#define OP_ST_TABLE(width)
952
#else
953
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
954
#define OP_LD_TABLE(width)                                                    \
955
static GenOpFunc *gen_op_l##width[] = {                                       \
956
    &gen_op_l##width##_kernel,                                                \
957
    &gen_op_l##width##_super,                                                 \
958
    &gen_op_l##width##_user,                                                  \
959
}
960
#define OP_ST_TABLE(width)                                                    \
961
static GenOpFunc *gen_op_s##width[] = {                                       \
962
    &gen_op_s##width##_kernel,                                                \
963
    &gen_op_s##width##_super,                                                 \
964
    &gen_op_s##width##_user,                                                  \
965
}
966
#endif
967

    
968
#if defined(TARGET_MIPS64)
969
OP_LD_TABLE(dl);
970
OP_LD_TABLE(dr);
971
OP_ST_TABLE(dl);
972
OP_ST_TABLE(dr);
973
#endif
974
OP_LD_TABLE(wl);
975
OP_LD_TABLE(wr);
976
OP_ST_TABLE(wl);
977
OP_ST_TABLE(wr);
978

    
979
#define OP_LD(insn,fname)                                        \
980
void inline op_ldst_##insn(DisasContext *ctx)                    \
981
{                                                                \
982
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
983
}
984
OP_LD(lb,ld8s);
985
OP_LD(lbu,ld8u);
986
OP_LD(lh,ld16s);
987
OP_LD(lhu,ld16u);
988
OP_LD(lw,ld32s);
989
#if defined(TARGET_MIPS64)
990
OP_LD(lwu,ld32u);
991
OP_LD(ld,ld64);
992
#endif
993
#undef OP_LD
994

    
995
#define OP_ST(insn,fname)                                        \
996
void inline op_ldst_##insn(DisasContext *ctx)                    \
997
{                                                                \
998
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
999
}
1000
OP_ST(sb,st8);
1001
OP_ST(sh,st16);
1002
OP_ST(sw,st32);
1003
#if defined(TARGET_MIPS64)
1004
OP_ST(sd,st64);
1005
#endif
1006
#undef OP_ST
1007

    
1008
#define OP_LD_ATOMIC(insn,fname)                                        \
1009
void inline op_ldst_##insn(DisasContext *ctx)                           \
1010
{                                                                       \
1011
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
1012
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1013
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1014
}
1015
OP_LD_ATOMIC(ll,ld32s);
1016
#if defined(TARGET_MIPS64)
1017
OP_LD_ATOMIC(lld,ld64);
1018
#endif
1019
#undef OP_LD_ATOMIC
1020

    
1021
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1022
void inline op_ldst_##insn(DisasContext *ctx)                           \
1023
{                                                                       \
1024
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1025
    int l1 = gen_new_label();                                           \
1026
    int l2 = gen_new_label();                                           \
1027
    int l3 = gen_new_label();                                           \
1028
                                                                        \
1029
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1030
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1031
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1032
    generate_exception(ctx, EXCP_AdES);                                 \
1033
    gen_set_label(l1);                                                  \
1034
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1035
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1036
    tcg_temp_free(r_tmp);                                               \
1037
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1038
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1039
    tcg_gen_br(l3);                                                     \
1040
    gen_set_label(l2);                                                  \
1041
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1042
    gen_set_label(l3);                                                  \
1043
}
1044
OP_ST_ATOMIC(sc,st32,0x3);
1045
#if defined(TARGET_MIPS64)
1046
OP_ST_ATOMIC(scd,st64,0x7);
1047
#endif
1048
#undef OP_ST_ATOMIC
1049

    
1050
/* Load and store */
1051
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1052
                      int base, int16_t offset)
1053
{
1054
    const char *opn = "ldst";
1055

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

    
1201
/* Load and store */
1202
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1203
                      int base, int16_t offset)
1204
{
1205
    const char *opn = "flt_ldst";
1206

    
1207
    if (base == 0) {
1208
        tcg_gen_movi_tl(cpu_T[0], offset);
1209
    } else if (offset == 0) {
1210
        gen_load_gpr(cpu_T[0], base);
1211
    } else {
1212
        gen_load_gpr(cpu_T[0], base);
1213
        tcg_gen_movi_tl(cpu_T[1], offset);
1214
        gen_op_addr_add();
1215
    }
1216
    /* Don't do NOP if destination is zero: we must perform the actual
1217
       memory access. */
1218
    switch (opc) {
1219
    case OPC_LWC1:
1220
        tcg_gen_qemu_ld32s(fpu32_T[0], cpu_T[0], ctx->mem_idx);
1221
        gen_store_fpr32(fpu32_T[0], ft);
1222
        opn = "lwc1";
1223
        break;
1224
    case OPC_SWC1:
1225
        gen_load_fpr32(fpu32_T[0], ft);
1226
        tcg_gen_qemu_st32(fpu32_T[0], cpu_T[0], ctx->mem_idx);
1227
        opn = "swc1";
1228
        break;
1229
    case OPC_LDC1:
1230
        tcg_gen_qemu_ld64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
1231
        gen_store_fpr64(ctx, fpu64_T[0], ft);
1232
        opn = "ldc1";
1233
        break;
1234
    case OPC_SDC1:
1235
        gen_load_fpr64(ctx, fpu64_T[0], ft);
1236
        tcg_gen_qemu_st64(fpu64_T[0], cpu_T[0], ctx->mem_idx);
1237
        opn = "sdc1";
1238
        break;
1239
    default:
1240
        MIPS_INVAL(opn);
1241
        generate_exception(ctx, EXCP_RI);
1242
        return;
1243
    }
1244
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1245
}
1246

    
1247
/* Arithmetic with immediate operand */
1248
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1249
                           int rt, int rs, int16_t imm)
1250
{
1251
    target_ulong uimm;
1252
    const char *opn = "imm arith";
1253

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

    
1303
            save_cpu_state(ctx, 1);
1304
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1305
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1306

    
1307
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1308
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1309
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1310
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1311
            tcg_temp_free(r_tmp2);
1312
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1313
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1314
            tcg_temp_free(r_tmp1);
1315
            /* operands of same sign, result different sign */
1316
            generate_exception(ctx, EXCP_OVERFLOW);
1317
            gen_set_label(l1);
1318

    
1319
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1320
        }
1321
        opn = "addi";
1322
        break;
1323
    case OPC_ADDIU:
1324
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1325
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1326
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1327
        opn = "addiu";
1328
        break;
1329
#if defined(TARGET_MIPS64)
1330
    case OPC_DADDI:
1331
        {
1332
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1333
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1334
            int l1 = gen_new_label();
1335

    
1336
            save_cpu_state(ctx, 1);
1337
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1338
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1339

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

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

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

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

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

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

    
1552
            save_cpu_state(ctx, 1);
1553
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1554
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1555
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1556

    
1557
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1558
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1559
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1560
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1561
            tcg_temp_free(r_tmp2);
1562
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1563
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1564
            tcg_temp_free(r_tmp1);
1565
            /* operands of same sign, result different sign */
1566
            generate_exception(ctx, EXCP_OVERFLOW);
1567
            gen_set_label(l1);
1568

    
1569
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1570
        }
1571
        opn = "add";
1572
        break;
1573
    case OPC_ADDU:
1574
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1575
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1576
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1577
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1578
        opn = "addu";
1579
        break;
1580
    case OPC_SUB:
1581
        {
1582
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1583
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1584
            int l1 = gen_new_label();
1585

    
1586
            save_cpu_state(ctx, 1);
1587
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1588
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1589
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1590

    
1591
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1592
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1593
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1594
            tcg_temp_free(r_tmp2);
1595
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1596
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1597
            tcg_temp_free(r_tmp1);
1598
            /* operands of different sign, first operand and result different sign */
1599
            generate_exception(ctx, EXCP_OVERFLOW);
1600
            gen_set_label(l1);
1601

    
1602
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1603
        }
1604
        opn = "sub";
1605
        break;
1606
    case OPC_SUBU:
1607
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1608
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1609
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1610
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1611
        opn = "subu";
1612
        break;
1613
#if defined(TARGET_MIPS64)
1614
    case OPC_DADD:
1615
        {
1616
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1617
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1618
            int l1 = gen_new_label();
1619

    
1620
            save_cpu_state(ctx, 1);
1621
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1622
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1623

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

    
1648
            save_cpu_state(ctx, 1);
1649
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1650
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1651

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

    
1706
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1707
            gen_store_gpr(cpu_T[0], rd);
1708
            gen_set_label(l1);
1709
        }
1710
        opn = "movn";
1711
        goto print;
1712
    case OPC_MOVZ:
1713
        {
1714
            int l1 = gen_new_label();
1715

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

    
1752
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1753
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1754
                {
1755
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1756
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1757
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1758

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

    
1814
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1815
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1816
                {
1817
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1818

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

    
1854
/* Arithmetic on HI/LO registers */
1855
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1856
{
1857
    const char *opn = "hilo";
1858

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

    
1893
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1894
                        int rs, int rt)
1895
{
1896
    const char *opn = "mul/div";
1897

    
1898
    gen_load_gpr(cpu_T[0], rs);
1899
    gen_load_gpr(cpu_T[1], rt);
1900
    switch (opc) {
1901
    case OPC_DIV:
1902
        {
1903
            int l1 = gen_new_label();
1904

    
1905
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1906
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1907
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1908
            {
1909
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1910
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1911
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1912

    
1913
                tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1914
                tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1915
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1916
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1917
                tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1918
                tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1919
                tcg_temp_free(r_tmp1);
1920
                tcg_temp_free(r_tmp2);
1921
                tcg_temp_free(r_tmp3);
1922
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1923
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1924
                gen_store_LO(cpu_T[0], 0);
1925
                gen_store_HI(cpu_T[1], 0);
1926
            }
1927
            gen_set_label(l1);
1928
        }
1929
        opn = "div";
1930
        break;
1931
    case OPC_DIVU:
1932
        {
1933
            int l1 = gen_new_label();
1934

    
1935
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1936
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1937
            {
1938
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1939
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1940
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1941

    
1942
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1943
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1944
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1945
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1946
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1947
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1948
                tcg_temp_free(r_tmp1);
1949
                tcg_temp_free(r_tmp2);
1950
                tcg_temp_free(r_tmp3);
1951
                gen_store_LO(cpu_T[0], 0);
1952
                gen_store_HI(cpu_T[1], 0);
1953
            }
1954
            gen_set_label(l1);
1955
        }
1956
        opn = "divu";
1957
        break;
1958
    case OPC_MULT:
1959
        {
1960
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1961
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1962

    
1963
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1964
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1965
            tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1966
            tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1967
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1968
            tcg_temp_free(r_tmp2);
1969
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1);
1970
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1971
            tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1);
1972
            tcg_temp_free(r_tmp1);
1973
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1974
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1975
            gen_store_LO(cpu_T[0], 0);
1976
            gen_store_HI(cpu_T[1], 0);
1977
        }
1978
        opn = "mult";
1979
        break;
1980
    case OPC_MULTU:
1981
        {
1982
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1983
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1984

    
1985
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1986
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1987
            tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]);
1988
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]);
1989
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1990
            tcg_temp_free(r_tmp2);
1991
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1);
1992
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1993
            tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1);
1994
            tcg_temp_free(r_tmp1);
1995
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1996
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1997
            gen_store_LO(cpu_T[0], 0);
1998
            gen_store_HI(cpu_T[1], 0);
1999
        }
2000
        opn = "multu";
2001
        break;
2002
#if defined(TARGET_MIPS64)
2003
    case OPC_DDIV:
2004
        {
2005
            int l1 = gen_new_label();
2006

    
2007
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
2008
            {
2009
                int l2 = gen_new_label();
2010

    
2011
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2);
2012
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2);
2013
                {
2014
                    tcg_gen_movi_tl(cpu_T[1], 0);
2015
                    gen_store_LO(cpu_T[0], 0);
2016
                    gen_store_HI(cpu_T[1], 0);
2017
                    tcg_gen_br(l1);
2018
                }
2019
                gen_set_label(l2);
2020
                {
2021
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2022
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2023

    
2024
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
2025
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
2026
                    gen_store_LO(r_tmp1, 0);
2027
                    gen_store_HI(r_tmp2, 0);
2028
                    tcg_temp_free(r_tmp1);
2029
                    tcg_temp_free(r_tmp2);
2030
                }
2031
            }
2032
            gen_set_label(l1);
2033
        }
2034
        opn = "ddiv";
2035
        break;
2036
    case OPC_DDIVU:
2037
        {
2038
            int l1 = gen_new_label();
2039

    
2040
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
2041
            {
2042
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2043
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2044

    
2045
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
2046
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
2047
                tcg_temp_free(r_tmp1);
2048
                tcg_temp_free(r_tmp2);
2049
                gen_store_LO(r_tmp1, 0);
2050
                gen_store_HI(r_tmp2, 0);
2051
            }
2052
            gen_set_label(l1);
2053
        }
2054
        opn = "ddivu";
2055
        break;
2056
    case OPC_DMULT:
2057
        tcg_gen_helper_0_0(do_dmult);
2058
        opn = "dmult";
2059
        break;
2060
    case OPC_DMULTU:
2061
        tcg_gen_helper_0_0(do_dmultu);
2062
        opn = "dmultu";
2063
        break;
2064
#endif
2065
    case OPC_MADD:
2066
        {
2067
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2068
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2069
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2070

    
2071
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2072
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
2073
            tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
2074
            tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
2075
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2076
            gen_load_LO(cpu_T[0], 0);
2077
            gen_load_HI(cpu_T[1], 0);
2078
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]);
2079
            tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]);
2080
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2081
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2082
            tcg_temp_free(r_tmp3);
2083
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2084
            tcg_temp_free(r_tmp2);
2085
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1);
2086
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2087
            tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1);
2088
            tcg_temp_free(r_tmp1);
2089
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2090
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
2091
            gen_store_LO(cpu_T[0], 0);
2092
            gen_store_HI(cpu_T[1], 0);
2093
        }
2094
        opn = "madd";
2095
        break;
2096
    case OPC_MADDU:
2097
       {
2098
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2099
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2100
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2101

    
2102
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
2103
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
2104
            tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]);
2105
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]);
2106
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2107
            gen_load_LO(cpu_T[0], 0);
2108
            gen_load_HI(cpu_T[1], 0);
2109
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]);
2110
            tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]);
2111
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2112
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2113
            tcg_temp_free(r_tmp3);
2114
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2115
            tcg_temp_free(r_tmp2);
2116
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1);
2117
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2118
            tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1);
2119
            tcg_temp_free(r_tmp1);
2120
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2121
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
2122
            gen_store_LO(cpu_T[0], 0);
2123
            gen_store_HI(cpu_T[1], 0);
2124
        }
2125
        opn = "maddu";
2126
        break;
2127
    case OPC_MSUB:
2128
        {
2129
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2130
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2131
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2132

    
2133
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2134
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
2135
            tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
2136
            tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
2137
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2138
            gen_load_LO(cpu_T[0], 0);
2139
            gen_load_HI(cpu_T[1], 0);
2140
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]);
2141
            tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]);
2142
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2143
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2144
            tcg_temp_free(r_tmp3);
2145
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2146
            tcg_temp_free(r_tmp2);
2147
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1);
2148
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2149
            tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1);
2150
            tcg_temp_free(r_tmp1);
2151
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2152
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
2153
            gen_store_LO(cpu_T[0], 0);
2154
            gen_store_HI(cpu_T[1], 0);
2155
        }
2156
        opn = "msub";
2157
        break;
2158
    case OPC_MSUBU:
2159
        {
2160
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2161
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2162
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2163

    
2164
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
2165
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
2166
            tcg_gen_extu_tl_i64(r_tmp1, cpu_T[0]);
2167
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[1]);
2168
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2169
            gen_load_LO(cpu_T[0], 0);
2170
            gen_load_HI(cpu_T[1], 0);
2171
            tcg_gen_extu_tl_i64(r_tmp2, cpu_T[0]);
2172
            tcg_gen_extu_tl_i64(r_tmp3, cpu_T[1]);
2173
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2174
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2175
            tcg_temp_free(r_tmp3);
2176
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2177
            tcg_temp_free(r_tmp2);
2178
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp1);
2179
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2180
            tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp1);
2181
            tcg_temp_free(r_tmp1);
2182
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2183
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
2184
            gen_store_LO(cpu_T[0], 0);
2185
            gen_store_HI(cpu_T[1], 0);
2186
        }
2187
        opn = "msubu";
2188
        break;
2189
    default:
2190
        MIPS_INVAL(opn);
2191
        generate_exception(ctx, EXCP_RI);
2192
        return;
2193
    }
2194
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2195
}
2196

    
2197
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2198
                            int rd, int rs, int rt)
2199
{
2200
    const char *opn = "mul vr54xx";
2201

    
2202
    gen_load_gpr(cpu_T[0], rs);
2203
    gen_load_gpr(cpu_T[1], rt);
2204

    
2205
    switch (opc) {
2206
    case OPC_VR54XX_MULS:
2207
        tcg_gen_helper_0_0(do_muls);
2208
        opn = "muls";
2209
        break;
2210
    case OPC_VR54XX_MULSU:
2211
        tcg_gen_helper_0_0(do_mulsu);
2212
        opn = "mulsu";
2213
        break;
2214
    case OPC_VR54XX_MACC:
2215
        tcg_gen_helper_0_0(do_macc);
2216
        opn = "macc";
2217
        break;
2218
    case OPC_VR54XX_MACCU:
2219
        tcg_gen_helper_0_0(do_maccu);
2220
        opn = "maccu";
2221
        break;
2222
    case OPC_VR54XX_MSAC:
2223
        tcg_gen_helper_0_0(do_msac);
2224
        opn = "msac";
2225
        break;
2226
    case OPC_VR54XX_MSACU:
2227
        tcg_gen_helper_0_0(do_msacu);
2228
        opn = "msacu";
2229
        break;
2230
    case OPC_VR54XX_MULHI:
2231
        tcg_gen_helper_0_0(do_mulhi);
2232
        opn = "mulhi";
2233
        break;
2234
    case OPC_VR54XX_MULHIU:
2235
        tcg_gen_helper_0_0(do_mulhiu);
2236
        opn = "mulhiu";
2237
        break;
2238
    case OPC_VR54XX_MULSHI:
2239
        tcg_gen_helper_0_0(do_mulshi);
2240
        opn = "mulshi";
2241
        break;
2242
    case OPC_VR54XX_MULSHIU:
2243
        tcg_gen_helper_0_0(do_mulshiu);
2244
        opn = "mulshiu";
2245
        break;
2246
    case OPC_VR54XX_MACCHI:
2247
        tcg_gen_helper_0_0(do_macchi);
2248
        opn = "macchi";
2249
        break;
2250
    case OPC_VR54XX_MACCHIU:
2251
        tcg_gen_helper_0_0(do_macchiu);
2252
        opn = "macchiu";
2253
        break;
2254
    case OPC_VR54XX_MSACHI:
2255
        tcg_gen_helper_0_0(do_msachi);
2256
        opn = "msachi";
2257
        break;
2258
    case OPC_VR54XX_MSACHIU:
2259
        tcg_gen_helper_0_0(do_msachiu);
2260
        opn = "msachiu";
2261
        break;
2262
    default:
2263
        MIPS_INVAL("mul vr54xx");
2264
        generate_exception(ctx, EXCP_RI);
2265
        return;
2266
    }
2267
    gen_store_gpr(cpu_T[0], rd);
2268
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2269
}
2270

    
2271
static void gen_cl (DisasContext *ctx, uint32_t opc,
2272
                    int rd, int rs)
2273
{
2274
    const char *opn = "CLx";
2275
    if (rd == 0) {
2276
        /* Treat as NOP. */
2277
        MIPS_DEBUG("NOP");
2278
        return;
2279
    }
2280
    gen_load_gpr(cpu_T[0], rs);
2281
    switch (opc) {
2282
    case OPC_CLO:
2283
        tcg_gen_helper_0_0(do_clo);
2284
        opn = "clo";
2285
        break;
2286
    case OPC_CLZ:
2287
        tcg_gen_helper_0_0(do_clz);
2288
        opn = "clz";
2289
        break;
2290
#if defined(TARGET_MIPS64)
2291
    case OPC_DCLO:
2292
        tcg_gen_helper_0_0(do_dclo);
2293
        opn = "dclo";
2294
        break;
2295
    case OPC_DCLZ:
2296
        tcg_gen_helper_0_0(do_dclz);
2297
        opn = "dclz";
2298
        break;
2299
#endif
2300
    default:
2301
        MIPS_INVAL(opn);
2302
        generate_exception(ctx, EXCP_RI);
2303
        return;
2304
    }
2305
    gen_store_gpr(cpu_T[0], rd);
2306
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2307
}
2308

    
2309
/* Traps */
2310
static void gen_trap (DisasContext *ctx, uint32_t opc,
2311
                      int rs, int rt, int16_t imm)
2312
{
2313
    int cond;
2314

    
2315
    cond = 0;
2316
    /* Load needed operands */
2317
    switch (opc) {
2318
    case OPC_TEQ:
2319
    case OPC_TGE:
2320
    case OPC_TGEU:
2321
    case OPC_TLT:
2322
    case OPC_TLTU:
2323
    case OPC_TNE:
2324
        /* Compare two registers */
2325
        if (rs != rt) {
2326
            gen_load_gpr(cpu_T[0], rs);
2327
            gen_load_gpr(cpu_T[1], rt);
2328
            cond = 1;
2329
        }
2330
        break;
2331
    case OPC_TEQI:
2332
    case OPC_TGEI:
2333
    case OPC_TGEIU:
2334
    case OPC_TLTI:
2335
    case OPC_TLTIU:
2336
    case OPC_TNEI:
2337
        /* Compare register to immediate */
2338
        if (rs != 0 || imm != 0) {
2339
            gen_load_gpr(cpu_T[0], rs);
2340
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2341
            cond = 1;
2342
        }
2343
        break;
2344
    }
2345
    if (cond == 0) {
2346
        switch (opc) {
2347
        case OPC_TEQ:   /* rs == rs */
2348
        case OPC_TEQI:  /* r0 == 0  */
2349
        case OPC_TGE:   /* rs >= rs */
2350
        case OPC_TGEI:  /* r0 >= 0  */
2351
        case OPC_TGEU:  /* rs >= rs unsigned */
2352
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2353
            /* Always trap */
2354
            tcg_gen_movi_tl(cpu_T[0], 1);
2355
            break;
2356
        case OPC_TLT:   /* rs < rs           */
2357
        case OPC_TLTI:  /* r0 < 0            */
2358
        case OPC_TLTU:  /* rs < rs unsigned  */
2359
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2360
        case OPC_TNE:   /* rs != rs          */
2361
        case OPC_TNEI:  /* r0 != 0           */
2362
            /* Never trap: treat as NOP. */
2363
            return;
2364
        default:
2365
            MIPS_INVAL("trap");
2366
            generate_exception(ctx, EXCP_RI);
2367
            return;
2368
        }
2369
    } else {
2370
        switch (opc) {
2371
        case OPC_TEQ:
2372
        case OPC_TEQI:
2373
            gen_op_eq();
2374
            break;
2375
        case OPC_TGE:
2376
        case OPC_TGEI:
2377
            gen_op_ge();
2378
            break;
2379
        case OPC_TGEU:
2380
        case OPC_TGEIU:
2381
            gen_op_geu();
2382
            break;
2383
        case OPC_TLT:
2384
        case OPC_TLTI:
2385
            gen_op_lt();
2386
            break;
2387
        case OPC_TLTU:
2388
        case OPC_TLTIU:
2389
            gen_op_ltu();
2390
            break;
2391
        case OPC_TNE:
2392
        case OPC_TNEI:
2393
            gen_op_ne();
2394
            break;
2395
        default:
2396
            MIPS_INVAL("trap");
2397
            generate_exception(ctx, EXCP_RI);
2398
            return;
2399
        }
2400
    }
2401
    save_cpu_state(ctx, 1);
2402
    {
2403
        int l1 = gen_new_label();
2404

    
2405
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
2406
        tcg_gen_helper_0_1i(do_raise_exception, EXCP_TRAP);
2407
        gen_set_label(l1);
2408
    }
2409
    ctx->bstate = BS_STOP;
2410
}
2411

    
2412
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2413
{
2414
    TranslationBlock *tb;
2415
    tb = ctx->tb;
2416
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2417
        tcg_gen_goto_tb(n);
2418
        gen_save_pc(dest);
2419
        tcg_gen_exit_tb((long)tb + n);
2420
    } else {
2421
        gen_save_pc(dest);
2422
        tcg_gen_exit_tb(0);
2423
    }
2424
}
2425

    
2426
/* Branches (before delay slot) */
2427
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2428
                                int rs, int rt, int32_t offset)
2429
{
2430
    target_ulong btarget = -1;
2431
    int blink = 0;
2432
    int bcond = 0;
2433

    
2434
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2435
#ifdef MIPS_DEBUG_DISAS
2436
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2437
            fprintf(logfile,
2438
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2439
                    ctx->pc);
2440
        }
2441
#endif
2442
        generate_exception(ctx, EXCP_RI);
2443
        return;
2444
    }
2445

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

    
2658
    ctx->btarget = btarget;
2659
    if (blink > 0) {
2660
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2661
        gen_store_gpr(cpu_T[0], blink);
2662
    }
2663
}
2664

    
2665
/* special3 bitfield operations */
2666
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2667
                       int rs, int lsb, int msb)
2668
{
2669
    gen_load_gpr(cpu_T[1], rs);
2670
    switch (opc) {
2671
    case OPC_EXT:
2672
        if (lsb + msb > 31)
2673
            goto fail;
2674
        tcg_gen_helper_0_2ii(do_ext, lsb, msb + 1);
2675
        break;
2676
#if defined(TARGET_MIPS64)
2677
    case OPC_DEXTM:
2678
        if (lsb + msb > 63)
2679
            goto fail;
2680
        tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1 + 32);
2681
        break;
2682
    case OPC_DEXTU:
2683
        if (lsb + msb > 63)
2684
            goto fail;
2685
        tcg_gen_helper_0_2ii(do_dext, lsb + 32, msb + 1);
2686
        break;
2687
    case OPC_DEXT:
2688
        if (lsb + msb > 63)
2689
            goto fail;
2690
        tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1);
2691
        break;
2692
#endif
2693
    case OPC_INS:
2694
        if (lsb > msb)
2695
            goto fail;
2696
        gen_load_gpr(cpu_T[0], rt);
2697
        tcg_gen_helper_0_2ii(do_ins, lsb, msb - lsb + 1);
2698
        break;
2699
#if defined(TARGET_MIPS64)
2700
    case OPC_DINSM:
2701
        if (lsb > msb)
2702
            goto fail;
2703
        gen_load_gpr(cpu_T[0], rt);
2704
        tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1 + 32);
2705
        break;
2706
    case OPC_DINSU:
2707
        if (lsb > msb)
2708
            goto fail;
2709
        gen_load_gpr(cpu_T[0], rt);
2710
        tcg_gen_helper_0_2ii(do_dins, lsb + 32, msb - lsb + 1);
2711
        break;
2712
    case OPC_DINS:
2713
        if (lsb > msb)
2714
            goto fail;
2715
        gen_load_gpr(cpu_T[0], rt);
2716
        tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1);
2717
        break;
2718
#endif
2719
    default:
2720
fail:
2721
        MIPS_INVAL("bitops");
2722
        generate_exception(ctx, EXCP_RI);
2723
        return;
2724
    }
2725
    gen_store_gpr(cpu_T[0], rt);
2726
}
2727

    
2728
/* CP0 (MMU and control) */
2729
#ifndef CONFIG_USER_ONLY
2730
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2731
{
2732
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2733

    
2734
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2735
    tcg_gen_ext_i32_tl(t, r_tmp);
2736
    tcg_temp_free(r_tmp);
2737
}
2738

    
2739
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2740
{
2741
    tcg_gen_ld_tl(t, cpu_env, off);
2742
    tcg_gen_ext32s_tl(t, t);
2743
}
2744

    
2745
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2746
{
2747
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2748

    
2749
    tcg_gen_trunc_tl_i32(r_tmp, t);
2750
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2751
    tcg_temp_free(r_tmp);
2752
}
2753

    
2754
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2755
{
2756
    tcg_gen_ext32s_tl(t, t);
2757
    tcg_gen_st_tl(t, cpu_env, off);
2758
}
2759

    
2760
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2761
{
2762
    const char *rn = "invalid";
2763

    
2764
    if (sel != 0)
2765
        check_insn(env, ctx, ISA_MIPS32);
2766

    
2767
    switch (reg) {
2768
    case 0:
2769
        switch (sel) {
2770
        case 0:
2771
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
2772
            rn = "Index";
2773
            break;
2774
        case 1:
2775
            check_insn(env, ctx, ASE_MT);
2776
            tcg_gen_helper_0_0(do_mfc0_mvpcontrol);
2777
            rn = "MVPControl";
2778
            break;
2779
        case 2:
2780
            check_insn(env, ctx, ASE_MT);
2781
            tcg_gen_helper_0_0(do_mfc0_mvpconf0);
2782
            rn = "MVPConf0";
2783
            break;
2784
        case 3:
2785
            check_insn(env, ctx, ASE_MT);
2786
            tcg_gen_helper_0_0(do_mfc0_mvpconf1);
2787
            rn = "MVPConf1";
2788
            break;
2789
        default:
2790
            goto die;
2791
        }
2792
        break;
2793
    case 1:
2794
        switch (sel) {
2795
        case 0:
2796
            tcg_gen_helper_0_0(do_mfc0_random);
2797
            rn = "Random";
2798
            break;
2799
        case 1:
2800
            check_insn(env, ctx, ASE_MT);
2801
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
2802
            rn = "VPEControl";
2803
            break;
2804
        case 2:
2805
            check_insn(env, ctx, ASE_MT);
2806
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
2807
            rn = "VPEConf0";
2808
            break;
2809
        case 3:
2810
            check_insn(env, ctx, ASE_MT);
2811
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
2812
            rn = "VPEConf1";
2813
            break;
2814
        case 4:
2815
            check_insn(env, ctx, ASE_MT);
2816
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_YQMask));
2817
            rn = "YQMask";
2818
            break;
2819
        case 5:
2820
            check_insn(env, ctx, ASE_MT);
2821
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule));
2822
            rn = "VPESchedule";
2823
            break;
2824
        case 6:
2825
            check_insn(env, ctx, ASE_MT);
2826
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack));
2827
            rn = "VPEScheFBack";
2828
            break;
2829
        case 7:
2830
            check_insn(env, ctx, ASE_MT);
2831
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
2832
            rn = "VPEOpt";
2833
            break;
2834
        default:
2835
            goto die;
2836
        }
2837
        break;
2838
    case 2:
2839
        switch (sel) {
2840
        case 0:
2841
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2842
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2843
            rn = "EntryLo0";
2844
            break;
2845
        case 1:
2846
            check_insn(env, ctx, ASE_MT);
2847
            tcg_gen_helper_0_0(do_mfc0_tcstatus);
2848
            rn = "TCStatus";
2849
            break;
2850
        case 2:
2851
            check_insn(env, ctx, ASE_MT);
2852
            tcg_gen_helper_0_0(do_mfc0_tcbind);
2853
            rn = "TCBind";
2854
            break;
2855
        case 3:
2856
            check_insn(env, ctx, ASE_MT);
2857
            tcg_gen_helper_0_0(do_mfc0_tcrestart);
2858
            rn = "TCRestart";
2859
            break;
2860
        case 4:
2861
            check_insn(env, ctx, ASE_MT);
2862
            tcg_gen_helper_0_0(do_mfc0_tchalt);
2863
            rn = "TCHalt";
2864
            break;
2865
        case 5:
2866
            check_insn(env, ctx, ASE_MT);
2867
            tcg_gen_helper_0_0(do_mfc0_tccontext);
2868
            rn = "TCContext";
2869
            break;
2870
        case 6:
2871
            check_insn(env, ctx, ASE_MT);
2872
            tcg_gen_helper_0_0(do_mfc0_tcschedule);
2873
            rn = "TCSchedule";
2874
            break;
2875
        case 7:
2876
            check_insn(env, ctx, ASE_MT);
2877
            tcg_gen_helper_0_0(do_mfc0_tcschefback);
2878
            rn = "TCScheFBack";
2879
            break;
2880
        default:
2881
            goto die;
2882
        }
2883
        break;
2884
    case 3:
2885
        switch (sel) {
2886
        case 0:
2887
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2888
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2889
            rn = "EntryLo1";
2890
            break;
2891
        default:
2892
            goto die;
2893
        }
2894
        break;
2895
    case 4:
2896
        switch (sel) {
2897
        case 0:
2898
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2899
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2900
            rn = "Context";
2901
            break;
2902
        case 1:
2903
//            tcg_gen_helper_0_0(do_mfc0_contextconfig); /* SmartMIPS ASE */
2904
            rn = "ContextConfig";
2905
//            break;
2906
        default:
2907
            goto die;
2908
        }
2909
        break;
2910
    case 5:
2911
        switch (sel) {
2912
        case 0:
2913
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
2914
            rn = "PageMask";
2915
            break;
2916
        case 1:
2917
            check_insn(env, ctx, ISA_MIPS32R2);
2918
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
2919
            rn = "PageGrain";
2920
            break;
2921
        default:
2922
            goto die;
2923
        }
2924
        break;
2925
    case 6:
2926
        switch (sel) {
2927
        case 0:
2928
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
2929
            rn = "Wired";
2930
            break;
2931
        case 1:
2932
            check_insn(env, ctx, ISA_MIPS32R2);
2933
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
2934
            rn = "SRSConf0";
2935
            break;
2936
        case 2:
2937
            check_insn(env, ctx, ISA_MIPS32R2);
2938
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
2939
            rn = "SRSConf1";
2940
            break;
2941
        case 3:
2942
            check_insn(env, ctx, ISA_MIPS32R2);
2943
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
2944
            rn = "SRSConf2";
2945
            break;
2946
        case 4:
2947
            check_insn(env, ctx, ISA_MIPS32R2);
2948
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
2949
            rn = "SRSConf3";
2950
            break;
2951
        case 5:
2952
            check_insn(env, ctx, ISA_MIPS32R2);
2953
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
2954
            rn = "SRSConf4";
2955
            break;
2956
        default:
2957
            goto die;
2958
        }
2959
        break;
2960
    case 7:
2961
        switch (sel) {
2962
        case 0:
2963
            check_insn(env, ctx, ISA_MIPS32R2);
2964
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
2965
            rn = "HWREna";
2966
            break;
2967
        default:
2968
            goto die;
2969
        }
2970
        break;
2971
    case 8:
2972
        switch (sel) {
2973
        case 0:
2974
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2975
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2976
            rn = "BadVAddr";
2977
            break;
2978
        default:
2979
            goto die;
2980
       }
2981
        break;
2982
    case 9:
2983
        switch (sel) {
2984
        case 0:
2985
            tcg_gen_helper_0_0(do_mfc0_count);
2986
            rn = "Count";
2987
            break;
2988
        /* 6,7 are implementation dependent */
2989
        default:
2990
            goto die;
2991
        }
2992
        break;
2993
    case 10:
2994
        switch (sel) {
2995
        case 0:
2996
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2997
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2998
            rn = "EntryHi";
2999
            break;
3000
        default:
3001
            goto die;
3002
        }
3003
        break;
3004
    case 11:
3005
        switch (sel) {
3006
        case 0:
3007
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
3008
            rn = "Compare";
3009
            break;
3010
        /* 6,7 are implementation dependent */
3011
        default:
3012
            goto die;
3013
        }
3014
        break;
3015
    case 12:
3016
        switch (sel) {
3017
        case 0:
3018
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
3019
            rn = "Status";
3020
            break;
3021
        case 1:
3022
            check_insn(env, ctx, ISA_MIPS32R2);
3023
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
3024
            rn = "IntCtl";
3025
            break;
3026
        case 2:
3027
            check_insn(env, ctx, ISA_MIPS32R2);
3028
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
3029
            rn = "SRSCtl";
3030
            break;
3031
        case 3:
3032
            check_insn(env, ctx, ISA_MIPS32R2);
3033
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
3034
            rn = "SRSMap";
3035
            break;
3036
        default:
3037
            goto die;
3038
       }
3039
        break;
3040
    case 13:
3041
        switch (sel) {
3042
        case 0:
3043
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
3044
            rn = "Cause";
3045
            break;
3046
        default:
3047
            goto die;
3048
       }
3049
        break;
3050
    case 14:
3051
        switch (sel) {
3052
        case 0:
3053
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
3054
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3055
            rn = "EPC";
3056
            break;
3057
        default:
3058
            goto die;
3059
        }
3060
        break;
3061
    case 15:
3062
        switch (sel) {
3063
        case 0:
3064
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
3065
            rn = "PRid";
3066
            break;
3067
        case 1:
3068
            check_insn(env, ctx, ISA_MIPS32R2);
3069
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
3070
            rn = "EBase";
3071
            break;
3072
        default:
3073
            goto die;
3074
       }
3075
        break;
3076
    case 16:
3077
        switch (sel) {
3078
        case 0:
3079
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
3080
            rn = "Config";
3081
            break;
3082
        case 1:
3083
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
3084
            rn = "Config1";
3085
            break;
3086
        case 2:
3087
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
3088
            rn = "Config2";
3089
            break;
3090
        case 3:
3091
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
3092
            rn = "Config3";
3093
            break;
3094
        /* 4,5 are reserved */
3095
        /* 6,7 are implementation dependent */
3096
        case 6:
3097
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
3098
            rn = "Config6";
3099
            break;
3100
        case 7:
3101
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
3102
            rn = "Config7";
3103
            break;
3104
        default:
3105
            goto die;
3106
        }
3107
        break;
3108
    case 17:
3109
        switch (sel) {
3110
        case 0:
3111
            tcg_gen_helper_0_0(do_mfc0_lladdr);
3112
            rn = "LLAddr";
3113
            break;
3114
        default:
3115
            goto die;
3116
        }
3117
        break;
3118
    case 18:
3119
        switch (sel) {
3120
        case 0 ... 7:
3121
            tcg_gen_helper_0_1i(do_mfc0_watchlo, sel);
3122
            rn = "WatchLo";
3123
            break;
3124
        default:
3125
            goto die;
3126
        }
3127
        break;
3128
    case 19:
3129
        switch (sel) {
3130
        case 0 ...7:
3131
            tcg_gen_helper_0_1i(do_mfc0_watchhi, sel);
3132
            rn = "WatchHi";
3133
            break;
3134
        default:
3135
            goto die;
3136
        }
3137
        break;
3138
    case 20:
3139
        switch (sel) {
3140
        case 0:
3141
#if defined(TARGET_MIPS64)
3142
            check_insn(env, ctx, ISA_MIPS3);
3143
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
3144
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3145
            rn = "XContext";
3146
            break;
3147
#endif
3148
        default:
3149
            goto die;
3150
        }
3151
        break;
3152
    case 21:
3153
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3154
        switch (sel) {
3155
        case 0:
3156
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
3157
            rn = "Framemask";
3158
            break;
3159
        default:
3160
            goto die;
3161
        }
3162
        break;
3163
    case 22:
3164
        /* ignored */
3165
        rn = "'Diagnostic"; /* implementation dependent */
3166
        break;
3167
    case 23:
3168
        switch (sel) {
3169
        case 0:
3170
            tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */
3171
            rn = "Debug";
3172
            break;
3173
        case 1:
3174
//            tcg_gen_helper_0_0(do_mfc0_tracecontrol); /* PDtrace support */
3175
            rn = "TraceControl";
3176
//            break;
3177
        case 2:
3178
//            tcg_gen_helper_0_0(do_mfc0_tracecontrol2); /* PDtrace support */
3179
            rn = "TraceControl2";
3180
//            break;
3181
        case 3:
3182
//            tcg_gen_helper_0_0(do_mfc0_usertracedata); /* PDtrace support */
3183
            rn = "UserTraceData";
3184
//            break;
3185
        case 4:
3186
//            tcg_gen_helper_0_0(do_mfc0_debug); /* PDtrace support */
3187
            rn = "TraceBPC";
3188
//            break;
3189
        default:
3190
            goto die;
3191
        }
3192
        break;
3193
    case 24:
3194
        switch (sel) {
3195
        case 0:
3196
            /* EJTAG support */
3197
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3198
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3199
            rn = "DEPC";
3200
            break;
3201
        default:
3202
            goto die;
3203
        }
3204
        break;
3205
    case 25:
3206
        switch (sel) {
3207
        case 0:
3208
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
3209
            rn = "Performance0";
3210
            break;
3211
        case 1:
3212
//            tcg_gen_helper_0_0(do_mfc0_performance1);
3213
            rn = "Performance1";
3214
//            break;
3215
        case 2:
3216
//            tcg_gen_helper_0_0(do_mfc0_performance2);
3217
            rn = "Performance2";
3218
//            break;
3219
        case 3:
3220
//            tcg_gen_helper_0_0(do_mfc0_performance3);
3221
            rn = "Performance3";
3222
//            break;
3223
        case 4:
3224
//            tcg_gen_helper_0_0(do_mfc0_performance4);
3225
            rn = "Performance4";
3226
//            break;
3227
        case 5:
3228
//            tcg_gen_helper_0_0(do_mfc0_performance5);
3229
            rn = "Performance5";
3230
//            break;
3231
        case 6:
3232
//            tcg_gen_helper_0_0(do_mfc0_performance6);
3233
            rn = "Performance6";
3234
//            break;
3235
        case 7:
3236
//            tcg_gen_helper_0_0(do_mfc0_performance7);
3237
            rn = "Performance7";
3238
//            break;
3239
        default:
3240
            goto die;
3241
        }
3242
        break;
3243
    case 26:
3244
       rn = "ECC";
3245
       break;
3246
    case 27:
3247
        switch (sel) {
3248
        /* ignored */
3249
        case 0 ... 3:
3250
            rn = "CacheErr";
3251
            break;
3252
        default:
3253
            goto die;
3254
        }
3255
        break;
3256
    case 28:
3257
        switch (sel) {
3258
        case 0:
3259
        case 2:
3260
        case 4:
3261
        case 6:
3262
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
3263
            rn = "TagLo";
3264
            break;
3265
        case 1:
3266
        case 3:
3267
        case 5:
3268
        case 7:
3269
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
3270
            rn = "DataLo";
3271
            break;
3272
        default:
3273
            goto die;
3274
        }
3275
        break;
3276
    case 29:
3277
        switch (sel) {
3278
        case 0:
3279
        case 2:
3280
        case 4:
3281
        case 6:
3282
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
3283
            rn = "TagHi";
3284
            break;
3285
        case 1:
3286
        case 3:
3287
        case 5:
3288
        case 7:
3289
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
3290
            rn = "DataHi";
3291
            break;
3292
        default:
3293
            goto die;
3294
        }
3295
        break;
3296
    case 30:
3297
        switch (sel) {
3298
        case 0:
3299
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3300
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3301
            rn = "ErrorEPC";
3302
            break;
3303
        default:
3304
            goto die;
3305
        }
3306
        break;
3307
    case 31:
3308
        switch (sel) {
3309
        case 0:
3310
            /* EJTAG support */
3311
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
3312
            rn = "DESAVE";
3313
            break;
3314
        default:
3315
            goto die;
3316
        }
3317
        break;
3318
    default:
3319
       goto die;
3320
    }
3321
#if defined MIPS_DEBUG_DISAS
3322
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3323
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3324
                rn, reg, sel);
3325
    }
3326
#endif
3327
    return;
3328

    
3329
die:
3330
#if defined MIPS_DEBUG_DISAS
3331
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3332
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3333
                rn, reg, sel);
3334
    }
3335
#endif
3336
    generate_exception(ctx, EXCP_RI);
3337
}
3338

    
3339
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3340
{
3341
    const char *rn = "invalid";
3342

    
3343
    if (sel != 0)
3344
        check_insn(env, ctx, ISA_MIPS32);
3345

    
3346
    switch (reg) {
3347
    case 0:
3348
        switch (sel) {
3349
        case 0:
3350
            tcg_gen_helper_0_0(do_mtc0_index);
3351
            rn = "Index";
3352
            break;
3353
        case 1:
3354
            check_insn(env, ctx, ASE_MT);
3355
            tcg_gen_helper_0_0(do_mtc0_mvpcontrol);
3356
            rn = "MVPControl";
3357
            break;
3358
        case 2:
3359
            check_insn(env, ctx, ASE_MT);
3360
            /* ignored */
3361
            rn = "MVPConf0";
3362
            break;
3363
        case 3:
3364
            check_insn(env, ctx, ASE_MT);
3365
            /* ignored */
3366
            rn = "MVPConf1";
3367
            break;
3368
        default:
3369
            goto die;
3370
        }
3371
        break;
3372
    case 1:
3373
        switch (sel) {
3374
        case 0:
3375
            /* ignored */
3376
            rn = "Random";
3377
            break;
3378
        case 1:
3379
            check_insn(env, ctx, ASE_MT);
3380
            tcg_gen_helper_0_0(do_mtc0_vpecontrol);
3381
            rn = "VPEControl";
3382
            break;
3383
        case 2:
3384
            check_insn(env, ctx, ASE_MT);
3385
            tcg_gen_helper_0_0(do_mtc0_vpeconf0);
3386
            rn = "VPEConf0";
3387
            break;
3388
        case 3:
3389
            check_insn(env, ctx, ASE_MT);
3390
            tcg_gen_helper_0_0(do_mtc0_vpeconf1);
3391
            rn = "VPEConf1";
3392
            break;
3393
        case 4:
3394
            check_insn(env, ctx, ASE_MT);
3395
            tcg_gen_helper_0_0(do_mtc0_yqmask);
3396
            rn = "YQMask";
3397
            break;
3398
        case 5:
3399
            check_insn(env, ctx, ASE_MT);
3400
            gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule));
3401
            rn = "VPESchedule";
3402
            break;
3403
        case 6:
3404
            check_insn(env, ctx, ASE_MT);
3405
            gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack));
3406
            rn = "VPEScheFBack";
3407
            break;
3408
        case 7:
3409
            check_insn(env, ctx, ASE_MT);
3410
            tcg_gen_helper_0_0(do_mtc0_vpeopt);
3411
            rn = "VPEOpt";
3412
            break;
3413
        default:
3414
            goto die;
3415
        }
3416
        break;
3417
    case 2:
3418
        switch (sel) {
3419
        case 0:
3420
            tcg_gen_helper_0_0(do_mtc0_entrylo0);
3421
            rn = "EntryLo0";
3422
            break;
3423
        case 1:
3424
            check_insn(env, ctx, ASE_MT);
3425
            tcg_gen_helper_0_0(do_mtc0_tcstatus);
3426
            rn = "TCStatus";
3427
            break;
3428
        case 2:
3429
            check_insn(env, ctx, ASE_MT);
3430
            tcg_gen_helper_0_0(do_mtc0_tcbind);
3431
            rn = "TCBind";
3432
            break;
3433
        case 3:
3434
            check_insn(env, ctx, ASE_MT);
3435
            tcg_gen_helper_0_0(do_mtc0_tcrestart);
3436
            rn = "TCRestart";
3437
            break;
3438
        case 4:
3439
            check_insn(env, ctx, ASE_MT);
3440
            tcg_gen_helper_0_0(do_mtc0_tchalt);
3441
            rn = "TCHalt";
3442
            break;
3443
        case 5:
3444
            check_insn(env, ctx, ASE_MT);
3445
            tcg_gen_helper_0_0(do_mtc0_tccontext);
3446
            rn = "TCContext";
3447
            break;
3448
        case 6:
3449
            check_insn(env, ctx, ASE_MT);
3450
            tcg_gen_helper_0_0(do_mtc0_tcschedule);
3451
            rn = "TCSchedule";
3452
            break;
3453
        case 7:
3454
            check_insn(env, ctx, ASE_MT);
3455
            tcg_gen_helper_0_0(do_mtc0_tcschefback);
3456
            rn = "TCScheFBack";
3457
            break;
3458
        default:
3459
            goto die;
3460
        }
3461
        break;
3462
    case 3:
3463
        switch (sel) {
3464
        case 0:
3465
            tcg_gen_helper_0_0(do_mtc0_entrylo1);
3466
            rn = "EntryLo1";
3467
            break;
3468
        default:
3469
            goto die;
3470
        }
3471
        break;
3472
    case 4:
3473
        switch (sel) {
3474
        case 0:
3475
            tcg_gen_helper_0_0(do_mtc0_context);
3476
            rn = "Context";
3477
            break;
3478
        case 1:
3479
//            tcg_gen_helper_0_0(do_mtc0_contextconfig); /* SmartMIPS ASE */
3480
            rn = "ContextConfig";
3481
//            break;
3482
        default:
3483
            goto die;
3484
        }
3485
        break;
3486
    case 5:
3487
        switch (sel) {
3488
        case 0:
3489
            tcg_gen_helper_0_0(do_mtc0_pagemask);
3490
            rn = "PageMask";
3491
            break;
3492
        case 1:
3493
            check_insn(env, ctx, ISA_MIPS32R2);
3494
            tcg_gen_helper_0_0(do_mtc0_pagegrain);
3495
            rn = "PageGrain";
3496
            break;
3497
        default:
3498
            goto die;
3499
        }
3500
        break;
3501
    case 6:
3502
        switch (sel) {
3503
        case 0:
3504
            tcg_gen_helper_0_0(do_mtc0_wired);
3505
            rn = "Wired";
3506
            break;
3507
        case 1:
3508
            check_insn(env, ctx, ISA_MIPS32R2);
3509
            tcg_gen_helper_0_0(do_mtc0_srsconf0);
3510
            rn = "SRSConf0";
3511
            break;
3512
        case 2:
3513
            check_insn(env, ctx, ISA_MIPS32R2);
3514
            tcg_gen_helper_0_0(do_mtc0_srsconf1);
3515
            rn = "SRSConf1";
3516
            break;
3517
        case 3:
3518
            check_insn(env, ctx, ISA_MIPS32R2);
3519
            tcg_gen_helper_0_0(do_mtc0_srsconf2);
3520
            rn = "SRSConf2";
3521
            break;
3522
        case 4:
3523
            check_insn(env, ctx, ISA_MIPS32R2);
3524
            tcg_gen_helper_0_0(do_mtc0_srsconf3);
3525
            rn = "SRSConf3";
3526
            break;
3527
        case 5:
3528
            check_insn(env, ctx, ISA_MIPS32R2);
3529
            tcg_gen_helper_0_0(do_mtc0_srsconf4);
3530
            rn = "SRSConf4";
3531
            break;
3532
        default:
3533
            goto die;
3534
        }
3535
        break;
3536
    case 7:
3537
        switch (sel) {
3538
        case 0:
3539
            check_insn(env, ctx, ISA_MIPS32R2);
3540
            tcg_gen_helper_0_0(do_mtc0_hwrena);
3541
            rn = "HWREna";
3542
            break;
3543
        default:
3544
            goto die;
3545
        }
3546
        break;
3547
    case 8:
3548
        /* ignored */
3549
        rn = "BadVAddr";
3550
        break;
3551
    case 9:
3552
        switch (sel) {
3553
        case 0:
3554
            tcg_gen_helper_0_0(do_mtc0_count);
3555
            rn = "Count";
3556
            break;
3557
        /* 6,7 are implementation dependent */
3558
        default:
3559
            goto die;
3560
        }
3561
        /* Stop translation as we may have switched the execution mode */
3562
        ctx->bstate = BS_STOP;
3563
        break;
3564
    case 10:
3565
        switch (sel) {
3566
        case 0:
3567
            tcg_gen_helper_0_0(do_mtc0_entryhi);
3568
            rn = "EntryHi";
3569
            break;
3570
        default:
3571
            goto die;
3572
        }
3573
        break;
3574
    case 11:
3575
        switch (sel) {
3576
        case 0:
3577
            tcg_gen_helper_0_0(do_mtc0_compare);
3578
            rn = "Compare";
3579
            break;
3580
        /* 6,7 are implementation dependent */
3581
        default:
3582
            goto die;
3583
        }
3584
        /* Stop translation as we may have switched the execution mode */
3585
        ctx->bstate = BS_STOP;
3586
        break;
3587
    case 12:
3588
        switch (sel) {
3589
        case 0:
3590
            tcg_gen_helper_0_0(do_mtc0_status);
3591
            /* BS_STOP isn't good enough here, hflags may have changed. */
3592
            gen_save_pc(ctx->pc + 4);
3593
            ctx->bstate = BS_EXCP;
3594
            rn = "Status";
3595
            break;
3596
        case 1:
3597
            check_insn(env, ctx, ISA_MIPS32R2);
3598
            tcg_gen_helper_0_0(do_mtc0_intctl);
3599
            /* Stop translation as we may have switched the execution mode */
3600
            ctx->bstate = BS_STOP;
3601
            rn = "IntCtl";
3602
            break;
3603
        case 2:
3604
            check_insn(env, ctx, ISA_MIPS32R2);
3605
            tcg_gen_helper_0_0(do_mtc0_srsctl);
3606
            /* Stop translation as we may have switched the execution mode */
3607
            ctx->bstate = BS_STOP;
3608
            rn = "SRSCtl";
3609
            break;
3610
        case 3:
3611
            check_insn(env, ctx, ISA_MIPS32R2);
3612
            gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
3613
            /* Stop translation as we may have switched the execution mode */
3614
            ctx->bstate = BS_STOP;
3615
            rn = "SRSMap";
3616
            break;
3617
        default:
3618
            goto die;
3619
        }
3620
        break;
3621
    case 13:
3622
        switch (sel) {
3623
        case 0:
3624
            tcg_gen_helper_0_0(do_mtc0_cause);
3625
            rn = "Cause";
3626
            break;
3627
        default:
3628
            goto die;
3629
        }
3630
        /* Stop translation as we may have switched the execution mode */
3631
        ctx->bstate = BS_STOP;
3632
        break;
3633
    case 14:
3634
        switch (sel) {
3635
        case 0:
3636
            gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_EPC));
3637
            rn = "EPC";
3638
            break;
3639
        default:
3640
            goto die;
3641
        }
3642
        break;
3643
    case 15:
3644
        switch (sel) {
3645
        case 0:
3646
            /* ignored */
3647
            rn = "PRid";
3648
            break;
3649
        case 1:
3650
            check_insn(env, ctx, ISA_MIPS32R2);
3651
            tcg_gen_helper_0_0(do_mtc0_ebase);
3652
            rn = "EBase";
3653
            break;
3654
        default:
3655
            goto die;
3656
        }
3657
        break;
3658
    case 16:
3659
        switch (sel) {
3660
        case 0:
3661
            tcg_gen_helper_0_0(do_mtc0_config0);
3662
            rn = "Config";
3663
            /* Stop translation as we may have switched the execution mode */
3664
            ctx->bstate = BS_STOP;
3665
            break;
3666
        case 1:
3667
            /* ignored, read only */
3668
            rn = "Config1";
3669
            break;
3670
        case 2:
3671
            tcg_gen_helper_0_0(do_mtc0_config2);
3672
            rn = "Config2";
3673
            /* Stop translation as we may have switched the execution mode */
3674
            ctx->bstate = BS_STOP;
3675
            break;
3676
        case 3:
3677
            /* ignored, read only */
3678
            rn = "Config3";
3679
            break;
3680
        /* 4,5 are reserved */
3681
        /* 6,7 are implementation dependent */
3682
        case 6:
3683
            /* ignored */
3684
            rn = "Config6";
3685
            break;
3686
        case 7:
3687
            /* ignored */
3688
            rn = "Config7";
3689
            break;
3690
        default:
3691
            rn = "Invalid config selector";
3692
            goto die;
3693
        }
3694
        break;
3695
    case 17:
3696
        switch (sel) {
3697
        case 0:
3698
            /* ignored */
3699
            rn = "LLAddr";
3700
            break;
3701
        default:
3702
            goto die;
3703
        }
3704
        break;
3705
    case 18:
3706
        switch (sel) {
3707
        case 0 ... 7:
3708
            tcg_gen_helper_0_1i(do_mtc0_watchlo, sel);
3709
            rn = "WatchLo";
3710
            break;
3711
        default:
3712
            goto die;
3713
        }
3714
        break;
3715
    case 19:
3716
        switch (sel) {
3717
        case 0 ... 7:
3718
            tcg_gen_helper_0_1i(do_mtc0_watchhi, sel);
3719
            rn = "WatchHi";
3720
            break;
3721
        default:
3722
            goto die;
3723
        }
3724
        break;
3725
    case 20:
3726
        switch (sel) {
3727
        case 0:
3728
#if defined(TARGET_MIPS64)
3729
            check_insn(env, ctx, ISA_MIPS3);
3730
            tcg_gen_helper_0_0(do_mtc0_xcontext);
3731
            rn = "XContext";
3732
            break;
3733
#endif
3734
        default:
3735
            goto die;
3736
        }
3737
        break;
3738
    case 21:
3739
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3740
        switch (sel) {
3741
        case 0:
3742
            tcg_gen_helper_0_0(do_mtc0_framemask);
3743
            rn = "Framemask";
3744
            break;
3745
        default:
3746
            goto die;
3747
        }
3748
        break;
3749
    case 22:
3750
        /* ignored */
3751
        rn = "Diagnostic"; /* implementation dependent */
3752
        break;
3753
    case 23:
3754
        switch (sel) {
3755
        case 0:
3756
            tcg_gen_helper_0_0(do_mtc0_debug); /* EJTAG support */
3757
            /* BS_STOP isn't good enough here, hflags may have changed. */
3758
            gen_save_pc(ctx->pc + 4);
3759
            ctx->bstate = BS_EXCP;
3760
            rn = "Debug";
3761
            break;
3762
        case 1:
3763
//            tcg_gen_helper_0_0(do_mtc0_tracecontrol); /* PDtrace support */
3764
            rn = "TraceControl";
3765
            /* Stop translation as we may have switched the execution mode */
3766
            ctx->bstate = BS_STOP;
3767
//            break;
3768
        case 2:
3769
//            tcg_gen_helper_0_0(do_mtc0_tracecontrol2); /* PDtrace support */
3770
            rn = "TraceControl2";
3771
            /* Stop translation as we may have switched the execution mode */
3772
            ctx->bstate = BS_STOP;
3773
//            break;
3774
        case 3:
3775
            /* Stop translation as we may have switched the execution mode */
3776
            ctx->bstate = BS_STOP;
3777
//            tcg_gen_helper_0_0(do_mtc0_usertracedata); /* PDtrace support */
3778
            rn = "UserTraceData";
3779
            /* Stop translation as we may have switched the execution mode */
3780
            ctx->bstate = BS_STOP;
3781
//            break;
3782
        case 4:
3783
//            tcg_gen_helper_0_0(do_mtc0_debug); /* PDtrace support */
3784
            /* Stop translation as we may have switched the execution mode */
3785
            ctx->bstate = BS_STOP;
3786
            rn = "TraceBPC";
3787
//            break;
3788
        default:
3789
            goto die;
3790
        }
3791
        break;
3792
    case 24:
3793
        switch (sel) {
3794
        case 0:
3795
            /* EJTAG support */
3796
            gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_DEPC));
3797
            rn = "DEPC";
3798
            break;
3799
        default:
3800
            goto die;
3801
        }
3802
        break;
3803
    case 25:
3804
        switch (sel) {
3805
        case 0:
3806
            tcg_gen_helper_0_0(do_mtc0_performance0);
3807
            rn = "Performance0";
3808
            break;
3809
        case 1:
3810
//            tcg_gen_helper_0_0(do_mtc0_performance1);
3811
            rn = "Performance1";
3812
//            break;
3813
        case 2:
3814
//            tcg_gen_helper_0_0(do_mtc0_performance2);
3815
            rn = "Performance2";
3816
//            break;
3817
        case 3:
3818
//            tcg_gen_helper_0_0(do_mtc0_performance3);
3819
            rn = "Performance3";
3820
//            break;
3821
        case 4:
3822
//            tcg_gen_helper_0_0(do_mtc0_performance4);
3823
            rn = "Performance4";
3824
//            break;
3825
        case 5:
3826
//            tcg_gen_helper_0_0(do_mtc0_performance5);
3827
            rn = "Performance5";
3828
//            break;
3829
        case 6:
3830
//            tcg_gen_helper_0_0(do_mtc0_performance6);
3831
            rn = "Performance6";
3832
//            break;
3833
        case 7:
3834
//            tcg_gen_helper_0_0(do_mtc0_performance7);
3835
            rn = "Performance7";
3836
//            break;
3837
        default:
3838
            goto die;
3839
        }
3840
       break;
3841
    case 26:
3842
        /* ignored */
3843
        rn = "ECC";
3844
        break;
3845
    case 27:
3846
        switch (sel) {
3847
        case 0 ... 3:
3848
            /* ignored */
3849
            rn = "CacheErr";
3850
            break;
3851
        default:
3852
            goto die;
3853
        }
3854
       break;
3855
    case 28:
3856
        switch (sel) {
3857
        case 0:
3858
        case 2:
3859
        case 4:
3860
        case 6:
3861
            tcg_gen_helper_0_0(do_mtc0_taglo);
3862
            rn = "TagLo";
3863
            break;
3864
        case 1:
3865
        case 3:
3866
        case 5:
3867
        case 7:
3868
            tcg_gen_helper_0_0(do_mtc0_datalo);
3869
            rn = "DataLo";
3870
            break;
3871
        default:
3872
            goto die;
3873
        }
3874
        break;
3875
    case 29:
3876
        switch (sel) {
3877
        case 0:
3878
        case 2:
3879
        case 4:
3880
        case 6:
3881
            tcg_gen_helper_0_0(do_mtc0_taghi);
3882
            rn = "TagHi";
3883
            break;
3884
        case 1:
3885
        case 3:
3886
        case 5:
3887
        case 7:
3888
            tcg_gen_helper_0_0(do_mtc0_datahi);
3889
            rn = "DataHi";
3890
            break;
3891
        default:
3892
            rn = "invalid sel";
3893
            goto die;
3894
        }
3895
       break;
3896
    case 30:
3897
        switch (sel) {
3898
        case 0:
3899
            gen_mtc0_store64(cpu_T[0], offsetof(CPUState, CP0_ErrorEPC));
3900
            rn = "ErrorEPC";
3901
            break;
3902
        default:
3903
            goto die;
3904
        }
3905
        break;
3906
    case 31:
3907
        switch (sel) {
3908
        case 0:
3909
            /* EJTAG support */
3910
            gen_mtc0_store32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
3911
            rn = "DESAVE";
3912
            break;
3913
        default:
3914
            goto die;
3915
        }
3916
        /* Stop translation as we may have switched the execution mode */
3917
        ctx->bstate = BS_STOP;
3918
        break;
3919
    default:
3920
       goto die;
3921
    }
3922
#if defined MIPS_DEBUG_DISAS
3923
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3924
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3925
                rn, reg, sel);
3926
    }
3927
#endif
3928
    return;
3929

    
3930
die:
3931
#if defined MIPS_DEBUG_DISAS
3932
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3933
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3934
                rn, reg, sel);
3935
    }
3936
#endif
3937
    generate_exception(ctx, EXCP_RI);
3938
}
3939

    
3940
#if defined(TARGET_MIPS64)
3941
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3942
{
3943
    const char *rn = "invalid";
3944

    
3945
    if (sel != 0)
3946
        check_insn(env, ctx, ISA_MIPS64);
3947

    
3948
    switch (reg) {
3949
    case 0:
3950
        switch (sel) {
3951
        case 0:
3952
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
3953
            rn = "Index";
3954
            break;
3955
        case 1:
3956
            check_insn(env, ctx, ASE_MT);
3957
            tcg_gen_helper_0_0(do_mfc0_mvpcontrol);
3958
            rn = "MVPControl";
3959
            break;
3960
        case 2:
3961
            check_insn(env, ctx, ASE_MT);
3962
            tcg_gen_helper_0_0(do_mfc0_mvpconf0);
3963
            rn = "MVPConf0";
3964
            break;
3965
        case 3:
3966
            check_insn(env, ctx, ASE_MT);
3967
            tcg_gen_helper_0_0(do_mfc0_mvpconf1);
3968
            rn = "MVPConf1";
3969
            break;
3970
        default:
3971
            goto die;
3972
        }
3973
        break;
3974
    case 1:
3975
        switch (sel) {
3976
        case 0:
3977
            tcg_gen_helper_0_0(do_mfc0_random);
3978
            rn = "Random";
3979
            break;
3980
        case 1:
3981
            check_insn(env, ctx, ASE_MT);
3982
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
3983
            rn = "VPEControl";
3984
            break;
3985
        case 2:
3986
            check_insn(env, ctx, ASE_MT);
3987
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
3988
            rn = "VPEConf0";
3989
            break;
3990
        case 3:
3991
            check_insn(env, ctx, ASE_MT);
3992
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
3993
            rn = "VPEConf1";
3994
            break;
3995
        case 4:
3996
            check_insn(env, ctx, ASE_MT);
3997
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3998
            rn = "YQMask";
3999
            break;
4000
        case 5:
4001
            check_insn(env, ctx, ASE_MT);
4002
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
4003
            rn = "VPESchedule";
4004
            break;
4005
        case 6:
4006
            check_insn(env, ctx, ASE_MT);
4007
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4008
            rn = "VPEScheFBack";
4009
            break;
4010
        case 7:
4011
            check_insn(env, ctx, ASE_MT);
4012
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
4013
            rn = "VPEOpt";
4014
            break;
4015
        default:
4016
            goto die;
4017
        }
4018
        break;
4019
    case 2:
4020
        switch (sel) {
4021
        case 0:
4022
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
4023
            rn = "EntryLo0";
4024
            break;
4025
        case 1:
4026
            check_insn(env, ctx, ASE_MT);
4027
            tcg_gen_helper_0_0(do_mfc0_tcstatus);
4028
            rn = "TCStatus";
4029
            break;
4030
        case 2:
4031
            check_insn(env, ctx, ASE_MT);
4032
            tcg_gen_helper_0_0(do_mfc0_tcbind);
4033
            rn = "TCBind";
4034
            break;
4035
        case 3:
4036
            check_insn(env, ctx, ASE_MT);
4037
            tcg_gen_helper_0_0(do_dmfc0_tcrestart);
4038
            rn = "TCRestart";
4039
            break;
4040
        case 4:
4041
            check_insn(env, ctx, ASE_MT);
4042
            tcg_gen_helper_0_0(do_dmfc0_tchalt);
4043
            rn = "TCHalt";
4044
            break;
4045
        case 5:
4046
            check_insn(env, ctx, ASE_MT);
4047
            tcg_gen_helper_0_0(do_dmfc0_tccontext);
4048
            rn = "TCContext";
4049
            break;
4050
        case 6:
4051
            check_insn(env, ctx, ASE_MT);
4052
            tcg_gen_helper_0_0(do_dmfc0_tcschedule);
4053
            rn = "TCSchedule";
4054
            break;
4055
        case 7:
4056
            check_insn(env, ctx, ASE_MT);
4057
            tcg_gen_helper_0_0(do_dmfc0_tcschefback);
4058
            rn = "TCScheFBack";
4059
            break;
4060
        default:
4061
            goto die;
4062
        }
4063
        break;
4064
    case 3:
4065
        switch (sel) {
4066
        case 0:
4067
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
4068
            rn = "EntryLo1";
4069
            break;
4070
        default:
4071
            goto die;
4072
        }
4073
        break;
4074
    case 4:
4075
        switch (sel) {
4076
        case 0:
4077
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
4078
            rn = "Context";
4079
            break;
4080
        case 1:
4081
//            tcg_gen_helper_0_0(do_dmfc0_contextconfig); /* SmartMIPS ASE */
4082
            rn = "ContextConfig";
4083
//            break;
4084
        default:
4085
            goto die;
4086
        }
4087
        break;
4088
    case 5:
4089
        switch (sel) {
4090
        case 0:
4091
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
4092
            rn = "PageMask";
4093
            break;
4094
        case 1:
4095
            check_insn(env, ctx, ISA_MIPS32R2);
4096
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
4097
            rn = "PageGrain";
4098
            break;
4099
        default:
4100
            goto die;
4101
        }
4102
        break;
4103
    case 6:
4104
        switch (sel) {
4105
        case 0:
4106
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
4107
            rn = "Wired";
4108
            break;
4109
        case 1:
4110
            check_insn(env, ctx, ISA_MIPS32R2);
4111
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
4112
            rn = "SRSConf0";
4113
            break;
4114
        case 2:
4115
            check_insn(env, ctx, ISA_MIPS32R2);
4116
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
4117
            rn = "SRSConf1";
4118
            break;
4119
        case 3:
4120
            check_insn(env, ctx, ISA_MIPS32R2);
4121
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
4122
            rn = "SRSConf2";
4123
            break;
4124
        case 4:
4125
            check_insn(env, ctx, ISA_MIPS32R2);
4126
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
4127
            rn = "SRSConf3";
4128
            break;
4129
        case 5:
4130
            check_insn(env, ctx, ISA_MIPS32R2);
4131
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
4132
            rn = "SRSConf4";
4133
            break;
4134
        default:
4135
            goto die;
4136
        }
4137
        break;
4138
    case 7:
4139
        switch (sel) {
4140
        case 0:
4141
            check_insn(env, ctx, ISA_MIPS32R2);
4142
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
4143
            rn = "HWREna";
4144
            break;
4145
        default:
4146
            goto die;
4147
        }
4148
        break;
4149
    case 8:
4150
        switch (sel) {
4151
        case 0:
4152
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4153
            rn = "BadVAddr";
4154
            break;
4155
        default:
4156
            goto die;
4157
        }
4158
        break;
4159
    case 9:
4160
        switch (sel) {
4161
        case 0:
4162
            tcg_gen_helper_0_0(do_mfc0_count);
4163
            rn = "Count";
4164
            break;
4165
        /* 6,7 are implementation dependent */
4166
        default:
4167
            goto die;
4168
        }
4169
        break;
4170
    case 10:
4171
        switch (sel) {
4172
        case 0:
4173
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4174
            rn = "EntryHi";
4175
            break;
4176
        default:
4177
            goto die;
4178
        }
4179
        break;
4180
    case 11:
4181
        switch (sel) {
4182
        case 0:
4183
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
4184
            rn = "Compare";
4185
            break;
4186
        /* 6,7 are implementation dependent */
4187
        default:
4188
            goto die;
4189
        }
4190
        break;
4191
    case 12:
4192
        switch (sel) {
4193
        case 0:
4194
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
4195
            rn = "Status";
4196
            break;
4197
        case 1:
4198
            check_insn(env, ctx, ISA_MIPS32R2);
4199
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
4200
            rn = "IntCtl";
4201
            break;
4202
        case 2:
4203
            check_insn(env, ctx, ISA_MIPS32R2);
4204
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
4205
            rn = "SRSCtl";
4206
            break;
4207
        case 3:
4208
            check_insn(env, ctx, ISA_MIPS32R2);
4209
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
4210
            rn = "SRSMap";
4211
            break;
4212
        default:
4213
            goto die;
4214
        }
4215
        break;
4216
    case 13:
4217
        switch (sel) {
4218
        case 0:
4219
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
4220
            rn = "Cause";
4221
            break;
4222
        default:
4223
            goto die;
4224
        }
4225
        break;
4226
    case 14:
4227
        switch (sel) {
4228
        case 0:
4229
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4230
            rn = "EPC";
4231
            break;
4232
        default:
4233
            goto die;
4234
        }
4235
        break;
4236
    case 15:
4237
        switch (sel) {
4238
        case 0:
4239
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
4240
            rn = "PRid";
4241
            break;
4242
        case 1:
4243
            check_insn(env, ctx, ISA_MIPS32R2);
4244
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
4245
            rn = "EBase";
4246
            break;
4247
        default:
4248
            goto die;
4249
        }
4250
        break;
4251
    case 16:
4252
        switch (sel) {
4253
        case 0:
4254
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
4255
            rn = "Config";
4256
            break;
4257
        case 1:
4258
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
4259
            rn = "Config1";
4260
            break;
4261
        case 2:
4262
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
4263
            rn = "Config2";
4264
            break;
4265
        case 3:
4266
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
4267
            rn = "Config3";
4268
            break;
4269
       /* 6,7 are implementation dependent */
4270
        case 6:
4271
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
4272
            rn = "Config6";
4273
            break;
4274
        case 7:
4275
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
4276
            rn = "Config7";
4277
            break;
4278
        default:
4279
            goto die;
4280
        }
4281
        break;
4282
    case 17:
4283
        switch (sel) {
4284
        case 0:
4285
            tcg_gen_helper_0_0(do_dmfc0_lladdr);
4286
            rn = "LLAddr";
4287
            break;
4288
        default:
4289
            goto die;
4290
        }
4291
        break;
4292
    case 18:
4293
        switch (sel) {
4294
        case 0 ... 7:
4295
            tcg_gen_helper_0_1i(do_dmfc0_watchlo, sel);
4296
            rn = "WatchLo";
4297
            break;
4298
        default:
4299
            goto die;
4300
        }
4301
        break;
4302
    case 19:
4303
        switch (sel) {
4304
        case 0 ... 7:
4305
            tcg_gen_helper_0_1i(do_mfc0_watchhi, sel);
4306
            rn = "WatchHi";
4307
            break;
4308
        default:
4309
            goto die;
4310
        }
4311
        break;
4312
    case 20:
4313
        switch (sel) {
4314
        case 0:
4315
            check_insn(env, ctx, ISA_MIPS3);
4316
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4317
            rn = "XContext";
4318
            break;
4319
        default:
4320
            goto die;
4321
        }
4322
        break;
4323
    case 21:
4324
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4325
        switch (sel) {
4326
        case 0:
4327
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
4328
            rn = "Framemask";
4329
            break;
4330
        default:
4331
            goto die;
4332
        }
4333
        break;
4334
    case 22:
4335
        /* ignored */
4336
        rn = "'Diagnostic"; /* implementation dependent */
4337
        break;
4338
    case 23:
4339
        switch (sel) {
4340
        case 0:
4341
            tcg_gen_helper_0_0(do_mfc0_debug); /* EJTAG support */
4342
            rn = "Debug";
4343
            break;
4344
        case 1:
4345
//            tcg_gen_helper_0_0(do_dmfc0_tracecontrol); /* PDtrace support */
4346
            rn = "TraceControl";
4347
//            break;
4348
        case 2:
4349
//            tcg_gen_helper_0_0(do_dmfc0_tracecontrol2); /* PDtrace support */
4350
            rn = "TraceControl2";
4351
//            break;
4352
        case 3:
4353
//            tcg_gen_helper_0_0(do_dmfc0_usertracedata); /* PDtrace support */
4354
            rn = "UserTraceData";
4355
//            break;
4356
        case 4:
4357
//            tcg_gen_helper_0_0(do_dmfc0_debug); /* PDtrace support */
4358
            rn = "TraceBPC";
4359
//            break;
4360
        default:
4361
            goto die;
4362
        }
4363
        break;
4364
    case 24:
4365
        switch (sel) {
4366
        case 0:
4367
            /* EJTAG support */
4368
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4369
            rn = "DEPC";
4370
            break;
4371
        default:
4372
            goto die;
4373
        }
4374
        break;
4375
    case 25:
4376
        switch (sel) {
4377
        case 0:
4378
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
4379
            rn = "Performance0";
4380
            break;
4381
        case 1:
4382
//            tcg_gen_helper_0_0(do_dmfc0_performance1);
4383
            rn = "Performance1";
4384
//            break;
4385
        case 2:
4386
//            tcg_gen_helper_0_0(do_dmfc0_performance2);
4387
            rn = "Performance2";
4388
//            break;
4389
        case 3:
4390
//            tcg_gen_helper_0_0(do_dmfc0_performance3);
4391
            rn = "Performance3";
4392
//            break;
4393
        case 4:
4394
//            tcg_gen_helper_0_0(do_dmfc0_performance4);
4395
            rn = "Performance4";
4396
//            break;
4397
        case 5:
4398
//            tcg_gen_helper_0_0(do_dmfc0_performance5);
4399
            rn = "Performance5";
4400
//            break;
4401
        case 6:
4402
//            tcg_gen_helper_0_0(do_dmfc0_performance6);
4403
            rn = "Performance6";
4404
//            break;
4405
        case 7:
4406
//            tcg_gen_helper_0_0(do_dmfc0_performance7);
4407
            rn = "Performance7";
4408
//            break;
4409
        default:
4410
            goto die;
4411
        }
4412
        break;
4413
    case 26:
4414
       rn = "ECC";
4415
       break;
4416
    case 27:
4417
        switch (sel) {
4418
        /* ignored */
4419
        case 0 ... 3:
4420
            rn = "CacheErr";
4421
            break;
4422
        default:
4423
            goto die;
4424
        }
4425
        break;
4426
    case 28:
4427
        switch (sel) {
4428
        case 0:
4429
        case 2:
4430
        case 4:
4431
        case 6:
4432
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
4433
            rn = "TagLo";
4434
            break;
4435
        case 1:
4436
        case 3:
4437
        case 5:
4438
        case 7:
4439
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
4440
            rn = "DataLo";
4441
            break;
4442
        default:
4443
            goto die;
4444
        }
4445
        break;
4446
    case 29:
4447
        switch (sel) {
4448
        case 0:
4449
        case 2:
4450
        case 4:
4451
        case 6:
4452
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
4453
            rn = "TagHi";
4454
            break;
4455
        case 1:
4456
        case 3:
4457
        case 5:
4458
        case 7:
4459
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
4460
            rn = "DataHi";
4461
            break;
4462
        default:
4463
            goto die;
4464
        }
4465
        break;
4466
    case 30:
4467
        switch (sel) {
4468
        case 0:
4469
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4470
            rn = "ErrorEPC";
4471
            break;
4472
        default:
4473
            goto die;
4474
        }
4475
        break;
4476
    case 31:
4477
        switch (sel) {
4478
        case 0:
4479
            /* EJTAG support */
4480
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
4481
            rn = "DESAVE";
4482
            break;
4483
        default:
4484
            goto die;
4485
        }
4486
        break;
4487
    default:
4488
        goto die;
4489
    }
4490
#if defined MIPS_DEBUG_DISAS
4491
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4492
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4493
                rn, reg, sel);
4494
    }
4495
#endif
4496
    return;
4497

    
4498
die:
4499
#if defined MIPS_DEBUG_DISAS
4500
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4501
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4502
                rn, reg, sel);
4503
    }
4504
#endif
4505
    generate_exception(ctx, EXCP_RI);
4506
}
4507

    
4508
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4509
{
4510
    const char *rn = "invalid";
4511

    
4512
    if (sel != 0)
4513
        check_insn(env, ctx, ISA_MIPS64);
4514

    
4515
    switch (reg) {
4516
    case 0:
4517
        switch (sel) {
4518
        case 0:
4519
            tcg_gen_helper_0_0(do_mtc0_index);
4520
            rn = "Index";
4521
            break;
4522
        case 1:
4523
            check_insn(env, ctx, ASE_MT);
4524
            tcg_gen_helper_0_0(do_mtc0_mvpcontrol);
4525
            rn = "MVPControl";
4526
            break;
4527
        case 2:
4528
            check_insn(env, ctx, ASE_MT);
4529
            /* ignored */
4530
            rn = "MVPConf0";
4531
            break;
4532
        case 3:
4533
            check_insn(env, ctx, ASE_MT);
4534
            /* ignored */
4535
            rn = "MVPConf1";
4536
            break;
4537
        default:
4538
            goto die;
4539
        }
4540
        break;
4541
    case 1:
4542
        switch (sel) {
4543
        case 0:
4544
            /* ignored */
4545
            rn = "Random";
4546
            break;
4547
        case 1:
4548
            check_insn(env, ctx, ASE_MT);
4549
            tcg_gen_helper_0_0(do_mtc0_vpecontrol);
4550
            rn = "VPEControl";
4551
            break;
4552
        case 2:
4553
            check_insn(env, ctx, ASE_MT);
4554
            tcg_gen_helper_0_0(do_mtc0_vpeconf0);
4555
            rn = "VPEConf0";
4556
            break;
4557
        case 3:
4558
            check_insn(env, ctx, ASE_MT);
4559
            tcg_gen_helper_0_0(do_mtc0_vpeconf1);
4560
            rn = "VPEConf1";
4561
            break;
4562
        case 4:
4563
            check_insn(env, ctx, ASE_MT);
4564
            tcg_gen_helper_0_0(do_mtc0_yqmask);
4565
            rn = "YQMask";
4566
            break;
4567
        case 5:
4568
            check_insn(env, ctx, ASE_MT);
4569
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
4570
            rn = "VPESchedule";
4571
            break;
4572
        case 6:
4573
            check_insn(env, ctx, ASE_MT);
4574
            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4575
            rn = "VPEScheFBack";
4576
            break;
4577
        case 7:
4578
            check_insn(env, ctx, ASE_MT);
4579
            tcg_gen_helper_0_0(do_mtc0_vpeopt);
4580
            rn = "VPEOpt";
4581
            break;
4582
        default:
4583
            goto die;
4584
        }
4585
        break;
4586
    case 2:
4587
        switch (sel) {
4588
        case 0:
4589
            tcg_gen_helper_0_0(do_mtc0_entrylo0);
4590
            rn = "EntryLo0";
4591
            break;
4592
        case 1:
4593
            check_insn(env, ctx, ASE_MT);
4594
            tcg_gen_helper_0_0(do_mtc0_tcstatus);
4595
            rn = "TCStatus";
4596
            break;
4597
        case 2:
4598
            check_insn(env, ctx, ASE_MT);
4599
            tcg_gen_helper_0_0(do_mtc0_tcbind);
4600
            rn = "TCBind";
4601
            break;
4602
        case 3:
4603
            check_insn(env, ctx, ASE_MT);
4604
            tcg_gen_helper_0_0(do_mtc0_tcrestart);
4605
            rn = "TCRestart";
4606
            break;
4607
        case 4:
4608
            check_insn(env, ctx, ASE_MT);
4609
            tcg_gen_helper_0_0(do_mtc0_tchalt);
4610
            rn = "TCHalt";
4611
            break;
4612
        case 5:
4613
            check_insn(env, ctx, ASE_MT);
4614
            tcg_gen_helper_0_0(do_mtc0_tccontext);
4615
            rn = "TCContext";
4616
            break;
4617
        case 6:
4618
            check_insn(env, ctx, ASE_MT);
4619
            tcg_gen_helper_0_0(do_mtc0_tcschedule);
4620
            rn = "TCSchedule";
4621
            break;
4622
        case 7:
4623
            check_insn(env, ctx, ASE_MT);
4624
            tcg_gen_helper_0_0(do_mtc0_tcschefback);
4625
            rn = "TCScheFBack";
4626
            break;
4627
        default:
4628
            goto die;
4629
        }
4630
        break;
4631
    case 3:
4632
        switch (sel) {
4633
        case 0:
4634
            tcg_gen_helper_0_0(do_mtc0_entrylo1);
4635
            rn = "EntryLo1";
4636
            break;
4637
        default:
4638
            goto die;
4639
        }
4640
        break;
4641
    case 4:
4642
        switch (sel) {
4643
        case 0:
4644
            tcg_gen_helper_0_0(do_mtc0_context);
4645
            rn = "Context";