Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 41db4607

History | View | Annotate | Download (243.6 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, bcond;
433
static TCGv_i32 hflags;
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
        tcg_gen_movi_i32(hflags, ctx->hflags);
762
        ctx->saved_hflags = ctx->hflags;
763
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
764
        case MIPS_HFLAG_BR:
765
            break;
766
        case MIPS_HFLAG_BC:
767
        case MIPS_HFLAG_BL:
768
        case MIPS_HFLAG_B:
769
            tcg_gen_movi_tl(btarget, ctx->btarget);
770
            break;
771
        }
772
    }
773
}
774

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

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

    
802
static inline void
803
generate_exception (DisasContext *ctx, int excp)
804
{
805
    save_cpu_state(ctx, 1);
806
    gen_helper_0i(raise_exception, excp);
807
    gen_helper_interrupt_restart();
808
    tcg_gen_exit_tb(0);
809
}
810

    
811
/* Addresses computation */
812
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
813
{
814
    tcg_gen_add_tl(t0, t0, t1);
815

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

    
827
static inline void check_cp0_enabled(DisasContext *ctx)
828
{
829
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
830
        generate_exception_err(ctx, EXCP_CpU, 1);
831
}
832

    
833
static inline void check_cp1_enabled(DisasContext *ctx)
834
{
835
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
836
        generate_exception_err(ctx, EXCP_CpU, 1);
837
}
838

    
839
/* Verify that the processor is running with COP1X instructions enabled.
840
   This is associated with the nabla symbol in the MIPS32 and MIPS64
841
   opcode tables.  */
842

    
843
static inline void check_cop1x(DisasContext *ctx)
844
{
845
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
846
        generate_exception(ctx, EXCP_RI);
847
}
848

    
849
/* Verify that the processor is running with 64-bit floating-point
850
   operations enabled.  */
851

    
852
static inline void check_cp1_64bitmode(DisasContext *ctx)
853
{
854
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
855
        generate_exception(ctx, EXCP_RI);
856
}
857

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1256
            save_cpu_state(ctx, 1);
1257
            tcg_gen_ext32s_tl(r_tmp1, t0);
1258
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1259

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

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

    
1286
            save_cpu_state(ctx, 1);
1287
            tcg_gen_mov_tl(r_tmp1, t0);
1288
            tcg_gen_addi_tl(t0, t0, uimm);
1289

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

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

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

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

    
1484
            save_cpu_state(ctx, 1);
1485
            tcg_gen_ext32s_tl(r_tmp1, t0);
1486
            tcg_gen_ext32s_tl(r_tmp2, t1);
1487
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1488

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

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

    
1515
            save_cpu_state(ctx, 1);
1516
            tcg_gen_ext32s_tl(r_tmp1, t0);
1517
            tcg_gen_ext32s_tl(r_tmp2, t1);
1518
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1519

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

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

    
1546
            save_cpu_state(ctx, 1);
1547
            tcg_gen_mov_tl(r_tmp1, t0);
1548
            tcg_gen_add_tl(t0, t0, t1);
1549

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

    
1573
            save_cpu_state(ctx, 1);
1574
            tcg_gen_mov_tl(r_tmp1, t0);
1575
            tcg_gen_sub_tl(t0, t0, t1);
1576

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

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

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

    
1670
                tcg_gen_andi_tl(t0, t0, 0x1f);
1671
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1672
                {
1673
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1674
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1675

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

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

    
1761
/* Arithmetic on HI/LO registers */
1762
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1763
{
1764
    const char *opn = "hilo";
1765

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

    
1798
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1799
                        int rs, int rt)
1800
{
1801
    const char *opn = "mul/div";
1802
    TCGv t0, t1;
1803

    
1804
    switch (opc) {
1805
    case OPC_DIV:
1806
    case OPC_DIVU:
1807
#if defined(TARGET_MIPS64)
1808
    case OPC_DDIV:
1809
    case OPC_DDIVU:
1810
#endif
1811
        t0 = tcg_temp_local_new();
1812
        t1 = tcg_temp_local_new();
1813
        break;
1814
    default:
1815
        t0 = tcg_temp_new();
1816
        t1 = tcg_temp_new();
1817
        break;
1818
    }
1819

    
1820
    gen_load_gpr(t0, rs);
1821
    gen_load_gpr(t1, rt);
1822
    switch (opc) {
1823
    case OPC_DIV:
1824
        {
1825
            int l1 = gen_new_label();
1826
            int l2 = gen_new_label();
1827

    
1828
            tcg_gen_ext32s_tl(t0, t0);
1829
            tcg_gen_ext32s_tl(t1, t1);
1830
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1831
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1832
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1833

    
1834
            tcg_gen_mov_tl(cpu_LO[0], t0);
1835
            tcg_gen_movi_tl(cpu_HI[0], 0);
1836
            tcg_gen_br(l1);
1837
            gen_set_label(l2);
1838
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1839
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1840
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1841
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1842
            gen_set_label(l1);
1843
        }
1844
        opn = "div";
1845
        break;
1846
    case OPC_DIVU:
1847
        {
1848
            int l1 = gen_new_label();
1849

    
1850
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1851
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1852
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1853
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1854
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1855
            gen_set_label(l1);
1856
        }
1857
        opn = "divu";
1858
        break;
1859
    case OPC_MULT:
1860
        {
1861
            TCGv_i64 t2 = tcg_temp_new_i64();
1862
            TCGv_i64 t3 = tcg_temp_new_i64();
1863

    
1864
            tcg_gen_ext_tl_i64(t2, t0);
1865
            tcg_gen_ext_tl_i64(t3, t1);
1866
            tcg_gen_mul_i64(t2, t2, t3);
1867
            tcg_temp_free_i64(t3);
1868
            tcg_gen_trunc_i64_tl(t0, t2);
1869
            tcg_gen_shri_i64(t2, t2, 32);
1870
            tcg_gen_trunc_i64_tl(t1, t2);
1871
            tcg_temp_free_i64(t2);
1872
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1873
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1874
        }
1875
        opn = "mult";
1876
        break;
1877
    case OPC_MULTU:
1878
        {
1879
            TCGv_i64 t2 = tcg_temp_new_i64();
1880
            TCGv_i64 t3 = tcg_temp_new_i64();
1881

    
1882
            tcg_gen_ext32u_tl(t0, t0);
1883
            tcg_gen_ext32u_tl(t1, t1);
1884
            tcg_gen_extu_tl_i64(t2, t0);
1885
            tcg_gen_extu_tl_i64(t3, t1);
1886
            tcg_gen_mul_i64(t2, t2, t3);
1887
            tcg_temp_free_i64(t3);
1888
            tcg_gen_trunc_i64_tl(t0, t2);
1889
            tcg_gen_shri_i64(t2, t2, 32);
1890
            tcg_gen_trunc_i64_tl(t1, t2);
1891
            tcg_temp_free_i64(t2);
1892
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1893
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1894
        }
1895
        opn = "multu";
1896
        break;
1897
#if defined(TARGET_MIPS64)
1898
    case OPC_DDIV:
1899
        {
1900
            int l1 = gen_new_label();
1901
            int l2 = gen_new_label();
1902

    
1903
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1904
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1905
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1906
            tcg_gen_mov_tl(cpu_LO[0], t0);
1907
            tcg_gen_movi_tl(cpu_HI[0], 0);
1908
            tcg_gen_br(l1);
1909
            gen_set_label(l2);
1910
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
1911
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1912
            gen_set_label(l1);
1913
        }
1914
        opn = "ddiv";
1915
        break;
1916
    case OPC_DDIVU:
1917
        {
1918
            int l1 = gen_new_label();
1919

    
1920
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1921
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1922
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1923
            gen_set_label(l1);
1924
        }
1925
        opn = "ddivu";
1926
        break;
1927
    case OPC_DMULT:
1928
        gen_helper_dmult(t0, t1);
1929
        opn = "dmult";
1930
        break;
1931
    case OPC_DMULTU:
1932
        gen_helper_dmultu(t0, t1);
1933
        opn = "dmultu";
1934
        break;
1935
#endif
1936
    case OPC_MADD:
1937
        {
1938
            TCGv_i64 t2 = tcg_temp_new_i64();
1939
            TCGv_i64 t3 = tcg_temp_new_i64();
1940

    
1941
            tcg_gen_ext_tl_i64(t2, t0);
1942
            tcg_gen_ext_tl_i64(t3, t1);
1943
            tcg_gen_mul_i64(t2, t2, t3);
1944
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1945
            tcg_gen_add_i64(t2, t2, t3);
1946
            tcg_temp_free_i64(t3);
1947
            tcg_gen_trunc_i64_tl(t0, t2);
1948
            tcg_gen_shri_i64(t2, t2, 32);
1949
            tcg_gen_trunc_i64_tl(t1, t2);
1950
            tcg_temp_free_i64(t2);
1951
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1952
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1953
        }
1954
        opn = "madd";
1955
        break;
1956
    case OPC_MADDU:
1957
       {
1958
            TCGv_i64 t2 = tcg_temp_new_i64();
1959
            TCGv_i64 t3 = tcg_temp_new_i64();
1960

    
1961
            tcg_gen_ext32u_tl(t0, t0);
1962
            tcg_gen_ext32u_tl(t1, t1);
1963
            tcg_gen_extu_tl_i64(t2, t0);
1964
            tcg_gen_extu_tl_i64(t3, t1);
1965
            tcg_gen_mul_i64(t2, t2, t3);
1966
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1967
            tcg_gen_add_i64(t2, t2, t3);
1968
            tcg_temp_free_i64(t3);
1969
            tcg_gen_trunc_i64_tl(t0, t2);
1970
            tcg_gen_shri_i64(t2, t2, 32);
1971
            tcg_gen_trunc_i64_tl(t1, t2);
1972
            tcg_temp_free_i64(t2);
1973
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1974
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1975
        }
1976
        opn = "maddu";
1977
        break;
1978
    case OPC_MSUB:
1979
        {
1980
            TCGv_i64 t2 = tcg_temp_new_i64();
1981
            TCGv_i64 t3 = tcg_temp_new_i64();
1982

    
1983
            tcg_gen_ext_tl_i64(t2, t0);
1984
            tcg_gen_ext_tl_i64(t3, t1);
1985
            tcg_gen_mul_i64(t2, t2, t3);
1986
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1987
            tcg_gen_sub_i64(t2, t2, t3);
1988
            tcg_temp_free_i64(t3);
1989
            tcg_gen_trunc_i64_tl(t0, t2);
1990
            tcg_gen_shri_i64(t2, t2, 32);
1991
            tcg_gen_trunc_i64_tl(t1, t2);
1992
            tcg_temp_free_i64(t2);
1993
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1994
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1995
        }
1996
        opn = "msub";
1997
        break;
1998
    case OPC_MSUBU:
1999
        {
2000
            TCGv_i64 t2 = tcg_temp_new_i64();
2001
            TCGv_i64 t3 = tcg_temp_new_i64();
2002

    
2003
            tcg_gen_ext32u_tl(t0, t0);
2004
            tcg_gen_ext32u_tl(t1, t1);
2005
            tcg_gen_extu_tl_i64(t2, t0);
2006
            tcg_gen_extu_tl_i64(t3, t1);
2007
            tcg_gen_mul_i64(t2, t2, t3);
2008
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2009
            tcg_gen_sub_i64(t2, t2, t3);
2010
            tcg_temp_free_i64(t3);
2011
            tcg_gen_trunc_i64_tl(t0, t2);
2012
            tcg_gen_shri_i64(t2, t2, 32);
2013
            tcg_gen_trunc_i64_tl(t1, t2);
2014
            tcg_temp_free_i64(t2);
2015
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2016
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2017
        }
2018
        opn = "msubu";
2019
        break;
2020
    default:
2021
        MIPS_INVAL(opn);
2022
        generate_exception(ctx, EXCP_RI);
2023
        goto out;
2024
    }
2025
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2026
 out:
2027
    tcg_temp_free(t0);
2028
    tcg_temp_free(t1);
2029
}
2030

    
2031
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2032
                            int rd, int rs, int rt)
2033
{
2034
    const char *opn = "mul vr54xx";
2035
    TCGv t0 = tcg_temp_new();
2036
    TCGv t1 = tcg_temp_new();
2037

    
2038
    gen_load_gpr(t0, rs);
2039
    gen_load_gpr(t1, rt);
2040

    
2041
    switch (opc) {
2042
    case OPC_VR54XX_MULS:
2043
        gen_helper_muls(t0, t0, t1);
2044
        opn = "muls";
2045
        break;
2046
    case OPC_VR54XX_MULSU:
2047
        gen_helper_mulsu(t0, t0, t1);
2048
        opn = "mulsu";
2049
        break;
2050
    case OPC_VR54XX_MACC:
2051
        gen_helper_macc(t0, t0, t1);
2052
        opn = "macc";
2053
        break;
2054
    case OPC_VR54XX_MACCU:
2055
        gen_helper_maccu(t0, t0, t1);
2056
        opn = "maccu";
2057
        break;
2058
    case OPC_VR54XX_MSAC:
2059
        gen_helper_msac(t0, t0, t1);
2060
        opn = "msac";
2061
        break;
2062
    case OPC_VR54XX_MSACU:
2063
        gen_helper_msacu(t0, t0, t1);
2064
        opn = "msacu";
2065
        break;
2066
    case OPC_VR54XX_MULHI:
2067
        gen_helper_mulhi(t0, t0, t1);
2068
        opn = "mulhi";
2069
        break;
2070
    case OPC_VR54XX_MULHIU:
2071
        gen_helper_mulhiu(t0, t0, t1);
2072
        opn = "mulhiu";
2073
        break;
2074
    case OPC_VR54XX_MULSHI:
2075
        gen_helper_mulshi(t0, t0, t1);
2076
        opn = "mulshi";
2077
        break;
2078
    case OPC_VR54XX_MULSHIU:
2079
        gen_helper_mulshiu(t0, t0, t1);
2080
        opn = "mulshiu";
2081
        break;
2082
    case OPC_VR54XX_MACCHI:
2083
        gen_helper_macchi(t0, t0, t1);
2084
        opn = "macchi";
2085
        break;
2086
    case OPC_VR54XX_MACCHIU:
2087
        gen_helper_macchiu(t0, t0, t1);
2088
        opn = "macchiu";
2089
        break;
2090
    case OPC_VR54XX_MSACHI:
2091
        gen_helper_msachi(t0, t0, t1);
2092
        opn = "msachi";
2093
        break;
2094
    case OPC_VR54XX_MSACHIU:
2095
        gen_helper_msachiu(t0, t0, t1);
2096
        opn = "msachiu";
2097
        break;
2098
    default:
2099
        MIPS_INVAL("mul vr54xx");
2100
        generate_exception(ctx, EXCP_RI);
2101
        goto out;
2102
    }
2103
    gen_store_gpr(t0, rd);
2104
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2105

    
2106
 out:
2107
    tcg_temp_free(t0);
2108
    tcg_temp_free(t1);
2109
}
2110

    
2111
static void gen_cl (DisasContext *ctx, uint32_t opc,
2112
                    int rd, int rs)
2113
{
2114
    const char *opn = "CLx";
2115
    TCGv t0;
2116

    
2117
    if (rd == 0) {
2118
        /* Treat as NOP. */
2119
        MIPS_DEBUG("NOP");
2120
        return;
2121
    }
2122
    t0 = tcg_temp_new();
2123
    gen_load_gpr(t0, rs);
2124
    switch (opc) {
2125
    case OPC_CLO:
2126
        gen_helper_clo(cpu_gpr[rd], t0);
2127
        opn = "clo";
2128
        break;
2129
    case OPC_CLZ:
2130
        gen_helper_clz(cpu_gpr[rd], t0);
2131
        opn = "clz";
2132
        break;
2133
#if defined(TARGET_MIPS64)
2134
    case OPC_DCLO:
2135
        gen_helper_dclo(cpu_gpr[rd], t0);
2136
        opn = "dclo";
2137
        break;
2138
    case OPC_DCLZ:
2139
        gen_helper_dclz(cpu_gpr[rd], t0);
2140
        opn = "dclz";
2141
        break;
2142
#endif
2143
    }
2144
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2145
    tcg_temp_free(t0);
2146
}
2147

    
2148
/* Traps */
2149
static void gen_trap (DisasContext *ctx, uint32_t opc,
2150
                      int rs, int rt, int16_t imm)
2151
{
2152
    int cond;
2153
    TCGv t0 = tcg_temp_new();
2154
    TCGv t1 = tcg_temp_new();
2155

    
2156
    cond = 0;
2157
    /* Load needed operands */
2158
    switch (opc) {
2159
    case OPC_TEQ:
2160
    case OPC_TGE:
2161
    case OPC_TGEU:
2162
    case OPC_TLT:
2163
    case OPC_TLTU:
2164
    case OPC_TNE:
2165
        /* Compare two registers */
2166
        if (rs != rt) {
2167
            gen_load_gpr(t0, rs);
2168
            gen_load_gpr(t1, rt);
2169
            cond = 1;
2170
        }
2171
        break;
2172
    case OPC_TEQI:
2173
    case OPC_TGEI:
2174
    case OPC_TGEIU:
2175
    case OPC_TLTI:
2176
    case OPC_TLTIU:
2177
    case OPC_TNEI:
2178
        /* Compare register to immediate */
2179
        if (rs != 0 || imm != 0) {
2180
            gen_load_gpr(t0, rs);
2181
            tcg_gen_movi_tl(t1, (int32_t)imm);
2182
            cond = 1;
2183
        }
2184
        break;
2185
    }
2186
    if (cond == 0) {
2187
        switch (opc) {
2188
        case OPC_TEQ:   /* rs == rs */
2189
        case OPC_TEQI:  /* r0 == 0  */
2190
        case OPC_TGE:   /* rs >= rs */
2191
        case OPC_TGEI:  /* r0 >= 0  */
2192
        case OPC_TGEU:  /* rs >= rs unsigned */
2193
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2194
            /* Always trap */
2195
            generate_exception(ctx, EXCP_TRAP);
2196
            break;
2197
        case OPC_TLT:   /* rs < rs           */
2198
        case OPC_TLTI:  /* r0 < 0            */
2199
        case OPC_TLTU:  /* rs < rs unsigned  */
2200
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2201
        case OPC_TNE:   /* rs != rs          */
2202
        case OPC_TNEI:  /* r0 != 0           */
2203
            /* Never trap: treat as NOP. */
2204
            break;
2205
        }
2206
    } else {
2207
        int l1 = gen_new_label();
2208

    
2209
        switch (opc) {
2210
        case OPC_TEQ:
2211
        case OPC_TEQI:
2212
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2213
            break;
2214
        case OPC_TGE:
2215
        case OPC_TGEI:
2216
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2217
            break;
2218
        case OPC_TGEU:
2219
        case OPC_TGEIU:
2220
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2221
            break;
2222
        case OPC_TLT:
2223
        case OPC_TLTI:
2224
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2225
            break;
2226
        case OPC_TLTU:
2227
        case OPC_TLTIU:
2228
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2229
            break;
2230
        case OPC_TNE:
2231
        case OPC_TNEI:
2232
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2233
            break;
2234
        }
2235
        generate_exception(ctx, EXCP_TRAP);
2236
        gen_set_label(l1);
2237
    }
2238
    tcg_temp_free(t0);
2239
    tcg_temp_free(t1);
2240
}
2241

    
2242
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2243
{
2244
    TranslationBlock *tb;
2245
    tb = ctx->tb;
2246
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2247
        tcg_gen_goto_tb(n);
2248
        gen_save_pc(dest);
2249
        tcg_gen_exit_tb((long)tb + n);
2250
    } else {
2251
        gen_save_pc(dest);
2252
        tcg_gen_exit_tb(0);
2253
    }
2254
}
2255

    
2256
/* Branches (before delay slot) */
2257
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2258
                                int rs, int rt, int32_t offset)
2259
{
2260
    target_ulong btgt = -1;
2261
    int blink = 0;
2262
    int bcond_compute = 0;
2263
    TCGv t0 = tcg_temp_new();
2264
    TCGv t1 = tcg_temp_new();
2265

    
2266
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2267
#ifdef MIPS_DEBUG_DISAS
2268
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2269
#endif
2270
        generate_exception(ctx, EXCP_RI);
2271
        goto out;
2272
    }
2273

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

    
2482
    ctx->btarget = btgt;
2483
    if (blink > 0) {
2484
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2485
    }
2486

    
2487
 out:
2488
    tcg_temp_free(t0);
2489
    tcg_temp_free(t1);
2490
}
2491

    
2492
/* special3 bitfield operations */
2493
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2494
                        int rs, int lsb, int msb)
2495
{
2496
    TCGv t0 = tcg_temp_new();
2497
    TCGv t1 = tcg_temp_new();
2498
    target_ulong mask;
2499

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

    
2585
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2586
{
2587
    TCGv t0;
2588

    
2589
    if (rd == 0) {
2590
        /* If no destination, treat it as a NOP. */
2591
        MIPS_DEBUG("NOP");
2592
        return;
2593
    }
2594

    
2595
    t0 = tcg_temp_new();
2596
    gen_load_gpr(t0, rt);
2597
    switch (op2) {
2598
    case OPC_WSBH:
2599
        {
2600
            TCGv t1 = tcg_temp_new();
2601

    
2602
            tcg_gen_shri_tl(t1, t0, 8);
2603
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2604
            tcg_gen_shli_tl(t0, t0, 8);
2605
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2606
            tcg_gen_or_tl(t0, t0, t1);
2607
            tcg_temp_free(t1);
2608
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2609
        }
2610
        break;
2611
    case OPC_SEB:
2612
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2613
        break;
2614
    case OPC_SEH:
2615
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2616
        break;
2617
#if defined(TARGET_MIPS64)
2618
    case OPC_DSBH:
2619
        {
2620
            TCGv t1 = tcg_temp_new();
2621

    
2622
            tcg_gen_shri_tl(t1, t0, 8);
2623
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2624
            tcg_gen_shli_tl(t0, t0, 8);
2625
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2626
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2627
            tcg_temp_free(t1);
2628
        }
2629
        break;
2630
    case OPC_DSHD:
2631
        {
2632
            TCGv t1 = tcg_temp_new();
2633

    
2634
            tcg_gen_shri_tl(t1, t0, 16);
2635
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2636
            tcg_gen_shli_tl(t0, t0, 16);
2637
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2638
            tcg_gen_or_tl(t0, t0, t1);
2639
            tcg_gen_shri_tl(t1, t0, 32);
2640
            tcg_gen_shli_tl(t0, t0, 32);
2641
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2642
            tcg_temp_free(t1);
2643
        }
2644
        break;
2645
#endif
2646
    default:
2647
        MIPS_INVAL("bsfhl");
2648
        generate_exception(ctx, EXCP_RI);
2649
        tcg_temp_free(t0);
2650
        return;
2651
    }
2652
    tcg_temp_free(t0);
2653
}
2654

    
2655
#ifndef CONFIG_USER_ONLY
2656
/* CP0 (MMU and control) */
2657
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2658
{
2659
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2660

    
2661
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2662
    tcg_gen_ext_i32_tl(t, r_tmp);
2663
    tcg_temp_free_i32(r_tmp);
2664
}
2665

    
2666
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2667
{
2668
    tcg_gen_ld_tl(t, cpu_env, off);
2669
    tcg_gen_ext32s_tl(t, t);
2670
}
2671

    
2672
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2673
{
2674
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2675

    
2676
    tcg_gen_trunc_tl_i32(r_tmp, t);
2677
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2678
    tcg_temp_free_i32(r_tmp);
2679
}
2680

    
2681
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2682
{
2683
    tcg_gen_ext32s_tl(t, t);
2684
    tcg_gen_st_tl(t, cpu_env, off);
2685
}
2686

    
2687
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2688
{
2689
    const char *rn = "invalid";
2690

    
2691
    if (sel != 0)
2692
        check_insn(env, ctx, ISA_MIPS32);
2693

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

    
3259
die:
3260
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3261
    generate_exception(ctx, EXCP_RI);
3262
}
3263

    
3264
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3265
{
3266
    const char *rn = "invalid";
3267

    
3268
    if (sel != 0)
3269
        check_insn(env, ctx, ISA_MIPS32);
3270

    
3271
    if (use_icount)
3272
        gen_io_start();
3273

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

    
3858
die:
3859
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3860
    generate_exception(ctx, EXCP_RI);
3861
}
3862

    
3863
#if defined(TARGET_MIPS64)
3864
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3865
{
3866
    const char *rn = "invalid";
3867

    
3868
    if (sel != 0)
3869
        check_insn(env, ctx, ISA_MIPS64);
3870

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

    
4425
die:
4426
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4427
    generate_exception(ctx, EXCP_RI);
4428
}
4429

    
4430
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4431
{
4432
    const char *rn = "invalid";
4433

    
4434
    if (sel != 0)
4435
        check_insn(env, ctx, ISA_MIPS64);
4436

    
4437
    if (use_icount)
4438
        gen_io_start();
4439

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