Statistics
| Branch: | Revision:

root / target-mips / translate.c @ bf20dc07

History | View | Annotate | Download (243.5 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, bcond, btarget, current_fpu;
427

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

    
431
#include "gen-icount.h"
432

    
433
static inline void tcg_gen_helper_0_i(void *func, TCGv arg)
434
{
435
    TCGv tmp = tcg_const_i32(arg);
436

    
437
    tcg_gen_helper_0_1(func, tmp);
438
    tcg_temp_free(tmp);
439
}
440

    
441
static inline void tcg_gen_helper_0_ii(void *func, TCGv arg1, TCGv arg2)
442
{
443
    TCGv tmp1 = tcg_const_i32(arg1);
444
    TCGv tmp2 = tcg_const_i32(arg2);
445

    
446
    tcg_gen_helper_0_2(func, tmp1, tmp2);
447
    tcg_temp_free(tmp1);
448
    tcg_temp_free(tmp2);
449
}
450

    
451
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg1, TCGv arg2)
452
{
453
    TCGv tmp = tcg_const_i32(arg2);
454

    
455
    tcg_gen_helper_0_2(func, arg1, tmp);
456
    tcg_temp_free(tmp);
457
}
458

    
459
static inline void tcg_gen_helper_0_2i(void *func, TCGv arg1, TCGv arg2, TCGv arg3)
460
{
461
    TCGv tmp = tcg_const_i32(arg3);
462

    
463
    tcg_gen_helper_0_3(func, arg1, arg2, tmp);
464
    tcg_temp_free(tmp);
465
}
466

    
467
static inline void tcg_gen_helper_0_1ii(void *func, TCGv arg1, TCGv arg2, TCGv arg3)
468
{
469
    TCGv tmp1 = tcg_const_i32(arg2);
470
    TCGv tmp2 = tcg_const_i32(arg3);
471

    
472
    tcg_gen_helper_0_3(func, arg1, tmp1, tmp2);
473
    tcg_temp_free(tmp1);
474
    tcg_temp_free(tmp2);
475
}
476

    
477
static inline void tcg_gen_helper_1_i(void *func, TCGv ret, TCGv arg)
478
{
479
    TCGv tmp = tcg_const_i32(arg);
480

    
481
    tcg_gen_helper_1_1(func, ret, tmp);
482
    tcg_temp_free(tmp);
483
}
484

    
485
static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, TCGv arg2)
486
{
487
    TCGv tmp = tcg_const_i32(arg2);
488

    
489
    tcg_gen_helper_1_2(func, ret, arg1, tmp);
490
    tcg_temp_free(tmp);
491
}
492

    
493
static inline void tcg_gen_helper_1_1ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
494
{
495
    TCGv tmp1 = tcg_const_i32(arg2);
496
    TCGv tmp2 = tcg_const_i32(arg3);
497

    
498
    tcg_gen_helper_1_3(func, ret, arg1, tmp1, tmp2);
499
    tcg_temp_free(tmp1);
500
    tcg_temp_free(tmp2);
501
}
502

    
503
static inline void tcg_gen_helper_1_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
504
{
505
    TCGv tmp = tcg_const_i32(arg3);
506

    
507
    tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp);
508
    tcg_temp_free(tmp);
509
}
510

    
511
static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4)
512
{
513
    TCGv tmp1 = tcg_const_i32(arg3);
514
    TCGv tmp2 = tcg_const_i32(arg4);
515

    
516
    tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2);
517
    tcg_temp_free(tmp1);
518
    tcg_temp_free(tmp2);
519
}
520

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

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

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

    
547
static const char *fregnames[] =
548
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
549
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
550
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
551
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
552

    
553
#ifdef MIPS_DEBUG_DISAS
554
#define MIPS_DEBUG(fmt, args...)                                              \
555
do {                                                                          \
556
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
557
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
558
                ctx->pc, ctx->opcode , ##args);                               \
559
    }                                                                         \
560
} while (0)
561
#else
562
#define MIPS_DEBUG(fmt, args...) do { } while(0)
563
#endif
564

    
565
#define MIPS_INVAL(op)                                                        \
566
do {                                                                          \
567
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
568
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
569
} while (0)
570

    
571
/* General purpose registers moves. */
572
static inline void gen_load_gpr (TCGv t, int reg)
573
{
574
    if (reg == 0)
575
        tcg_gen_movi_tl(t, 0);
576
    else
577
        tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
578
                                  sizeof(target_ulong) * reg);
579
}
580

    
581
static inline void gen_store_gpr (TCGv t, int reg)
582
{
583
    if (reg != 0)
584
        tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
585
                                  sizeof(target_ulong) * reg);
586
}
587

    
588
/* Moves to/from HI and LO registers.  */
589
static inline void gen_load_LO (TCGv t, int reg)
590
{
591
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
592
                              sizeof(target_ulong) * reg);
593
}
594

    
595
static inline void gen_store_LO (TCGv t, int reg)
596
{
597
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
598
                              sizeof(target_ulong) * reg);
599
}
600

    
601
static inline void gen_load_HI (TCGv t, int reg)
602
{
603
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
604
                              sizeof(target_ulong) * reg);
605
}
606

    
607
static inline void gen_store_HI (TCGv t, int reg)
608
{
609
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
610
                              sizeof(target_ulong) * reg);
611
}
612

    
613
/* Moves to/from shadow registers. */
614
static inline void gen_load_srsgpr (int from, int to)
615
{
616
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
617

    
618
    if (from == 0)
619
        tcg_gen_movi_tl(r_tmp1, 0);
620
    else {
621
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
622

    
623
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
624
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
625
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
626
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
627
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
628

    
629
        tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from);
630
        tcg_temp_free(r_tmp2);
631
    }
632
    gen_store_gpr(r_tmp1, to);
633
    tcg_temp_free(r_tmp1);
634
}
635

    
636
static inline void gen_store_srsgpr (int from, int to)
637
{
638
    if (to != 0) {
639
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
640
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
641

    
642
        gen_load_gpr(r_tmp1, from);
643
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
644
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
645
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
646
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
647
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
648

    
649
        tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to);
650
        tcg_temp_free(r_tmp1);
651
        tcg_temp_free(r_tmp2);
652
    }
653
}
654

    
655
/* Floating point register moves. */
656
static inline void gen_load_fpr32 (TCGv t, int reg)
657
{
658
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
659
}
660

    
661
static inline void gen_store_fpr32 (TCGv t, int reg)
662
{
663
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
664
}
665

    
666
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
667
{
668
    if (ctx->hflags & MIPS_HFLAG_F64) {
669
        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
670
    } else {
671
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
672
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
673

    
674
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
675
        tcg_gen_extu_i32_i64(t, r_tmp1);
676
        tcg_gen_shli_i64(t, t, 32);
677
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
678
        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
679
        tcg_gen_or_i64(t, t, r_tmp2);
680
        tcg_temp_free(r_tmp1);
681
        tcg_temp_free(r_tmp2);
682
    }
683
}
684

    
685
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
686
{
687
    if (ctx->hflags & MIPS_HFLAG_F64) {
688
        tcg_gen_st_i64(t, current_fpu, 8 * reg);
689
    } else {
690
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
691

    
692
        tcg_gen_trunc_i64_i32(r_tmp, t);
693
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
694
        tcg_gen_shri_i64(t, t, 32);
695
        tcg_gen_trunc_i64_i32(r_tmp, t);
696
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
697
        tcg_temp_free(r_tmp);
698
    }
699
}
700

    
701
static inline void gen_load_fpr32h (TCGv t, int reg)
702
{
703
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
704
}
705

    
706
static inline void gen_store_fpr32h (TCGv t, int reg)
707
{
708
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
709
}
710

    
711
static inline void get_fp_cond (TCGv t)
712
{
713
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
714
    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
715

    
716
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
717
    tcg_gen_shri_i32(r_tmp2, r_tmp1, 24);
718
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
719
    tcg_gen_shri_i32(r_tmp1, r_tmp1, 23);
720
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
721
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
722
    tcg_temp_free(r_tmp1);
723
    tcg_temp_free(r_tmp2);
724
}
725

    
726
#define FOP_CONDS(type, fmt)                                              \
727
static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = {            \
728
    do_cmp ## type ## _ ## fmt ## _f,                                     \
729
    do_cmp ## type ## _ ## fmt ## _un,                                    \
730
    do_cmp ## type ## _ ## fmt ## _eq,                                    \
731
    do_cmp ## type ## _ ## fmt ## _ueq,                                   \
732
    do_cmp ## type ## _ ## fmt ## _olt,                                   \
733
    do_cmp ## type ## _ ## fmt ## _ult,                                   \
734
    do_cmp ## type ## _ ## fmt ## _ole,                                   \
735
    do_cmp ## type ## _ ## fmt ## _ule,                                   \
736
    do_cmp ## type ## _ ## fmt ## _sf,                                    \
737
    do_cmp ## type ## _ ## fmt ## _ngle,                                  \
738
    do_cmp ## type ## _ ## fmt ## _seq,                                   \
739
    do_cmp ## type ## _ ## fmt ## _ngl,                                   \
740
    do_cmp ## type ## _ ## fmt ## _lt,                                    \
741
    do_cmp ## type ## _ ## fmt ## _nge,                                   \
742
    do_cmp ## type ## _ ## fmt ## _le,                                    \
743
    do_cmp ## type ## _ ## fmt ## _ngt,                                   \
744
};                                                                        \
745
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)            \
746
{                                                                         \
747
    tcg_gen_helper_0_i(fcmp ## type ## _ ## fmt ## _table[n], cc);        \
748
}
749

    
750
FOP_CONDS(, d)
751
FOP_CONDS(abs, d)
752
FOP_CONDS(, s)
753
FOP_CONDS(abs, s)
754
FOP_CONDS(, ps)
755
FOP_CONDS(abs, ps)
756
#undef FOP_CONDS
757

    
758
/* Tests */
759
#define OP_COND(name, cond)                                   \
760
void glue(gen_op_, name) (TCGv t0, TCGv t1)                   \
761
{                                                             \
762
    int l1 = gen_new_label();                                 \
763
    int l2 = gen_new_label();                                 \
764
                                                              \
765
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
766
    tcg_gen_movi_tl(t0, 0);                                   \
767
    tcg_gen_br(l2);                                           \
768
    gen_set_label(l1);                                        \
769
    tcg_gen_movi_tl(t0, 1);                                   \
770
    gen_set_label(l2);                                        \
771
}
772
OP_COND(eq, TCG_COND_EQ);
773
OP_COND(ne, TCG_COND_NE);
774
OP_COND(ge, TCG_COND_GE);
775
OP_COND(geu, TCG_COND_GEU);
776
OP_COND(lt, TCG_COND_LT);
777
OP_COND(ltu, TCG_COND_LTU);
778
#undef OP_COND
779

    
780
#define OP_CONDI(name, cond)                                  \
781
void glue(gen_op_, name) (TCGv t, target_ulong val)           \
782
{                                                             \
783
    int l1 = gen_new_label();                                 \
784
    int l2 = gen_new_label();                                 \
785
                                                              \
786
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
787
    tcg_gen_movi_tl(t, 0);                                    \
788
    tcg_gen_br(l2);                                           \
789
    gen_set_label(l1);                                        \
790
    tcg_gen_movi_tl(t, 1);                                    \
791
    gen_set_label(l2);                                        \
792
}
793
OP_CONDI(lti, TCG_COND_LT);
794
OP_CONDI(ltiu, TCG_COND_LTU);
795
#undef OP_CONDI
796

    
797
#define OP_CONDZ(name, cond)                                  \
798
void glue(gen_op_, name) (TCGv t)                             \
799
{                                                             \
800
    int l1 = gen_new_label();                                 \
801
    int l2 = gen_new_label();                                 \
802
                                                              \
803
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
804
    tcg_gen_movi_tl(t, 0);                                    \
805
    tcg_gen_br(l2);                                           \
806
    gen_set_label(l1);                                        \
807
    tcg_gen_movi_tl(t, 1);                                    \
808
    gen_set_label(l2);                                        \
809
}
810
OP_CONDZ(gez, TCG_COND_GE);
811
OP_CONDZ(gtz, TCG_COND_GT);
812
OP_CONDZ(lez, TCG_COND_LE);
813
OP_CONDZ(ltz, TCG_COND_LT);
814
#undef OP_CONDZ
815

    
816
static inline void gen_save_pc(target_ulong pc)
817
{
818
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
819

    
820
    tcg_gen_movi_tl(r_tmp, pc);
821
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC));
822
    tcg_temp_free(r_tmp);
823
}
824

    
825
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
826
{
827
#if defined MIPS_DEBUG_DISAS
828
    if (loglevel & CPU_LOG_TB_IN_ASM) {
829
            fprintf(logfile, "hflags %08x saved %08x\n",
830
                    ctx->hflags, ctx->saved_hflags);
831
    }
832
#endif
833
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
834
        gen_save_pc(ctx->pc);
835
        ctx->saved_pc = ctx->pc;
836
    }
837
    if (ctx->hflags != ctx->saved_hflags) {
838
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
839

    
840
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
841
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
842
        tcg_temp_free(r_tmp);
843
        ctx->saved_hflags = ctx->hflags;
844
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
845
        case MIPS_HFLAG_BR:
846
            break;
847
        case MIPS_HFLAG_BC:
848
        case MIPS_HFLAG_BL:
849
        case MIPS_HFLAG_B:
850
            tcg_gen_movi_tl(btarget, ctx->btarget);
851
            break;
852
        }
853
    }
854
}
855

    
856
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
857
{
858
    ctx->saved_hflags = ctx->hflags;
859
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
860
    case MIPS_HFLAG_BR:
861
        break;
862
    case MIPS_HFLAG_BC:
863
    case MIPS_HFLAG_BL:
864
    case MIPS_HFLAG_B:
865
        ctx->btarget = env->btarget;
866
        break;
867
    }
868
}
869

    
870
static always_inline void
871
generate_exception_err (DisasContext *ctx, int excp, int err)
872
{
873
    save_cpu_state(ctx, 1);
874
    tcg_gen_helper_0_ii(do_raise_exception_err, excp, err);
875
    tcg_gen_helper_0_0(do_interrupt_restart);
876
    tcg_gen_exit_tb(0);
877
}
878

    
879
static always_inline void
880
generate_exception (DisasContext *ctx, int excp)
881
{
882
    save_cpu_state(ctx, 1);
883
    tcg_gen_helper_0_i(do_raise_exception, excp);
884
    tcg_gen_helper_0_0(do_interrupt_restart);
885
    tcg_gen_exit_tb(0);
886
}
887

    
888
/* Addresses computation */
889
static inline void gen_op_addr_add (TCGv t0, TCGv t1)
890
{
891
    tcg_gen_add_tl(t0, t0, t1);
892

    
893
#if defined(TARGET_MIPS64)
894
    /* For compatibility with 32-bit code, data reference in user mode
895
       with Status_UX = 0 should be casted to 32-bit and sign extended.
896
       See the MIPS64 PRA manual, section 4.10. */
897
    {
898
        int l1 = gen_new_label();
899
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
900

    
901
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
902
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
903
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
904
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
905
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
906
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
907
        tcg_temp_free(r_tmp);
908
        tcg_gen_ext32s_i64(t0, t0);
909
        gen_set_label(l1);
910
    }
911
#endif
912
}
913

    
914
static always_inline void check_cp0_enabled(DisasContext *ctx)
915
{
916
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
917
        generate_exception_err(ctx, EXCP_CpU, 1);
918
}
919

    
920
static always_inline void check_cp1_enabled(DisasContext *ctx)
921
{
922
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
923
        generate_exception_err(ctx, EXCP_CpU, 1);
924
}
925

    
926
/* Verify that the processor is running with COP1X instructions enabled.
927
   This is associated with the nabla symbol in the MIPS32 and MIPS64
928
   opcode tables.  */
929

    
930
static always_inline void check_cop1x(DisasContext *ctx)
931
{
932
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
933
        generate_exception(ctx, EXCP_RI);
934
}
935

    
936
/* Verify that the processor is running with 64-bit floating-point
937
   operations enabled.  */
938

    
939
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
940
{
941
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
942
        generate_exception(ctx, EXCP_RI);
943
}
944

    
945
/*
946
 * Verify if floating point register is valid; an operation is not defined
947
 * if bit 0 of any register specification is set and the FR bit in the
948
 * Status register equals zero, since the register numbers specify an
949
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
950
 * in the Status register equals one, both even and odd register numbers
951
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
952
 *
953
 * Multiple 64 bit wide registers can be checked by calling
954
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
955
 */
956
void check_cp1_registers(DisasContext *ctx, int regs)
957
{
958
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
959
        generate_exception(ctx, EXCP_RI);
960
}
961

    
962
/* This code generates a "reserved instruction" exception if the
963
   CPU does not support the instruction set corresponding to flags. */
964
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
965
{
966
    if (unlikely(!(env->insn_flags & flags)))
967
        generate_exception(ctx, EXCP_RI);
968
}
969

    
970
/* This code generates a "reserved instruction" exception if 64-bit
971
   instructions are not enabled. */
972
static always_inline void check_mips_64(DisasContext *ctx)
973
{
974
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
975
        generate_exception(ctx, EXCP_RI);
976
}
977

    
978
/* load/store instructions. */
979
#define OP_LD(insn,fname)                                        \
980
void inline op_ldst_##insn(TCGv t0, DisasContext *ctx)           \
981
{                                                                \
982
    tcg_gen_qemu_##fname(t0, t0, 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(TCGv t0, TCGv t1, DisasContext *ctx)  \
997
{                                                                \
998
    tcg_gen_qemu_##fname(t1, t0, 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(TCGv t0, TCGv t1, DisasContext *ctx)         \
1010
{                                                                       \
1011
    tcg_gen_mov_tl(t1, t0);                                             \
1012
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
1013
    tcg_gen_st_tl(t1, 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(TCGv t0, TCGv t1, 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, t0, almask);                                 \
1030
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1031
    tcg_gen_st_tl(t0, 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, t0, r_tmp, l2);                      \
1036
    tcg_temp_free(r_tmp);                                               \
1037
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
1038
    tcg_gen_movi_tl(t0, 1);                                             \
1039
    tcg_gen_br(l3);                                                     \
1040
    gen_set_label(l2);                                                  \
1041
    tcg_gen_movi_tl(t0, 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
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1056
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1057

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

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

    
1221
    if (base == 0) {
1222
        tcg_gen_movi_tl(t0, offset);
1223
    } else if (offset == 0) {
1224
        gen_load_gpr(t0, base);
1225
    } else {
1226
        TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1227

    
1228
        gen_load_gpr(t0, base);
1229
        tcg_gen_movi_tl(t1, offset);
1230
        gen_op_addr_add(t0, t1);
1231
        tcg_temp_free(t1);
1232
    }
1233
    /* Don't do NOP if destination is zero: we must perform the actual
1234
       memory access. */
1235
    switch (opc) {
1236
    case OPC_LWC1:
1237
        tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx);
1238
        gen_store_fpr32(fpu32_T[0], ft);
1239
        opn = "lwc1";
1240
        break;
1241
    case OPC_SWC1:
1242
        gen_load_fpr32(fpu32_T[0], ft);
1243
        tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx);
1244
        opn = "swc1";
1245
        break;
1246
    case OPC_LDC1:
1247
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
1248
        gen_store_fpr64(ctx, fpu64_T[0], ft);
1249
        opn = "ldc1";
1250
        break;
1251
    case OPC_SDC1:
1252
        gen_load_fpr64(ctx, fpu64_T[0], ft);
1253
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
1254
        opn = "sdc1";
1255
        break;
1256
    default:
1257
        MIPS_INVAL(opn);
1258
        generate_exception(ctx, EXCP_RI);
1259
        goto out;
1260
    }
1261
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1262
 out:
1263
    tcg_temp_free(t0);
1264
}
1265

    
1266
/* Arithmetic with immediate operand */
1267
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1268
                           int rt, int rs, int16_t imm)
1269
{
1270
    target_ulong uimm;
1271
    const char *opn = "imm arith";
1272
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1273

    
1274
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1275
        /* If no destination, treat it as a NOP.
1276
           For addi, we must generate the overflow exception when needed. */
1277
        MIPS_DEBUG("NOP");
1278
        goto out;
1279
    }
1280
    uimm = (uint16_t)imm;
1281
    switch (opc) {
1282
    case OPC_ADDI:
1283
    case OPC_ADDIU:
1284
#if defined(TARGET_MIPS64)
1285
    case OPC_DADDI:
1286
    case OPC_DADDIU:
1287
#endif
1288
    case OPC_SLTI:
1289
    case OPC_SLTIU:
1290
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1291
        /* Fall through. */
1292
    case OPC_ANDI:
1293
    case OPC_ORI:
1294
    case OPC_XORI:
1295
        gen_load_gpr(t0, rs);
1296
        break;
1297
    case OPC_LUI:
1298
        tcg_gen_movi_tl(t0, imm << 16);
1299
        break;
1300
    case OPC_SLL:
1301
    case OPC_SRA:
1302
    case OPC_SRL:
1303
#if defined(TARGET_MIPS64)
1304
    case OPC_DSLL:
1305
    case OPC_DSRA:
1306
    case OPC_DSRL:
1307
    case OPC_DSLL32:
1308
    case OPC_DSRA32:
1309
    case OPC_DSRL32:
1310
#endif
1311
        uimm &= 0x1f;
1312
        gen_load_gpr(t0, rs);
1313
        break;
1314
    }
1315
    switch (opc) {
1316
    case OPC_ADDI:
1317
        {
1318
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1319
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1320
            int l1 = gen_new_label();
1321

    
1322
            save_cpu_state(ctx, 1);
1323
            tcg_gen_ext32s_tl(r_tmp1, t0);
1324
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1325

    
1326
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1327
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1328
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1329
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1330
            tcg_temp_free(r_tmp2);
1331
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1332
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1333
            tcg_temp_free(r_tmp1);
1334
            /* operands of same sign, result different sign */
1335
            generate_exception(ctx, EXCP_OVERFLOW);
1336
            gen_set_label(l1);
1337

    
1338
            tcg_gen_ext32s_tl(t0, t0);
1339
        }
1340
        opn = "addi";
1341
        break;
1342
    case OPC_ADDIU:
1343
        tcg_gen_ext32s_tl(t0, t0);
1344
        tcg_gen_addi_tl(t0, t0, uimm);
1345
        tcg_gen_ext32s_tl(t0, t0);
1346
        opn = "addiu";
1347
        break;
1348
#if defined(TARGET_MIPS64)
1349
    case OPC_DADDI:
1350
        {
1351
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1352
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1353
            int l1 = gen_new_label();
1354

    
1355
            save_cpu_state(ctx, 1);
1356
            tcg_gen_mov_tl(r_tmp1, t0);
1357
            tcg_gen_addi_tl(t0, t0, uimm);
1358

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

    
1428
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1429
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1430
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1431
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1432
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1433
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1434
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1435
                    tcg_temp_free(r_tmp1);
1436
                    tcg_temp_free(r_tmp2);
1437
                }
1438
                opn = "rotr";
1439
            } else {
1440
                tcg_gen_ext32u_tl(t0, t0);
1441
                tcg_gen_shri_tl(t0, t0, uimm);
1442
                tcg_gen_ext32s_tl(t0, t0);
1443
                opn = "srl";
1444
            }
1445
            break;
1446
        default:
1447
            MIPS_INVAL("invalid srl flag");
1448
            generate_exception(ctx, EXCP_RI);
1449
            break;
1450
        }
1451
        break;
1452
#if defined(TARGET_MIPS64)
1453
    case OPC_DSLL:
1454
        tcg_gen_shli_tl(t0, t0, uimm);
1455
        opn = "dsll";
1456
        break;
1457
    case OPC_DSRA:
1458
        tcg_gen_sari_tl(t0, t0, uimm);
1459
        opn = "dsra";
1460
        break;
1461
    case OPC_DSRL:
1462
        switch ((ctx->opcode >> 21) & 0x1f) {
1463
        case 0:
1464
            tcg_gen_shri_tl(t0, t0, uimm);
1465
            opn = "dsrl";
1466
            break;
1467
        case 1:
1468
            /* drotr is decoded as dsrl on non-R2 CPUs */
1469
            if (env->insn_flags & ISA_MIPS32R2) {
1470
                if (uimm != 0) {
1471
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1472

    
1473
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1474
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1475
                    tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1476
                    tcg_gen_shri_tl(t0, t0, uimm);
1477
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1478
                    tcg_temp_free(r_tmp1);
1479
                }
1480
                opn = "drotr";
1481
            } else {
1482
                tcg_gen_shri_tl(t0, t0, uimm);
1483
                opn = "dsrl";
1484
            }
1485
            break;
1486
        default:
1487
            MIPS_INVAL("invalid dsrl flag");
1488
            generate_exception(ctx, EXCP_RI);
1489
            break;
1490
        }
1491
        break;
1492
    case OPC_DSLL32:
1493
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1494
        opn = "dsll32";
1495
        break;
1496
    case OPC_DSRA32:
1497
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1498
        opn = "dsra32";
1499
        break;
1500
    case OPC_DSRL32:
1501
        switch ((ctx->opcode >> 21) & 0x1f) {
1502
        case 0:
1503
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1504
            opn = "dsrl32";
1505
            break;
1506
        case 1:
1507
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1508
            if (env->insn_flags & ISA_MIPS32R2) {
1509
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1510
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1511

    
1512
                tcg_gen_movi_tl(r_tmp1, 0x40);
1513
                tcg_gen_movi_tl(r_tmp2, 32);
1514
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1515
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1516
                tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1517
                tcg_gen_shr_tl(t0, t0, r_tmp2);
1518
                tcg_gen_or_tl(t0, t0, r_tmp1);
1519
                tcg_temp_free(r_tmp1);
1520
                tcg_temp_free(r_tmp2);
1521
                opn = "drotr32";
1522
            } else {
1523
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1524
                opn = "dsrl32";
1525
            }
1526
            break;
1527
        default:
1528
            MIPS_INVAL("invalid dsrl32 flag");
1529
            generate_exception(ctx, EXCP_RI);
1530
            break;
1531
        }
1532
        break;
1533
#endif
1534
    default:
1535
        MIPS_INVAL(opn);
1536
        generate_exception(ctx, EXCP_RI);
1537
        goto out;
1538
    }
1539
    gen_store_gpr(t0, rt);
1540
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1541
 out:
1542
    tcg_temp_free(t0);
1543
}
1544

    
1545
/* Arithmetic */
1546
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1547
                       int rd, int rs, int rt)
1548
{
1549
    const char *opn = "arith";
1550
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1551
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1552

    
1553
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1554
       && opc != OPC_DADD && opc != OPC_DSUB) {
1555
        /* If no destination, treat it as a NOP.
1556
           For add & sub, we must generate the overflow exception when needed. */
1557
        MIPS_DEBUG("NOP");
1558
        goto out;
1559
    }
1560
    gen_load_gpr(t0, rs);
1561
    /* Specialcase the conventional move operation. */
1562
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1563
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1564
        gen_store_gpr(t0, rd);
1565
        goto out;
1566
    }
1567
    gen_load_gpr(t1, rt);
1568
    switch (opc) {
1569
    case OPC_ADD:
1570
        {
1571
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1572
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1573
            int l1 = gen_new_label();
1574

    
1575
            save_cpu_state(ctx, 1);
1576
            tcg_gen_ext32s_tl(r_tmp1, t0);
1577
            tcg_gen_ext32s_tl(r_tmp2, t1);
1578
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1579

    
1580
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1581
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1582
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1583
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1584
            tcg_temp_free(r_tmp2);
1585
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1586
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1587
            tcg_temp_free(r_tmp1);
1588
            /* operands of same sign, result different sign */
1589
            generate_exception(ctx, EXCP_OVERFLOW);
1590
            gen_set_label(l1);
1591

    
1592
            tcg_gen_ext32s_tl(t0, t0);
1593
        }
1594
        opn = "add";
1595
        break;
1596
    case OPC_ADDU:
1597
        tcg_gen_ext32s_tl(t0, t0);
1598
        tcg_gen_ext32s_tl(t1, t1);
1599
        tcg_gen_add_tl(t0, t0, t1);
1600
        tcg_gen_ext32s_tl(t0, t0);
1601
        opn = "addu";
1602
        break;
1603
    case OPC_SUB:
1604
        {
1605
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1606
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1607
            int l1 = gen_new_label();
1608

    
1609
            save_cpu_state(ctx, 1);
1610
            tcg_gen_ext32s_tl(r_tmp1, t0);
1611
            tcg_gen_ext32s_tl(r_tmp2, t1);
1612
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1613

    
1614
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1615
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1616
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1617
            tcg_temp_free(r_tmp2);
1618
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1619
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1620
            tcg_temp_free(r_tmp1);
1621
            /* operands of different sign, first operand and result different sign */
1622
            generate_exception(ctx, EXCP_OVERFLOW);
1623
            gen_set_label(l1);
1624

    
1625
            tcg_gen_ext32s_tl(t0, t0);
1626
        }
1627
        opn = "sub";
1628
        break;
1629
    case OPC_SUBU:
1630
        tcg_gen_ext32s_tl(t0, t0);
1631
        tcg_gen_ext32s_tl(t1, t1);
1632
        tcg_gen_sub_tl(t0, t0, t1);
1633
        tcg_gen_ext32s_tl(t0, t0);
1634
        opn = "subu";
1635
        break;
1636
#if defined(TARGET_MIPS64)
1637
    case OPC_DADD:
1638
        {
1639
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1640
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1641
            int l1 = gen_new_label();
1642

    
1643
            save_cpu_state(ctx, 1);
1644
            tcg_gen_mov_tl(r_tmp1, t0);
1645
            tcg_gen_add_tl(t0, t0, t1);
1646

    
1647
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1648
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1649
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1650
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1651
            tcg_temp_free(r_tmp2);
1652
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1653
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1654
            tcg_temp_free(r_tmp1);
1655
            /* operands of same sign, result different sign */
1656
            generate_exception(ctx, EXCP_OVERFLOW);
1657
            gen_set_label(l1);
1658
        }
1659
        opn = "dadd";
1660
        break;
1661
    case OPC_DADDU:
1662
        tcg_gen_add_tl(t0, t0, t1);
1663
        opn = "daddu";
1664
        break;
1665
    case OPC_DSUB:
1666
        {
1667
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1668
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1669
            int l1 = gen_new_label();
1670

    
1671
            save_cpu_state(ctx, 1);
1672
            tcg_gen_mov_tl(r_tmp1, t0);
1673
            tcg_gen_sub_tl(t0, t0, t1);
1674

    
1675
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1676
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1677
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1678
            tcg_temp_free(r_tmp2);
1679
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1680
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1681
            tcg_temp_free(r_tmp1);
1682
            /* operands of different sign, first operand and result different sign */
1683
            generate_exception(ctx, EXCP_OVERFLOW);
1684
            gen_set_label(l1);
1685
        }
1686
        opn = "dsub";
1687
        break;
1688
    case OPC_DSUBU:
1689
        tcg_gen_sub_tl(t0, t0, t1);
1690
        opn = "dsubu";
1691
        break;
1692
#endif
1693
    case OPC_SLT:
1694
        gen_op_lt(t0, t1);
1695
        opn = "slt";
1696
        break;
1697
    case OPC_SLTU:
1698
        gen_op_ltu(t0, t1);
1699
        opn = "sltu";
1700
        break;
1701
    case OPC_AND:
1702
        tcg_gen_and_tl(t0, t0, t1);
1703
        opn = "and";
1704
        break;
1705
    case OPC_NOR:
1706
        tcg_gen_or_tl(t0, t0, t1);
1707
        tcg_gen_not_tl(t0, t0);
1708
        opn = "nor";
1709
        break;
1710
    case OPC_OR:
1711
        tcg_gen_or_tl(t0, t0, t1);
1712
        opn = "or";
1713
        break;
1714
    case OPC_XOR:
1715
        tcg_gen_xor_tl(t0, t0, t1);
1716
        opn = "xor";
1717
        break;
1718
    case OPC_MUL:
1719
        tcg_gen_ext32s_tl(t0, t0);
1720
        tcg_gen_ext32s_tl(t1, t1);
1721
        tcg_gen_mul_tl(t0, t0, t1);
1722
        tcg_gen_ext32s_tl(t0, t0);
1723
        opn = "mul";
1724
        break;
1725
    case OPC_MOVN:
1726
        {
1727
            int l1 = gen_new_label();
1728

    
1729
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1730
            gen_store_gpr(t0, rd);
1731
            gen_set_label(l1);
1732
        }
1733
        opn = "movn";
1734
        goto print;
1735
    case OPC_MOVZ:
1736
        {
1737
            int l1 = gen_new_label();
1738

    
1739
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1740
            gen_store_gpr(t0, rd);
1741
            gen_set_label(l1);
1742
        }
1743
        opn = "movz";
1744
        goto print;
1745
    case OPC_SLLV:
1746
        tcg_gen_ext32u_tl(t0, t0);
1747
        tcg_gen_ext32u_tl(t1, t1);
1748
        tcg_gen_andi_tl(t0, t0, 0x1f);
1749
        tcg_gen_shl_tl(t0, t1, t0);
1750
        tcg_gen_ext32s_tl(t0, t0);
1751
        opn = "sllv";
1752
        break;
1753
    case OPC_SRAV:
1754
        tcg_gen_ext32s_tl(t1, t1);
1755
        tcg_gen_andi_tl(t0, t0, 0x1f);
1756
        tcg_gen_sar_tl(t0, t1, t0);
1757
        tcg_gen_ext32s_tl(t0, t0);
1758
        opn = "srav";
1759
        break;
1760
    case OPC_SRLV:
1761
        switch ((ctx->opcode >> 6) & 0x1f) {
1762
        case 0:
1763
            tcg_gen_ext32u_tl(t1, t1);
1764
            tcg_gen_andi_tl(t0, t0, 0x1f);
1765
            tcg_gen_shr_tl(t0, t1, t0);
1766
            tcg_gen_ext32s_tl(t0, t0);
1767
            opn = "srlv";
1768
            break;
1769
        case 1:
1770
            /* rotrv is decoded as srlv on non-R2 CPUs */
1771
            if (env->insn_flags & ISA_MIPS32R2) {
1772
                int l1 = gen_new_label();
1773
                int l2 = gen_new_label();
1774

    
1775
                tcg_gen_andi_tl(t0, t0, 0x1f);
1776
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1777
                {
1778
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1779
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1780
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1781

    
1782
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1783
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1784
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1785
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1786
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1787
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1788
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1789
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1790
                    tcg_temp_free(r_tmp1);
1791
                    tcg_temp_free(r_tmp2);
1792
                    tcg_temp_free(r_tmp3);
1793
                    tcg_gen_br(l2);
1794
                }
1795
                gen_set_label(l1);
1796
                tcg_gen_mov_tl(t0, t1);
1797
                gen_set_label(l2);
1798
                opn = "rotrv";
1799
            } else {
1800
                tcg_gen_ext32u_tl(t1, t1);
1801
                tcg_gen_andi_tl(t0, t0, 0x1f);
1802
                tcg_gen_shr_tl(t0, t1, t0);
1803
                tcg_gen_ext32s_tl(t0, t0);
1804
                opn = "srlv";
1805
            }
1806
            break;
1807
        default:
1808
            MIPS_INVAL("invalid srlv flag");
1809
            generate_exception(ctx, EXCP_RI);
1810
            break;
1811
        }
1812
        break;
1813
#if defined(TARGET_MIPS64)
1814
    case OPC_DSLLV:
1815
        tcg_gen_andi_tl(t0, t0, 0x3f);
1816
        tcg_gen_shl_tl(t0, t1, t0);
1817
        opn = "dsllv";
1818
        break;
1819
    case OPC_DSRAV:
1820
        tcg_gen_andi_tl(t0, t0, 0x3f);
1821
        tcg_gen_sar_tl(t0, t1, t0);
1822
        opn = "dsrav";
1823
        break;
1824
    case OPC_DSRLV:
1825
        switch ((ctx->opcode >> 6) & 0x1f) {
1826
        case 0:
1827
            tcg_gen_andi_tl(t0, t0, 0x3f);
1828
            tcg_gen_shr_tl(t0, t1, t0);
1829
            opn = "dsrlv";
1830
            break;
1831
        case 1:
1832
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1833
            if (env->insn_flags & ISA_MIPS32R2) {
1834
                int l1 = gen_new_label();
1835
                int l2 = gen_new_label();
1836

    
1837
                tcg_gen_andi_tl(t0, t0, 0x3f);
1838
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1839
                {
1840
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1841

    
1842
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1843
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, t0);
1844
                    tcg_gen_shl_tl(r_tmp1, t1, r_tmp1);
1845
                    tcg_gen_shr_tl(t0, t1, t0);
1846
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1847
                    tcg_temp_free(r_tmp1);
1848
                    tcg_gen_br(l2);
1849
                }
1850
                gen_set_label(l1);
1851
                tcg_gen_mov_tl(t0, t1);
1852
                gen_set_label(l2);
1853
                opn = "drotrv";
1854
            } else {
1855
                tcg_gen_andi_tl(t0, t0, 0x3f);
1856
                tcg_gen_shr_tl(t0, t1, t0);
1857
                opn = "dsrlv";
1858
            }
1859
            break;
1860
        default:
1861
            MIPS_INVAL("invalid dsrlv flag");
1862
            generate_exception(ctx, EXCP_RI);
1863
            break;
1864
        }
1865
        break;
1866
#endif
1867
    default:
1868
        MIPS_INVAL(opn);
1869
        generate_exception(ctx, EXCP_RI);
1870
        goto out;
1871
    }
1872
    gen_store_gpr(t0, rd);
1873
 print:
1874
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1875
 out:
1876
    tcg_temp_free(t0);
1877
    tcg_temp_free(t1);
1878
}
1879

    
1880
/* Arithmetic on HI/LO registers */
1881
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1882
{
1883
    const char *opn = "hilo";
1884
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1885

    
1886
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1887
        /* Treat as NOP. */
1888
        MIPS_DEBUG("NOP");
1889
        goto out;
1890
    }
1891
    switch (opc) {
1892
    case OPC_MFHI:
1893
        gen_load_HI(t0, 0);
1894
        gen_store_gpr(t0, reg);
1895
        opn = "mfhi";
1896
        break;
1897
    case OPC_MFLO:
1898
        gen_load_LO(t0, 0);
1899
        gen_store_gpr(t0, reg);
1900
        opn = "mflo";
1901
        break;
1902
    case OPC_MTHI:
1903
        gen_load_gpr(t0, reg);
1904
        gen_store_HI(t0, 0);
1905
        opn = "mthi";
1906
        break;
1907
    case OPC_MTLO:
1908
        gen_load_gpr(t0, reg);
1909
        gen_store_LO(t0, 0);
1910
        opn = "mtlo";
1911
        break;
1912
    default:
1913
        MIPS_INVAL(opn);
1914
        generate_exception(ctx, EXCP_RI);
1915
        goto out;
1916
    }
1917
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1918
 out:
1919
    tcg_temp_free(t0);
1920
}
1921

    
1922
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1923
                        int rs, int rt)
1924
{
1925
    const char *opn = "mul/div";
1926
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1927
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1928

    
1929
    gen_load_gpr(t0, rs);
1930
    gen_load_gpr(t1, rt);
1931
    switch (opc) {
1932
    case OPC_DIV:
1933
        {
1934
            int l1 = gen_new_label();
1935

    
1936
            tcg_gen_ext32s_tl(t0, t0);
1937
            tcg_gen_ext32s_tl(t1, t1);
1938
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1939
            {
1940
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1941
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1942
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1943

    
1944
                tcg_gen_ext_tl_i64(r_tmp1, t0);
1945
                tcg_gen_ext_tl_i64(r_tmp2, t1);
1946
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1947
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1948
                tcg_gen_trunc_i64_tl(t0, r_tmp3);
1949
                tcg_gen_trunc_i64_tl(t1, r_tmp2);
1950
                tcg_temp_free(r_tmp1);
1951
                tcg_temp_free(r_tmp2);
1952
                tcg_temp_free(r_tmp3);
1953
                tcg_gen_ext32s_tl(t0, t0);
1954
                tcg_gen_ext32s_tl(t1, t1);
1955
                gen_store_LO(t0, 0);
1956
                gen_store_HI(t1, 0);
1957
            }
1958
            gen_set_label(l1);
1959
        }
1960
        opn = "div";
1961
        break;
1962
    case OPC_DIVU:
1963
        {
1964
            int l1 = gen_new_label();
1965

    
1966
            tcg_gen_ext32s_tl(t1, t1);
1967
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1968
            {
1969
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1970
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1971
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1972

    
1973
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1974
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1975
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1976
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1977
                tcg_gen_ext_i32_tl(t0, r_tmp3);
1978
                tcg_gen_ext_i32_tl(t1, r_tmp1);
1979
                tcg_temp_free(r_tmp1);
1980
                tcg_temp_free(r_tmp2);
1981
                tcg_temp_free(r_tmp3);
1982
                gen_store_LO(t0, 0);
1983
                gen_store_HI(t1, 0);
1984
            }
1985
            gen_set_label(l1);
1986
        }
1987
        opn = "divu";
1988
        break;
1989
    case OPC_MULT:
1990
        {
1991
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1992
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1993

    
1994
            tcg_gen_ext32s_tl(t0, t0);
1995
            tcg_gen_ext32s_tl(t1, t1);
1996
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1997
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1998
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1999
            tcg_temp_free(r_tmp2);
2000
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2001
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2002
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2003
            tcg_temp_free(r_tmp1);
2004
            tcg_gen_ext32s_tl(t0, t0);
2005
            tcg_gen_ext32s_tl(t1, t1);
2006
            gen_store_LO(t0, 0);
2007
            gen_store_HI(t1, 0);
2008
        }
2009
        opn = "mult";
2010
        break;
2011
    case OPC_MULTU:
2012
        {
2013
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2014
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2015

    
2016
            tcg_gen_ext32u_tl(t0, t0);
2017
            tcg_gen_ext32u_tl(t1, t1);
2018
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2019
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2020
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2021
            tcg_temp_free(r_tmp2);
2022
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2023
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2024
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2025
            tcg_temp_free(r_tmp1);
2026
            tcg_gen_ext32s_tl(t0, t0);
2027
            tcg_gen_ext32s_tl(t1, t1);
2028
            gen_store_LO(t0, 0);
2029
            gen_store_HI(t1, 0);
2030
        }
2031
        opn = "multu";
2032
        break;
2033
#if defined(TARGET_MIPS64)
2034
    case OPC_DDIV:
2035
        {
2036
            int l1 = gen_new_label();
2037

    
2038
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2039
            {
2040
                int l2 = gen_new_label();
2041

    
2042
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2043
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2044
                {
2045
                    tcg_gen_movi_tl(t1, 0);
2046
                    gen_store_LO(t0, 0);
2047
                    gen_store_HI(t1, 0);
2048
                    tcg_gen_br(l1);
2049
                }
2050
                gen_set_label(l2);
2051
                {
2052
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2053
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2054

    
2055
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2056
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2057
                    gen_store_LO(r_tmp1, 0);
2058
                    gen_store_HI(r_tmp2, 0);
2059
                    tcg_temp_free(r_tmp1);
2060
                    tcg_temp_free(r_tmp2);
2061
                }
2062
            }
2063
            gen_set_label(l1);
2064
        }
2065
        opn = "ddiv";
2066
        break;
2067
    case OPC_DDIVU:
2068
        {
2069
            int l1 = gen_new_label();
2070

    
2071
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2072
            {
2073
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2074
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2075

    
2076
                tcg_gen_divu_i64(r_tmp1, t0, t1);
2077
                tcg_gen_remu_i64(r_tmp2, t0, t1);
2078
                tcg_temp_free(r_tmp1);
2079
                tcg_temp_free(r_tmp2);
2080
                gen_store_LO(r_tmp1, 0);
2081
                gen_store_HI(r_tmp2, 0);
2082
            }
2083
            gen_set_label(l1);
2084
        }
2085
        opn = "ddivu";
2086
        break;
2087
    case OPC_DMULT:
2088
        tcg_gen_helper_0_2(do_dmult, t0, t1);
2089
        opn = "dmult";
2090
        break;
2091
    case OPC_DMULTU:
2092
        tcg_gen_helper_0_2(do_dmultu, t0, t1);
2093
        opn = "dmultu";
2094
        break;
2095
#endif
2096
    case OPC_MADD:
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_ext32s_tl(t0, t0);
2103
            tcg_gen_ext32s_tl(t1, t1);
2104
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2105
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2106
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2107
            gen_load_LO(t0, 0);
2108
            gen_load_HI(t1, 0);
2109
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2110
            tcg_gen_extu_tl_i64(r_tmp3, t1);
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(t0, r_tmp1);
2117
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2118
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2119
            tcg_temp_free(r_tmp1);
2120
            tcg_gen_ext32s_tl(t0, t0);
2121
            tcg_gen_ext32s_tl(t1, t1);
2122
            gen_store_LO(t0, 0);
2123
            gen_store_HI(t1, 0);
2124
        }
2125
        opn = "madd";
2126
        break;
2127
    case OPC_MADDU:
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_ext32u_tl(t0, t0);
2134
            tcg_gen_ext32u_tl(t1, t1);
2135
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2136
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2137
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2138
            gen_load_LO(t0, 0);
2139
            gen_load_HI(t1, 0);
2140
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2141
            tcg_gen_extu_tl_i64(r_tmp3, t1);
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_add_i64(r_tmp1, r_tmp1, r_tmp2);
2146
            tcg_temp_free(r_tmp2);
2147
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2148
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2149
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2150
            tcg_temp_free(r_tmp1);
2151
            tcg_gen_ext32s_tl(t0, t0);
2152
            tcg_gen_ext32s_tl(t1, t1);
2153
            gen_store_LO(t0, 0);
2154
            gen_store_HI(t1, 0);
2155
        }
2156
        opn = "maddu";
2157
        break;
2158
    case OPC_MSUB:
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_ext32s_tl(t0, t0);
2165
            tcg_gen_ext32s_tl(t1, t1);
2166
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2167
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2168
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2169
            gen_load_LO(t0, 0);
2170
            gen_load_HI(t1, 0);
2171
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2172
            tcg_gen_extu_tl_i64(r_tmp3, t1);
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(t0, r_tmp1);
2179
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2180
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2181
            tcg_temp_free(r_tmp1);
2182
            tcg_gen_ext32s_tl(t0, t0);
2183
            tcg_gen_ext32s_tl(t1, t1);
2184
            gen_store_LO(t0, 0);
2185
            gen_store_HI(t1, 0);
2186
        }
2187
        opn = "msub";
2188
        break;
2189
    case OPC_MSUBU:
2190
        {
2191
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2192
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2193
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2194

    
2195
            tcg_gen_ext32u_tl(t0, t0);
2196
            tcg_gen_ext32u_tl(t1, t1);
2197
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2198
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2199
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2200
            gen_load_LO(t0, 0);
2201
            gen_load_HI(t1, 0);
2202
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2203
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2204
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2205
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2206
            tcg_temp_free(r_tmp3);
2207
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2208
            tcg_temp_free(r_tmp2);
2209
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2210
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2211
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2212
            tcg_temp_free(r_tmp1);
2213
            tcg_gen_ext32s_tl(t0, t0);
2214
            tcg_gen_ext32s_tl(t1, t1);
2215
            gen_store_LO(t0, 0);
2216
            gen_store_HI(t1, 0);
2217
        }
2218
        opn = "msubu";
2219
        break;
2220
    default:
2221
        MIPS_INVAL(opn);
2222
        generate_exception(ctx, EXCP_RI);
2223
        goto out;
2224
    }
2225
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2226
 out:
2227
    tcg_temp_free(t0);
2228
    tcg_temp_free(t1);
2229
}
2230

    
2231
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2232
                            int rd, int rs, int rt)
2233
{
2234
    const char *opn = "mul vr54xx";
2235
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2236
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2237

    
2238
    gen_load_gpr(t0, rs);
2239
    gen_load_gpr(t1, rt);
2240

    
2241
    switch (opc) {
2242
    case OPC_VR54XX_MULS:
2243
        tcg_gen_helper_1_2(do_muls, t0, t0, t1);
2244
        opn = "muls";
2245
        break;
2246
    case OPC_VR54XX_MULSU:
2247
        tcg_gen_helper_1_2(do_mulsu, t0, t0, t1);
2248
        opn = "mulsu";
2249
        break;
2250
    case OPC_VR54XX_MACC:
2251
        tcg_gen_helper_1_2(do_macc, t0, t0, t1);
2252
        opn = "macc";
2253
        break;
2254
    case OPC_VR54XX_MACCU:
2255
        tcg_gen_helper_1_2(do_maccu, t0, t0, t1);
2256
        opn = "maccu";
2257
        break;
2258
    case OPC_VR54XX_MSAC:
2259
        tcg_gen_helper_1_2(do_msac, t0, t0, t1);
2260
        opn = "msac";
2261
        break;
2262
    case OPC_VR54XX_MSACU:
2263
        tcg_gen_helper_1_2(do_msacu, t0, t0, t1);
2264
        opn = "msacu";
2265
        break;
2266
    case OPC_VR54XX_MULHI:
2267
        tcg_gen_helper_1_2(do_mulhi, t0, t0, t1);
2268
        opn = "mulhi";
2269
        break;
2270
    case OPC_VR54XX_MULHIU:
2271
        tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1);
2272
        opn = "mulhiu";
2273
        break;
2274
    case OPC_VR54XX_MULSHI:
2275
        tcg_gen_helper_1_2(do_mulshi, t0, t0, t1);
2276
        opn = "mulshi";
2277
        break;
2278
    case OPC_VR54XX_MULSHIU:
2279
        tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1);
2280
        opn = "mulshiu";
2281
        break;
2282
    case OPC_VR54XX_MACCHI:
2283
        tcg_gen_helper_1_2(do_macchi, t0, t0, t1);
2284
        opn = "macchi";
2285
        break;
2286
    case OPC_VR54XX_MACCHIU:
2287
        tcg_gen_helper_1_2(do_macchiu, t0, t0, t1);
2288
        opn = "macchiu";
2289
        break;
2290
    case OPC_VR54XX_MSACHI:
2291
        tcg_gen_helper_1_2(do_msachi, t0, t0, t1);
2292
        opn = "msachi";
2293
        break;
2294
    case OPC_VR54XX_MSACHIU:
2295
        tcg_gen_helper_1_2(do_msachiu, t0, t0, t1);
2296
        opn = "msachiu";
2297
        break;
2298
    default:
2299
        MIPS_INVAL("mul vr54xx");
2300
        generate_exception(ctx, EXCP_RI);
2301
        goto out;
2302
    }
2303
    gen_store_gpr(t0, rd);
2304
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2305

    
2306
 out:
2307
    tcg_temp_free(t0);
2308
    tcg_temp_free(t1);
2309
}
2310

    
2311
static void gen_cl (DisasContext *ctx, uint32_t opc,
2312
                    int rd, int rs)
2313
{
2314
    const char *opn = "CLx";
2315
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2316

    
2317
    if (rd == 0) {
2318
        /* Treat as NOP. */
2319
        MIPS_DEBUG("NOP");
2320
        goto out;
2321
    }
2322
    gen_load_gpr(t0, rs);
2323
    switch (opc) {
2324
    case OPC_CLO:
2325
        tcg_gen_helper_1_1(do_clo, t0, t0);
2326
        opn = "clo";
2327
        break;
2328
    case OPC_CLZ:
2329
        tcg_gen_helper_1_1(do_clz, t0, t0);
2330
        opn = "clz";
2331
        break;
2332
#if defined(TARGET_MIPS64)
2333
    case OPC_DCLO:
2334
        tcg_gen_helper_1_1(do_dclo, t0, t0);
2335
        opn = "dclo";
2336
        break;
2337
    case OPC_DCLZ:
2338
        tcg_gen_helper_1_1(do_dclz, t0, t0);
2339
        opn = "dclz";
2340
        break;
2341
#endif
2342
    default:
2343
        MIPS_INVAL(opn);
2344
        generate_exception(ctx, EXCP_RI);
2345
        goto out;
2346
    }
2347
    gen_store_gpr(t0, rd);
2348
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2349

    
2350
 out:
2351
    tcg_temp_free(t0);
2352
}
2353

    
2354
/* Traps */
2355
static void gen_trap (DisasContext *ctx, uint32_t opc,
2356
                      int rs, int rt, int16_t imm)
2357
{
2358
    int cond;
2359
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2360
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2361

    
2362
    cond = 0;
2363
    /* Load needed operands */
2364
    switch (opc) {
2365
    case OPC_TEQ:
2366
    case OPC_TGE:
2367
    case OPC_TGEU:
2368
    case OPC_TLT:
2369
    case OPC_TLTU:
2370
    case OPC_TNE:
2371
        /* Compare two registers */
2372
        if (rs != rt) {
2373
            gen_load_gpr(t0, rs);
2374
            gen_load_gpr(t1, rt);
2375
            cond = 1;
2376
        }
2377
        break;
2378
    case OPC_TEQI:
2379
    case OPC_TGEI:
2380
    case OPC_TGEIU:
2381
    case OPC_TLTI:
2382
    case OPC_TLTIU:
2383
    case OPC_TNEI:
2384
        /* Compare register to immediate */
2385
        if (rs != 0 || imm != 0) {
2386
            gen_load_gpr(t0, rs);
2387
            tcg_gen_movi_tl(t1, (int32_t)imm);
2388
            cond = 1;
2389
        }
2390
        break;
2391
    }
2392
    if (cond == 0) {
2393
        switch (opc) {
2394
        case OPC_TEQ:   /* rs == rs */
2395
        case OPC_TEQI:  /* r0 == 0  */
2396
        case OPC_TGE:   /* rs >= rs */
2397
        case OPC_TGEI:  /* r0 >= 0  */
2398
        case OPC_TGEU:  /* rs >= rs unsigned */
2399
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2400
            /* Always trap */
2401
            tcg_gen_movi_tl(t0, 1);
2402
            break;
2403
        case OPC_TLT:   /* rs < rs           */
2404
        case OPC_TLTI:  /* r0 < 0            */
2405
        case OPC_TLTU:  /* rs < rs unsigned  */
2406
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2407
        case OPC_TNE:   /* rs != rs          */
2408
        case OPC_TNEI:  /* r0 != 0           */
2409
            /* Never trap: treat as NOP. */
2410
            goto out;
2411
        default:
2412
            MIPS_INVAL("trap");
2413
            generate_exception(ctx, EXCP_RI);
2414
            goto out;
2415
        }
2416
    } else {
2417
        switch (opc) {
2418
        case OPC_TEQ:
2419
        case OPC_TEQI:
2420
            gen_op_eq(t0, t1);
2421
            break;
2422
        case OPC_TGE:
2423
        case OPC_TGEI:
2424
            gen_op_ge(t0, t1);
2425
            break;
2426
        case OPC_TGEU:
2427
        case OPC_TGEIU:
2428
            gen_op_geu(t0, t1);
2429
            break;
2430
        case OPC_TLT:
2431
        case OPC_TLTI:
2432
            gen_op_lt(t0, t1);
2433
            break;
2434
        case OPC_TLTU:
2435
        case OPC_TLTIU:
2436
            gen_op_ltu(t0, t1);
2437
            break;
2438
        case OPC_TNE:
2439
        case OPC_TNEI:
2440
            gen_op_ne(t0, t1);
2441
            break;
2442
        default:
2443
            MIPS_INVAL("trap");
2444
            generate_exception(ctx, EXCP_RI);
2445
            goto out;
2446
        }
2447
    }
2448
    save_cpu_state(ctx, 1);
2449
    {
2450
        int l1 = gen_new_label();
2451

    
2452
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2453
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2454
        gen_set_label(l1);
2455
    }
2456
    ctx->bstate = BS_STOP;
2457
 out:
2458
    tcg_temp_free(t0);
2459
    tcg_temp_free(t1);
2460
}
2461

    
2462
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2463
{
2464
    TranslationBlock *tb;
2465
    tb = ctx->tb;
2466
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2467
        tcg_gen_goto_tb(n);
2468
        gen_save_pc(dest);
2469
        tcg_gen_exit_tb((long)tb + n);
2470
    } else {
2471
        gen_save_pc(dest);
2472
        tcg_gen_exit_tb(0);
2473
    }
2474
}
2475

    
2476
/* Branches (before delay slot) */
2477
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2478
                                int rs, int rt, int32_t offset)
2479
{
2480
    target_ulong btgt = -1;
2481
    int blink = 0;
2482
    int bcond = 0;
2483
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2484
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2485

    
2486
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2487
#ifdef MIPS_DEBUG_DISAS
2488
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2489
            fprintf(logfile,
2490
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2491
                    ctx->pc);
2492
        }
2493
#endif
2494
        generate_exception(ctx, EXCP_RI);
2495
        goto out;
2496
    }
2497

    
2498
    /* Load needed operands */
2499
    switch (opc) {
2500
    case OPC_BEQ:
2501
    case OPC_BEQL:
2502
    case OPC_BNE:
2503
    case OPC_BNEL:
2504
        /* Compare two registers */
2505
        if (rs != rt) {
2506
            gen_load_gpr(t0, rs);
2507
            gen_load_gpr(t1, rt);
2508
            bcond = 1;
2509
        }
2510
        btgt = ctx->pc + 4 + offset;
2511
        break;
2512
    case OPC_BGEZ:
2513
    case OPC_BGEZAL:
2514
    case OPC_BGEZALL:
2515
    case OPC_BGEZL:
2516
    case OPC_BGTZ:
2517
    case OPC_BGTZL:
2518
    case OPC_BLEZ:
2519
    case OPC_BLEZL:
2520
    case OPC_BLTZ:
2521
    case OPC_BLTZAL:
2522
    case OPC_BLTZALL:
2523
    case OPC_BLTZL:
2524
        /* Compare to zero */
2525
        if (rs != 0) {
2526
            gen_load_gpr(t0, rs);
2527
            bcond = 1;
2528
        }
2529
        btgt = ctx->pc + 4 + offset;
2530
        break;
2531
    case OPC_J:
2532
    case OPC_JAL:
2533
        /* Jump to immediate */
2534
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2535
        break;
2536
    case OPC_JR:
2537
    case OPC_JALR:
2538
        /* Jump to register */
2539
        if (offset != 0 && offset != 16) {
2540
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2541
               others are reserved. */
2542
            MIPS_INVAL("jump hint");
2543
            generate_exception(ctx, EXCP_RI);
2544
            goto out;
2545
        }
2546
        gen_load_gpr(btarget, rs);
2547
        break;
2548
    default:
2549
        MIPS_INVAL("branch/jump");
2550
        generate_exception(ctx, EXCP_RI);
2551
        goto out;
2552
    }
2553
    if (bcond == 0) {
2554
        /* No condition to be computed */
2555
        switch (opc) {
2556
        case OPC_BEQ:     /* rx == rx        */
2557
        case OPC_BEQL:    /* rx == rx likely */
2558
        case OPC_BGEZ:    /* 0 >= 0          */
2559
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2560
        case OPC_BLEZ:    /* 0 <= 0          */
2561
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2562
            /* Always take */
2563
            ctx->hflags |= MIPS_HFLAG_B;
2564
            MIPS_DEBUG("balways");
2565
            break;
2566
        case OPC_BGEZAL:  /* 0 >= 0          */
2567
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2568
            /* Always take and link */
2569
            blink = 31;
2570
            ctx->hflags |= MIPS_HFLAG_B;
2571
            MIPS_DEBUG("balways and link");
2572
            break;
2573
        case OPC_BNE:     /* rx != rx        */
2574
        case OPC_BGTZ:    /* 0 > 0           */
2575
        case OPC_BLTZ:    /* 0 < 0           */
2576
            /* Treat as NOP. */
2577
            MIPS_DEBUG("bnever (NOP)");
2578
            goto out;
2579
        case OPC_BLTZAL:  /* 0 < 0           */
2580
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2581
            gen_store_gpr(t0, 31);
2582
            MIPS_DEBUG("bnever and link");
2583
            goto out;
2584
        case OPC_BLTZALL: /* 0 < 0 likely */
2585
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2586
            gen_store_gpr(t0, 31);
2587
            /* Skip the instruction in the delay slot */
2588
            MIPS_DEBUG("bnever, link and skip");
2589
            ctx->pc += 4;
2590
            goto out;
2591
        case OPC_BNEL:    /* rx != rx likely */
2592
        case OPC_BGTZL:   /* 0 > 0 likely */
2593
        case OPC_BLTZL:   /* 0 < 0 likely */
2594
            /* Skip the instruction in the delay slot */
2595
            MIPS_DEBUG("bnever and skip");
2596
            ctx->pc += 4;
2597
            goto out;
2598
        case OPC_J:
2599
            ctx->hflags |= MIPS_HFLAG_B;
2600
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2601
            break;
2602
        case OPC_JAL:
2603
            blink = 31;
2604
            ctx->hflags |= MIPS_HFLAG_B;
2605
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2606
            break;
2607
        case OPC_JR:
2608
            ctx->hflags |= MIPS_HFLAG_BR;
2609
            MIPS_DEBUG("jr %s", regnames[rs]);
2610
            break;
2611
        case OPC_JALR:
2612
            blink = rt;
2613
            ctx->hflags |= MIPS_HFLAG_BR;
2614
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2615
            break;
2616
        default:
2617
            MIPS_INVAL("branch/jump");
2618
            generate_exception(ctx, EXCP_RI);
2619
            goto out;
2620
        }
2621
    } else {
2622
        switch (opc) {
2623
        case OPC_BEQ:
2624
            gen_op_eq(t0, t1);
2625
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2626
                       regnames[rs], regnames[rt], btgt);
2627
            goto not_likely;
2628
        case OPC_BEQL:
2629
            gen_op_eq(t0, t1);
2630
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2631
                       regnames[rs], regnames[rt], btgt);
2632
            goto likely;
2633
        case OPC_BNE:
2634
            gen_op_ne(t0, t1);
2635
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2636
                       regnames[rs], regnames[rt], btgt);
2637
            goto not_likely;
2638
        case OPC_BNEL:
2639
            gen_op_ne(t0, t1);
2640
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2641
                       regnames[rs], regnames[rt], btgt);
2642
            goto likely;
2643
        case OPC_BGEZ:
2644
            gen_op_gez(t0);
2645
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2646
            goto not_likely;
2647
        case OPC_BGEZL:
2648
            gen_op_gez(t0);
2649
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2650
            goto likely;
2651
        case OPC_BGEZAL:
2652
            gen_op_gez(t0);
2653
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2654
            blink = 31;
2655
            goto not_likely;
2656
        case OPC_BGEZALL:
2657
            gen_op_gez(t0);
2658
            blink = 31;
2659
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2660
            goto likely;
2661
        case OPC_BGTZ:
2662
            gen_op_gtz(t0);
2663
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2664
            goto not_likely;
2665
        case OPC_BGTZL:
2666
            gen_op_gtz(t0);
2667
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2668
            goto likely;
2669
        case OPC_BLEZ:
2670
            gen_op_lez(t0);
2671
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2672
            goto not_likely;
2673
        case OPC_BLEZL:
2674
            gen_op_lez(t0);
2675
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2676
            goto likely;
2677
        case OPC_BLTZ:
2678
            gen_op_ltz(t0);
2679
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2680
            goto not_likely;
2681
        case OPC_BLTZL:
2682
            gen_op_ltz(t0);
2683
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2684
            goto likely;
2685
        case OPC_BLTZAL:
2686
            gen_op_ltz(t0);
2687
            blink = 31;
2688
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2689
        not_likely:
2690
            ctx->hflags |= MIPS_HFLAG_BC;
2691
            tcg_gen_trunc_tl_i32(bcond, t0);
2692
            break;
2693
        case OPC_BLTZALL:
2694
            gen_op_ltz(t0);
2695
            blink = 31;
2696
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2697
        likely:
2698
            ctx->hflags |= MIPS_HFLAG_BL;
2699
            tcg_gen_trunc_tl_i32(bcond, t0);
2700
            break;
2701
        default:
2702
            MIPS_INVAL("conditional branch/jump");
2703
            generate_exception(ctx, EXCP_RI);
2704
            goto out;
2705
        }
2706
    }
2707
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2708
               blink, ctx->hflags, btgt);
2709

    
2710
    ctx->btarget = btgt;
2711
    if (blink > 0) {
2712
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2713
        gen_store_gpr(t0, blink);
2714
    }
2715

    
2716
 out:
2717
    tcg_temp_free(t0);
2718
    tcg_temp_free(t1);
2719
}
2720

    
2721
/* special3 bitfield operations */
2722
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2723
                       int rs, int lsb, int msb)
2724
{
2725
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2726
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2727

    
2728
    gen_load_gpr(t1, rs);
2729
    switch (opc) {
2730
    case OPC_EXT:
2731
        if (lsb + msb > 31)
2732
            goto fail;
2733
        tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1);
2734
        break;
2735
#if defined(TARGET_MIPS64)
2736
    case OPC_DEXTM:
2737
        if (lsb + msb > 63)
2738
            goto fail;
2739
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32);
2740
        break;
2741
    case OPC_DEXTU:
2742
        if (lsb + msb > 63)
2743
            goto fail;
2744
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1);
2745
        break;
2746
    case OPC_DEXT:
2747
        if (lsb + msb > 63)
2748
            goto fail;
2749
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1);
2750
        break;
2751
#endif
2752
    case OPC_INS:
2753
        if (lsb > msb)
2754
            goto fail;
2755
        gen_load_gpr(t0, rt);
2756
        tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
2757
        break;
2758
#if defined(TARGET_MIPS64)
2759
    case OPC_DINSM:
2760
        if (lsb > msb)
2761
            goto fail;
2762
        gen_load_gpr(t0, rt);
2763
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
2764
        break;
2765
    case OPC_DINSU:
2766
        if (lsb > msb)
2767
            goto fail;
2768
        gen_load_gpr(t0, rt);
2769
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
2770
        break;
2771
    case OPC_DINS:
2772
        if (lsb > msb)
2773
            goto fail;
2774
        gen_load_gpr(t0, rt);
2775
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
2776
        break;
2777
#endif
2778
    default:
2779
fail:
2780
        MIPS_INVAL("bitops");
2781
        generate_exception(ctx, EXCP_RI);
2782
        tcg_temp_free(t0);
2783
        tcg_temp_free(t1);
2784
        return;
2785
    }
2786
    gen_store_gpr(t0, rt);
2787
    tcg_temp_free(t0);
2788
    tcg_temp_free(t1);
2789
}
2790

    
2791
/* CP0 (MMU and control) */
2792
#ifndef CONFIG_USER_ONLY
2793
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2794
{
2795
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2796

    
2797
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2798
    tcg_gen_ext_i32_tl(t, r_tmp);
2799
    tcg_temp_free(r_tmp);
2800
}
2801

    
2802
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2803
{
2804
    tcg_gen_ld_tl(t, cpu_env, off);
2805
    tcg_gen_ext32s_tl(t, t);
2806
}
2807

    
2808
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2809
{
2810
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2811

    
2812
    tcg_gen_trunc_tl_i32(r_tmp, t);
2813
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2814
    tcg_temp_free(r_tmp);
2815
}
2816

    
2817
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2818
{
2819
    tcg_gen_ext32s_tl(t, t);
2820
    tcg_gen_st_tl(t, cpu_env, off);
2821
}
2822

    
2823
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2824
{
2825
    const char *rn = "invalid";
2826

    
2827
    if (sel != 0)
2828
        check_insn(env, ctx, ISA_MIPS32);
2829

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

    
3399
die:
3400
#if defined MIPS_DEBUG_DISAS
3401
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3402
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3403
                rn, reg, sel);
3404
    }
3405
#endif
3406
    generate_exception(ctx, EXCP_RI);
3407
}
3408

    
3409
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3410
{
3411
    const char *rn = "invalid";
3412

    
3413
    if (sel != 0)
3414
        check_insn(env, ctx, ISA_MIPS32);
3415

    
3416
    if (use_icount)
3417
        gen_io_start();
3418

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

    
4008
die:
4009
#if defined MIPS_DEBUG_DISAS
4010
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4011
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
4012
                rn, reg, sel);
4013
    }
4014
#endif
4015
    generate_exception(ctx, EXCP_RI);
4016
}
4017

    
4018
#if defined(TARGET_MIPS64)
4019
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4020
{
4021
    const char *rn = "invalid";
4022

    
4023
    if (sel != 0)
4024
        check_insn(env, ctx, ISA_MIPS64);
4025

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

    
4583
die:
4584
#if defined MIPS_DEBUG_DISAS
4585
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4586
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4587
                rn, reg, sel);
4588
    }
4589
#endif
4590
    generate_exception(ctx, EXCP_RI);
4591
}
4592

    
4593
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4594
{
4595
    const char *rn = "invalid";
4596

    
4597
    if (sel != 0)
4598
        check_insn(env, ctx, ISA_MIPS64);
4599

    
4600
    if (use_icount)
4601
        gen_io_start();
4602

    
4603
    switch (reg) {
4604
    case 0:
4605
        switch (sel) {
4606
        case 0:
4607
            tcg_gen_helper_0_1(do_mtc0_index, t0);
4608
            rn = "Index";
4609
            break;
4610
        case 1:
4611
            check_insn(env, ctx, ASE_MT);
4612
            tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0);
4613
            rn = "MVPControl";
4614
            break;
4615
        case 2:
4616
            check_insn(env, ctx, ASE_MT);
4617
            /* ignored */
4618
            rn = "MVPConf0";
4619
            break;
4620
        case 3:
4621
            check_insn(env, ctx, ASE_MT);
4622
            /* ignored */
4623
            rn = "MVPConf1";
4624
            break;
4625
        default:
4626
            goto die;
4627
        }
4628
        break;
4629
    case 1:
4630
        switch (sel) {
4631
        case 0:
4632
            /* ignored */
4633
            rn = "Random";
4634
            break;
4635
        case 1:
4636
            check_insn(env, ctx, ASE_MT);
4637
            tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0);
4638
            rn = "VPEControl";
4639
            break;
4640
        case 2:
4641
            check_insn(env, ctx, ASE_MT);
4642
            tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0);
4643
            rn = "VPEConf0";
4644
            break;
4645
        case 3:
4646
            check_insn(env, ctx, ASE_MT);
4647
            tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0);
4648
            rn = "VPEConf1";
4649
            break;
4650
        case 4:
4651
            check_insn(env, ctx, ASE_MT);
4652
            tcg_gen_helper_0_1(do_mtc0_yqmask, t0);
4653
            rn = "YQMask";
4654
            break;
4655
        case 5:
4656
            check_insn(env, ctx, ASE_MT);
4657
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4658
            rn = "VPESchedule";
4659
            break;
4660
        case 6:
4661
            check_insn(env, ctx, ASE_MT);
4662
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4663
            rn = "VPEScheFBack";
4664
            break;
4665
        case 7:
4666
            check_insn(env, ctx, ASE_MT);
4667
            tcg_gen_helper_0_1(do_mtc0_vpeopt, t0);
4668
            rn = "VPEOpt";
4669
            break;
4670
        default:
4671
            goto die;
4672
        }
4673
        break;
4674
    case 2:
4675
        switch (sel) {
4676
        case 0:
4677
            tcg_gen_helper_0_1(do_mtc0_entrylo0, t0);
4678
            rn = "EntryLo0";
4679
            break;
4680
        case 1:
4681
            check_insn(env, ctx, ASE_MT);
4682
            tcg_gen_helper_0_1(do_mtc0_tcstatus, t0);
4683
            rn = "TCStatus";
4684
            break;
4685
        case 2:
4686
            check_insn(env, ctx, ASE_MT);
4687
            tcg_gen_helper_0_1(do_mtc0_tcbind, t0);
4688
            rn = "TCBind";
4689
            break;
4690
        case 3:
4691
            check_insn(env, ctx, ASE_MT);
4692
            tcg_gen_helper_0_1(do_mtc0_tcrestart, t0);
4693
            rn = "TCRestart";
4694
            break;
4695
        case 4:
4696
            check_insn(env, ctx, ASE_MT);
4697
            tcg_gen_helper_0_1(do_mtc0_tchalt, t0);
4698
            rn = "TCHalt";
4699
            break;
4700
        case 5:
4701
            check_insn(env, ctx, ASE_MT);
4702
            tcg_gen_helper_0_1(do_mtc0_tccontext, t0);
4703
            rn = "TCContext";
4704
            break;
4705
        case 6:
4706
            check_insn(env, ctx, ASE_MT);
4707
            tcg_gen_helper_0_1(do_mtc0_tcschedule, t0);
4708
            rn = "TCSchedule";
4709
            break;
4710
        case 7:
4711
            check_insn(env, ctx, ASE_MT);
4712
            tcg_gen_helper_0_1(do_mtc0_tcschefback, t0);
4713
            rn = "TCScheFBack";
4714
            break;
4715
        default:
4716
            goto die;
4717
        }
4718
        break;
4719
    case 3:
4720
        switch (sel) {
4721
        case 0:
4722
            tcg_gen_helper_0_1(do_mtc0_entrylo1, t0);
4723
            rn = "EntryLo1";
4724
            break;
4725
        default:
4726
            goto die;
4727
        }
4728
        break;
4729
    case 4:
4730
        switch (sel) {
4731
        case 0:
4732
            tcg_gen_helper_0_1(do_mtc0_context, t0);
4733
            rn = "Context";
4734
            break;
4735
        case 1:
4736
//           tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */
4737
            rn = "ContextConfig";
4738
//           break;
4739
        default:
4740
            goto die;
4741
        }
4742
        break;
4743
    case 5:
4744
        switch (sel) {
4745
        case 0:
4746
            tcg_gen_helper_0_1(do_mtc0_pagemask, t0);
4747
            rn = "PageMask";
4748
            break;
4749
        case 1:
4750
            check_insn(env, ctx, ISA_MIPS32R2);
4751
            tcg_gen_helper_0_1(do_mtc0_pagegrain, t0);
4752
            rn = "PageGrain";
4753
            break;
4754
        default:
4755