Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 52a0e9eb

History | View | Annotate | Download (244.4 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., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 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 "tcg-op.h"
33
#include "qemu-common.h"
34

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

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

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

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

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

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

    
186
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
187

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
388
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
389

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

    
402
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
403

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

    
427
/* global register indices */
428
static TCGv_ptr cpu_env;
429
static TCGv cpu_gpr[32], cpu_PC;
430
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
431
static TCGv cpu_dspctrl, btarget, bcond;
432
static TCGv_i32 hflags;
433
static TCGv_i32 fpu_fcr0, fpu_fcr31;
434

    
435
#include "gen-icount.h"
436

    
437
#define gen_helper_0i(name, arg) do {                             \
438
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
439
    gen_helper_##name(helper_tmp);                                \
440
    tcg_temp_free_i32(helper_tmp);                                \
441
    } while(0)
442

    
443
#define gen_helper_1i(name, arg1, arg2) do {                      \
444
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
445
    gen_helper_##name(arg1, helper_tmp);                          \
446
    tcg_temp_free_i32(helper_tmp);                                \
447
    } while(0)
448

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

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

    
461
typedef struct DisasContext {
462
    struct TranslationBlock *tb;
463
    target_ulong pc, saved_pc;
464
    uint32_t opcode;
465
    /* Routine used to access memory */
466
    int mem_idx;
467
    uint32_t hflags, saved_hflags;
468
    int bstate;
469
    target_ulong btarget;
470
} DisasContext;
471

    
472
enum {
473
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
474
                      * exception condition */
475
    BS_STOP     = 1, /* We want to stop translation for any reason */
476
    BS_BRANCH   = 2, /* We reached a branch condition     */
477
    BS_EXCP     = 3, /* We reached an exception condition */
478
};
479

    
480
static const char *regnames[] =
481
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
482
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
483
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
484
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
485

    
486
static const char *regnames_HI[] =
487
    { "HI0", "HI1", "HI2", "HI3", };
488

    
489
static const char *regnames_LO[] =
490
    { "LO0", "LO1", "LO2", "LO3", };
491

    
492
static const char *regnames_ACX[] =
493
    { "ACX0", "ACX1", "ACX2", "ACX3", };
494

    
495
static const char *fregnames[] =
496
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
497
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
498
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
499
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
500

    
501
#ifdef MIPS_DEBUG_DISAS
502
#define MIPS_DEBUG(fmt, args...)                         \
503
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
504
                       TARGET_FMT_lx ": %08x " fmt "\n", \
505
                       ctx->pc, ctx->opcode , ##args)
506
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
507
#else
508
#define MIPS_DEBUG(fmt, args...) do { } while(0)
509
#define LOG_DISAS(...) do { } while (0)
510
#endif
511

    
512
#define MIPS_INVAL(op)                                                        \
513
do {                                                                          \
514
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
515
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
516
} while (0)
517

    
518
/* General purpose registers moves. */
519
static inline void gen_load_gpr (TCGv t, int reg)
520
{
521
    if (reg == 0)
522
        tcg_gen_movi_tl(t, 0);
523
    else
524
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
525
}
526

    
527
static inline void gen_store_gpr (TCGv t, int reg)
528
{
529
    if (reg != 0)
530
        tcg_gen_mov_tl(cpu_gpr[reg], t);
531
}
532

    
533
/* Moves to/from ACX register.  */
534
static inline void gen_load_ACX (TCGv t, int reg)
535
{
536
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
537
}
538

    
539
static inline void gen_store_ACX (TCGv t, int reg)
540
{
541
    tcg_gen_mov_tl(cpu_ACX[reg], t);
542
}
543

    
544
/* Moves to/from shadow registers. */
545
static inline void gen_load_srsgpr (int from, int to)
546
{
547
    TCGv r_tmp1 = tcg_temp_new();
548

    
549
    if (from == 0)
550
        tcg_gen_movi_tl(r_tmp1, 0);
551
    else {
552
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
553
        TCGv_ptr addr = tcg_temp_new_ptr();
554

    
555
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
556
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
557
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
558
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
559
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
560
        tcg_gen_add_ptr(addr, cpu_env, addr);
561

    
562
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
563
        tcg_temp_free_ptr(addr);
564
        tcg_temp_free_i32(r_tmp2);
565
    }
566
    gen_store_gpr(r_tmp1, to);
567
    tcg_temp_free(r_tmp1);
568
}
569

    
570
static inline void gen_store_srsgpr (int from, int to)
571
{
572
    if (to != 0) {
573
        TCGv r_tmp1 = tcg_temp_new();
574
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
575
        TCGv_ptr addr = tcg_temp_new_ptr();
576

    
577
        gen_load_gpr(r_tmp1, from);
578
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
579
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
580
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
581
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
582
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
583
        tcg_gen_add_ptr(addr, cpu_env, addr);
584

    
585
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
586
        tcg_temp_free_ptr(addr);
587
        tcg_temp_free_i32(r_tmp2);
588
        tcg_temp_free(r_tmp1);
589
    }
590
}
591

    
592
/* Floating point register moves. */
593
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
594
{
595
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
596
}
597

    
598
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
599
{
600
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
601
}
602

    
603
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
604
{
605
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
606
}
607

    
608
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
609
{
610
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
611
}
612

    
613
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
614
{
615
    if (ctx->hflags & MIPS_HFLAG_F64) {
616
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
617
    } else {
618
        TCGv_i32 t0 = tcg_temp_new_i32();
619
        TCGv_i32 t1 = tcg_temp_new_i32();
620
        gen_load_fpr32(t0, reg & ~1);
621
        gen_load_fpr32(t1, reg | 1);
622
        tcg_gen_concat_i32_i64(t, t0, t1);
623
        tcg_temp_free_i32(t0);
624
        tcg_temp_free_i32(t1);
625
    }
626
}
627

    
628
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
629
{
630
    if (ctx->hflags & MIPS_HFLAG_F64) {
631
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
632
    } else {
633
        TCGv_i64 t0 = tcg_temp_new_i64();
634
        TCGv_i32 t1 = tcg_temp_new_i32();
635
        tcg_gen_trunc_i64_i32(t1, t);
636
        gen_store_fpr32(t1, reg & ~1);
637
        tcg_gen_shri_i64(t0, t, 32);
638
        tcg_gen_trunc_i64_i32(t1, t0);
639
        gen_store_fpr32(t1, reg | 1);
640
        tcg_temp_free_i32(t1);
641
        tcg_temp_free_i64(t0);
642
    }
643
}
644

    
645
static inline int get_fp_bit (int cc)
646
{
647
    if (cc)
648
        return 24 + cc;
649
    else
650
        return 23;
651
}
652

    
653
#define FOP_CONDS(type, fmt, bits)                                            \
654
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
655
                                               TCGv_i##bits b, int cc)        \
656
{                                                                             \
657
    switch (n) {                                                              \
658
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
659
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
660
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
661
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
662
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
663
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
664
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
665
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
666
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
667
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
668
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
669
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
670
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
671
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
672
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
673
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
674
    default: abort();                                                         \
675
    }                                                                         \
676
}
677

    
678
FOP_CONDS(, d, 64)
679
FOP_CONDS(abs, d, 64)
680
FOP_CONDS(, s, 32)
681
FOP_CONDS(abs, s, 32)
682
FOP_CONDS(, ps, 64)
683
FOP_CONDS(abs, ps, 64)
684
#undef FOP_CONDS
685

    
686
/* Tests */
687
#define OP_COND(name, cond)                                         \
688
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
689
{                                                                   \
690
    int l1 = gen_new_label();                                       \
691
    int l2 = gen_new_label();                                       \
692
                                                                    \
693
    tcg_gen_brcond_tl(cond, t0, t1, l1);                            \
694
    tcg_gen_movi_tl(ret, 0);                                        \
695
    tcg_gen_br(l2);                                                 \
696
    gen_set_label(l1);                                              \
697
    tcg_gen_movi_tl(ret, 1);                                        \
698
    gen_set_label(l2);                                              \
699
}
700
OP_COND(eq, TCG_COND_EQ);
701
OP_COND(ne, TCG_COND_NE);
702
OP_COND(ge, TCG_COND_GE);
703
OP_COND(geu, TCG_COND_GEU);
704
OP_COND(lt, TCG_COND_LT);
705
OP_COND(ltu, TCG_COND_LTU);
706
#undef OP_COND
707

    
708
#define OP_CONDI(name, cond)                                                 \
709
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
710
{                                                                            \
711
    int l1 = gen_new_label();                                                \
712
    int l2 = gen_new_label();                                                \
713
                                                                             \
714
    tcg_gen_brcondi_tl(cond, t0, val, l1);                                   \
715
    tcg_gen_movi_tl(ret, 0);                                                 \
716
    tcg_gen_br(l2);                                                          \
717
    gen_set_label(l1);                                                       \
718
    tcg_gen_movi_tl(ret, 1);                                                 \
719
    gen_set_label(l2);                                                       \
720
}
721
OP_CONDI(lti, TCG_COND_LT);
722
OP_CONDI(ltiu, TCG_COND_LTU);
723
#undef OP_CONDI
724

    
725
#define OP_CONDZ(name, cond)                                  \
726
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0)    \
727
{                                                             \
728
    int l1 = gen_new_label();                                 \
729
    int l2 = gen_new_label();                                 \
730
                                                              \
731
    tcg_gen_brcondi_tl(cond, t0, 0, l1);                      \
732
    tcg_gen_movi_tl(ret, 0);                                  \
733
    tcg_gen_br(l2);                                           \
734
    gen_set_label(l1);                                        \
735
    tcg_gen_movi_tl(ret, 1);                                  \
736
    gen_set_label(l2);                                        \
737
}
738
OP_CONDZ(gez, TCG_COND_GE);
739
OP_CONDZ(gtz, TCG_COND_GT);
740
OP_CONDZ(lez, TCG_COND_LE);
741
OP_CONDZ(ltz, TCG_COND_LT);
742
#undef OP_CONDZ
743

    
744
static inline void gen_save_pc(target_ulong pc)
745
{
746
    tcg_gen_movi_tl(cpu_PC, pc);
747
}
748

    
749
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
750
{
751
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
752
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
753
        gen_save_pc(ctx->pc);
754
        ctx->saved_pc = ctx->pc;
755
    }
756
    if (ctx->hflags != ctx->saved_hflags) {
757
        tcg_gen_movi_i32(hflags, ctx->hflags);
758
        ctx->saved_hflags = ctx->hflags;
759
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
760
        case MIPS_HFLAG_BR:
761
            break;
762
        case MIPS_HFLAG_BC:
763
        case MIPS_HFLAG_BL:
764
        case MIPS_HFLAG_B:
765
            tcg_gen_movi_tl(btarget, ctx->btarget);
766
            break;
767
        }
768
    }
769
}
770

    
771
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
772
{
773
    ctx->saved_hflags = ctx->hflags;
774
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
775
    case MIPS_HFLAG_BR:
776
        break;
777
    case MIPS_HFLAG_BC:
778
    case MIPS_HFLAG_BL:
779
    case MIPS_HFLAG_B:
780
        ctx->btarget = env->btarget;
781
        break;
782
    }
783
}
784

    
785
static inline void
786
generate_exception_err (DisasContext *ctx, int excp, int err)
787
{
788
    TCGv_i32 texcp = tcg_const_i32(excp);
789
    TCGv_i32 terr = tcg_const_i32(err);
790
    save_cpu_state(ctx, 1);
791
    gen_helper_raise_exception_err(texcp, terr);
792
    tcg_temp_free_i32(terr);
793
    tcg_temp_free_i32(texcp);
794
    gen_helper_interrupt_restart();
795
    tcg_gen_exit_tb(0);
796
}
797

    
798
static inline void
799
generate_exception (DisasContext *ctx, int excp)
800
{
801
    save_cpu_state(ctx, 1);
802
    gen_helper_0i(raise_exception, excp);
803
    gen_helper_interrupt_restart();
804
    tcg_gen_exit_tb(0);
805
}
806

    
807
/* Addresses computation */
808
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
809
{
810
    tcg_gen_add_tl(t0, t0, t1);
811

    
812
#if defined(TARGET_MIPS64)
813
    /* For compatibility with 32-bit code, data reference in user mode
814
       with Status_UX = 0 should be casted to 32-bit and sign extended.
815
       See the MIPS64 PRA manual, section 4.10. */
816
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
817
        !(ctx->hflags & MIPS_HFLAG_UX)) {
818
        tcg_gen_ext32s_i64(t0, t0);
819
    }
820
#endif
821
}
822

    
823
static inline void check_cp0_enabled(DisasContext *ctx)
824
{
825
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
826
        generate_exception_err(ctx, EXCP_CpU, 1);
827
}
828

    
829
static inline void check_cp1_enabled(DisasContext *ctx)
830
{
831
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
832
        generate_exception_err(ctx, EXCP_CpU, 1);
833
}
834

    
835
/* Verify that the processor is running with COP1X instructions enabled.
836
   This is associated with the nabla symbol in the MIPS32 and MIPS64
837
   opcode tables.  */
838

    
839
static inline void check_cop1x(DisasContext *ctx)
840
{
841
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
842
        generate_exception(ctx, EXCP_RI);
843
}
844

    
845
/* Verify that the processor is running with 64-bit floating-point
846
   operations enabled.  */
847

    
848
static inline void check_cp1_64bitmode(DisasContext *ctx)
849
{
850
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
851
        generate_exception(ctx, EXCP_RI);
852
}
853

    
854
/*
855
 * Verify if floating point register is valid; an operation is not defined
856
 * if bit 0 of any register specification is set and the FR bit in the
857
 * Status register equals zero, since the register numbers specify an
858
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
859
 * in the Status register equals one, both even and odd register numbers
860
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
861
 *
862
 * Multiple 64 bit wide registers can be checked by calling
863
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
864
 */
865
static inline void check_cp1_registers(DisasContext *ctx, int regs)
866
{
867
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
868
        generate_exception(ctx, EXCP_RI);
869
}
870

    
871
/* This code generates a "reserved instruction" exception if the
872
   CPU does not support the instruction set corresponding to flags. */
873
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
874
{
875
    if (unlikely(!(env->insn_flags & flags)))
876
        generate_exception(ctx, EXCP_RI);
877
}
878

    
879
/* This code generates a "reserved instruction" exception if 64-bit
880
   instructions are not enabled. */
881
static inline void check_mips_64(DisasContext *ctx)
882
{
883
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
884
        generate_exception(ctx, EXCP_RI);
885
}
886

    
887
/* load/store instructions. */
888
#define OP_LD(insn,fname)                                        \
889
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
890
{                                                                \
891
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
892
}
893
OP_LD(lb,ld8s);
894
OP_LD(lbu,ld8u);
895
OP_LD(lh,ld16s);
896
OP_LD(lhu,ld16u);
897
OP_LD(lw,ld32s);
898
#if defined(TARGET_MIPS64)
899
OP_LD(lwu,ld32u);
900
OP_LD(ld,ld64);
901
#endif
902
#undef OP_LD
903

    
904
#define OP_ST(insn,fname)                                        \
905
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
906
{                                                                \
907
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
908
}
909
OP_ST(sb,st8);
910
OP_ST(sh,st16);
911
OP_ST(sw,st32);
912
#if defined(TARGET_MIPS64)
913
OP_ST(sd,st64);
914
#endif
915
#undef OP_ST
916

    
917
#define OP_LD_ATOMIC(insn,fname)                                        \
918
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
919
{                                                                       \
920
    tcg_gen_mov_tl(t1, t0);                                             \
921
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
922
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
923
}
924
OP_LD_ATOMIC(ll,ld32s);
925
#if defined(TARGET_MIPS64)
926
OP_LD_ATOMIC(lld,ld64);
927
#endif
928
#undef OP_LD_ATOMIC
929

    
930
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
931
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
932
{                                                                       \
933
    TCGv r_tmp = tcg_temp_local_new();                       \
934
    int l1 = gen_new_label();                                           \
935
    int l2 = gen_new_label();                                           \
936
    int l3 = gen_new_label();                                           \
937
                                                                        \
938
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
939
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
940
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
941
    generate_exception(ctx, EXCP_AdES);                                 \
942
    gen_set_label(l1);                                                  \
943
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
944
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
945
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
946
    tcg_gen_movi_tl(t0, 1);                                             \
947
    tcg_gen_br(l3);                                                     \
948
    gen_set_label(l2);                                                  \
949
    tcg_gen_movi_tl(t0, 0);                                             \
950
    gen_set_label(l3);                                                  \
951
    tcg_temp_free(r_tmp);                                               \
952
}
953
OP_ST_ATOMIC(sc,st32,0x3);
954
#if defined(TARGET_MIPS64)
955
OP_ST_ATOMIC(scd,st64,0x7);
956
#endif
957
#undef OP_ST_ATOMIC
958

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

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

    
1122
/* Load and store */
1123
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1124
                          int base, int16_t offset)
1125
{
1126
    const char *opn = "flt_ldst";
1127
    TCGv t0 = tcg_temp_new();
1128

    
1129
    if (base == 0) {
1130
        tcg_gen_movi_tl(t0, offset);
1131
    } else if (offset == 0) {
1132
        gen_load_gpr(t0, base);
1133
    } else {
1134
        tcg_gen_movi_tl(t0, offset);
1135
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1136
    }
1137
    /* Don't do NOP if destination is zero: we must perform the actual
1138
       memory access. */
1139
    switch (opc) {
1140
    case OPC_LWC1:
1141
        {
1142
            TCGv_i32 fp0 = tcg_temp_new_i32();
1143
            TCGv t1 = tcg_temp_new();
1144

    
1145
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1146
            tcg_gen_trunc_tl_i32(fp0, t1);
1147
            gen_store_fpr32(fp0, ft);
1148
            tcg_temp_free(t1);
1149
            tcg_temp_free_i32(fp0);
1150
        }
1151
        opn = "lwc1";
1152
        break;
1153
    case OPC_SWC1:
1154
        {
1155
            TCGv_i32 fp0 = tcg_temp_new_i32();
1156
            TCGv t1 = tcg_temp_new();
1157

    
1158
            gen_load_fpr32(fp0, ft);
1159
            tcg_gen_extu_i32_tl(t1, fp0);
1160
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1161
            tcg_temp_free(t1);
1162
            tcg_temp_free_i32(fp0);
1163
        }
1164
        opn = "swc1";
1165
        break;
1166
    case OPC_LDC1:
1167
        {
1168
            TCGv_i64 fp0 = tcg_temp_new_i64();
1169

    
1170
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1171
            gen_store_fpr64(ctx, fp0, ft);
1172
            tcg_temp_free_i64(fp0);
1173
        }
1174
        opn = "ldc1";
1175
        break;
1176
    case OPC_SDC1:
1177
        {
1178
            TCGv_i64 fp0 = tcg_temp_new_i64();
1179

    
1180
            gen_load_fpr64(ctx, fp0, ft);
1181
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1182
            tcg_temp_free_i64(fp0);
1183
        }
1184
        opn = "sdc1";
1185
        break;
1186
    default:
1187
        MIPS_INVAL(opn);
1188
        generate_exception(ctx, EXCP_RI);
1189
        goto out;
1190
    }
1191
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1192
 out:
1193
    tcg_temp_free(t0);
1194
}
1195

    
1196
/* Arithmetic with immediate operand */
1197
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1198
                           int rt, int rs, int16_t imm)
1199
{
1200
    target_ulong uimm;
1201
    const char *opn = "imm arith";
1202
    TCGv t0 = tcg_temp_local_new();
1203

    
1204
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1205
        /* If no destination, treat it as a NOP.
1206
           For addi, we must generate the overflow exception when needed. */
1207
        MIPS_DEBUG("NOP");
1208
        goto out;
1209
    }
1210
    uimm = (uint16_t)imm;
1211
    switch (opc) {
1212
    case OPC_ADDI:
1213
    case OPC_ADDIU:
1214
#if defined(TARGET_MIPS64)
1215
    case OPC_DADDI:
1216
    case OPC_DADDIU:
1217
#endif
1218
    case OPC_SLTI:
1219
    case OPC_SLTIU:
1220
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1221
        /* Fall through. */
1222
    case OPC_ANDI:
1223
    case OPC_ORI:
1224
    case OPC_XORI:
1225
        gen_load_gpr(t0, rs);
1226
        break;
1227
    case OPC_LUI:
1228
        tcg_gen_movi_tl(t0, imm << 16);
1229
        break;
1230
    case OPC_SLL:
1231
    case OPC_SRA:
1232
    case OPC_SRL:
1233
#if defined(TARGET_MIPS64)
1234
    case OPC_DSLL:
1235
    case OPC_DSRA:
1236
    case OPC_DSRL:
1237
    case OPC_DSLL32:
1238
    case OPC_DSRA32:
1239
    case OPC_DSRL32:
1240
#endif
1241
        uimm &= 0x1f;
1242
        gen_load_gpr(t0, rs);
1243
        break;
1244
    }
1245
    switch (opc) {
1246
    case OPC_ADDI:
1247
        {
1248
            TCGv r_tmp1 = tcg_temp_new();
1249
            TCGv r_tmp2 = tcg_temp_new();
1250
            int l1 = gen_new_label();
1251

    
1252
            save_cpu_state(ctx, 1);
1253
            tcg_gen_ext32s_tl(r_tmp1, t0);
1254
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1255

    
1256
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1257
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1258
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1259
            tcg_temp_free(r_tmp2);
1260
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1261
            /* operands of same sign, result different sign */
1262
            generate_exception(ctx, EXCP_OVERFLOW);
1263
            gen_set_label(l1);
1264
            tcg_temp_free(r_tmp1);
1265

    
1266
            tcg_gen_ext32s_tl(t0, t0);
1267
        }
1268
        opn = "addi";
1269
        break;
1270
    case OPC_ADDIU:
1271
        tcg_gen_addi_tl(t0, t0, uimm);
1272
        tcg_gen_ext32s_tl(t0, t0);
1273
        opn = "addiu";
1274
        break;
1275
#if defined(TARGET_MIPS64)
1276
    case OPC_DADDI:
1277
        {
1278
            TCGv r_tmp1 = tcg_temp_new();
1279
            TCGv r_tmp2 = tcg_temp_new();
1280
            int l1 = gen_new_label();
1281

    
1282
            save_cpu_state(ctx, 1);
1283
            tcg_gen_mov_tl(r_tmp1, t0);
1284
            tcg_gen_addi_tl(t0, t0, uimm);
1285

    
1286
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1287
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1288
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1289
            tcg_temp_free(r_tmp2);
1290
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1291
            /* operands of same sign, result different sign */
1292
            generate_exception(ctx, EXCP_OVERFLOW);
1293
            gen_set_label(l1);
1294
            tcg_temp_free(r_tmp1);
1295
        }
1296
        opn = "daddi";
1297
        break;
1298
    case OPC_DADDIU:
1299
        tcg_gen_addi_tl(t0, t0, uimm);
1300
        opn = "daddiu";
1301
        break;
1302
#endif
1303
    case OPC_SLTI:
1304
        gen_op_lti(t0, t0, uimm);
1305
        opn = "slti";
1306
        break;
1307
    case OPC_SLTIU:
1308
        gen_op_ltiu(t0, t0, uimm);
1309
        opn = "sltiu";
1310
        break;
1311
    case OPC_ANDI:
1312
        tcg_gen_andi_tl(t0, t0, uimm);
1313
        opn = "andi";
1314
        break;
1315
    case OPC_ORI:
1316
        tcg_gen_ori_tl(t0, t0, uimm);
1317
        opn = "ori";
1318
        break;
1319
    case OPC_XORI:
1320
        tcg_gen_xori_tl(t0, t0, uimm);
1321
        opn = "xori";
1322
        break;
1323
    case OPC_LUI:
1324
        opn = "lui";
1325
        break;
1326
    case OPC_SLL:
1327
        tcg_gen_shli_tl(t0, t0, uimm);
1328
        tcg_gen_ext32s_tl(t0, t0);
1329
        opn = "sll";
1330
        break;
1331
    case OPC_SRA:
1332
        tcg_gen_ext32s_tl(t0, t0);
1333
        tcg_gen_sari_tl(t0, t0, uimm);
1334
        opn = "sra";
1335
        break;
1336
    case OPC_SRL:
1337
        switch ((ctx->opcode >> 21) & 0x1f) {
1338
        case 0:
1339
            if (uimm != 0) {
1340
                tcg_gen_ext32u_tl(t0, t0);
1341
                tcg_gen_shri_tl(t0, t0, uimm);
1342
            } else {
1343
                tcg_gen_ext32s_tl(t0, t0);
1344
            }
1345
            opn = "srl";
1346
            break;
1347
        case 1:
1348
            /* rotr is decoded as srl on non-R2 CPUs */
1349
            if (env->insn_flags & ISA_MIPS32R2) {
1350
                if (uimm != 0) {
1351
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1352

    
1353
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1354
                    tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
1355
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1356
                    tcg_temp_free_i32(r_tmp1);
1357
                }
1358
                opn = "rotr";
1359
            } else {
1360
                if (uimm != 0) {
1361
                    tcg_gen_ext32u_tl(t0, t0);
1362
                    tcg_gen_shri_tl(t0, t0, uimm);
1363
                } else {
1364
                    tcg_gen_ext32s_tl(t0, t0);
1365
                }
1366
                opn = "srl";
1367
            }
1368
            break;
1369
        default:
1370
            MIPS_INVAL("invalid srl flag");
1371
            generate_exception(ctx, EXCP_RI);
1372
            break;
1373
        }
1374
        break;
1375
#if defined(TARGET_MIPS64)
1376
    case OPC_DSLL:
1377
        tcg_gen_shli_tl(t0, t0, uimm);
1378
        opn = "dsll";
1379
        break;
1380
    case OPC_DSRA:
1381
        tcg_gen_sari_tl(t0, t0, uimm);
1382
        opn = "dsra";
1383
        break;
1384
    case OPC_DSRL:
1385
        switch ((ctx->opcode >> 21) & 0x1f) {
1386
        case 0:
1387
            tcg_gen_shri_tl(t0, t0, uimm);
1388
            opn = "dsrl";
1389
            break;
1390
        case 1:
1391
            /* drotr is decoded as dsrl on non-R2 CPUs */
1392
            if (env->insn_flags & ISA_MIPS32R2) {
1393
                if (uimm != 0) {
1394
                    tcg_gen_rotri_tl(t0, t0, uimm);
1395
                }
1396
                opn = "drotr";
1397
            } else {
1398
                tcg_gen_shri_tl(t0, t0, uimm);
1399
                opn = "dsrl";
1400
            }
1401
            break;
1402
        default:
1403
            MIPS_INVAL("invalid dsrl flag");
1404
            generate_exception(ctx, EXCP_RI);
1405
            break;
1406
        }
1407
        break;
1408
    case OPC_DSLL32:
1409
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1410
        opn = "dsll32";
1411
        break;
1412
    case OPC_DSRA32:
1413
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1414
        opn = "dsra32";
1415
        break;
1416
    case OPC_DSRL32:
1417
        switch ((ctx->opcode >> 21) & 0x1f) {
1418
        case 0:
1419
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1420
            opn = "dsrl32";
1421
            break;
1422
        case 1:
1423
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1424
            if (env->insn_flags & ISA_MIPS32R2) {
1425
                tcg_gen_rotri_tl(t0, t0, uimm + 32);
1426
                opn = "drotr32";
1427
            } else {
1428
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1429
                opn = "dsrl32";
1430
            }
1431
            break;
1432
        default:
1433
            MIPS_INVAL("invalid dsrl32 flag");
1434
            generate_exception(ctx, EXCP_RI);
1435
            break;
1436
        }
1437
        break;
1438
#endif
1439
    default:
1440
        MIPS_INVAL(opn);
1441
        generate_exception(ctx, EXCP_RI);
1442
        goto out;
1443
    }
1444
    gen_store_gpr(t0, rt);
1445
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1446
 out:
1447
    tcg_temp_free(t0);
1448
}
1449

    
1450
/* Arithmetic */
1451
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1452
                       int rd, int rs, int rt)
1453
{
1454
    const char *opn = "arith";
1455

    
1456
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1457
       && opc != OPC_DADD && opc != OPC_DSUB) {
1458
        /* If no destination, treat it as a NOP.
1459
           For add & sub, we must generate the overflow exception when needed. */
1460
        MIPS_DEBUG("NOP");
1461
        return;
1462
    }
1463

    
1464
    switch (opc) {
1465
    case OPC_ADD:
1466
        {
1467
            TCGv t0 = tcg_temp_local_new();
1468
            TCGv t1 = tcg_temp_new();
1469
            TCGv t2 = tcg_temp_new();
1470
            int l1 = gen_new_label();
1471

    
1472
            gen_load_gpr(t1, rs);
1473
            gen_load_gpr(t2, rt);
1474
            tcg_gen_add_tl(t0, t1, t2);
1475
            tcg_gen_ext32s_tl(t0, t0);
1476
            tcg_gen_xor_tl(t1, t1, t2);
1477
            tcg_gen_not_tl(t1, t1);
1478
            tcg_gen_xor_tl(t2, t0, t2);
1479
            tcg_gen_and_tl(t1, t1, t2);
1480
            tcg_temp_free(t2);
1481
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1482
            tcg_temp_free(t1);
1483
            /* operands of same sign, result different sign */
1484
            generate_exception(ctx, EXCP_OVERFLOW);
1485
            gen_set_label(l1);
1486
            gen_store_gpr(t0, rd);
1487
            tcg_temp_free(t0);
1488
        }
1489
        opn = "add";
1490
        break;
1491
    case OPC_ADDU:
1492
        if (rs != 0 && rt != 0) {
1493
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1494
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1495
        } else if (rs == 0 && rt != 0) {
1496
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1497
        } else if (rs != 0 && rt == 0) {
1498
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1499
        } else {
1500
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1501
        }
1502
        opn = "addu";
1503
        break;
1504
    case OPC_SUB:
1505
        {
1506
            TCGv t0 = tcg_temp_local_new();
1507
            TCGv t1 = tcg_temp_new();
1508
            TCGv t2 = tcg_temp_new();
1509
            int l1 = gen_new_label();
1510

    
1511
            gen_load_gpr(t1, rs);
1512
            gen_load_gpr(t2, rt);
1513
            tcg_gen_sub_tl(t0, t1, t2);
1514
            tcg_gen_ext32s_tl(t0, t0);
1515
            tcg_gen_xor_tl(t2, t1, t2);
1516
            tcg_gen_xor_tl(t1, t0, t1);
1517
            tcg_gen_and_tl(t1, t1, t2);
1518
            tcg_temp_free(t2);
1519
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1520
            tcg_temp_free(t1);
1521
            /* operands of same sign, result different sign */
1522
            generate_exception(ctx, EXCP_OVERFLOW);
1523
            gen_set_label(l1);
1524
            gen_store_gpr(t0, rd);
1525
            tcg_temp_free(t0);
1526
        }
1527
        opn = "sub";
1528
        break;
1529
    case OPC_SUBU:
1530
        if (rs != 0 && rt != 0) {
1531
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1532
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1533
        } else if (rs == 0 && rt != 0) {
1534
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1535
        } else if (rs != 0 && rt == 0) {
1536
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1537
        } else {
1538
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1539
        }
1540
        opn = "subu";
1541
        break;
1542
#if defined(TARGET_MIPS64)
1543
    case OPC_DADD:
1544
        {
1545
            TCGv t0 = tcg_temp_local_new();
1546
            TCGv t1 = tcg_temp_new();
1547
            TCGv t2 = tcg_temp_new();
1548
            int l1 = gen_new_label();
1549

    
1550
            gen_load_gpr(t1, rs);
1551
            gen_load_gpr(t2, rt);
1552
            tcg_gen_add_tl(t0, t1, t2);
1553
            tcg_gen_xor_tl(t1, t1, t2);
1554
            tcg_gen_not_tl(t1, t1);
1555
            tcg_gen_xor_tl(t2, t0, t2);
1556
            tcg_gen_and_tl(t1, t1, t2);
1557
            tcg_temp_free(t2);
1558
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1559
            tcg_temp_free(t1);
1560
            /* operands of same sign, result different sign */
1561
            generate_exception(ctx, EXCP_OVERFLOW);
1562
            gen_set_label(l1);
1563
            gen_store_gpr(t0, rd);
1564
            tcg_temp_free(t0);
1565
        }
1566
        opn = "dadd";
1567
        break;
1568
    case OPC_DADDU:
1569
        if (rs != 0 && rt != 0) {
1570
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1571
        } else if (rs == 0 && rt != 0) {
1572
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1573
        } else if (rs != 0 && rt == 0) {
1574
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1575
        } else {
1576
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1577
        }
1578
        opn = "daddu";
1579
        break;
1580
    case OPC_DSUB:
1581
        {
1582
            TCGv t0 = tcg_temp_local_new();
1583
            TCGv t1 = tcg_temp_new();
1584
            TCGv t2 = tcg_temp_new();
1585
            int l1 = gen_new_label();
1586

    
1587
            gen_load_gpr(t1, rs);
1588
            gen_load_gpr(t2, rt);
1589
            tcg_gen_sub_tl(t0, t1, t2);
1590
            tcg_gen_xor_tl(t2, t1, t2);
1591
            tcg_gen_xor_tl(t1, t0, t1);
1592
            tcg_gen_and_tl(t1, t1, t2);
1593
            tcg_temp_free(t2);
1594
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1595
            tcg_temp_free(t1);
1596
            /* operands of same sign, result different sign */
1597
            generate_exception(ctx, EXCP_OVERFLOW);
1598
            gen_set_label(l1);
1599
            gen_store_gpr(t0, rd);
1600
            tcg_temp_free(t0);
1601
        }
1602
        opn = "dsub";
1603
        break;
1604
    case OPC_DSUBU:
1605
        if (rs != 0 && rt != 0) {
1606
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1607
        } else if (rs == 0 && rt != 0) {
1608
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1609
        } else if (rs != 0 && rt == 0) {
1610
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1611
        } else {
1612
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1613
        }
1614
        opn = "dsubu";
1615
        break;
1616
#endif
1617
    case OPC_MUL:
1618
        if (likely(rs != 0 && rt != 0)) {
1619
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1620
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1621
        } else {
1622
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1623
        }
1624
        opn = "mul";
1625
        break;
1626
    }
1627
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1628
}
1629

    
1630
/* Conditional move */
1631
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1632
{
1633
    const char *opn = "cond move";
1634
    int l1;
1635

    
1636
    if (rd == 0) {
1637
        /* If no destination, treat it as a NOP.
1638
           For add & sub, we must generate the overflow exception when needed. */
1639
        MIPS_DEBUG("NOP");
1640
        return;
1641
    }
1642

    
1643
    l1 = gen_new_label();
1644
    switch (opc) {
1645
    case OPC_MOVN:
1646
        if (likely(rt != 0))
1647
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1648
        else
1649
            tcg_gen_br(l1);
1650
        opn = "movn";
1651
        break;
1652
    case OPC_MOVZ:
1653
        if (likely(rt != 0))
1654
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1655
        opn = "movz";
1656
        break;
1657
    }
1658
    if (rs != 0)
1659
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1660
    else
1661
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1662
    gen_set_label(l1);
1663

    
1664
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1665
}
1666

    
1667
/* Logic */
1668
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1669
{
1670
    const char *opn = "logic";
1671

    
1672
    if (rd == 0) {
1673
        /* If no destination, treat it as a NOP. */
1674
        MIPS_DEBUG("NOP");
1675
        return;
1676
    }
1677

    
1678
    switch (opc) {
1679
    case OPC_AND:
1680
        if (likely(rs != 0 && rt != 0)) {
1681
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1682
        } else {
1683
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1684
        }
1685
        opn = "and";
1686
        break;
1687
    case OPC_NOR:
1688
        if (rs != 0 && rt != 0) {
1689
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1690
        } else if (rs == 0 && rt != 0) {
1691
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1692
        } else if (rs != 0 && rt == 0) {
1693
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1694
        } else {
1695
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1696
        }
1697
        opn = "nor";
1698
        break;
1699
    case OPC_OR:
1700
        if (likely(rs != 0 && rt != 0)) {
1701
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1702
        } else if (rs == 0 && rt != 0) {
1703
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1704
        } else if (rs != 0 && rt == 0) {
1705
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1706
        } else {
1707
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1708
        }
1709
        opn = "or";
1710
        break;
1711
    case OPC_XOR:
1712
        if (likely(rs != 0 && rt != 0)) {
1713
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1714
        } else if (rs == 0 && rt != 0) {
1715
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1716
        } else if (rs != 0 && rt == 0) {
1717
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1718
        } else {
1719
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1720
        }
1721
        opn = "xor";
1722
        break;
1723
    }
1724
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1725
}
1726

    
1727
/* Set on lower than */
1728
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1729
{
1730
    const char *opn = "slt";
1731
    TCGv t0, t1;
1732

    
1733
    if (rd == 0) {
1734
        /* If no destination, treat it as a NOP. */
1735
        MIPS_DEBUG("NOP");
1736
        return;
1737
    }
1738

    
1739
    t0 = tcg_temp_new();
1740
    t1 = tcg_temp_new();
1741
    gen_load_gpr(t0, rs);
1742
    gen_load_gpr(t1, rt);
1743
    switch (opc) {
1744
    case OPC_SLT:
1745
        gen_op_lt(cpu_gpr[rd], t0, t1);
1746
        opn = "slt";
1747
        break;
1748
    case OPC_SLTU:
1749
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1750
        opn = "sltu";
1751
        break;
1752
    }
1753
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1754
    tcg_temp_free(t0);
1755
    tcg_temp_free(t1);
1756
}
1757

    
1758
/* Shifts */
1759
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1760
                       int rd, int rs, int rt)
1761
{
1762
    const char *opn = "shifts";
1763
    TCGv t0, t1;
1764

    
1765
    if (rd == 0) {
1766
        /* If no destination, treat it as a NOP.
1767
           For add & sub, we must generate the overflow exception when needed. */
1768
        MIPS_DEBUG("NOP");
1769
        return;
1770
    }
1771

    
1772
    t0 = tcg_temp_new();
1773
    t1 = tcg_temp_new();
1774
    gen_load_gpr(t0, rs);
1775
    gen_load_gpr(t1, rt);
1776
    switch (opc) {
1777
    case OPC_SLLV:
1778
        tcg_gen_andi_tl(t0, t0, 0x1f);
1779
        tcg_gen_shl_tl(t0, t1, t0);
1780
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1781
        opn = "sllv";
1782
        break;
1783
    case OPC_SRAV:
1784
        tcg_gen_ext32s_tl(t1, t1);
1785
        tcg_gen_andi_tl(t0, t0, 0x1f);
1786
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1787
        opn = "srav";
1788
        break;
1789
    case OPC_SRLV:
1790
        switch ((ctx->opcode >> 6) & 0x1f) {
1791
        case 0:
1792
            tcg_gen_ext32u_tl(t1, t1);
1793
            tcg_gen_andi_tl(t0, t0, 0x1f);
1794
            tcg_gen_shr_tl(t0, t1, t0);
1795
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1796
            opn = "srlv";
1797
            break;
1798
        case 1:
1799
            /* rotrv is decoded as srlv on non-R2 CPUs */
1800
            if (env->insn_flags & ISA_MIPS32R2) {
1801
                TCGv_i32 t2 = tcg_temp_new_i32();
1802
                TCGv_i32 t3 = tcg_temp_new_i32();
1803

    
1804
                tcg_gen_trunc_tl_i32(t2, t0);
1805
                tcg_gen_trunc_tl_i32(t3, t1);
1806
                tcg_gen_andi_i32(t2, t2, 0x1f);
1807
                tcg_gen_rotr_i32(t2, t3, t2);
1808
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1809
                tcg_temp_free_i32(t2);
1810
                tcg_temp_free_i32(t3);
1811
                opn = "rotrv";
1812
            } else {
1813
                tcg_gen_ext32u_tl(t1, t1);
1814
                tcg_gen_andi_tl(t0, t0, 0x1f);
1815
                tcg_gen_shr_tl(t0, t1, t0);
1816
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1817
                opn = "srlv";
1818
            }
1819
            break;
1820
        default:
1821
            MIPS_INVAL("invalid srlv flag");
1822
            generate_exception(ctx, EXCP_RI);
1823
            break;
1824
        }
1825
        break;
1826
#if defined(TARGET_MIPS64)
1827
    case OPC_DSLLV:
1828
        tcg_gen_andi_tl(t0, t0, 0x3f);
1829
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1830
        opn = "dsllv";
1831
        break;
1832
    case OPC_DSRAV:
1833
        tcg_gen_andi_tl(t0, t0, 0x3f);
1834
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1835
        opn = "dsrav";
1836
        break;
1837
    case OPC_DSRLV:
1838
        switch ((ctx->opcode >> 6) & 0x1f) {
1839
        case 0:
1840
            tcg_gen_andi_tl(t0, t0, 0x3f);
1841
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1842
            opn = "dsrlv";
1843
            break;
1844
        case 1:
1845
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1846
            if (env->insn_flags & ISA_MIPS32R2) {
1847
                tcg_gen_andi_tl(t0, t0, 0x3f);
1848
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1849
                opn = "drotrv";
1850
            } else {
1851
                tcg_gen_andi_tl(t0, t0, 0x3f);
1852
                tcg_gen_shr_tl(t0, t1, t0);
1853
                opn = "dsrlv";
1854
            }
1855
            break;
1856
        default:
1857
            MIPS_INVAL("invalid dsrlv flag");
1858
            generate_exception(ctx, EXCP_RI);
1859
            break;
1860
        }
1861
        break;
1862
#endif
1863
    }
1864
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1865
    tcg_temp_free(t0);
1866
    tcg_temp_free(t1);
1867
}
1868

    
1869
/* Arithmetic on HI/LO registers */
1870
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1871
{
1872
    const char *opn = "hilo";
1873

    
1874
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1875
        /* Treat as NOP. */
1876
        MIPS_DEBUG("NOP");
1877
        return;
1878
    }
1879
    switch (opc) {
1880
    case OPC_MFHI:
1881
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1882
        opn = "mfhi";
1883
        break;
1884
    case OPC_MFLO:
1885
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1886
        opn = "mflo";
1887
        break;
1888
    case OPC_MTHI:
1889
        if (reg != 0)
1890
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1891
        else
1892
            tcg_gen_movi_tl(cpu_HI[0], 0);
1893
        opn = "mthi";
1894
        break;
1895
    case OPC_MTLO:
1896
        if (reg != 0)
1897
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1898
        else
1899
            tcg_gen_movi_tl(cpu_LO[0], 0);
1900
        opn = "mtlo";
1901
        break;
1902
    }
1903
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1904
}
1905

    
1906
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1907
                        int rs, int rt)
1908
{
1909
    const char *opn = "mul/div";
1910
    TCGv t0, t1;
1911

    
1912
    switch (opc) {
1913
    case OPC_DIV:
1914
    case OPC_DIVU:
1915
#if defined(TARGET_MIPS64)
1916
    case OPC_DDIV:
1917
    case OPC_DDIVU:
1918
#endif
1919
        t0 = tcg_temp_local_new();
1920
        t1 = tcg_temp_local_new();
1921
        break;
1922
    default:
1923
        t0 = tcg_temp_new();
1924
        t1 = tcg_temp_new();
1925
        break;
1926
    }
1927

    
1928
    gen_load_gpr(t0, rs);
1929
    gen_load_gpr(t1, rt);
1930
    switch (opc) {
1931
    case OPC_DIV:
1932
        {
1933
            int l1 = gen_new_label();
1934
            int l2 = 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
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1940
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1941

    
1942
            tcg_gen_mov_tl(cpu_LO[0], t0);
1943
            tcg_gen_movi_tl(cpu_HI[0], 0);
1944
            tcg_gen_br(l1);
1945
            gen_set_label(l2);
1946
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1947
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1948
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1949
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1950
            gen_set_label(l1);
1951
        }
1952
        opn = "div";
1953
        break;
1954
    case OPC_DIVU:
1955
        {
1956
            int l1 = gen_new_label();
1957

    
1958
            tcg_gen_ext32u_tl(t0, t0);
1959
            tcg_gen_ext32u_tl(t1, t1);
1960
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1961
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1962
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1963
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1964
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1965
            gen_set_label(l1);
1966
        }
1967
        opn = "divu";
1968
        break;
1969
    case OPC_MULT:
1970
        {
1971
            TCGv_i64 t2 = tcg_temp_new_i64();
1972
            TCGv_i64 t3 = tcg_temp_new_i64();
1973

    
1974
            tcg_gen_ext_tl_i64(t2, t0);
1975
            tcg_gen_ext_tl_i64(t3, t1);
1976
            tcg_gen_mul_i64(t2, t2, t3);
1977
            tcg_temp_free_i64(t3);
1978
            tcg_gen_trunc_i64_tl(t0, t2);
1979
            tcg_gen_shri_i64(t2, t2, 32);
1980
            tcg_gen_trunc_i64_tl(t1, t2);
1981
            tcg_temp_free_i64(t2);
1982
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1983
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1984
        }
1985
        opn = "mult";
1986
        break;
1987
    case OPC_MULTU:
1988
        {
1989
            TCGv_i64 t2 = tcg_temp_new_i64();
1990
            TCGv_i64 t3 = tcg_temp_new_i64();
1991

    
1992
            tcg_gen_ext32u_tl(t0, t0);
1993
            tcg_gen_ext32u_tl(t1, t1);
1994
            tcg_gen_extu_tl_i64(t2, t0);
1995
            tcg_gen_extu_tl_i64(t3, t1);
1996
            tcg_gen_mul_i64(t2, t2, t3);
1997
            tcg_temp_free_i64(t3);
1998
            tcg_gen_trunc_i64_tl(t0, t2);
1999
            tcg_gen_shri_i64(t2, t2, 32);
2000
            tcg_gen_trunc_i64_tl(t1, t2);
2001
            tcg_temp_free_i64(t2);
2002
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2003
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2004
        }
2005
        opn = "multu";
2006
        break;
2007
#if defined(TARGET_MIPS64)
2008
    case OPC_DDIV:
2009
        {
2010
            int l1 = gen_new_label();
2011
            int l2 = gen_new_label();
2012

    
2013
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2014
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2015
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2016
            tcg_gen_mov_tl(cpu_LO[0], t0);
2017
            tcg_gen_movi_tl(cpu_HI[0], 0);
2018
            tcg_gen_br(l1);
2019
            gen_set_label(l2);
2020
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2021
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2022
            gen_set_label(l1);
2023
        }
2024
        opn = "ddiv";
2025
        break;
2026
    case OPC_DDIVU:
2027
        {
2028
            int l1 = gen_new_label();
2029

    
2030
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2031
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2032
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2033
            gen_set_label(l1);
2034
        }
2035
        opn = "ddivu";
2036
        break;
2037
    case OPC_DMULT:
2038
        gen_helper_dmult(t0, t1);
2039
        opn = "dmult";
2040
        break;
2041
    case OPC_DMULTU:
2042
        gen_helper_dmultu(t0, t1);
2043
        opn = "dmultu";
2044
        break;
2045
#endif
2046
    case OPC_MADD:
2047
        {
2048
            TCGv_i64 t2 = tcg_temp_new_i64();
2049
            TCGv_i64 t3 = tcg_temp_new_i64();
2050

    
2051
            tcg_gen_ext_tl_i64(t2, t0);
2052
            tcg_gen_ext_tl_i64(t3, t1);
2053
            tcg_gen_mul_i64(t2, t2, t3);
2054
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2055
            tcg_gen_add_i64(t2, t2, t3);
2056
            tcg_temp_free_i64(t3);
2057
            tcg_gen_trunc_i64_tl(t0, t2);
2058
            tcg_gen_shri_i64(t2, t2, 32);
2059
            tcg_gen_trunc_i64_tl(t1, t2);
2060
            tcg_temp_free_i64(t2);
2061
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2062
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
2063
        }
2064
        opn = "madd";
2065
        break;
2066
    case OPC_MADDU:
2067
       {
2068
            TCGv_i64 t2 = tcg_temp_new_i64();
2069
            TCGv_i64 t3 = tcg_temp_new_i64();
2070

    
2071
            tcg_gen_ext32u_tl(t0, t0);
2072
            tcg_gen_ext32u_tl(t1, t1);
2073
            tcg_gen_extu_tl_i64(t2, t0);
2074
            tcg_gen_extu_tl_i64(t3, t1);
2075
            tcg_gen_mul_i64(t2, t2, t3);
2076
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2077
            tcg_gen_add_i64(t2, t2, t3);
2078
            tcg_temp_free_i64(t3);
2079
            tcg_gen_trunc_i64_tl(t0, t2);
2080
            tcg_gen_shri_i64(t2, t2, 32);
2081
            tcg_gen_trunc_i64_tl(t1, t2);
2082
            tcg_temp_free_i64(t2);
2083
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2084
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2085
        }
2086
        opn = "maddu";
2087
        break;
2088
    case OPC_MSUB:
2089
        {
2090
            TCGv_i64 t2 = tcg_temp_new_i64();
2091
            TCGv_i64 t3 = tcg_temp_new_i64();
2092

    
2093
            tcg_gen_ext_tl_i64(t2, t0);
2094
            tcg_gen_ext_tl_i64(t3, t1);
2095
            tcg_gen_mul_i64(t2, t2, t3);
2096
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2097
            tcg_gen_sub_i64(t2, t2, t3);
2098
            tcg_temp_free_i64(t3);
2099
            tcg_gen_trunc_i64_tl(t0, t2);
2100
            tcg_gen_shri_i64(t2, t2, 32);
2101
            tcg_gen_trunc_i64_tl(t1, t2);
2102
            tcg_temp_free_i64(t2);
2103
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2104
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2105
        }
2106
        opn = "msub";
2107
        break;
2108
    case OPC_MSUBU:
2109
        {
2110
            TCGv_i64 t2 = tcg_temp_new_i64();
2111
            TCGv_i64 t3 = tcg_temp_new_i64();
2112

    
2113
            tcg_gen_ext32u_tl(t0, t0);
2114
            tcg_gen_ext32u_tl(t1, t1);
2115
            tcg_gen_extu_tl_i64(t2, t0);
2116
            tcg_gen_extu_tl_i64(t3, t1);
2117
            tcg_gen_mul_i64(t2, t2, t3);
2118
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2119
            tcg_gen_sub_i64(t2, t2, t3);
2120
            tcg_temp_free_i64(t3);
2121
            tcg_gen_trunc_i64_tl(t0, t2);
2122
            tcg_gen_shri_i64(t2, t2, 32);
2123
            tcg_gen_trunc_i64_tl(t1, t2);
2124
            tcg_temp_free_i64(t2);
2125
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2126
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2127
        }
2128
        opn = "msubu";
2129
        break;
2130
    default:
2131
        MIPS_INVAL(opn);
2132
        generate_exception(ctx, EXCP_RI);
2133
        goto out;
2134
    }
2135
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2136
 out:
2137
    tcg_temp_free(t0);
2138
    tcg_temp_free(t1);
2139
}
2140

    
2141
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2142
                            int rd, int rs, int rt)
2143
{
2144
    const char *opn = "mul vr54xx";
2145
    TCGv t0 = tcg_temp_new();
2146
    TCGv t1 = tcg_temp_new();
2147

    
2148
    gen_load_gpr(t0, rs);
2149
    gen_load_gpr(t1, rt);
2150

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

    
2216
 out:
2217
    tcg_temp_free(t0);
2218
    tcg_temp_free(t1);
2219
}
2220

    
2221
static void gen_cl (DisasContext *ctx, uint32_t opc,
2222
                    int rd, int rs)
2223
{
2224
    const char *opn = "CLx";
2225
    TCGv t0;
2226

    
2227
    if (rd == 0) {
2228
        /* Treat as NOP. */
2229
        MIPS_DEBUG("NOP");
2230
        return;
2231
    }
2232
    t0 = tcg_temp_new();
2233
    gen_load_gpr(t0, rs);
2234
    switch (opc) {
2235
    case OPC_CLO:
2236
        gen_helper_clo(cpu_gpr[rd], t0);
2237
        opn = "clo";
2238
        break;
2239
    case OPC_CLZ:
2240
        gen_helper_clz(cpu_gpr[rd], t0);
2241
        opn = "clz";
2242
        break;
2243
#if defined(TARGET_MIPS64)
2244
    case OPC_DCLO:
2245
        gen_helper_dclo(cpu_gpr[rd], t0);
2246
        opn = "dclo";
2247
        break;
2248
    case OPC_DCLZ:
2249
        gen_helper_dclz(cpu_gpr[rd], t0);
2250
        opn = "dclz";
2251
        break;
2252
#endif
2253
    }
2254
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2255
    tcg_temp_free(t0);
2256
}
2257

    
2258
/* Traps */
2259
static void gen_trap (DisasContext *ctx, uint32_t opc,
2260
                      int rs, int rt, int16_t imm)
2261
{
2262
    int cond;
2263
    TCGv t0 = tcg_temp_new();
2264
    TCGv t1 = tcg_temp_new();
2265

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

    
2319
        switch (opc) {
2320
        case OPC_TEQ:
2321
        case OPC_TEQI:
2322
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2323
            break;
2324
        case OPC_TGE:
2325
        case OPC_TGEI:
2326
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2327
            break;
2328
        case OPC_TGEU:
2329
        case OPC_TGEIU:
2330
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2331
            break;
2332
        case OPC_TLT:
2333
        case OPC_TLTI:
2334
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2335
            break;
2336
        case OPC_TLTU:
2337
        case OPC_TLTIU:
2338
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2339
            break;
2340
        case OPC_TNE:
2341
        case OPC_TNEI:
2342
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2343
            break;
2344
        }
2345
        generate_exception(ctx, EXCP_TRAP);
2346
        gen_set_label(l1);
2347
    }
2348
    tcg_temp_free(t0);
2349
    tcg_temp_free(t1);
2350
}
2351

    
2352
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2353
{
2354
    TranslationBlock *tb;
2355
    tb = ctx->tb;
2356
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2357
        tcg_gen_goto_tb(n);
2358
        gen_save_pc(dest);
2359
        tcg_gen_exit_tb((long)tb + n);
2360
    } else {
2361
        gen_save_pc(dest);
2362
        tcg_gen_exit_tb(0);
2363
    }
2364
}
2365

    
2366
/* Branches (before delay slot) */
2367
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2368
                                int rs, int rt, int32_t offset)
2369
{
2370
    target_ulong btgt = -1;
2371
    int blink = 0;
2372
    int bcond_compute = 0;
2373
    TCGv t0 = tcg_temp_new();
2374
    TCGv t1 = tcg_temp_new();
2375

    
2376
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2377
#ifdef MIPS_DEBUG_DISAS
2378
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2379
#endif
2380
        generate_exception(ctx, EXCP_RI);
2381
        goto out;
2382
    }
2383

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

    
2592
    ctx->btarget = btgt;
2593
    if (blink > 0) {
2594
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2595
    }
2596

    
2597
 out:
2598
    tcg_temp_free(t0);
2599
    tcg_temp_free(t1);
2600
}
2601

    
2602
/* special3 bitfield operations */
2603
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2604
                        int rs, int lsb, int msb)
2605
{
2606
    TCGv t0 = tcg_temp_new();
2607
    TCGv t1 = tcg_temp_new();
2608
    target_ulong mask;
2609

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

    
2695
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2696
{
2697
    TCGv t0;
2698

    
2699
    if (rd == 0) {
2700
        /* If no destination, treat it as a NOP. */
2701
        MIPS_DEBUG("NOP");
2702
        return;
2703
    }
2704

    
2705
    t0 = tcg_temp_new();
2706
    gen_load_gpr(t0, rt);
2707
    switch (op2) {
2708
    case OPC_WSBH:
2709
        {
2710
            TCGv t1 = tcg_temp_new();
2711

    
2712
            tcg_gen_shri_tl(t1, t0, 8);
2713
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2714
            tcg_gen_shli_tl(t0, t0, 8);
2715
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2716
            tcg_gen_or_tl(t0, t0, t1);
2717
            tcg_temp_free(t1);
2718
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2719
        }
2720
        break;
2721
    case OPC_SEB:
2722
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2723
        break;
2724
    case OPC_SEH:
2725
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2726
        break;
2727
#if defined(TARGET_MIPS64)
2728
    case OPC_DSBH:
2729
        {
2730
            TCGv t1 = tcg_temp_new();
2731

    
2732
            tcg_gen_shri_tl(t1, t0, 8);
2733
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2734
            tcg_gen_shli_tl(t0, t0, 8);
2735
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2736
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2737
            tcg_temp_free(t1);
2738
        }
2739
        break;
2740
    case OPC_DSHD:
2741
        {
2742
            TCGv t1 = tcg_temp_new();
2743

    
2744
            tcg_gen_shri_tl(t1, t0, 16);
2745
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2746
            tcg_gen_shli_tl(t0, t0, 16);
2747
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2748
            tcg_gen_or_tl(t0, t0, t1);
2749
            tcg_gen_shri_tl(t1, t0, 32);
2750
            tcg_gen_shli_tl(t0, t0, 32);
2751
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2752
            tcg_temp_free(t1);
2753
        }
2754
        break;
2755
#endif
2756
    default:
2757
        MIPS_INVAL("bsfhl");
2758
        generate_exception(ctx, EXCP_RI);
2759
        tcg_temp_free(t0);
2760
        return;
2761
    }
2762
    tcg_temp_free(t0);
2763
}
2764

    
2765
#ifndef CONFIG_USER_ONLY
2766
/* CP0 (MMU and control) */
2767
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2768
{
2769
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2770

    
2771
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2772
    tcg_gen_ext_i32_tl(t, r_tmp);
2773
    tcg_temp_free_i32(r_tmp);
2774
}
2775

    
2776
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2777
{
2778
    tcg_gen_ld_tl(t, cpu_env, off);
2779
    tcg_gen_ext32s_tl(t, t);
2780
}
2781

    
2782
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2783
{
2784
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2785

    
2786
    tcg_gen_trunc_tl_i32(r_tmp, t);
2787
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2788
    tcg_temp_free_i32(r_tmp);
2789
}
2790

    
2791
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2792
{
2793
    tcg_gen_ext32s_tl(t, t);
2794
    tcg_gen_st_tl(t, cpu_env, off);
2795
}
2796

    
2797
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2798
{
2799
    const char *rn = "invalid";
2800

    
2801
    if (sel != 0)
2802
        check_insn(env, ctx, ISA_MIPS32);
2803

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

    
3369
die:
3370
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3371
    generate_exception(ctx, EXCP_RI);
3372
}
3373

    
3374
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3375
{
3376
    const char *rn = "invalid";
3377

    
3378
    if (sel != 0)
3379
        check_insn(env, ctx, ISA_MIPS32);
3380

    
3381
    if (use_icount)
3382
        gen_io_start();
3383

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

    
3962
die:
3963
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3964
    generate_exception(ctx, EXCP_RI);
3965
}
3966

    
3967
#if defined(TARGET_MIPS64)
3968
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3969
{
3970
    const char *rn = "invalid";
3971

    
3972
    if (sel != 0)
3973
        check_insn(env, ctx, ISA_MIPS64);
3974

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

    
4529
die:
4530
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4531
    generate_exception(ctx, EXCP_RI);
4532
}
4533

    
4534
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4535
{
4536
    const char *rn = "invalid";
4537

    
4538
    if (sel != 0)
4539
        check_insn(env, ctx, ISA_MIPS64);
4540

    
4541
    if (use_icount)
4542
        gen_io_start();
4543

    
4544
    switch (reg) {
4545
    case 0:
4546
        switch (sel) {
4547
        case 0:
4548
            gen_helper_mtc0_index(t0);
4549
            rn = "Index";
4550
            break;
4551
        case 1:
4552
            check_insn(env, ctx, ASE_MT);
4553
            gen_helper_mtc0_mvpcontrol(t0);
4554
            rn = "MVPControl";
4555
            break;
4556
        case 2:
4557
            check_insn(env, ctx, ASE_MT);
4558
            /* ignored */
4559
            rn = "MVPConf0";
4560
            break;
4561
        case 3:
4562
            check_insn(env, ctx, ASE_MT);
4563
            /* ignored */
4564
            rn = "MVPConf1";
4565
            break;
4566
        default:
4567
            goto die;
4568
        }
4569
        break;
4570
    case 1:
4571
        switch (sel) {
4572
        case 0:
4573
            /* ignored */
4574
            rn = "Random";
4575
            break;
4576
        case 1:
4577
            check_insn(env, ctx, ASE_MT);
4578
            gen_helper_mtc0_vpecontrol(t0);
4579
            rn = "VPEControl";
4580
            break;
4581
        case 2:
4582
            check_insn(env, ctx, ASE_MT);
4583
            gen_helper_mtc0_vpeconf0(t0);
4584
            rn = "VPEConf0";
4585
            break;
4586
        case 3:
4587
            check_insn(env, ctx, ASE_MT);
4588
            gen_helper_mtc0_vpeconf1(t0);
4589
            rn = "VPEConf1";
4590
            break;
4591
        case 4:
4592
            check_insn(env, ctx, ASE_MT);
4593
            gen_helper_mtc0_yqmask(t0);
4594
            rn = "YQMask";
4595
            break;
4596
        case 5:
4597
            check_insn(env, ctx, ASE_MT);
4598
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4599
            rn = "VPESchedule";
4600
            break;
4601
        case 6:
4602
            check_insn(env, ctx, ASE_MT);
4603
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4604
            rn = "VPEScheFBack";
4605
            break;
4606
        case 7:
4607
            check_insn(env, ctx, ASE_MT);
4608
            gen_helper_mtc0_vpeopt(t0);
4609
            rn = "VPEOpt";
4610
            break;
4611
        default:
4612
            goto die;
4613
        }
4614
        break;
4615
    case 2:
4616
        switch (sel) {
4617
        case 0:
4618
            gen_helper_mtc0_entrylo0(t0);
4619
            rn = "EntryLo0";
4620
            break;
4621
        case 1:
4622
            check_insn(env, ctx, ASE_MT);
4623
            gen_helper_mtc0_tcstatus(t0);
4624
            rn = "TCStatus";
4625
            break;
4626
        case 2:
4627
            check_insn(env, ctx, ASE_MT);
4628
            gen_helper_mtc0_tcbind(t0);
4629
            rn = "TCBind";
4630
            break;
4631
        case 3:
4632
            check_insn(env, ctx, ASE_MT);
4633
            gen_helper_mtc0_tcrestart(t0);
4634
            rn = "TCRestart";
4635
            break;
4636
        case 4:
4637
            check_insn(env, ctx, ASE_MT);
4638
            gen_helper_mtc0_tchalt(t0);
4639
            rn = "TCHalt";
4640
            break;
4641
        case 5:
4642
            check_insn(env, ctx, ASE_MT);
4643
            gen_helper_mtc0_tccontext(t0);
4644
            rn = "TCContext";
4645
            break;
4646
        case 6:
4647
            check_insn(env, ctx, ASE_MT);
4648
            gen_helper_mtc0_tcschedule(t0);
4649
            rn = "TCSchedule";
4650
            break;
4651
        case 7:
4652
            check_insn(env, ctx, ASE_MT);
4653
            gen_helper_mtc0_tcschefback(t0);
4654
            rn = "TCScheFBack";
4655
            break;
4656
        default:
4657
            goto die;
4658
        }
4659
        break;
4660
    case 3:
4661
        switch (sel) {
4662
        case 0:
4663
            gen_helper_mtc0_entrylo1(t0);
4664
            rn = "EntryLo1";
4665
            break;
4666
        default:
4667
            goto die;
4668
        }
4669
        break;
4670
    case 4:
4671
        switch (sel) {
4672
        case 0:
4673
            gen_helper_mtc0_context(t0);
4674
            rn = "Context";
4675
            break;
4676
        case 1:
4677
//           gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4678
            rn = "ContextConfig";
4679
//           break;
4680
        default:
4681
            goto die;
4682
        }
4683
        break;
4684
    case 5:
4685
        switch (sel) {
4686
        case 0:
4687
            gen_helper_mtc0_pagemask(t0);
4688
            rn = "PageMask";
4689
            break;
4690
        case 1:
4691
            check_insn(env, ctx, ISA_MIPS32R2);
4692
            gen_helper_mtc0_pagegrain(t0);
4693
            rn = "PageGrain";
4694
            break;
4695
        default:
4696
            goto die;
4697
        }
4698
        break;
4699
    case 6:
4700
        switch (sel) {
4701
        case 0:
4702
            gen_helper_mtc0_wired(t0);
4703
            rn = "Wired";
4704
            break;
4705
        case 1:
4706
            check_insn(env, ctx, ISA_MIPS32R2);
4707
            gen_helper_mtc0_srsconf0(t0);
4708
            rn = "SRSConf0";
4709
            break;
4710
        case 2:
4711
            check_insn(env, ctx, ISA_MIPS32R2);
4712
            gen_helper_mtc0_srsconf1(t0);
4713
            rn = "SRSConf1";
4714