Statistics
| Branch: | Revision:

root / target-mips / translate.c @ cdc0faa6

History | View | Annotate | Download (245 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
//#define MIPS_SINGLE_STEP
42

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

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

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

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
437
#include "gen-icount.h"
438

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

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

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

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

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

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

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

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

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

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

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

    
503
static const char *fregnames_h[] =
504
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
505
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
506
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
507
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
508

    
509
#ifdef MIPS_DEBUG_DISAS
510
#define MIPS_DEBUG(fmt, args...)                         \
511
        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
512
                       TARGET_FMT_lx ": %08x " fmt "\n", \
513
                       ctx->pc, ctx->opcode , ##args)
514
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
515
#else
516
#define MIPS_DEBUG(fmt, args...) do { } while(0)
517
#define LOG_DISAS(...) do { } while (0)
518
#endif
519

    
520
#define MIPS_INVAL(op)                                                        \
521
do {                                                                          \
522
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
523
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
524
} while (0)
525

    
526
/* General purpose registers moves. */
527
static inline void gen_load_gpr (TCGv t, int reg)
528
{
529
    if (reg == 0)
530
        tcg_gen_movi_tl(t, 0);
531
    else
532
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
533
}
534

    
535
static inline void gen_store_gpr (TCGv t, int reg)
536
{
537
    if (reg != 0)
538
        tcg_gen_mov_tl(cpu_gpr[reg], t);
539
}
540

    
541
/* Moves to/from ACX register.  */
542
static inline void gen_load_ACX (TCGv t, int reg)
543
{
544
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
545
}
546

    
547
static inline void gen_store_ACX (TCGv t, int reg)
548
{
549
    tcg_gen_mov_tl(cpu_ACX[reg], t);
550
}
551

    
552
/* Moves to/from shadow registers. */
553
static inline void gen_load_srsgpr (int from, int to)
554
{
555
    TCGv r_tmp1 = tcg_temp_new();
556

    
557
    if (from == 0)
558
        tcg_gen_movi_tl(r_tmp1, 0);
559
    else {
560
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
561
        TCGv_ptr addr = tcg_temp_new_ptr();
562

    
563
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
564
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
565
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
566
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
567
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
568
        tcg_gen_add_ptr(addr, cpu_env, addr);
569

    
570
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
571
        tcg_temp_free_ptr(addr);
572
        tcg_temp_free_i32(r_tmp2);
573
    }
574
    gen_store_gpr(r_tmp1, to);
575
    tcg_temp_free(r_tmp1);
576
}
577

    
578
static inline void gen_store_srsgpr (int from, int to)
579
{
580
    if (to != 0) {
581
        TCGv r_tmp1 = tcg_temp_new();
582
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
583
        TCGv_ptr addr = tcg_temp_new_ptr();
584

    
585
        gen_load_gpr(r_tmp1, from);
586
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
587
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
588
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
589
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
590
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
591
        tcg_gen_add_ptr(addr, cpu_env, addr);
592

    
593
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
594
        tcg_temp_free_ptr(addr);
595
        tcg_temp_free_i32(r_tmp2);
596
        tcg_temp_free(r_tmp1);
597
    }
598
}
599

    
600
/* Floating point register moves. */
601
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
602
{
603
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
604
}
605

    
606
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
607
{
608
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
609
}
610

    
611
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
612
{
613
    if (ctx->hflags & MIPS_HFLAG_F64) {
614
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg], fpu_fpr32h[reg]);
615
    } else {
616
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
617
    }
618
}
619

    
620
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
621
{
622
    if (ctx->hflags & MIPS_HFLAG_F64) {
623
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg], t);
624
        tcg_gen_shri_i64(t, t, 32);
625
        tcg_gen_trunc_i64_i32(fpu_fpr32h[reg], t);
626
    } else {
627
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
628
        tcg_gen_shri_i64(t, t, 32);
629
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
630
    }
631
}
632

    
633
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
634
{
635
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
636
}
637

    
638
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
639
{
640
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
641
}
642

    
643
static inline void get_fp_cond (TCGv_i32 t)
644
{
645
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
646
    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
647

    
648
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
649
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
650
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
651
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
652
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
653
    tcg_temp_free_i32(r_tmp1);
654
    tcg_temp_free_i32(r_tmp2);
655
}
656

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

    
682
FOP_CONDS(, d, 64)
683
FOP_CONDS(abs, d, 64)
684
FOP_CONDS(, s, 32)
685
FOP_CONDS(abs, s, 32)
686
FOP_CONDS(, ps, 64)
687
FOP_CONDS(abs, ps, 64)
688
#undef FOP_CONDS
689

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

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

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

    
748
static inline void gen_save_pc(target_ulong pc)
749
{
750
    tcg_gen_movi_tl(cpu_PC, pc);
751
}
752

    
753
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
754
{
755
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
756
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
757
        gen_save_pc(ctx->pc);
758
        ctx->saved_pc = ctx->pc;
759
    }
760
    if (ctx->hflags != ctx->saved_hflags) {
761
        TCGv_i32 r_tmp = tcg_temp_new_i32();
762

    
763
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
764
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
765
        tcg_temp_free_i32(r_tmp);
766
        ctx->saved_hflags = ctx->hflags;
767
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
768
        case MIPS_HFLAG_BR:
769
            break;
770
        case MIPS_HFLAG_BC:
771
        case MIPS_HFLAG_BL:
772
        case MIPS_HFLAG_B:
773
            tcg_gen_movi_tl(btarget, ctx->btarget);
774
            break;
775
        }
776
    }
777
}
778

    
779
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
780
{
781
    ctx->saved_hflags = ctx->hflags;
782
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
783
    case MIPS_HFLAG_BR:
784
        break;
785
    case MIPS_HFLAG_BC:
786
    case MIPS_HFLAG_BL:
787
    case MIPS_HFLAG_B:
788
        ctx->btarget = env->btarget;
789
        break;
790
    }
791
}
792

    
793
static inline void
794
generate_exception_err (DisasContext *ctx, int excp, int err)
795
{
796
    TCGv_i32 texcp = tcg_const_i32(excp);
797
    TCGv_i32 terr = tcg_const_i32(err);
798
    save_cpu_state(ctx, 1);
799
    gen_helper_raise_exception_err(texcp, terr);
800
    tcg_temp_free_i32(terr);
801
    tcg_temp_free_i32(texcp);
802
    gen_helper_interrupt_restart();
803
    tcg_gen_exit_tb(0);
804
}
805

    
806
static inline void
807
generate_exception (DisasContext *ctx, int excp)
808
{
809
    save_cpu_state(ctx, 1);
810
    gen_helper_0i(raise_exception, excp);
811
    gen_helper_interrupt_restart();
812
    tcg_gen_exit_tb(0);
813
}
814

    
815
/* Addresses computation */
816
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
817
{
818
    tcg_gen_add_tl(t0, t0, t1);
819

    
820
#if defined(TARGET_MIPS64)
821
    /* For compatibility with 32-bit code, data reference in user mode
822
       with Status_UX = 0 should be casted to 32-bit and sign extended.
823
       See the MIPS64 PRA manual, section 4.10. */
824
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
825
        !(ctx->hflags & MIPS_HFLAG_UX)) {
826
        tcg_gen_ext32s_i64(t0, t0);
827
    }
828
#endif
829
}
830

    
831
static inline void check_cp0_enabled(DisasContext *ctx)
832
{
833
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
834
        generate_exception_err(ctx, EXCP_CpU, 1);
835
}
836

    
837
static inline void check_cp1_enabled(DisasContext *ctx)
838
{
839
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
840
        generate_exception_err(ctx, EXCP_CpU, 1);
841
}
842

    
843
/* Verify that the processor is running with COP1X instructions enabled.
844
   This is associated with the nabla symbol in the MIPS32 and MIPS64
845
   opcode tables.  */
846

    
847
static inline void check_cop1x(DisasContext *ctx)
848
{
849
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
850
        generate_exception(ctx, EXCP_RI);
851
}
852

    
853
/* Verify that the processor is running with 64-bit floating-point
854
   operations enabled.  */
855

    
856
static inline void check_cp1_64bitmode(DisasContext *ctx)
857
{
858
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
859
        generate_exception(ctx, EXCP_RI);
860
}
861

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

    
879
/* This code generates a "reserved instruction" exception if the
880
   CPU does not support the instruction set corresponding to flags. */
881
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
882
{
883
    if (unlikely(!(env->insn_flags & flags)))
884
        generate_exception(ctx, EXCP_RI);
885
}
886

    
887
/* This code generates a "reserved instruction" exception if 64-bit
888
   instructions are not enabled. */
889
static inline void check_mips_64(DisasContext *ctx)
890
{
891
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
892
        generate_exception(ctx, EXCP_RI);
893
}
894

    
895
/* load/store instructions. */
896
#define OP_LD(insn,fname)                                        \
897
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
898
{                                                                \
899
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
900
}
901
OP_LD(lb,ld8s);
902
OP_LD(lbu,ld8u);
903
OP_LD(lh,ld16s);
904
OP_LD(lhu,ld16u);
905
OP_LD(lw,ld32s);
906
#if defined(TARGET_MIPS64)
907
OP_LD(lwu,ld32u);
908
OP_LD(ld,ld64);
909
#endif
910
#undef OP_LD
911

    
912
#define OP_ST(insn,fname)                                        \
913
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
914
{                                                                \
915
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
916
}
917
OP_ST(sb,st8);
918
OP_ST(sh,st16);
919
OP_ST(sw,st32);
920
#if defined(TARGET_MIPS64)
921
OP_ST(sd,st64);
922
#endif
923
#undef OP_ST
924

    
925
#define OP_LD_ATOMIC(insn,fname)                                        \
926
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
927
{                                                                       \
928
    tcg_gen_mov_tl(t1, t0);                                             \
929
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
930
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
931
}
932
OP_LD_ATOMIC(ll,ld32s);
933
#if defined(TARGET_MIPS64)
934
OP_LD_ATOMIC(lld,ld64);
935
#endif
936
#undef OP_LD_ATOMIC
937

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

    
967
/* Load and store */
968
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
969
                      int base, int16_t offset)
970
{
971
    const char *opn = "ldst";
972
    TCGv t0 = tcg_temp_local_new();
973
    TCGv t1 = tcg_temp_local_new();
974

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

    
1130
/* Load and store */
1131
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1132
                          int base, int16_t offset)
1133
{
1134
    const char *opn = "flt_ldst";
1135
    TCGv t0 = tcg_temp_local_new();
1136

    
1137
    if (base == 0) {
1138
        tcg_gen_movi_tl(t0, offset);
1139
    } else if (offset == 0) {
1140
        gen_load_gpr(t0, base);
1141
    } else {
1142
        tcg_gen_movi_tl(t0, offset);
1143
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1144
    }
1145
    /* Don't do NOP if destination is zero: we must perform the actual
1146
       memory access. */
1147
    switch (opc) {
1148
    case OPC_LWC1:
1149
        {
1150
            TCGv_i32 fp0 = tcg_temp_new_i32();
1151
            TCGv t1 = tcg_temp_new();
1152

    
1153
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1154
            tcg_gen_trunc_tl_i32(fp0, t1);
1155
            gen_store_fpr32(fp0, ft);
1156
            tcg_temp_free(t1);
1157
            tcg_temp_free_i32(fp0);
1158
        }
1159
        opn = "lwc1";
1160
        break;
1161
    case OPC_SWC1:
1162
        {
1163
            TCGv_i32 fp0 = tcg_temp_new_i32();
1164
            TCGv t1 = tcg_temp_new();
1165

    
1166
            gen_load_fpr32(fp0, ft);
1167
            tcg_gen_extu_i32_tl(t1, fp0);
1168
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1169
            tcg_temp_free(t1);
1170
            tcg_temp_free_i32(fp0);
1171
        }
1172
        opn = "swc1";
1173
        break;
1174
    case OPC_LDC1:
1175
        {
1176
            TCGv_i64 fp0 = tcg_temp_new_i64();
1177

    
1178
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1179
            gen_store_fpr64(ctx, fp0, ft);
1180
            tcg_temp_free_i64(fp0);
1181
        }
1182
        opn = "ldc1";
1183
        break;
1184
    case OPC_SDC1:
1185
        {
1186
            TCGv_i64 fp0 = tcg_temp_new_i64();
1187

    
1188
            gen_load_fpr64(ctx, fp0, ft);
1189
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1190
            tcg_temp_free_i64(fp0);
1191
        }
1192
        opn = "sdc1";
1193
        break;
1194
    default:
1195
        MIPS_INVAL(opn);
1196
        generate_exception(ctx, EXCP_RI);
1197
        goto out;
1198
    }
1199
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1200
 out:
1201
    tcg_temp_free(t0);
1202
}
1203

    
1204
/* Arithmetic with immediate operand */
1205
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1206
                           int rt, int rs, int16_t imm)
1207
{
1208
    target_ulong uimm;
1209
    const char *opn = "imm arith";
1210
    TCGv t0 = tcg_temp_local_new();
1211

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

    
1260
            save_cpu_state(ctx, 1);
1261
            tcg_gen_ext32s_tl(r_tmp1, t0);
1262
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1263

    
1264
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1265
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1266
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1267
            tcg_temp_free(r_tmp2);
1268
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1269
            /* operands of same sign, result different sign */
1270
            generate_exception(ctx, EXCP_OVERFLOW);
1271
            gen_set_label(l1);
1272
            tcg_temp_free(r_tmp1);
1273

    
1274
            tcg_gen_ext32s_tl(t0, t0);
1275
        }
1276
        opn = "addi";
1277
        break;
1278
    case OPC_ADDIU:
1279
        tcg_gen_addi_tl(t0, t0, uimm);
1280
        tcg_gen_ext32s_tl(t0, t0);
1281
        opn = "addiu";
1282
        break;
1283
#if defined(TARGET_MIPS64)
1284
    case OPC_DADDI:
1285
        {
1286
            TCGv r_tmp1 = tcg_temp_new();
1287
            TCGv r_tmp2 = tcg_temp_new();
1288
            int l1 = gen_new_label();
1289

    
1290
            save_cpu_state(ctx, 1);
1291
            tcg_gen_mov_tl(r_tmp1, t0);
1292
            tcg_gen_addi_tl(t0, t0, uimm);
1293

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

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

    
1458
/* Arithmetic */
1459
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1460
                       int rd, int rs, int rt)
1461
{
1462
    const char *opn = "arith";
1463
    TCGv t0 = tcg_temp_local_new();
1464
    TCGv t1 = tcg_temp_local_new();
1465

    
1466
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1467
       && opc != OPC_DADD && opc != OPC_DSUB) {
1468
        /* If no destination, treat it as a NOP.
1469
           For add & sub, we must generate the overflow exception when needed. */
1470
        MIPS_DEBUG("NOP");
1471
        goto out;
1472
    }
1473
    gen_load_gpr(t0, rs);
1474
    /* Specialcase the conventional move operation. */
1475
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1476
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1477
        gen_store_gpr(t0, rd);
1478
        goto out;
1479
    }
1480
    gen_load_gpr(t1, rt);
1481
    switch (opc) {
1482
    case OPC_ADD:
1483
        {
1484
            TCGv r_tmp1 = tcg_temp_new();
1485
            TCGv r_tmp2 = tcg_temp_new();
1486
            int l1 = gen_new_label();
1487

    
1488
            save_cpu_state(ctx, 1);
1489
            tcg_gen_ext32s_tl(r_tmp1, t0);
1490
            tcg_gen_ext32s_tl(r_tmp2, t1);
1491
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1492

    
1493
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1494
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1495
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1496
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1497
            tcg_temp_free(r_tmp2);
1498
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1499
            /* operands of same sign, result different sign */
1500
            generate_exception(ctx, EXCP_OVERFLOW);
1501
            gen_set_label(l1);
1502
            tcg_temp_free(r_tmp1);
1503

    
1504
            tcg_gen_ext32s_tl(t0, t0);
1505
        }
1506
        opn = "add";
1507
        break;
1508
    case OPC_ADDU:
1509
        tcg_gen_add_tl(t0, t0, t1);
1510
        tcg_gen_ext32s_tl(t0, t0);
1511
        opn = "addu";
1512
        break;
1513
    case OPC_SUB:
1514
        {
1515
            TCGv r_tmp1 = tcg_temp_new();
1516
            TCGv r_tmp2 = tcg_temp_new();
1517
            int l1 = gen_new_label();
1518

    
1519
            save_cpu_state(ctx, 1);
1520
            tcg_gen_ext32s_tl(r_tmp1, t0);
1521
            tcg_gen_ext32s_tl(r_tmp2, t1);
1522
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1523

    
1524
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1525
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1526
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1527
            tcg_temp_free(r_tmp2);
1528
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1529
            /* operands of different sign, first operand and result different sign */
1530
            generate_exception(ctx, EXCP_OVERFLOW);
1531
            gen_set_label(l1);
1532
            tcg_temp_free(r_tmp1);
1533

    
1534
            tcg_gen_ext32s_tl(t0, t0);
1535
        }
1536
        opn = "sub";
1537
        break;
1538
    case OPC_SUBU:
1539
        tcg_gen_sub_tl(t0, t0, t1);
1540
        tcg_gen_ext32s_tl(t0, t0);
1541
        opn = "subu";
1542
        break;
1543
#if defined(TARGET_MIPS64)
1544
    case OPC_DADD:
1545
        {
1546
            TCGv r_tmp1 = tcg_temp_new();
1547
            TCGv r_tmp2 = tcg_temp_new();
1548
            int l1 = gen_new_label();
1549

    
1550
            save_cpu_state(ctx, 1);
1551
            tcg_gen_mov_tl(r_tmp1, t0);
1552
            tcg_gen_add_tl(t0, t0, t1);
1553

    
1554
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1555
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1556
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1557
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1558
            tcg_temp_free(r_tmp2);
1559
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1560
            /* operands of same sign, result different sign */
1561
            generate_exception(ctx, EXCP_OVERFLOW);
1562
            gen_set_label(l1);
1563
            tcg_temp_free(r_tmp1);
1564
        }
1565
        opn = "dadd";
1566
        break;
1567
    case OPC_DADDU:
1568
        tcg_gen_add_tl(t0, t0, t1);
1569
        opn = "daddu";
1570
        break;
1571
    case OPC_DSUB:
1572
        {
1573
            TCGv r_tmp1 = tcg_temp_new();
1574
            TCGv r_tmp2 = tcg_temp_new();
1575
            int l1 = gen_new_label();
1576

    
1577
            save_cpu_state(ctx, 1);
1578
            tcg_gen_mov_tl(r_tmp1, t0);
1579
            tcg_gen_sub_tl(t0, t0, t1);
1580

    
1581
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1582
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1583
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1584
            tcg_temp_free(r_tmp2);
1585
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1586
            /* operands of different sign, first operand and result different sign */
1587
            generate_exception(ctx, EXCP_OVERFLOW);
1588
            gen_set_label(l1);
1589
            tcg_temp_free(r_tmp1);
1590
        }
1591
        opn = "dsub";
1592
        break;
1593
    case OPC_DSUBU:
1594
        tcg_gen_sub_tl(t0, t0, t1);
1595
        opn = "dsubu";
1596
        break;
1597
#endif
1598
    case OPC_SLT:
1599
        gen_op_lt(t0, t0, t1);
1600
        opn = "slt";
1601
        break;
1602
    case OPC_SLTU:
1603
        gen_op_ltu(t0, t0, t1);
1604
        opn = "sltu";
1605
        break;
1606
    case OPC_AND:
1607
        tcg_gen_and_tl(t0, t0, t1);
1608
        opn = "and";
1609
        break;
1610
    case OPC_NOR:
1611
        tcg_gen_nor_tl(t0, t0, t1);
1612
        opn = "nor";
1613
        break;
1614
    case OPC_OR:
1615
        tcg_gen_or_tl(t0, t0, t1);
1616
        opn = "or";
1617
        break;
1618
    case OPC_XOR:
1619
        tcg_gen_xor_tl(t0, t0, t1);
1620
        opn = "xor";
1621
        break;
1622
    case OPC_MUL:
1623
        tcg_gen_mul_tl(t0, t0, t1);
1624
        tcg_gen_ext32s_tl(t0, t0);
1625
        opn = "mul";
1626
        break;
1627
    case OPC_MOVN:
1628
        {
1629
            int l1 = gen_new_label();
1630

    
1631
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1632
            gen_store_gpr(t0, rd);
1633
            gen_set_label(l1);
1634
        }
1635
        opn = "movn";
1636
        goto print;
1637
    case OPC_MOVZ:
1638
        {
1639
            int l1 = gen_new_label();
1640

    
1641
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1642
            gen_store_gpr(t0, rd);
1643
            gen_set_label(l1);
1644
        }
1645
        opn = "movz";
1646
        goto print;
1647
    case OPC_SLLV:
1648
        tcg_gen_andi_tl(t0, t0, 0x1f);
1649
        tcg_gen_shl_tl(t0, t1, t0);
1650
        tcg_gen_ext32s_tl(t0, t0);
1651
        opn = "sllv";
1652
        break;
1653
    case OPC_SRAV:
1654
        tcg_gen_ext32s_tl(t1, t1);
1655
        tcg_gen_andi_tl(t0, t0, 0x1f);
1656
        tcg_gen_sar_tl(t0, t1, t0);
1657
        opn = "srav";
1658
        break;
1659
    case OPC_SRLV:
1660
        switch ((ctx->opcode >> 6) & 0x1f) {
1661
        case 0:
1662
            tcg_gen_ext32u_tl(t1, t1);
1663
            tcg_gen_andi_tl(t0, t0, 0x1f);
1664
            tcg_gen_shr_tl(t0, t1, t0);
1665
            tcg_gen_ext32s_tl(t0, t0);
1666
            opn = "srlv";
1667
            break;
1668
        case 1:
1669
            /* rotrv is decoded as srlv on non-R2 CPUs */
1670
            if (env->insn_flags & ISA_MIPS32R2) {
1671
                int l1 = gen_new_label();
1672
                int l2 = gen_new_label();
1673

    
1674
                tcg_gen_andi_tl(t0, t0, 0x1f);
1675
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1676
                {
1677
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1678
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1679

    
1680
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1681
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1682
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1683
                    tcg_temp_free_i32(r_tmp1);
1684
                    tcg_temp_free_i32(r_tmp2);
1685
                    tcg_gen_br(l2);
1686
                }
1687
                gen_set_label(l1);
1688
                tcg_gen_mov_tl(t0, t1);
1689
                gen_set_label(l2);
1690
                opn = "rotrv";
1691
            } else {
1692
                tcg_gen_ext32u_tl(t1, t1);
1693
                tcg_gen_andi_tl(t0, t0, 0x1f);
1694
                tcg_gen_shr_tl(t0, t1, t0);
1695
                tcg_gen_ext32s_tl(t0, t0);
1696
                opn = "srlv";
1697
            }
1698
            break;
1699
        default:
1700
            MIPS_INVAL("invalid srlv flag");
1701
            generate_exception(ctx, EXCP_RI);
1702
            break;
1703
        }
1704
        break;
1705
#if defined(TARGET_MIPS64)
1706
    case OPC_DSLLV:
1707
        tcg_gen_andi_tl(t0, t0, 0x3f);
1708
        tcg_gen_shl_tl(t0, t1, t0);
1709
        opn = "dsllv";
1710
        break;
1711
    case OPC_DSRAV:
1712
        tcg_gen_andi_tl(t0, t0, 0x3f);
1713
        tcg_gen_sar_tl(t0, t1, t0);
1714
        opn = "dsrav";
1715
        break;
1716
    case OPC_DSRLV:
1717
        switch ((ctx->opcode >> 6) & 0x1f) {
1718
        case 0:
1719
            tcg_gen_andi_tl(t0, t0, 0x3f);
1720
            tcg_gen_shr_tl(t0, t1, t0);
1721
            opn = "dsrlv";
1722
            break;
1723
        case 1:
1724
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1725
            if (env->insn_flags & ISA_MIPS32R2) {
1726
                int l1 = gen_new_label();
1727
                int l2 = gen_new_label();
1728

    
1729
                tcg_gen_andi_tl(t0, t0, 0x3f);
1730
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1731
                {
1732
                    tcg_gen_rotr_tl(t0, t1, t0);
1733
                    tcg_gen_br(l2);
1734
                }
1735
                gen_set_label(l1);
1736
                tcg_gen_mov_tl(t0, t1);
1737
                gen_set_label(l2);
1738
                opn = "drotrv";
1739
            } else {
1740
                tcg_gen_andi_tl(t0, t0, 0x3f);
1741
                tcg_gen_shr_tl(t0, t1, t0);
1742
                opn = "dsrlv";
1743
            }
1744
            break;
1745
        default:
1746
            MIPS_INVAL("invalid dsrlv flag");
1747
            generate_exception(ctx, EXCP_RI);
1748
            break;
1749
        }
1750
        break;
1751
#endif
1752
    default:
1753
        MIPS_INVAL(opn);
1754
        generate_exception(ctx, EXCP_RI);
1755
        goto out;
1756
    }
1757
    gen_store_gpr(t0, rd);
1758
 print:
1759
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1760
 out:
1761
    tcg_temp_free(t0);
1762
    tcg_temp_free(t1);
1763
}
1764

    
1765
/* Arithmetic on HI/LO registers */
1766
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1767
{
1768
    const char *opn = "hilo";
1769

    
1770
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1771
        /* Treat as NOP. */
1772
        MIPS_DEBUG("NOP");
1773
        return;
1774
    }
1775
    switch (opc) {
1776
    case OPC_MFHI:
1777
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1778
        opn = "mfhi";
1779
        break;
1780
    case OPC_MFLO:
1781
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1782
        opn = "mflo";
1783
        break;
1784
    case OPC_MTHI:
1785
        if (reg != 0)
1786
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1787
        else
1788
            tcg_gen_movi_tl(cpu_HI[0], 0);
1789
        opn = "mthi";
1790
        break;
1791
    case OPC_MTLO:
1792
        if (reg != 0)
1793
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1794
        else
1795
            tcg_gen_movi_tl(cpu_LO[0], 0);
1796
        opn = "mtlo";
1797
        break;
1798
    default:
1799
        MIPS_INVAL(opn);
1800
        generate_exception(ctx, EXCP_RI);
1801
        return;
1802
    }
1803
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1804
}
1805

    
1806
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1807
                        int rs, int rt)
1808
{
1809
    const char *opn = "mul/div";
1810
    TCGv t0 = tcg_temp_local_new();
1811
    TCGv t1 = tcg_temp_local_new();
1812

    
1813
    gen_load_gpr(t0, rs);
1814
    gen_load_gpr(t1, rt);
1815
    switch (opc) {
1816
    case OPC_DIV:
1817
        {
1818
            int l1 = gen_new_label();
1819

    
1820
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1821
            {
1822
                int l2 = gen_new_label();
1823
                TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
1824
                TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
1825
                TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
1826

    
1827
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1828
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1829
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
1830
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
1831
                tcg_gen_ext32s_tl(cpu_LO[0], t0);
1832
                tcg_gen_movi_tl(cpu_HI[0], 0);
1833
                tcg_gen_br(l1);
1834
                gen_set_label(l2);
1835
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1836
                tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
1837
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1838
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
1839
                tcg_temp_free_i32(r_tmp1);
1840
                tcg_temp_free_i32(r_tmp2);
1841
                tcg_temp_free_i32(r_tmp3);
1842
            }
1843
            gen_set_label(l1);
1844
        }
1845
        opn = "div";
1846
        break;
1847
    case OPC_DIVU:
1848
        {
1849
            int l1 = gen_new_label();
1850

    
1851
            tcg_gen_ext32s_tl(t1, t1);
1852
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1853
            {
1854
                TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1855
                TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1856
                TCGv_i32 r_tmp3 = tcg_temp_new_i32();
1857

    
1858
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1859
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1860
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1861
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1862
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1863
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
1864
                tcg_temp_free_i32(r_tmp1);
1865
                tcg_temp_free_i32(r_tmp2);
1866
                tcg_temp_free_i32(r_tmp3);
1867
            }
1868
            gen_set_label(l1);
1869
        }
1870
        opn = "divu";
1871
        break;
1872
    case OPC_MULT:
1873
        {
1874
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1875
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1876

    
1877
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1878
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1879
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1880
            tcg_temp_free_i64(r_tmp2);
1881
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1882
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1883
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1884
            tcg_temp_free_i64(r_tmp1);
1885
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1886
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1887
        }
1888
        opn = "mult";
1889
        break;
1890
    case OPC_MULTU:
1891
        {
1892
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1893
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1894

    
1895
            tcg_gen_ext32u_tl(t0, t0);
1896
            tcg_gen_ext32u_tl(t1, t1);
1897
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1898
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1899
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1900
            tcg_temp_free_i64(r_tmp2);
1901
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1902
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1903
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1904
            tcg_temp_free_i64(r_tmp1);
1905
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1906
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1907
        }
1908
        opn = "multu";
1909
        break;
1910
#if defined(TARGET_MIPS64)
1911
    case OPC_DDIV:
1912
        {
1913
            int l1 = gen_new_label();
1914

    
1915
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1916
            {
1917
                int l2 = gen_new_label();
1918

    
1919
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1920
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1921
                tcg_gen_mov_tl(cpu_LO[0], t0);
1922
                tcg_gen_movi_tl(cpu_HI[0], 0);
1923
                tcg_gen_br(l1);
1924
                gen_set_label(l2);
1925
                tcg_gen_div_i64(cpu_LO[0], t0, t1);
1926
                tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1927
            }
1928
            gen_set_label(l1);
1929
        }
1930
        opn = "ddiv";
1931
        break;
1932
    case OPC_DDIVU:
1933
        {
1934
            int l1 = gen_new_label();
1935

    
1936
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1937
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1938
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1939
            gen_set_label(l1);
1940
        }
1941
        opn = "ddivu";
1942
        break;
1943
    case OPC_DMULT:
1944
        gen_helper_dmult(t0, t1);
1945
        opn = "dmult";
1946
        break;
1947
    case OPC_DMULTU:
1948
        gen_helper_dmultu(t0, t1);
1949
        opn = "dmultu";
1950
        break;
1951
#endif
1952
    case OPC_MADD:
1953
        {
1954
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1955
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1956

    
1957
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1958
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1959
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1960
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1961
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1962
            tcg_temp_free_i64(r_tmp2);
1963
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1964
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1965
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1966
            tcg_temp_free_i64(r_tmp1);
1967
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1968
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1969
        }
1970
        opn = "madd";
1971
        break;
1972
    case OPC_MADDU:
1973
       {
1974
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1975
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1976

    
1977
            tcg_gen_ext32u_tl(t0, t0);
1978
            tcg_gen_ext32u_tl(t1, t1);
1979
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1980
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1981
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1982
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1983
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1984
            tcg_temp_free_i64(r_tmp2);
1985
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1986
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1987
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1988
            tcg_temp_free_i64(r_tmp1);
1989
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1990
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1991
        }
1992
        opn = "maddu";
1993
        break;
1994
    case OPC_MSUB:
1995
        {
1996
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1997
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1998

    
1999
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2000
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2001
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2002
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2003
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2004
            tcg_temp_free_i64(r_tmp2);
2005
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2006
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2007
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2008
            tcg_temp_free_i64(r_tmp1);
2009
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2010
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2011
        }
2012
        opn = "msub";
2013
        break;
2014
    case OPC_MSUBU:
2015
        {
2016
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2017
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2018

    
2019
            tcg_gen_ext32u_tl(t0, t0);
2020
            tcg_gen_ext32u_tl(t1, t1);
2021
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2022
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2023
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2024
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2025
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2026
            tcg_temp_free_i64(r_tmp2);
2027
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2028
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2029
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2030
            tcg_temp_free_i64(r_tmp1);
2031
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2032
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2033
        }
2034
        opn = "msubu";
2035
        break;
2036
    default:
2037
        MIPS_INVAL(opn);
2038
        generate_exception(ctx, EXCP_RI);
2039
        goto out;
2040
    }
2041
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2042
 out:
2043
    tcg_temp_free(t0);
2044
    tcg_temp_free(t1);
2045
}
2046

    
2047
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2048
                            int rd, int rs, int rt)
2049
{
2050
    const char *opn = "mul vr54xx";
2051
    TCGv t0 = tcg_temp_new();
2052
    TCGv t1 = tcg_temp_new();
2053

    
2054
    gen_load_gpr(t0, rs);
2055
    gen_load_gpr(t1, rt);
2056

    
2057
    switch (opc) {
2058
    case OPC_VR54XX_MULS:
2059
        gen_helper_muls(t0, t0, t1);
2060
        opn = "muls";
2061
        break;
2062
    case OPC_VR54XX_MULSU:
2063
        gen_helper_mulsu(t0, t0, t1);
2064
        opn = "mulsu";
2065
        break;
2066
    case OPC_VR54XX_MACC:
2067
        gen_helper_macc(t0, t0, t1);
2068
        opn = "macc";
2069
        break;
2070
    case OPC_VR54XX_MACCU:
2071
        gen_helper_maccu(t0, t0, t1);
2072
        opn = "maccu";
2073
        break;
2074
    case OPC_VR54XX_MSAC:
2075
        gen_helper_msac(t0, t0, t1);
2076
        opn = "msac";
2077
        break;
2078
    case OPC_VR54XX_MSACU:
2079
        gen_helper_msacu(t0, t0, t1);
2080
        opn = "msacu";
2081
        break;
2082
    case OPC_VR54XX_MULHI:
2083
        gen_helper_mulhi(t0, t0, t1);
2084
        opn = "mulhi";
2085
        break;
2086
    case OPC_VR54XX_MULHIU:
2087
        gen_helper_mulhiu(t0, t0, t1);
2088
        opn = "mulhiu";
2089
        break;
2090
    case OPC_VR54XX_MULSHI:
2091
        gen_helper_mulshi(t0, t0, t1);
2092
        opn = "mulshi";
2093
        break;
2094
    case OPC_VR54XX_MULSHIU:
2095
        gen_helper_mulshiu(t0, t0, t1);
2096
        opn = "mulshiu";
2097
        break;
2098
    case OPC_VR54XX_MACCHI:
2099
        gen_helper_macchi(t0, t0, t1);
2100
        opn = "macchi";
2101
        break;
2102
    case OPC_VR54XX_MACCHIU:
2103
        gen_helper_macchiu(t0, t0, t1);
2104
        opn = "macchiu";
2105
        break;
2106
    case OPC_VR54XX_MSACHI:
2107
        gen_helper_msachi(t0, t0, t1);
2108
        opn = "msachi";
2109
        break;
2110
    case OPC_VR54XX_MSACHIU:
2111
        gen_helper_msachiu(t0, t0, t1);
2112
        opn = "msachiu";
2113
        break;
2114
    default:
2115
        MIPS_INVAL("mul vr54xx");
2116
        generate_exception(ctx, EXCP_RI);
2117
        goto out;
2118
    }
2119
    gen_store_gpr(t0, rd);
2120
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2121

    
2122
 out:
2123
    tcg_temp_free(t0);
2124
    tcg_temp_free(t1);
2125
}
2126

    
2127
static void gen_cl (DisasContext *ctx, uint32_t opc,
2128
                    int rd, int rs)
2129
{
2130
    const char *opn = "CLx";
2131
    TCGv t0;
2132

    
2133
    if (rd == 0) {
2134
        /* Treat as NOP. */
2135
        MIPS_DEBUG("NOP");
2136
        return;
2137
    }
2138
    t0 = tcg_temp_new();
2139
    gen_load_gpr(t0, rs);
2140
    switch (opc) {
2141
    case OPC_CLO:
2142
        gen_helper_clo(cpu_gpr[rd], t0);
2143
        opn = "clo";
2144
        break;
2145
    case OPC_CLZ:
2146
        gen_helper_clz(cpu_gpr[rd], t0);
2147
        opn = "clz";
2148
        break;
2149
#if defined(TARGET_MIPS64)
2150
    case OPC_DCLO:
2151
        gen_helper_dclo(cpu_gpr[rd], t0);
2152
        opn = "dclo";
2153
        break;
2154
    case OPC_DCLZ:
2155
        gen_helper_dclz(cpu_gpr[rd], t0);
2156
        opn = "dclz";
2157
        break;
2158
#endif
2159
    }
2160
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2161
    tcg_temp_free(t0);
2162
}
2163

    
2164
/* Traps */
2165
static void gen_trap (DisasContext *ctx, uint32_t opc,
2166
                      int rs, int rt, int16_t imm)
2167
{
2168
    int cond;
2169
    TCGv t0 = tcg_temp_new();
2170
    TCGv t1 = tcg_temp_new();
2171

    
2172
    cond = 0;
2173
    /* Load needed operands */
2174
    switch (opc) {
2175
    case OPC_TEQ:
2176
    case OPC_TGE:
2177
    case OPC_TGEU:
2178
    case OPC_TLT:
2179
    case OPC_TLTU:
2180
    case OPC_TNE:
2181
        /* Compare two registers */
2182
        if (rs != rt) {
2183
            gen_load_gpr(t0, rs);
2184
            gen_load_gpr(t1, rt);
2185
            cond = 1;
2186
        }
2187
        break;
2188
    case OPC_TEQI:
2189
    case OPC_TGEI:
2190
    case OPC_TGEIU:
2191
    case OPC_TLTI:
2192
    case OPC_TLTIU:
2193
    case OPC_TNEI:
2194
        /* Compare register to immediate */
2195
        if (rs != 0 || imm != 0) {
2196
            gen_load_gpr(t0, rs);
2197
            tcg_gen_movi_tl(t1, (int32_t)imm);
2198
            cond = 1;
2199
        }
2200
        break;
2201
    }
2202
    if (cond == 0) {
2203
        switch (opc) {
2204
        case OPC_TEQ:   /* rs == rs */
2205
        case OPC_TEQI:  /* r0 == 0  */
2206
        case OPC_TGE:   /* rs >= rs */
2207
        case OPC_TGEI:  /* r0 >= 0  */
2208
        case OPC_TGEU:  /* rs >= rs unsigned */
2209
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2210
            /* Always trap */
2211
            generate_exception(ctx, EXCP_TRAP);
2212
            break;
2213
        case OPC_TLT:   /* rs < rs           */
2214
        case OPC_TLTI:  /* r0 < 0            */
2215
        case OPC_TLTU:  /* rs < rs unsigned  */
2216
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2217
        case OPC_TNE:   /* rs != rs          */
2218
        case OPC_TNEI:  /* r0 != 0           */
2219
            /* Never trap: treat as NOP. */
2220
            break;
2221
        }
2222
    } else {
2223
        int l1 = gen_new_label();
2224

    
2225
        switch (opc) {
2226
        case OPC_TEQ:
2227
        case OPC_TEQI:
2228
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2229
            break;
2230
        case OPC_TGE:
2231
        case OPC_TGEI:
2232
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2233
            break;
2234
        case OPC_TGEU:
2235
        case OPC_TGEIU:
2236
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2237
            break;
2238
        case OPC_TLT:
2239
        case OPC_TLTI:
2240
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2241
            break;
2242
        case OPC_TLTU:
2243
        case OPC_TLTIU:
2244
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2245
            break;
2246
        case OPC_TNE:
2247
        case OPC_TNEI:
2248
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2249
            break;
2250
        }
2251
        generate_exception(ctx, EXCP_TRAP);
2252
        gen_set_label(l1);
2253
    }
2254
    tcg_temp_free(t0);
2255
    tcg_temp_free(t1);
2256
}
2257

    
2258
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2259
{
2260
    TranslationBlock *tb;
2261
    tb = ctx->tb;
2262
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2263
        tcg_gen_goto_tb(n);
2264
        gen_save_pc(dest);
2265
        tcg_gen_exit_tb((long)tb + n);
2266
    } else {
2267
        gen_save_pc(dest);
2268
        tcg_gen_exit_tb(0);
2269
    }
2270
}
2271

    
2272
/* Branches (before delay slot) */
2273
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2274
                                int rs, int rt, int32_t offset)
2275
{
2276
    target_ulong btgt = -1;
2277
    int blink = 0;
2278
    int bcond_compute = 0;
2279
    TCGv t0 = tcg_temp_new();
2280
    TCGv t1 = tcg_temp_new();
2281

    
2282
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2283
#ifdef MIPS_DEBUG_DISAS
2284
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2285
#endif
2286
        generate_exception(ctx, EXCP_RI);
2287
        goto out;
2288
    }
2289

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

    
2498
    ctx->btarget = btgt;
2499
    if (blink > 0) {
2500
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2501
    }
2502

    
2503
 out:
2504
    tcg_temp_free(t0);
2505
    tcg_temp_free(t1);
2506
}
2507

    
2508
/* special3 bitfield operations */
2509
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2510
                        int rs, int lsb, int msb)
2511
{
2512
    TCGv t0 = tcg_temp_new();
2513
    TCGv t1 = tcg_temp_new();
2514
    target_ulong mask;
2515

    
2516
    gen_load_gpr(t1, rs);
2517
    switch (opc) {
2518
    case OPC_EXT:
2519
        if (lsb + msb > 31)
2520
            goto fail;
2521
        tcg_gen_shri_tl(t0, t1, lsb);
2522
        if (msb != 31) {
2523
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2524
        } else {
2525
            tcg_gen_ext32s_tl(t0, t0);
2526
        }
2527
        break;
2528
#if defined(TARGET_MIPS64)
2529
    case OPC_DEXTM:
2530
        tcg_gen_shri_tl(t0, t1, lsb);
2531
        if (msb != 31) {
2532
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2533
        }
2534
        break;
2535
    case OPC_DEXTU:
2536
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2537
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2538
        break;
2539
    case OPC_DEXT:
2540
        tcg_gen_shri_tl(t0, t1, lsb);
2541
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2542
        break;
2543
#endif
2544
    case OPC_INS:
2545
        if (lsb > msb)
2546
            goto fail;
2547
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2548
        gen_load_gpr(t0, rt);
2549
        tcg_gen_andi_tl(t0, t0, ~mask);
2550
        tcg_gen_shli_tl(t1, t1, lsb);
2551
        tcg_gen_andi_tl(t1, t1, mask);
2552
        tcg_gen_or_tl(t0, t0, t1);
2553
        tcg_gen_ext32s_tl(t0, t0);
2554
        break;
2555
#if defined(TARGET_MIPS64)
2556
    case OPC_DINSM:
2557
        if (lsb > msb)
2558
            goto fail;
2559
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2560
        gen_load_gpr(t0, rt);
2561
        tcg_gen_andi_tl(t0, t0, ~mask);
2562
        tcg_gen_shli_tl(t1, t1, lsb);
2563
        tcg_gen_andi_tl(t1, t1, mask);
2564
        tcg_gen_or_tl(t0, t0, t1);
2565
        break;
2566
    case OPC_DINSU:
2567
        if (lsb > msb)
2568
            goto fail;
2569
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2570
        gen_load_gpr(t0, rt);
2571
        tcg_gen_andi_tl(t0, t0, ~mask);
2572
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2573
        tcg_gen_andi_tl(t1, t1, mask);
2574
        tcg_gen_or_tl(t0, t0, t1);
2575
        break;
2576
    case OPC_DINS:
2577
        if (lsb > msb)
2578
            goto fail;
2579
        gen_load_gpr(t0, rt);
2580
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2581
        gen_load_gpr(t0, rt);
2582
        tcg_gen_andi_tl(t0, t0, ~mask);
2583
        tcg_gen_shli_tl(t1, t1, lsb);
2584
        tcg_gen_andi_tl(t1, t1, mask);
2585
        tcg_gen_or_tl(t0, t0, t1);
2586
        break;
2587
#endif
2588
    default:
2589
fail:
2590
        MIPS_INVAL("bitops");
2591
        generate_exception(ctx, EXCP_RI);
2592
        tcg_temp_free(t0);
2593
        tcg_temp_free(t1);
2594
        return;
2595
    }
2596
    gen_store_gpr(t0, rt);
2597
    tcg_temp_free(t0);
2598
    tcg_temp_free(t1);
2599
}
2600

    
2601
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2602
{
2603
    TCGv t0;
2604

    
2605
    if (rd == 0) {
2606
        /* If no destination, treat it as a NOP. */
2607
        MIPS_DEBUG("NOP");
2608
        return;
2609
    }
2610

    
2611
    t0 = tcg_temp_new();
2612
    gen_load_gpr(t0, rt);
2613
    switch (op2) {
2614
    case OPC_WSBH:
2615
        {
2616
            TCGv t1 = tcg_temp_new();
2617

    
2618
            tcg_gen_shri_tl(t1, t0, 8);
2619
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2620
            tcg_gen_shli_tl(t0, t0, 8);
2621
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2622
            tcg_gen_or_tl(t0, t0, t1);
2623
            tcg_temp_free(t1);
2624
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2625
        }
2626
        break;
2627
    case OPC_SEB:
2628
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2629
        break;
2630
    case OPC_SEH:
2631
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2632
        break;
2633
#if defined(TARGET_MIPS64)
2634
    case OPC_DSBH:
2635
        {
2636
            TCGv t1 = tcg_temp_new();
2637

    
2638
            tcg_gen_shri_tl(t1, t0, 8);
2639
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2640
            tcg_gen_shli_tl(t0, t0, 8);
2641
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2642
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2643
            tcg_temp_free(t1);
2644
        }
2645
        break;
2646
    case OPC_DSHD:
2647
        {
2648
            TCGv t1 = tcg_temp_new();
2649

    
2650
            tcg_gen_shri_tl(t1, t0, 16);
2651
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2652
            tcg_gen_shli_tl(t0, t0, 16);
2653
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2654
            tcg_gen_or_tl(t0, t0, t1);
2655
            tcg_gen_shri_tl(t1, t0, 32);
2656
            tcg_gen_shli_tl(t0, t0, 32);
2657
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2658
            tcg_temp_free(t1);
2659
        }
2660
        break;
2661
#endif
2662
    default:
2663
        MIPS_INVAL("bsfhl");
2664
        generate_exception(ctx, EXCP_RI);
2665
        tcg_temp_free(t0);
2666
        return;
2667
    }
2668
    tcg_temp_free(t0);
2669
}
2670

    
2671
#ifndef CONFIG_USER_ONLY
2672
/* CP0 (MMU and control) */
2673
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2674
{
2675
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2676

    
2677
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2678
    tcg_gen_ext_i32_tl(t, r_tmp);
2679
    tcg_temp_free_i32(r_tmp);
2680
}
2681

    
2682
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2683
{
2684
    tcg_gen_ld_tl(t, cpu_env, off);
2685
    tcg_gen_ext32s_tl(t, t);
2686
}
2687

    
2688
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2689
{
2690
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2691

    
2692
    tcg_gen_trunc_tl_i32(r_tmp, t);
2693
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2694
    tcg_temp_free_i32(r_tmp);
2695
}
2696

    
2697
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2698
{
2699
    tcg_gen_ext32s_tl(t, t);
2700
    tcg_gen_st_tl(t, cpu_env, off);
2701
}
2702

    
2703
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2704
{
2705
    const char *rn = "invalid";
2706

    
2707
    if (sel != 0)
2708
        check_insn(env, ctx, ISA_MIPS32);
2709

    
2710
    switch (reg) {
2711
    case 0:
2712
        switch (sel) {
2713
        case 0:
2714
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
2715
            rn = "Index";
2716
            break;
2717
        case 1:
2718
            check_insn(env, ctx, ASE_MT);
2719
            gen_helper_mfc0_mvpcontrol(t0);
2720
            rn = "MVPControl";
2721
            break;
2722
        case 2:
2723
            check_insn(env, ctx, ASE_MT);
2724
            gen_helper_mfc0_mvpconf0(t0);
2725
            rn = "MVPConf0";
2726
            break;
2727
        case 3:
2728
            check_insn(env, ctx, ASE_MT);
2729
            gen_helper_mfc0_mvpconf1(t0);
2730
            rn = "MVPConf1";
2731
            break;
2732
        default:
2733
            goto die;
2734
        }
2735
        break;
2736
    case 1:
2737
        switch (sel) {
2738
        case 0:
2739
            gen_helper_mfc0_random(t0);
2740
            rn = "Random";
2741
            break;
2742
        case 1:
2743
            check_insn(env, ctx, ASE_MT);
2744
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
2745
            rn = "VPEControl";
2746
            break;
2747
        case 2:
2748
            check_insn(env, ctx, ASE_MT);
2749
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
2750
            rn = "VPEConf0";
2751
            break;
2752
        case 3:
2753
            check_insn(env, ctx, ASE_MT);
2754
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
2755
            rn = "VPEConf1";
2756
            break;
2757
        case 4:
2758
            check_insn(env, ctx, ASE_MT);
2759
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask));
2760
            rn = "YQMask";
2761
            break;
2762
        case 5:
2763
            check_insn(env, ctx, ASE_MT);
2764
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule));
2765
            rn = "VPESchedule";
2766
            break;
2767
        case 6:
2768
            check_insn(env, ctx, ASE_MT);
2769
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack));
2770
            rn = "VPEScheFBack";
2771
            break;
2772
        case 7:
2773
            check_insn(env, ctx, ASE_MT);
2774
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
2775
            rn = "VPEOpt";
2776
            break;
2777
        default:
2778
            goto die;
2779
        }
2780
        break;
2781
    case 2:
2782
        switch (sel) {
2783
        case 0:
2784
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2785
            tcg_gen_ext32s_tl(t0, t0);
2786
            rn = "EntryLo0";
2787
            break;
2788
        case 1:
2789
            check_insn(env, ctx, ASE_MT);
2790
            gen_helper_mfc0_tcstatus(t0);
2791
            rn = "TCStatus";
2792
            break;
2793
        case 2:
2794
            check_insn(env, ctx, ASE_MT);
2795
            gen_helper_mfc0_tcbind(t0);
2796
            rn = "TCBind";
2797
            break;
2798
        case 3:
2799
            check_insn(env, ctx, ASE_MT);
2800
            gen_helper_mfc0_tcrestart(t0);
2801
            rn = "TCRestart";
2802
            break;
2803
        case 4:
2804
            check_insn(env, ctx, ASE_MT);
2805
            gen_helper_mfc0_tchalt(t0);
2806
            rn = "TCHalt";
2807
            break;
2808
        case 5:
2809
            check_insn(env, ctx, ASE_MT);
2810
            gen_helper_mfc0_tccontext(t0);
2811
            rn = "TCContext";
2812
            break;
2813
        case 6:
2814
            check_insn(env, ctx, ASE_MT);
2815
            gen_helper_mfc0_tcschedule(t0);
2816
            rn = "TCSchedule";
2817
            break;
2818
        case 7:
2819
            check_insn(env, ctx, ASE_MT);
2820
            gen_helper_mfc0_tcschefback(t0);
2821
            rn = "TCScheFBack";
2822
            break;
2823
        default:
2824
            goto die;
2825
        }
2826
        break;
2827
    case 3:
2828
        switch (sel) {
2829
        case 0:
2830
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
2831
            tcg_gen_ext32s_tl(t0, t0);
2832
            rn = "EntryLo1";
2833
            break;
2834
        default:
2835
            goto die;
2836
        }
2837
        break;
2838
    case 4:
2839
        switch (sel) {
2840
        case 0:
2841
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
2842
            tcg_gen_ext32s_tl(t0, t0);
2843
            rn = "Context";
2844
            break;
2845
        case 1:
2846
//            gen_helper_mfc0_contextconfig(t0); /* SmartMIPS ASE */
2847
            rn = "ContextConfig";
2848
//            break;
2849
        default:
2850
            goto die;
2851
        }
2852
        break;
2853
    case 5:
2854
        switch (sel) {
2855
        case 0:
2856
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
2857
            rn = "PageMask";
2858
            break;
2859
        case 1:
2860
            check_insn(env, ctx, ISA_MIPS32R2);
2861
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
2862
            rn = "PageGrain";
2863
            break;
2864
        default:
2865
            goto die;
2866
        }
2867
        break;
2868
    case 6:
2869
        switch (sel) {
2870
        case 0:
2871
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
2872
            rn = "Wired";
2873
            break;
2874
        case 1:
2875
            check_insn(env, ctx, ISA_MIPS32R2);
2876
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
2877
            rn = "SRSConf0";
2878
            break;
2879
        case 2:
2880
            check_insn(env, ctx, ISA_MIPS32R2);
2881
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
2882
            rn = "SRSConf1";
2883
            break;
2884
        case 3:
2885
            check_insn(env, ctx, ISA_MIPS32R2);
2886
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
2887
            rn = "SRSConf2";
2888
            break;
2889
        case 4:
2890
            check_insn(env, ctx, ISA_MIPS32R2);
2891
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
2892
            rn = "SRSConf3";
2893
            break;
2894
        case 5:
2895
            check_insn(env, ctx, ISA_MIPS32R2);
2896
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
2897
            rn = "SRSConf4";
2898
            break;
2899
        default:
2900
            goto die;
2901
        }
2902
        break;
2903
    case 7:
2904
        switch (sel) {
2905
        case 0:
2906
            check_insn(env, ctx, ISA_MIPS32R2);
2907
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
2908
            rn = "HWREna";
2909
            break;
2910
        default:
2911
            goto die;
2912
        }
2913
        break;
2914
    case 8:
2915
        switch (sel) {
2916
        case 0:
2917
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
2918
            tcg_gen_ext32s_tl(t0, t0);
2919
            rn = "BadVAddr";
2920
            break;
2921
        default:
2922
            goto die;
2923
       }
2924
        break;
2925
    case 9:
2926
        switch (sel) {
2927
        case 0:
2928
            /* Mark as an IO operation because we read the time.  */
2929
            if (use_icount)
2930
                gen_io_start();
2931
            gen_helper_mfc0_count(t0);
2932
            if (use_icount) {
2933
                gen_io_end();
2934
                ctx->bstate = BS_STOP;
2935
            }
2936
            rn = "Count";
2937
            break;
2938
        /* 6,7 are implementation dependent */
2939
        default:
2940
            goto die;
2941
        }
2942
        break;
2943
    case 10:
2944
        switch (sel) {
2945
        case 0:
2946
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
2947
            tcg_gen_ext32s_tl(t0, t0);
2948
            rn = "EntryHi";
2949
            break;
2950
        default:
2951
            goto die;
2952
        }
2953
        break;
2954
    case 11:
2955
        switch (sel) {
2956
        case 0:
2957
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
2958
            rn = "Compare";
2959
            break;
2960
        /* 6,7 are implementation dependent */
2961
        default:
2962
            goto die;
2963
        }
2964
        break;
2965
    case 12:
2966
        switch (sel) {
2967
        case 0:
2968
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
2969
            rn = "Status";
2970
            break;
2971
        case 1:
2972
            check_insn(env, ctx, ISA_MIPS32R2);
2973
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
2974
            rn = "IntCtl";
2975
            break;
2976
        case 2:
2977
            check_insn(env, ctx, ISA_MIPS32R2);
2978
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
2979
            rn = "SRSCtl";
2980
            break;
2981
        case 3:
2982
            check_insn(env, ctx, ISA_MIPS32R2);
2983
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
2984
            rn = "SRSMap";
2985
            break;
2986
        default:
2987
            goto die;
2988
       }
2989
        break;
2990
    case 13:
2991
        switch (sel) {
2992
        case 0:
2993
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
2994
            rn = "Cause";
2995
            break;
2996
        default:
2997
            goto die;
2998
       }
2999
        break;
3000
    case 14:
3001
        switch (sel) {
3002
        case 0:
3003
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
3004
            tcg_gen_ext32s_tl(t0, t0);
3005
            rn = "EPC";
3006
            break;
3007
        default:
3008
            goto die;
3009
        }
3010
        break;
3011
    case 15:
3012
        switch (sel) {
3013
        case 0:
3014
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
3015
            rn = "PRid";
3016
            break;
3017
        case 1:
3018
            check_insn(env, ctx, ISA_MIPS32R2);
3019
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
3020
            rn = "EBase";
3021
            break;
3022
        default:
3023
            goto die;
3024
       }
3025
        break;
3026
    case 16:
3027
        switch (sel) {
3028
        case 0:
3029
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
3030
            rn = "Config";
3031
            break;
3032
        case 1:
3033
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
3034
            rn = "Config1";
3035
            break;
3036
        case 2:
3037
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
3038
            rn = "Config2";
3039
            break;
3040
        case 3:
3041
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
3042
            rn = "Config3";
3043
            break;
3044
        /* 4,5 are reserved */
3045
        /* 6,7 are implementation dependent */
3046
        case 6:
3047
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
3048
            rn = "Config6";
3049
            break;
3050
        case 7:
3051
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
3052
            rn = "Config7";
3053
            break;
3054
        default:
3055
            goto die;
3056
        }
3057
        break;
3058
    case 17:
3059
        switch (sel) {
3060
        case 0:
3061
            gen_helper_mfc0_lladdr(t0);
3062
            rn = "LLAddr";
3063
            break;
3064
        default:
3065
            goto die;
3066
        }
3067
        break;
3068
    case 18:
3069
        switch (sel) {
3070
        case 0 ... 7:
3071
            gen_helper_1i(mfc0_watchlo, t0, sel);
3072
            rn = "WatchLo";
3073
            break;
3074
        default:
3075
            goto die;
3076
        }
3077
        break;
3078
    case 19:
3079
        switch (sel) {
3080
        case 0 ...7:
3081
            gen_helper_1i(mfc0_watchhi, t0, sel);
3082
            rn = "WatchHi";
3083
            break;
3084
        default:
3085
            goto die;
3086
        }
3087
        break;
3088
    case 20:
3089
        switch (sel) {
3090
        case 0:
3091
#if defined(TARGET_MIPS64)
3092
            check_insn(env, ctx, ISA_MIPS3);
3093
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
3094
            tcg_gen_ext32s_tl(t0, t0);
3095
            rn = "XContext";
3096
            break;
3097
#endif
3098
        default:
3099
            goto die;
3100
        }
3101
        break;
3102
    case 21:
3103
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3104
        switch (sel) {
3105
        case 0:
3106
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
3107
            rn = "Framemask";
3108
            break;
3109
        default:
3110
            goto die;
3111
        }
3112
        break;
3113
    case 22:
3114
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
3115
        rn = "'Diagnostic"; /* implementation dependent */
3116
        break;
3117
    case 23:
3118
        switch (sel) {
3119
        case 0:
3120
            gen_helper_mfc0_debug(t0); /* EJTAG support */
3121
            rn = "Debug";
3122
            break;
3123
        case 1:
3124
//            gen_helper_mfc0_tracecontrol(t0); /* PDtrace support */
3125
            rn = "TraceControl";
3126
//            break;
3127
        case 2:
3128
//            gen_helper_mfc0_tracecontrol2(t0); /* PDtrace support */
3129
            rn = "TraceControl2";
3130
//            break;
3131
        case 3:
3132
//            gen_helper_mfc0_usertracedata(t0); /* PDtrace support */
3133
            rn = "UserTraceData";
3134
//            break;
3135
        case 4:
3136
//            gen_helper_mfc0_tracebpc(t0); /* PDtrace support */
3137
            rn = "TraceBPC";
3138
//            break;
3139
        default:
3140
            goto die;
3141
        }
3142
        break;
3143
    case 24:
3144
        switch (sel) {
3145
        case 0:
3146
            /* EJTAG support */
3147
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
3148
            tcg_gen_ext32s_tl(t0, t0);
3149
            rn = "DEPC";
3150
            break;
3151
        default:
3152
            goto die;
3153
        }
3154
        break;
3155
    case 25:
3156
        switch (sel) {
3157
        case 0:
3158
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
3159
            rn = "Performance0";
3160
            break;
3161
        case 1:
3162
//            gen_helper_mfc0_performance1(t0);
3163
            rn = "Performance1";
3164
//            break;
3165
        case 2:
3166
//            gen_helper_mfc0_performance2(t0);
3167
            rn = "Performance2";
3168
//            break;
3169
        case 3:
3170
//            gen_helper_mfc0_performance3(t0);
3171
            rn = "Performance3";
3172
//            break;
3173
        case 4:
3174
//            gen_helper_mfc0_performance4(t0);
3175
            rn = "Performance4";
3176
//            break;
3177
        case 5:
3178
//            gen_helper_mfc0_performance5(t0);
3179
            rn = "Performance5";
3180
//            break;
3181
        case 6:
3182
//            gen_helper_mfc0_performance6(t0);
3183
            rn = "Performance6";
3184
//            break;
3185
        case 7:
3186
//            gen_helper_mfc0_performance7(t0);
3187
            rn = "Performance7";
3188
//            break;
3189
        default:
3190
            goto die;
3191
        }
3192
        break;
3193
    case 26:
3194
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
3195
        rn = "ECC";
3196
        break;
3197
    case 27:
3198
        switch (sel) {
3199
        case 0 ... 3:
3200
            tcg_gen_movi_tl(t0, 0); /* unimplemented */
3201
            rn = "CacheErr";
3202
            break;
3203
        default:
3204
            goto die;
3205
        }
3206
        break;
3207
    case 28:
3208
        switch (sel) {
3209
        case 0:
3210
        case 2:
3211
        case 4:
3212
        case 6:
3213
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
3214
            rn = "TagLo";
3215
            break;
3216
        case 1:
3217
        case 3:
3218
        case 5:
3219
        case 7:
3220
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
3221
            rn = "DataLo";
3222
            break;
3223
        default:
3224
            goto die;
3225
        }
3226
        break;
3227
    case 29:
3228
        switch (sel) {
3229
        case 0:
3230
        case 2:
3231
        case 4:
3232
        case 6:
3233
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
3234
            rn = "TagHi";
3235
            break;
3236
        case 1:
3237
        case 3:
3238
        case 5:
3239
        case 7:
3240
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
3241
            rn = "DataHi";
3242
            break;
3243
        default:
3244
            goto die;
3245
        }
3246
        break;
3247
    case 30:
3248
        switch (sel) {
3249
        case 0:
3250
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3251
            tcg_gen_ext32s_tl(t0, t0);
3252
            rn = "ErrorEPC";
3253
            break;
3254
        default:
3255
            goto die;
3256
        }
3257
        break;
3258
    case 31:
3259
        switch (sel) {
3260
        case 0:
3261
            /* EJTAG support */
3262
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
3263
            rn = "DESAVE";
3264
            break;
3265
        default:
3266
            goto die;
3267
        }
3268
        break;
3269
    default:
3270
       goto die;
3271
    }
3272
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3273
    return;
3274

    
3275
die:
3276
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3277
    generate_exception(ctx, EXCP_RI);
3278
}
3279

    
3280
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3281
{
3282
    const char *rn = "invalid";
3283

    
3284
    if (sel != 0)
3285
        check_insn(env, ctx, ISA_MIPS32);
3286

    
3287
    if (use_icount)
3288
        gen_io_start();
3289

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

    
3874
die:
3875
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3876
    generate_exception(ctx, EXCP_RI);
3877
}
3878

    
3879
#if defined(TARGET_MIPS64)
3880
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3881
{
3882
    const char *rn = "invalid";
3883

    
3884
    if (sel != 0)
3885
        check_insn(env, ctx, ISA_MIPS64);
3886

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

    
4441
die:
4442
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4443
    generate_exception(ctx, EXCP_RI);
4444
}
4445

    
4446
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4447
{
4448
    const char *rn = "invalid";
4449

    
4450
    if (sel != 0)
4451
        check_insn(env, ctx, ISA_MIPS64);
4452

    
4453
    if (use_icount)
4454
        gen_io_start();
4455

    
4456
    switch (reg) {
4457
    case 0:
4458
        switch (sel) {
4459
        case 0:
4460
            gen_helper_mtc0_index(t0);
4461
            rn = "Index";
4462
            break;
4463
        case 1:
4464
            check_insn(env, ctx, ASE_MT);
4465
            gen_helper_mtc0_mvpcontrol(t0);
4466
            rn = "MVPControl";
4467
            break;
4468
        case 2:
4469
            check_insn(env, ctx, ASE_MT);
4470
            /* ignored */
4471
            rn = "MVPConf0";
4472
            break;
4473
        case 3:
4474
            check_insn(env, ctx, ASE_MT);
4475
            /* ignored */
4476
            rn = "MVPConf1";
4477
            break;
4478
        default:
4479
            goto die;
4480
        }
4481
        break;
4482
    case 1:
4483
        switch (sel) {
4484
        case 0:
4485
            /* ignored */
4486
            rn = "Random";
4487
            break;
4488
        case 1:
4489
            check_insn(env, ctx, ASE_MT);
4490
            gen_helper_mtc0_vpecontrol(t0);
4491
            rn = "VPEControl";
4492
            break;
4493
        case 2:
4494
            check_insn(env, ctx, ASE_MT);
4495
            gen_helper_mtc0_vpeconf0(t0);
4496
            rn = "VPEConf0";
4497
            break;
4498
        case 3:
4499
            check_insn(env, ctx, ASE_MT);
4500
            gen_helper_mtc0_vpeconf1(t0);
4501
            rn = "VPEConf1";
4502
            break;
4503
        case 4:
4504
            check_insn(env, ctx, ASE_MT);
4505
            gen_helper_mtc0_yqmask(t0);
4506
            rn = "YQMask";
4507
            break;
4508
        case 5:
4509
            check_insn(env, ctx, ASE_MT);
4510
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4511
            rn = "VPESchedule";
4512
            break;
4513
        case 6:
4514
            check_insn(env, ctx, ASE_MT);
4515
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4516
            rn = "VPEScheFBack";
4517
            break;
4518
        case 7:
4519
            check_insn(env, ctx, ASE_MT);
4520
            gen_helper_mtc0_vpeopt(t0);
4521
            rn = "VPEOpt";
4522
            break;
4523
        default:
4524
            goto die;
4525
        }
4526
        break;
4527
    case 2:
4528
        switch (sel) {
4529
        case 0:
4530
            gen_helper_mtc0_entrylo0(t0);
4531
            rn = "EntryLo0";
4532
            break;
4533
        case 1:
4534
            check_insn(env, ctx, ASE_MT);
4535
            gen_helper_mtc0_tcstatus(t0);
4536
            rn = "TCStatus";
4537
            break;
4538
        case 2:
4539
            check_insn(env, ctx, ASE_MT);
4540
            gen_helper_mtc0_tcbind(t0);
4541
            rn = "TCBind";
4542
            break;
4543
        case 3:
4544
            check_insn(env, ctx, ASE_MT);
4545
            gen_helper_mtc0_tcrestart(t0);
4546
            rn = "TCRestart";
4547
            break;
4548
        case 4:
4549
            check_insn(env, ctx, ASE_MT);
4550
            gen_helper_mtc0_tchalt(t0);
4551
            rn = "TCHalt";
4552
            break;
4553
        case 5:
4554
            check_insn(env, ctx, ASE_MT);
4555
            gen_helper_mtc0_tccontext(t0);
4556
            rn = "TCContext";
4557
            break;
4558
        case 6:
4559
            check_insn(env, ctx, ASE_MT);
4560
            gen_helper_mtc0_tcschedule(t0);
4561
            rn = "TCSchedule";
4562
            break;
4563
        case 7:
4564
            check_insn(env, ctx, ASE_MT);
4565
            gen_helper_mtc0_tcschefback(t0);
4566
            rn = "TCScheFBack";
4567
            break;
4568
        default:
4569
            goto die;
4570
        }
4571
        break;
4572
    case 3:
4573
        switch (sel) {
4574
        case 0:
4575
            gen_helper_mtc0_entrylo1(t0);
4576
            rn = "EntryLo1";
4577
            break;
4578
        default:
4579
            goto die;
4580
        }
4581
        break;
4582
    case 4:
4583
        switch (sel) {
4584
        case 0:
4585
            gen_helper_mtc0_context(t0);
4586
            rn = "Context";
4587
            break;
4588
        case 1:
4589
//           gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4590
            rn = "ContextConfig";
4591
//           break;
4592
        default:
4593
            goto die;
4594
        }
4595
        break;
4596
    case 5:
4597
        switch (sel) {
4598
        case 0:
4599
            gen_helper_mtc0_pagemask(t0);
4600
            rn = "PageMask";
4601
            break;
4602
        case 1:
4603
            check_insn(env, ctx, ISA_MIPS32R2);
4604
            gen_helper_mtc0_pagegrain(t0);
4605
            rn = "PageGrain";
4606
            break;
4607
        default:
4608
            goto die;
4609
        }
4610
        break;
4611
    case 6:
4612
        switch (sel) {
4613
        case 0:
4614
            gen_helper_mtc0_wired(t0);
4615
            rn = "Wired";
4616
            break;
4617
        case 1:
4618
            check_insn(env, ctx, ISA_MIPS32R2);
4619
            gen_helper_mtc0_srsconf0(t0);
4620
            rn = "SRSConf0";
4621
            break;
4622
        case 2:
4623
            check_insn(env, ctx, ISA_MIPS32R2);
4624
            gen_helper_mtc0_srsconf1(t0);
4625
            rn = "SRSConf1";
4626
            break;
4627
        case 3:
4628
            check_insn(env, ctx, ISA_MIPS32R2);
4629
            gen_helper_mtc0_srsconf2(t0);
4630
            rn = "SRSConf2";
4631
            break;
4632
        case 4:
4633
            check_insn(env, ctx, ISA_MIPS32R2);
4634
            gen_helper_mtc0_srsconf3(t0);
4635
            rn = "SRSConf3";
4636
            break;
4637
        case 5:
4638
            check_insn(env, ctx, ISA_MIPS32R2);
4639
            gen_helper_mtc0_srsconf4(t0);
4640
            rn = "SRSConf4";
4641
            break;
4642
        default:
4643
            goto die;
4644
        }
4645
        break;
4646
    case 7:
4647
        switch (sel) {
4648
        case 0:
4649
            check_insn(env, ctx, ISA_MIPS32R2);
4650
            gen_helper_mtc0_hwrena(t0);
4651
            rn = "HWREna";
4652
            break;
4653
        default:
4654
            goto die;
4655
        }
4656
        break;
4657
    case 8:
4658
        /* ignored */
4659
        rn = "BadVAddr";
4660
        break;
4661
    case 9:
4662
        switch (sel) {
4663
        case 0:
4664
            gen_helper_mtc0_count(t0);
4665
            rn = "Count";
4666
            break;
4667
        /* 6,7 are implementation dependent */
4668
        default:
4669
            goto die;
4670
        }
4671
        /* Stop translation as we may have switched the execution mode */
4672
        ctx->bstate = BS_STOP;
4673
        break;
4674
    case 10:
4675
        switch (sel) {
4676
        case 0:
4677
            gen_helper_mtc0_entryhi(t0);
4678
            rn = "EntryHi";
4679
            break;
4680
        default:
4681
            goto die;
4682
        }
4683
        break;
4684
    case 11:
4685
        switch (sel) {
4686
        case 0:
4687
            gen_helper_mtc0_compare(t0);
4688
            rn = "Compare";
4689
            break;
4690
        /* 6,7 are implementation dependent */
4691
        default:
4692
            goto die;
4693
        }
4694
        /* Stop translation as we may have switched the execution mode */
4695
        ctx->bstate = BS_STOP;
4696
        break;
4697
    case 12:
4698
        switch (sel) {
4699
        case 0:
4700
            gen_helper_mtc0_status(t0);
4701
            /* BS_STOP isn't good enough here, hflags may have changed. */
4702
            gen_save_pc(ctx->pc + 4);
4703
            ctx->bstate = BS_EXCP;
4704
            rn = "Status";
4705
            break;
4706
        case