Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c239529e

History | View | Annotate | Download (217.3 kB)

1
/*
2
 *  MIPS32 emulation for qemu: main translation routines.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *  Copyright (c) 2006 Marius Groeger (FPU operations)
6
 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22

    
23
#include <stdarg.h>
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#include <inttypes.h>
28

    
29
#include "cpu.h"
30
#include "exec-all.h"
31
#include "disas.h"
32
#include "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

    
36
//#define MIPS_DEBUG_DISAS
37
//#define MIPS_DEBUG_SIGN_EXTENSIONS
38
//#define MIPS_SINGLE_STEP
39

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
386
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387

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

    
400
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
401

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

    
425
/* global register indices */
426
static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2];
427

    
428
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg)
429
{
430
    TCGv t = tcg_const_i32(arg);
431

    
432
    tcg_gen_helper_0_1(func, t);
433
    tcg_temp_free(t);
434
}
435

    
436
static inline void tcg_gen_helper_0_2ii(void *func, TCGv arg1, TCGv arg2)
437
{
438
    TCGv t1 = tcg_const_i32(arg1);
439
    TCGv t2 = tcg_const_i32(arg2);
440

    
441
    tcg_gen_helper_0_2(func, t1, t2);
442
    tcg_temp_free(t1);
443
    tcg_temp_free(t2);
444
}
445

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

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

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

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

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

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

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

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

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

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

    
529
static inline void gen_load_HI (TCGv t, int reg)
530
{
531
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
532
}
533

    
534
static inline void gen_store_HI (TCGv t, int reg)
535
{
536
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
537
}
538

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

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

    
553
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
554
        tcg_temp_free(r_tmp);
555
    }
556
}
557

    
558
static inline void gen_store_srsgpr (TCGv t, int reg)
559
{
560
    if (reg != 0) {
561
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
562

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

    
569
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
570
        tcg_temp_free(r_tmp);
571
    }
572
}
573

    
574
/* Floating point register moves. */
575
#define FGEN32(func, NAME)                       \
576
static GenOpFunc *NAME ## _table [32] = {        \
577
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
578
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
579
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
580
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
581
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
582
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
583
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
584
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
585
};                                               \
586
static always_inline void func(int n)            \
587
{                                                \
588
    NAME ## _table[n]();                         \
589
}
590

    
591
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
592
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
593

    
594
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
595
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
596

    
597
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
598
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
599

    
600
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
601
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
602

    
603
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
604
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
605

    
606
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
607
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
608

    
609
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
610
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
611

    
612
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
613
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
614

    
615
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
616
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
617

    
618
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
619
do {                                                                          \
620
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
621
} while (0)
622

    
623
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
624
do {                                                                          \
625
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
626
} while (0)
627

    
628
#define FOP_CONDS(type, fmt)                                            \
629
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
630
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
631
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
632
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
633
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
634
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
635
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
636
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
637
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
638
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
639
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
640
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
641
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
642
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
643
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
644
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
645
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
646
};                                                                      \
647
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
648
{                                                                       \
649
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
650
}
651

    
652
FOP_CONDS(, d)
653
FOP_CONDS(abs, d)
654
FOP_CONDS(, s)
655
FOP_CONDS(abs, s)
656
FOP_CONDS(, ps)
657
FOP_CONDS(abs, ps)
658

    
659
/* Tests */
660
#define OP_COND(name, cond)                                   \
661
void glue(gen_op_, name) (void)                               \
662
{                                                             \
663
    int l1 = gen_new_label();                                 \
664
    int l2 = gen_new_label();                                 \
665
                                                              \
666
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
667
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
668
    tcg_gen_br(l2);                                           \
669
    gen_set_label(l1);                                        \
670
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
671
    gen_set_label(l2);                                        \
672
}
673
OP_COND(eq, TCG_COND_EQ);
674
OP_COND(ne, TCG_COND_NE);
675
OP_COND(ge, TCG_COND_GE);
676
OP_COND(geu, TCG_COND_GEU);
677
OP_COND(lt, TCG_COND_LT);
678
OP_COND(ltu, TCG_COND_LTU);
679
#undef OP_COND
680

    
681
#define OP_CONDI(name, cond)                                  \
682
void glue(gen_op_, name) (target_ulong val)                   \
683
{                                                             \
684
    int l1 = gen_new_label();                                 \
685
    int l2 = gen_new_label();                                 \
686
                                                              \
687
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
688
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
689
    tcg_gen_br(l2);                                           \
690
    gen_set_label(l1);                                        \
691
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
692
    gen_set_label(l2);                                        \
693
}
694
OP_CONDI(lti, TCG_COND_LT);
695
OP_CONDI(ltiu, TCG_COND_LTU);
696
#undef OP_CONDI
697

    
698
#define OP_CONDZ(name, cond)                                  \
699
void glue(gen_op_, name) (void)                               \
700
{                                                             \
701
    int l1 = gen_new_label();                                 \
702
    int l2 = gen_new_label();                                 \
703
                                                              \
704
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1);                \
705
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
706
    tcg_gen_br(l2);                                           \
707
    gen_set_label(l1);                                        \
708
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
709
    gen_set_label(l2);                                        \
710
}
711
OP_CONDZ(gez, TCG_COND_GE);
712
OP_CONDZ(gtz, TCG_COND_GT);
713
OP_CONDZ(lez, TCG_COND_LE);
714
OP_CONDZ(ltz, TCG_COND_LT);
715
#undef OP_CONDZ
716

    
717
static inline void gen_save_pc(target_ulong pc)
718
{
719
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
720
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
721
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
722
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
723

    
724
    tcg_gen_movi_tl(r_tmp, pc);
725
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
726
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
727
    tcg_gen_ext_i32_ptr(r_tc_off_ptr, r_tc_off);
728
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_ptr);
729
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
730
    tcg_temp_free(r_tc_off);
731
    tcg_temp_free(r_tc_off_ptr);
732
    tcg_temp_free(r_ptr);
733
    tcg_temp_free(r_tmp);
734
}
735

    
736
static inline void gen_breg_pc(void)
737
{
738
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
739
    TCGv r_tc_off = tcg_temp_new(TCG_TYPE_I32);
740
    TCGv r_tc_off_ptr = tcg_temp_new(TCG_TYPE_PTR);
741
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
742

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

    
755
static inline void gen_save_btarget(target_ulong btarget)
756
{
757
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
758

    
759
    tcg_gen_movi_tl(r_tmp, btarget);
760
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
761
    tcg_temp_free(r_tmp);
762
}
763

    
764
static always_inline void gen_save_breg_target(int reg)
765
{
766
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
767

    
768
    gen_load_gpr(r_tmp, reg);
769
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
770
    tcg_temp_free(r_tmp);
771
}
772

    
773
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
774
{
775
#if defined MIPS_DEBUG_DISAS
776
    if (loglevel & CPU_LOG_TB_IN_ASM) {
777
            fprintf(logfile, "hflags %08x saved %08x\n",
778
                    ctx->hflags, ctx->saved_hflags);
779
    }
780
#endif
781
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
782
        gen_save_pc(ctx->pc);
783
        ctx->saved_pc = ctx->pc;
784
    }
785
    if (ctx->hflags != ctx->saved_hflags) {
786
        gen_op_save_state(ctx->hflags);
787
        ctx->saved_hflags = ctx->hflags;
788
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
789
        case MIPS_HFLAG_BR:
790
            break;
791
        case MIPS_HFLAG_BC:
792
        case MIPS_HFLAG_BL:
793
        case MIPS_HFLAG_B:
794
            gen_save_btarget(ctx->btarget);
795
            break;
796
        }
797
    }
798
}
799

    
800
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
801
{
802
    ctx->saved_hflags = ctx->hflags;
803
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
804
    case MIPS_HFLAG_BR:
805
        break;
806
    case MIPS_HFLAG_BC:
807
    case MIPS_HFLAG_BL:
808
    case MIPS_HFLAG_B:
809
        ctx->btarget = env->btarget;
810
        break;
811
    }
812
}
813

    
814
static always_inline void
815
generate_exception_err (DisasContext *ctx, int excp, int err)
816
{
817
    save_cpu_state(ctx, 1);
818
    tcg_gen_helper_0_2ii(do_raise_exception_err, excp, err);
819
    tcg_gen_helper_0_0(do_interrupt_restart);
820
    tcg_gen_exit_tb(0);
821
}
822

    
823
static always_inline void
824
generate_exception (DisasContext *ctx, int excp)
825
{
826
    save_cpu_state(ctx, 1);
827
    tcg_gen_helper_0_1i(do_raise_exception, excp);
828
    tcg_gen_helper_0_0(do_interrupt_restart);
829
    tcg_gen_exit_tb(0);
830
}
831

    
832
/* Addresses computation */
833
static inline void gen_op_addr_add (void)
834
{
835
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
836

    
837
#if defined(TARGET_MIPS64)
838
    /* For compatibility with 32-bit code, data reference in user mode
839
       with Status_UX = 0 should be casted to 32-bit and sign extended.
840
       See the MIPS64 PRA manual, section 4.10. */
841
    {
842
        int l1 = gen_new_label();
843

    
844
        {
845
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
846

    
847
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
848
            tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
849
            tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
850
        }
851
        {
852
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
853

    
854
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
855
            tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
856
            tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
857
        }
858
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
859
        gen_set_label(l1);
860
    }
861
#endif
862
}
863

    
864
static always_inline void check_cp0_enabled(DisasContext *ctx)
865
{
866
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
867
        generate_exception_err(ctx, EXCP_CpU, 1);
868
}
869

    
870
static always_inline void check_cp1_enabled(DisasContext *ctx)
871
{
872
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
873
        generate_exception_err(ctx, EXCP_CpU, 1);
874
}
875

    
876
/* Verify that the processor is running with COP1X instructions enabled.
877
   This is associated with the nabla symbol in the MIPS32 and MIPS64
878
   opcode tables.  */
879

    
880
static always_inline void check_cop1x(DisasContext *ctx)
881
{
882
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
883
        generate_exception(ctx, EXCP_RI);
884
}
885

    
886
/* Verify that the processor is running with 64-bit floating-point
887
   operations enabled.  */
888

    
889
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
890
{
891
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
892
        generate_exception(ctx, EXCP_RI);
893
}
894

    
895
/*
896
 * Verify if floating point register is valid; an operation is not defined
897
 * if bit 0 of any register specification is set and the FR bit in the
898
 * Status register equals zero, since the register numbers specify an
899
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
900
 * in the Status register equals one, both even and odd register numbers
901
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
902
 *
903
 * Multiple 64 bit wide registers can be checked by calling
904
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
905
 */
906
void check_cp1_registers(DisasContext *ctx, int regs)
907
{
908
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
909
        generate_exception(ctx, EXCP_RI);
910
}
911

    
912
/* This code generates a "reserved instruction" exception if the
913
   CPU does not support the instruction set corresponding to flags. */
914
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
915
{
916
    if (unlikely(!(env->insn_flags & flags)))
917
        generate_exception(ctx, EXCP_RI);
918
}
919

    
920
/* This code generates a "reserved instruction" exception if 64-bit
921
   instructions are not enabled. */
922
static always_inline void check_mips_64(DisasContext *ctx)
923
{
924
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
925
        generate_exception(ctx, EXCP_RI);
926
}
927

    
928
/* load/store instructions. */
929
#if defined(CONFIG_USER_ONLY)
930
#define op_ldst(name)        gen_op_##name##_raw()
931
#define OP_LD_TABLE(width)
932
#define OP_ST_TABLE(width)
933
#else
934
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
935
#define OP_LD_TABLE(width)                                                    \
936
static GenOpFunc *gen_op_l##width[] = {                                       \
937
    &gen_op_l##width##_kernel,                                                \
938
    &gen_op_l##width##_super,                                                 \
939
    &gen_op_l##width##_user,                                                  \
940
}
941
#define OP_ST_TABLE(width)                                                    \
942
static GenOpFunc *gen_op_s##width[] = {                                       \
943
    &gen_op_s##width##_kernel,                                                \
944
    &gen_op_s##width##_super,                                                 \
945
    &gen_op_s##width##_user,                                                  \
946
}
947
#endif
948

    
949
#if defined(TARGET_MIPS64)
950
OP_LD_TABLE(dl);
951
OP_LD_TABLE(dr);
952
OP_ST_TABLE(dl);
953
OP_ST_TABLE(dr);
954
#endif
955
OP_LD_TABLE(wl);
956
OP_LD_TABLE(wr);
957
OP_ST_TABLE(wl);
958
OP_ST_TABLE(wr);
959
OP_LD_TABLE(wc1);
960
OP_ST_TABLE(wc1);
961
OP_LD_TABLE(dc1);
962
OP_ST_TABLE(dc1);
963
OP_LD_TABLE(uxc1);
964
OP_ST_TABLE(uxc1);
965

    
966
#define OP_LD(insn,fname)                                        \
967
void inline op_ldst_##insn(DisasContext *ctx)                    \
968
{                                                                \
969
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
970
}
971
OP_LD(lb,ld8s);
972
OP_LD(lbu,ld8u);
973
OP_LD(lh,ld16s);
974
OP_LD(lhu,ld16u);
975
OP_LD(lw,ld32s);
976
#if defined(TARGET_MIPS64)
977
OP_LD(lwu,ld32u);
978
OP_LD(ld,ld64);
979
#endif
980
#undef OP_LD
981

    
982
#define OP_ST(insn,fname)                                        \
983
void inline op_ldst_##insn(DisasContext *ctx)                    \
984
{                                                                \
985
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
986
}
987
OP_ST(sb,st8);
988
OP_ST(sh,st16);
989
OP_ST(sw,st32);
990
#if defined(TARGET_MIPS64)
991
OP_ST(sd,st64);
992
#endif
993
#undef OP_ST
994

    
995
#define OP_LD_ATOMIC(insn,fname)                                        \
996
void inline op_ldst_##insn(DisasContext *ctx)                           \
997
{                                                                       \
998
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
999
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1000
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1001
}
1002
OP_LD_ATOMIC(ll,ld32s);
1003
#if defined(TARGET_MIPS64)
1004
OP_LD_ATOMIC(lld,ld64);
1005
#endif
1006
#undef OP_LD_ATOMIC
1007

    
1008
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1009
void inline op_ldst_##insn(DisasContext *ctx)                           \
1010
{                                                                       \
1011
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1012
    int l1 = gen_new_label();                                           \
1013
    int l2 = gen_new_label();                                           \
1014
    int l3 = gen_new_label();                                           \
1015
                                                                        \
1016
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1017
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1018
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1019
    generate_exception(ctx, EXCP_AdES);                                 \
1020
    gen_set_label(l1);                                                  \
1021
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1022
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1023
    tcg_temp_free(r_tmp);                                               \
1024
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1025
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1026
    tcg_gen_br(l3);                                                     \
1027
    gen_set_label(l2);                                                  \
1028
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1029
    gen_set_label(l3);                                                  \
1030
}
1031
OP_ST_ATOMIC(sc,st32,0x3);
1032
#if defined(TARGET_MIPS64)
1033
OP_ST_ATOMIC(scd,st64,0x7);
1034
#endif
1035
#undef OP_ST_ATOMIC
1036

    
1037
void inline op_ldst_lwc1(DisasContext *ctx)
1038
{
1039
    op_ldst(lwc1);
1040
}
1041

    
1042
void inline op_ldst_ldc1(DisasContext *ctx)
1043
{
1044
    op_ldst(ldc1);
1045
}
1046

    
1047
void inline op_ldst_swc1(DisasContext *ctx)
1048
{
1049
    op_ldst(swc1);
1050
}
1051

    
1052
void inline op_ldst_sdc1(DisasContext *ctx)
1053
{
1054
    op_ldst(sdc1);
1055
}
1056

    
1057
/* Load and store */
1058
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1059
                      int base, int16_t offset)
1060
{
1061
    const char *opn = "ldst";
1062

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

    
1208
/* Load and store */
1209
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1210
                      int base, int16_t offset)
1211
{
1212
    const char *opn = "flt_ldst";
1213

    
1214
    if (base == 0) {
1215
        tcg_gen_movi_tl(cpu_T[0], offset);
1216
    } else if (offset == 0) {
1217
        gen_load_gpr(cpu_T[0], base);
1218
    } else {
1219
        gen_load_gpr(cpu_T[0], base);
1220
        tcg_gen_movi_tl(cpu_T[1], offset);
1221
        gen_op_addr_add();
1222
    }
1223
    /* Don't do NOP if destination is zero: we must perform the actual
1224
       memory access. */
1225
    switch (opc) {
1226
    case OPC_LWC1:
1227
        op_ldst_lwc1(ctx);
1228
        GEN_STORE_FTN_FREG(ft, WT0);
1229
        opn = "lwc1";
1230
        break;
1231
    case OPC_SWC1:
1232
        GEN_LOAD_FREG_FTN(WT0, ft);
1233
        op_ldst_swc1(ctx);
1234
        opn = "swc1";
1235
        break;
1236
    case OPC_LDC1:
1237
        op_ldst_ldc1(ctx);
1238
        GEN_STORE_FTN_FREG(ft, DT0);
1239
        opn = "ldc1";
1240
        break;
1241
    case OPC_SDC1:
1242
        GEN_LOAD_FREG_FTN(DT0, ft);
1243
        op_ldst_sdc1(ctx);
1244
        opn = "sdc1";
1245
        break;
1246
    default:
1247
        MIPS_INVAL(opn);
1248
        generate_exception(ctx, EXCP_RI);
1249
        return;
1250
    }
1251
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1252
}
1253

    
1254
/* Arithmetic with immediate operand */
1255
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1256
                           int rt, int rs, int16_t imm)
1257
{
1258
    target_ulong uimm;
1259
    const char *opn = "imm arith";
1260

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

    
1310
            save_cpu_state(ctx, 1);
1311
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1312
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1313

    
1314
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1315
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1316
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1317
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1318
            tcg_temp_free(r_tmp2);
1319
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1320
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1321
            tcg_temp_free(r_tmp1);
1322
            /* operands of same sign, result different sign */
1323
            generate_exception(ctx, EXCP_OVERFLOW);
1324
            gen_set_label(l1);
1325

    
1326
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1327
        }
1328
        opn = "addi";
1329
        break;
1330
    case OPC_ADDIU:
1331
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1332
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1333
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1334
        opn = "addiu";
1335
        break;
1336
#if defined(TARGET_MIPS64)
1337
    case OPC_DADDI:
1338
        {
1339
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1340
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1341
            int l1 = gen_new_label();
1342

    
1343
            save_cpu_state(ctx, 1);
1344
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1345
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1346

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

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

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

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

    
1531
/* Arithmetic */
1532
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1533
                       int rd, int rs, int rt)
1534
{
1535
    const char *opn = "arith";
1536

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

    
1559
            save_cpu_state(ctx, 1);
1560
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1561
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1562
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1563

    
1564
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1565
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1566
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1567
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1568
            tcg_temp_free(r_tmp2);
1569
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1570
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1571
            tcg_temp_free(r_tmp1);
1572
            /* operands of same sign, result different sign */
1573
            generate_exception(ctx, EXCP_OVERFLOW);
1574
            gen_set_label(l1);
1575

    
1576
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1577
        }
1578
        opn = "add";
1579
        break;
1580
    case OPC_ADDU:
1581
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1582
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1583
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1584
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1585
        opn = "addu";
1586
        break;
1587
    case OPC_SUB:
1588
        {
1589
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1590
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1591
            int l1 = gen_new_label();
1592

    
1593
            save_cpu_state(ctx, 1);
1594
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1595
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1596
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1597

    
1598
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1599
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1600
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1601
            tcg_temp_free(r_tmp2);
1602
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1603
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1604
            tcg_temp_free(r_tmp1);
1605
            /* operands of different sign, first operand and result different sign */
1606
            generate_exception(ctx, EXCP_OVERFLOW);
1607
            gen_set_label(l1);
1608

    
1609
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1610
        }
1611
        opn = "sub";
1612
        break;
1613
    case OPC_SUBU:
1614
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1615
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1616
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1617
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1618
        opn = "subu";
1619
        break;
1620
#if defined(TARGET_MIPS64)
1621
    case OPC_DADD:
1622
        {
1623
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1624
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1625
            int l1 = gen_new_label();
1626

    
1627
            save_cpu_state(ctx, 1);
1628
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1629
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1630

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

    
1655
            save_cpu_state(ctx, 1);
1656
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1657
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1658

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

    
1713
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1714
            gen_store_gpr(cpu_T[0], rd);
1715
            gen_set_label(l1);
1716
        }
1717
        opn = "movn";
1718
        goto print;
1719
    case OPC_MOVZ:
1720
        {
1721
            int l1 = gen_new_label();
1722

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

    
1759
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1760
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1761
                {
1762
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1763
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1764
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1765

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

    
1821
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1822
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1823
                {
1824
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1825

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

    
1861
/* Arithmetic on HI/LO registers */
1862
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1863
{
1864
    const char *opn = "hilo";
1865

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

    
1900
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1901
                        int rs, int rt)
1902
{
1903
    const char *opn = "mul/div";
1904

    
1905
    gen_load_gpr(cpu_T[0], rs);
1906
    gen_load_gpr(cpu_T[1], rt);
1907
    switch (opc) {
1908
    case OPC_DIV:
1909
        {
1910
            int l1 = gen_new_label();
1911

    
1912
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1913
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1914
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1915
            {
1916
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1917
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1918
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1919

    
1920
                tcg_gen_ext_tl_i64(r_tmp1, cpu_T[0]);
1921
                tcg_gen_ext_tl_i64(r_tmp2, cpu_T[1]);
1922
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1923
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1924
                tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp3);
1925
                tcg_gen_trunc_i64_tl(cpu_T[1], r_tmp2);
1926
                tcg_temp_free(r_tmp1);
1927
                tcg_temp_free(r_tmp2);
1928
                tcg_temp_free(r_tmp3);
1929
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1930
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1931
                gen_store_LO(cpu_T[0], 0);
1932
                gen_store_HI(cpu_T[1], 0);
1933
            }
1934
            gen_set_label(l1);
1935
        }
1936
        opn = "div";
1937
        break;
1938
    case OPC_DIVU:
1939
        {
1940
            int l1 = gen_new_label();
1941

    
1942
            tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1943
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1944
            {
1945
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1946
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1947
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1948

    
1949
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1950
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1951
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1952
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1953
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1954
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1955
                tcg_temp_free(r_tmp1);
1956
                tcg_temp_free(r_tmp2);
1957
                tcg_temp_free(r_tmp3);
1958
                gen_store_LO(cpu_T[0], 0);
1959
                gen_store_HI(cpu_T[1], 0);
1960
            }
1961
            gen_set_label(l1);
1962
        }
1963
        opn = "divu";
1964
        break;
1965
    case OPC_MULT:
1966
        gen_op_mult();
1967
        opn = "mult";
1968
        break;
1969
    case OPC_MULTU:
1970
        gen_op_multu();
1971
        opn = "multu";
1972
        break;
1973
#if defined(TARGET_MIPS64)
1974
    case OPC_DDIV:
1975
        {
1976
            int l1 = gen_new_label();
1977

    
1978
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1979
            {
1980
                int l2 = gen_new_label();
1981

    
1982
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], -1LL << 63, l2);
1983
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1LL, l2);
1984
                {
1985
                    tcg_gen_movi_tl(cpu_T[1], 0);
1986
                    gen_store_LO(cpu_T[0], 0);
1987
                    gen_store_HI(cpu_T[1], 0);
1988
                    tcg_gen_br(l1);
1989
                }
1990
                gen_set_label(l2);
1991
                {
1992
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1993
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1994

    
1995
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1996
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1997
                    gen_store_LO(r_tmp1, 0);
1998
                    gen_store_HI(r_tmp2, 0);
1999
                    tcg_temp_free(r_tmp1);
2000
                    tcg_temp_free(r_tmp2);
2001
                }
2002
            }
2003
            gen_set_label(l1);
2004
        }
2005
        opn = "ddiv";
2006
        break;
2007
    case OPC_DDIVU:
2008
        {
2009
            int l1 = gen_new_label();
2010

    
2011
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
2012
            {
2013
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2014
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2015

    
2016
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
2017
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
2018
                tcg_temp_free(r_tmp1);
2019
                tcg_temp_free(r_tmp2);
2020
                gen_store_LO(r_tmp1, 0);
2021
                gen_store_HI(r_tmp2, 0);
2022
            }
2023
            gen_set_label(l1);
2024
        }
2025
        opn = "ddivu";
2026
        break;
2027
    case OPC_DMULT:
2028
        gen_op_dmult();
2029
        opn = "dmult";
2030
        break;
2031
    case OPC_DMULTU:
2032
        gen_op_dmultu();
2033
        opn = "dmultu";
2034
        break;
2035
#endif
2036
    case OPC_MADD:
2037
        gen_op_madd();
2038
        opn = "madd";
2039
        break;
2040
    case OPC_MADDU:
2041
        gen_op_maddu();
2042
        opn = "maddu";
2043
        break;
2044
    case OPC_MSUB:
2045
        gen_op_msub();
2046
        opn = "msub";
2047
        break;
2048
    case OPC_MSUBU:
2049
        gen_op_msubu();
2050
        opn = "msubu";
2051
        break;
2052
    default:
2053
        MIPS_INVAL(opn);
2054
        generate_exception(ctx, EXCP_RI);
2055
        return;
2056
    }
2057
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2058
}
2059

    
2060
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2061
                            int rd, int rs, int rt)
2062
{
2063
    const char *opn = "mul vr54xx";
2064

    
2065
    gen_load_gpr(cpu_T[0], rs);
2066
    gen_load_gpr(cpu_T[1], rt);
2067

    
2068
    switch (opc) {
2069
    case OPC_VR54XX_MULS:
2070
        gen_op_muls();
2071
        opn = "muls";
2072
        break;
2073
    case OPC_VR54XX_MULSU:
2074
        gen_op_mulsu();
2075
        opn = "mulsu";
2076
        break;
2077
    case OPC_VR54XX_MACC:
2078
        gen_op_macc();
2079
        opn = "macc";
2080
        break;
2081
    case OPC_VR54XX_MACCU:
2082
        gen_op_maccu();
2083
        opn = "maccu";
2084
        break;
2085
    case OPC_VR54XX_MSAC:
2086
        gen_op_msac();
2087
        opn = "msac";
2088
        break;
2089
    case OPC_VR54XX_MSACU:
2090
        gen_op_msacu();
2091
        opn = "msacu";
2092
        break;
2093
    case OPC_VR54XX_MULHI:
2094
        gen_op_mulhi();
2095
        opn = "mulhi";
2096
        break;
2097
    case OPC_VR54XX_MULHIU:
2098
        gen_op_mulhiu();
2099
        opn = "mulhiu";
2100
        break;
2101
    case OPC_VR54XX_MULSHI:
2102
        gen_op_mulshi();
2103
        opn = "mulshi";
2104
        break;
2105
    case OPC_VR54XX_MULSHIU:
2106
        gen_op_mulshiu();
2107
        opn = "mulshiu";
2108
        break;
2109
    case OPC_VR54XX_MACCHI:
2110
        gen_op_macchi();
2111
        opn = "macchi";
2112
        break;
2113
    case OPC_VR54XX_MACCHIU:
2114
        gen_op_macchiu();
2115
        opn = "macchiu";
2116
        break;
2117
    case OPC_VR54XX_MSACHI:
2118
        gen_op_msachi();
2119
        opn = "msachi";
2120
        break;
2121
    case OPC_VR54XX_MSACHIU:
2122
        gen_op_msachiu();
2123
        opn = "msachiu";
2124
        break;
2125
    default:
2126
        MIPS_INVAL("mul vr54xx");
2127
        generate_exception(ctx, EXCP_RI);
2128
        return;
2129
    }
2130
    gen_store_gpr(cpu_T[0], rd);
2131
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2132
}
2133

    
2134
static void gen_cl (DisasContext *ctx, uint32_t opc,
2135
                    int rd, int rs)
2136
{
2137
    const char *opn = "CLx";
2138
    if (rd == 0) {
2139
        /* Treat as NOP. */
2140
        MIPS_DEBUG("NOP");
2141
        return;
2142
    }
2143
    gen_load_gpr(cpu_T[0], rs);
2144
    switch (opc) {
2145
    case OPC_CLO:
2146
        tcg_gen_helper_0_0(do_clo);
2147
        opn = "clo";
2148
        break;
2149
    case OPC_CLZ:
2150
        tcg_gen_helper_0_0(do_clz);
2151
        opn = "clz";
2152
        break;
2153
#if defined(TARGET_MIPS64)
2154
    case OPC_DCLO:
2155
        tcg_gen_helper_0_0(do_dclo);
2156
        opn = "dclo";
2157
        break;
2158
    case OPC_DCLZ:
2159
        tcg_gen_helper_0_0(do_dclz);
2160
        opn = "dclz";
2161
        break;
2162
#endif
2163
    default:
2164
        MIPS_INVAL(opn);
2165
        generate_exception(ctx, EXCP_RI);
2166
        return;
2167
    }
2168
    gen_store_gpr(cpu_T[0], rd);
2169
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2170
}
2171

    
2172
/* Traps */
2173
static void gen_trap (DisasContext *ctx, uint32_t opc,
2174
                      int rs, int rt, int16_t imm)
2175
{
2176
    int cond;
2177

    
2178
    cond = 0;
2179
    /* Load needed operands */
2180
    switch (opc) {
2181
    case OPC_TEQ:
2182
    case OPC_TGE:
2183
    case OPC_TGEU:
2184
    case OPC_TLT:
2185
    case OPC_TLTU:
2186
    case OPC_TNE:
2187
        /* Compare two registers */
2188
        if (rs != rt) {
2189
            gen_load_gpr(cpu_T[0], rs);
2190
            gen_load_gpr(cpu_T[1], rt);
2191
            cond = 1;
2192
        }
2193
        break;
2194
    case OPC_TEQI:
2195
    case OPC_TGEI:
2196
    case OPC_TGEIU:
2197
    case OPC_TLTI:
2198
    case OPC_TLTIU:
2199
    case OPC_TNEI:
2200
        /* Compare register to immediate */
2201
        if (rs != 0 || imm != 0) {
2202
            gen_load_gpr(cpu_T[0], rs);
2203
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2204
            cond = 1;
2205
        }
2206
        break;
2207
    }
2208
    if (cond == 0) {
2209
        switch (opc) {
2210
        case OPC_TEQ:   /* rs == rs */
2211
        case OPC_TEQI:  /* r0 == 0  */
2212
        case OPC_TGE:   /* rs >= rs */
2213
        case OPC_TGEI:  /* r0 >= 0  */
2214
        case OPC_TGEU:  /* rs >= rs unsigned */
2215
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2216
            /* Always trap */
2217
            tcg_gen_movi_tl(cpu_T[0], 1);
2218
            break;
2219
        case OPC_TLT:   /* rs < rs           */
2220
        case OPC_TLTI:  /* r0 < 0            */
2221
        case OPC_TLTU:  /* rs < rs unsigned  */
2222
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2223
        case OPC_TNE:   /* rs != rs          */
2224
        case OPC_TNEI:  /* r0 != 0           */
2225
            /* Never trap: treat as NOP. */
2226
            return;
2227
        default:
2228
            MIPS_INVAL("trap");
2229
            generate_exception(ctx, EXCP_RI);
2230
            return;
2231
        }
2232
    } else {
2233
        switch (opc) {
2234
        case OPC_TEQ:
2235
        case OPC_TEQI:
2236
            gen_op_eq();
2237
            break;
2238
        case OPC_TGE:
2239
        case OPC_TGEI:
2240
            gen_op_ge();
2241
            break;
2242
        case OPC_TGEU:
2243
        case OPC_TGEIU:
2244
            gen_op_geu();
2245
            break;
2246
        case OPC_TLT:
2247
        case OPC_TLTI:
2248
            gen_op_lt();
2249
            break;
2250
        case OPC_TLTU:
2251
        case OPC_TLTIU:
2252
            gen_op_ltu();
2253
            break;
2254
        case OPC_TNE:
2255
        case OPC_TNEI:
2256
            gen_op_ne();
2257
            break;
2258
        default:
2259
            MIPS_INVAL("trap");
2260
            generate_exception(ctx, EXCP_RI);
2261
            return;
2262
        }
2263
    }
2264
    save_cpu_state(ctx, 1);
2265
    gen_op_trap();
2266
    ctx->bstate = BS_STOP;
2267
}
2268

    
2269
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2270
{
2271
    TranslationBlock *tb;
2272
    tb = ctx->tb;
2273
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2274
        tcg_gen_goto_tb(n);
2275
        gen_save_pc(dest);
2276
        tcg_gen_exit_tb((long)tb + n);
2277
    } else {
2278
        gen_save_pc(dest);
2279
        tcg_gen_exit_tb(0);
2280
    }
2281
}
2282

    
2283
/* Branches (before delay slot) */
2284
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2285
                                int rs, int rt, int32_t offset)
2286
{
2287
    target_ulong btarget = -1;
2288
    int blink = 0;
2289
    int bcond = 0;
2290

    
2291
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2292
#ifdef MIPS_DEBUG_DISAS
2293
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2294
            fprintf(logfile,
2295
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2296
                    ctx->pc);
2297
        }
2298
#endif
2299
        generate_exception(ctx, EXCP_RI);
2300
        return;
2301
    }
2302

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

    
2515
    ctx->btarget = btarget;
2516
    if (blink > 0) {
2517
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2518
        gen_store_gpr(cpu_T[0], blink);
2519
    }
2520
}
2521

    
2522
/* special3 bitfield operations */
2523
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2524
                       int rs, int lsb, int msb)
2525
{
2526
    gen_load_gpr(cpu_T[1], rs);
2527
    switch (opc) {
2528
    case OPC_EXT:
2529
        if (lsb + msb > 31)
2530
            goto fail;
2531
        gen_op_ext(lsb, msb + 1);
2532
        break;
2533
#if defined(TARGET_MIPS64)
2534
    case OPC_DEXTM:
2535
        if (lsb + msb > 63)
2536
            goto fail;
2537
        gen_op_dext(lsb, msb + 1 + 32);
2538
        break;
2539
    case OPC_DEXTU:
2540
        if (lsb + msb > 63)
2541
            goto fail;
2542
        gen_op_dext(lsb + 32, msb + 1);
2543
        break;
2544
    case OPC_DEXT:
2545
        if (lsb + msb > 63)
2546
            goto fail;
2547
        gen_op_dext(lsb, msb + 1);
2548
        break;
2549
#endif
2550
    case OPC_INS:
2551
        if (lsb > msb)
2552
            goto fail;
2553
        gen_load_gpr(cpu_T[0], rt);
2554
        gen_op_ins(lsb, msb - lsb + 1);
2555
        break;
2556
#if defined(TARGET_MIPS64)
2557
    case OPC_DINSM:
2558
        if (lsb > msb)
2559
            goto fail;
2560
        gen_load_gpr(cpu_T[0], rt);
2561
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2562
        break;
2563
    case OPC_DINSU:
2564
        if (lsb > msb)
2565
            goto fail;
2566
        gen_load_gpr(cpu_T[0], rt);
2567
        gen_op_dins(lsb + 32, msb - lsb + 1);
2568
        break;
2569
    case OPC_DINS:
2570
        if (lsb > msb)
2571
            goto fail;
2572
        gen_load_gpr(cpu_T[0], rt);
2573
        gen_op_dins(lsb, msb - lsb + 1);
2574
        break;
2575
#endif
2576
    default:
2577
fail:
2578
        MIPS_INVAL("bitops");
2579
        generate_exception(ctx, EXCP_RI);
2580
        return;
2581
    }
2582
    gen_store_gpr(cpu_T[0], rt);
2583
}
2584

    
2585
/* CP0 (MMU and control) */
2586
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2587
{
2588
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2589

    
2590
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2591
    tcg_gen_ext_i32_tl(t, r_tmp);
2592
    tcg_temp_free(r_tmp);
2593
}
2594

    
2595
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2596
{
2597
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I64);
2598

    
2599
    tcg_gen_ld_i64(r_tmp, cpu_env, off);
2600
    tcg_gen_trunc_i64_tl(t, r_tmp);
2601
    tcg_temp_free(r_tmp);
2602
}
2603

    
2604
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2605
{
2606
    const char *rn = "invalid";
2607

    
2608
    if (sel != 0)
2609
        check_insn(env, ctx, ISA_MIPS32);
2610

    
2611
    switch (reg) {
2612
    case 0:
2613
        switch (sel) {
2614
        case 0:
2615
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
2616
            rn = "Index";
2617
            break;
2618
        case 1:
2619
            check_insn(env, ctx, ASE_MT);
2620
            gen_op_mfc0_mvpcontrol();
2621
            rn = "MVPControl";
2622
            break;
2623
        case 2:
2624
            check_insn(env, ctx, ASE_MT);
2625
            gen_op_mfc0_mvpconf0();
2626
            rn = "MVPConf0";
2627
            break;
2628
        case 3:
2629
            check_insn(env, ctx, ASE_MT);
2630
            gen_op_mfc0_mvpconf1();
2631
            rn = "MVPConf1";
2632
            break;
2633
        default:
2634
            goto die;
2635
        }
2636
        break;
2637
    case 1:
2638
        switch (sel) {
2639
        case 0:
2640
            gen_op_mfc0_random();
2641
            rn = "Random";
2642
            break;
2643
        case 1:
2644
            check_insn(env, ctx, ASE_MT);
2645
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
2646
            rn = "VPEControl";
2647
            break;
2648
        case 2:
2649
            check_insn(env, ctx, ASE_MT);
2650
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
2651
            rn = "VPEConf0";
2652
            break;
2653
        case 3:
2654
            check_insn(env, ctx, ASE_MT);
2655
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
2656
            rn = "VPEConf1";
2657
            break;
2658
        case 4:
2659
            check_insn(env, ctx, ASE_MT);
2660
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_YQMask));
2661
            rn = "YQMask";
2662
            break;
2663
        case 5:
2664
            check_insn(env, ctx, ASE_MT);
2665
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPESchedule));
2666
            rn = "VPESchedule";
2667
            break;
2668
        case 6:
2669
            check_insn(env, ctx, ASE_MT);
2670
            gen_mfc0_load64(cpu_T[0], offsetof(CPUState, CP0_VPEScheFBack));
2671
            rn = "VPEScheFBack";
2672
            break;
2673
        case 7:
2674
            check_insn(env, ctx, ASE_MT);
2675
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
2676
            rn = "VPEOpt";
2677
            break;
2678
        default:
2679
            goto die;
2680
        }
2681
        break;
2682
    case 2:
2683
        switch (sel) {
2684
        case 0:
2685
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2686
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2687
            rn = "EntryLo0";
2688
            break;
2689
        case 1:
2690
            check_insn(env, ctx, ASE_MT);
2691
            gen_op_mfc0_tcstatus();
2692
            rn = "TCStatus";
2693
            break;
2694
        case 2:
2695
            check_insn(env, ctx, ASE_MT);
2696
            gen_op_mfc0_tcbind();
2697
            rn = "TCBind";
2698
            break;
2699
        case 3:
2700
            check_insn(env, ctx, ASE_MT);
2701
            gen_op_mfc0_tcrestart();
2702
            rn = "TCRestart";
2703
            break;
2704
        case 4:
2705
            check_insn(env, ctx, ASE_MT);
2706
            gen_op_mfc0_tchalt();
2707
            rn = "TCHalt";
2708
            break;
2709
        case 5:
2710
            check_insn(env, ctx, ASE_MT);
2711
            gen_op_mfc0_tccontext();
2712
            rn = "TCContext";
2713
            break;
2714
        case 6:
2715
            check_insn(env, ctx, ASE_MT);
2716
            gen_op_mfc0_tcschedule();
2717
            rn = "TCSchedule";
2718
            break;
2719
        case 7:
2720
            check_insn(env, ctx, ASE_MT);
2721
            gen_op_mfc0_tcschefback();
2722
            rn = "TCScheFBack";
2723
            break;
2724
        default:
2725
            goto die;
2726
        }
2727
        break;
2728
    case 3:
2729
        switch (sel) {
2730
        case 0:
2731
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2732
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2733
            rn = "EntryLo1";
2734
            break;
2735
        default:
2736
            goto die;
2737
        }
2738
        break;
2739
    case 4:
2740
        switch (sel) {
2741
        case 0:
2742
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2743
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2744
            rn = "Context";
2745
            break;
2746
        case 1:
2747
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2748
            rn = "ContextConfig";
2749
//            break;
2750
        default:
2751
            goto die;
2752
        }
2753
        break;
2754
    case 5:
2755
        switch (sel) {
2756
        case 0:
2757
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
2758
            rn = "PageMask";
2759
            break;
2760
        case 1:
2761
            check_insn(env, ctx, ISA_MIPS32R2);
2762
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
2763
            rn = "PageGrain";
2764
            break;
2765
        default:
2766
            goto die;
2767
        }
2768
        break;
2769
    case 6:
2770
        switch (sel) {
2771
        case 0:
2772
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
2773
            rn = "Wired";
2774
            break;
2775
        case 1:
2776
            check_insn(env, ctx, ISA_MIPS32R2);
2777
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
2778
            rn = "SRSConf0";
2779
            break;
2780
        case 2:
2781
            check_insn(env, ctx, ISA_MIPS32R2);
2782
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
2783
            rn = "SRSConf1";
2784
            break;
2785
        case 3:
2786
            check_insn(env, ctx, ISA_MIPS32R2);
2787
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
2788
            rn = "SRSConf2";
2789
            break;
2790
        case 4:
2791
            check_insn(env, ctx, ISA_MIPS32R2);
2792
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
2793
            rn = "SRSConf3";
2794
            break;
2795
        case 5:
2796
            check_insn(env, ctx, ISA_MIPS32R2);
2797
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
2798
            rn = "SRSConf4";
2799
            break;
2800
        default:
2801
            goto die;
2802
        }
2803
        break;
2804
    case 7:
2805
        switch (sel) {
2806
        case 0:
2807
            check_insn(env, ctx, ISA_MIPS32R2);
2808
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
2809
            rn = "HWREna";
2810
            break;
2811
        default:
2812
            goto die;
2813
        }
2814
        break;
2815
    case 8:
2816
        switch (sel) {
2817
        case 0:
2818
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2819
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2820
            rn = "BadVAddr";
2821
            break;
2822
        default:
2823
            goto die;
2824
       }
2825
        break;
2826
    case 9:
2827
        switch (sel) {
2828
        case 0:
2829
            gen_op_mfc0_count();
2830
            rn = "Count";
2831
            break;
2832
        /* 6,7 are implementation dependent */
2833
        default:
2834
            goto die;
2835
        }
2836
        break;
2837
    case 10:
2838
        switch (sel) {
2839
        case 0:
2840
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2841
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2842
            rn = "EntryHi";
2843
            break;
2844
        default:
2845
            goto die;
2846
        }
2847
        break;
2848
    case 11:
2849
        switch (sel) {
2850
        case 0:
2851
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
2852
            rn = "Compare";
2853
            break;
2854
        /* 6,7 are implementation dependent */
2855
        default:
2856
            goto die;
2857
        }
2858
        break;
2859
    case 12:
2860
        switch (sel) {
2861
        case 0:
2862
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
2863
            rn = "Status";
2864
            break;
2865
        case 1:
2866
            check_insn(env, ctx, ISA_MIPS32R2);
2867
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
2868
            rn = "IntCtl";
2869
            break;
2870
        case 2:
2871
            check_insn(env, ctx, ISA_MIPS32R2);
2872
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
2873
            rn = "SRSCtl";
2874
            break;
2875
        case 3:
2876
            check_insn(env, ctx, ISA_MIPS32R2);
2877
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
2878
            rn = "SRSMap";
2879
            break;
2880
        default:
2881
            goto die;
2882
       }
2883
        break;
2884
    case 13:
2885
        switch (sel) {
2886
        case 0:
2887
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
2888
            rn = "Cause";
2889
            break;
2890
        default:
2891
            goto die;
2892
       }
2893
        break;
2894
    case 14:
2895
        switch (sel) {
2896
        case 0:
2897
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2898
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2899
            rn = "EPC";
2900
            break;
2901
        default:
2902
            goto die;
2903
        }
2904
        break;
2905
    case 15:
2906
        switch (sel) {
2907
        case 0:
2908
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
2909
            rn = "PRid";
2910
            break;
2911
        case 1:
2912
            check_insn(env, ctx, ISA_MIPS32R2);
2913
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
2914
            rn = "EBase";
2915
            break;
2916
        default:
2917
            goto die;
2918
       }
2919
        break;
2920
    case 16:
2921
        switch (sel) {
2922
        case 0:
2923
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
2924
            rn = "Config";
2925
            break;
2926
        case 1:
2927
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
2928
            rn = "Config1";
2929
            break;
2930
        case 2:
2931
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
2932
            rn = "Config2";
2933
            break;
2934
        case 3:
2935
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
2936
            rn = "Config3";
2937
            break;
2938
        /* 4,5 are reserved */
2939
        /* 6,7 are implementation dependent */
2940
        case 6:
2941
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
2942
            rn = "Config6";
2943
            break;
2944
        case 7:
2945
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
2946
            rn = "Config7";
2947
            break;
2948
        default:
2949
            goto die;
2950
        }
2951
        break;
2952
    case 17:
2953
        switch (sel) {
2954
        case 0:
2955
            gen_op_mfc0_lladdr();
2956
            rn = "LLAddr";
2957
            break;
2958
        default:
2959
            goto die;
2960
        }
2961
        break;
2962
    case 18:
2963
        switch (sel) {
2964
        case 0 ... 7:
2965
            gen_op_mfc0_watchlo(sel);
2966
            rn = "WatchLo";
2967
            break;
2968
        default:
2969
            goto die;
2970
        }
2971
        break;
2972
    case 19:
2973
        switch (sel) {
2974
        case 0 ...7:
2975
            gen_op_mfc0_watchhi(sel);
2976
            rn = "WatchHi";
2977
            break;
2978
        default:
2979
            goto die;
2980
        }
2981
        break;
2982
    case 20:
2983
        switch (sel) {
2984
        case 0:
2985
#if defined(TARGET_MIPS64)
2986
            check_insn(env, ctx, ISA_MIPS3);
2987
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2988
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2989
            rn = "XContext";
2990
            break;
2991
#endif
2992
        default:
2993
            goto die;
2994
        }
2995
        break;
2996
    case 21:
2997
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2998
        switch (sel) {
2999
        case 0:
3000
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
3001
            rn = "Framemask";
3002
            break;
3003
        default:
3004
            goto die;
3005
        }
3006
        break;
3007
    case 22:
3008
        /* ignored */
3009
        rn = "'Diagnostic"; /* implementation dependent */
3010
        break;
3011
    case 23:
3012
        switch (sel) {
3013
        case 0:
3014
            gen_op_mfc0_debug(); /* EJTAG support */
3015
            rn = "Debug";
3016
            break;
3017
        case 1:
3018
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3019
            rn = "TraceControl";
3020
//            break;
3021
        case 2:
3022
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3023
            rn = "TraceControl2";
3024
//            break;
3025
        case 3:
3026
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3027
            rn = "UserTraceData";
3028
//            break;
3029
        case 4:
3030
//            gen_op_mfc0_debug(); /* PDtrace support */
3031
            rn = "TraceBPC";
3032
//            break;
3033
        default:
3034
            goto die;
3035
        }
3036
        break;
3037
    case 24:
3038
        switch (sel) {
3039
        case 0:
3040
            /* EJTAG support */
3041
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3042
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3043
            rn = "DEPC";
3044
            break;
3045
        default:
3046
            goto die;
3047
        }
3048
        break;
3049
    case 25:
3050
        switch (sel) {
3051
        case 0:
3052
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
3053
            rn = "Performance0";
3054
            break;
3055
        case 1:
3056
//            gen_op_mfc0_performance1();
3057
            rn = "Performance1";
3058
//            break;
3059
        case 2:
3060
//            gen_op_mfc0_performance2();
3061
            rn = "Performance2";
3062
//            break;
3063
        case 3:
3064
//            gen_op_mfc0_performance3();
3065
            rn = "Performance3";
3066
//            break;
3067
        case 4:
3068
//            gen_op_mfc0_performance4();
3069
            rn = "Performance4";
3070
//            break;
3071
        case 5:
3072
//            gen_op_mfc0_performance5();
3073
            rn = "Performance5";
3074
//            break;
3075
        case 6:
3076
//            gen_op_mfc0_performance6();
3077
            rn = "Performance6";
3078
//            break;
3079
        case 7:
3080
//            gen_op_mfc0_performance7();
3081
            rn = "Performance7";
3082
//            break;
3083
        default:
3084
            goto die;
3085
        }
3086
        break;
3087
    case 26:
3088
       rn = "ECC";
3089
       break;
3090
    case 27:
3091
        switch (sel) {
3092
        /* ignored */
3093
        case 0 ... 3:
3094
            rn = "CacheErr";
3095
            break;
3096
        default:
3097
            goto die;
3098
        }
3099
        break;
3100
    case 28:
3101
        switch (sel) {
3102
        case 0:
3103
        case 2:
3104
        case 4:
3105
        case 6:
3106
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
3107
            rn = "TagLo";
3108
            break;
3109
        case 1:
3110
        case 3:
3111
        case 5:
3112
        case 7:
3113
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
3114
            rn = "DataLo";
3115
            break;
3116
        default:
3117
            goto die;
3118
        }
3119
        break;
3120
    case 29:
3121
        switch (sel) {
3122
        case 0:
3123
        case 2:
3124
        case 4:
3125
        case 6:
3126
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
3127
            rn = "TagHi";
3128
            break;
3129
        case 1:
3130
        case 3:
3131
        case 5:
3132
        case 7:
3133
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
3134
            rn = "DataHi";
3135
            break;
3136
        default:
3137
            goto die;
3138
        }
3139
        break;
3140
    case 30:
3141
        switch (sel) {
3142
        case 0:
3143
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3144
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3145
            rn = "ErrorEPC";
3146
            break;
3147
        default:
3148
            goto die;
3149
        }
3150
        break;
3151
    case 31:
3152
        switch (sel) {
3153
        case 0:
3154
            /* EJTAG support */
3155
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
3156
            rn = "DESAVE";
3157
            break;
3158
        default:
3159
            goto die;
3160
        }
3161
        break;
3162
    default:
3163
       goto die;
3164
    }
3165
#if defined MIPS_DEBUG_DISAS
3166
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3167
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3168
                rn, reg, sel);
3169
    }
3170
#endif
3171
    return;
3172

    
3173
die:
3174
#if defined MIPS_DEBUG_DISAS
3175
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3176
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3177
                rn, reg, sel);
3178
    }
3179
#endif
3180
    generate_exception(ctx, EXCP_RI);
3181
}
3182

    
3183
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3184
{
3185
    const char *rn = "invalid";
3186

    
3187
    if (sel != 0)
3188
        check_insn(env, ctx, ISA_MIPS32);
3189

    
3190
    switch (reg) {
3191
    case 0:
3192
        switch (sel) {
3193
        case 0:
3194
            gen_op_mtc0_index();
3195
            rn = "Index";
3196
            break;
3197
        case 1:
3198
            check_insn(env, ctx, ASE_MT);
3199
            gen_op_mtc0_mvpcontrol();
3200
            rn = "MVPControl";
3201
            break;
3202
        case 2:
3203
            check_insn(env, ctx, ASE_MT);
3204
            /* ignored */
3205
            rn = "MVPConf0";
3206
            break;
3207
        case 3:
3208
            check_insn(env, ctx, ASE_MT);
3209
            /* ignored */
3210
            rn = "MVPConf1";
3211
            break;
3212
        default:
3213
            goto die;
3214
        }
3215
        break;
3216
    case 1:
3217
        switch (sel) {
3218
        case 0:
3219
            /* ignored */
3220
            rn = "Random";
3221
            break;
3222
        case 1:
3223
            check_insn(env, ctx, ASE_MT);
3224
            gen_op_mtc0_vpecontrol();
3225
            rn = "VPEControl";
3226
            break;
3227
        case 2:
3228
            check_insn(env, ctx, ASE_MT);
3229
            gen_op_mtc0_vpeconf0();
3230
            rn = "VPEConf0";
3231
            break;
3232
        case 3:
3233
            check_insn(env, ctx, ASE_MT);
3234
            gen_op_mtc0_vpeconf1();
3235
            rn = "VPEConf1";
3236
            break;
3237
        case 4:
3238
            check_insn(env, ctx, ASE_MT);
3239
            gen_op_mtc0_yqmask();
3240
            rn = "YQMask";
3241
            break;
3242
        case 5:
3243
            check_insn(env, ctx, ASE_MT);
3244
            gen_op_mtc0_vpeschedule();
3245
            rn = "VPESchedule";
3246
            break;
3247
        case 6:
3248
            check_insn(env, ctx, ASE_MT);
3249
            gen_op_mtc0_vpeschefback();
3250
            rn = "VPEScheFBack";
3251
            break;
3252
        case 7:
3253
            check_insn(env, ctx, ASE_MT);
3254
            gen_op_mtc0_vpeopt();
3255
            rn = "VPEOpt";
3256
            break;
3257
        default:
3258
            goto die;
3259
        }
3260
        break;
3261
    case 2:
3262
        switch (sel) {
3263
        case 0:
3264
            gen_op_mtc0_entrylo0();
3265
            rn = "EntryLo0";
3266
            break;
3267
        case 1:
3268
            check_insn(env, ctx, ASE_MT);
3269
            gen_op_mtc0_tcstatus();
3270
            rn = "TCStatus";
3271
            break;
3272
        case 2:
3273
            check_insn(env, ctx, ASE_MT);
3274
            gen_op_mtc0_tcbind();
3275
            rn = "TCBind";
3276
            break;
3277
        case 3:
3278
            check_insn(env, ctx, ASE_MT);
3279
            gen_op_mtc0_tcrestart();
3280
            rn = "TCRestart";
3281
            break;
3282
        case 4:
3283
            check_insn(env, ctx, ASE_MT);
3284
            gen_op_mtc0_tchalt();
3285
            rn = "TCHalt";
3286
            break;
3287
        case 5:
3288
            check_insn(env, ctx, ASE_MT);
3289
            gen_op_mtc0_tccontext();
3290
            rn = "TCContext";
3291
            break;
3292
        case 6:
3293
            check_insn(env, ctx, ASE_MT);
3294
            gen_op_mtc0_tcschedule();
3295
            rn = "TCSchedule";
3296
            break;
3297
        case 7:
3298
            check_insn(env, ctx, ASE_MT);
3299
            gen_op_mtc0_tcschefback();
3300
            rn = "TCScheFBack";
3301
            break;
3302
        default:
3303
            goto die;
3304
        }
3305
        break;
3306
    case 3:
3307
        switch (sel) {
3308
        case 0:
3309
            gen_op_mtc0_entrylo1();
3310
            rn = "EntryLo1";
3311
            break;
3312
        default:
3313
            goto die;
3314
        }
3315
        break;
3316
    case 4:
3317
        switch (sel) {
3318
        case 0:
3319
            gen_op_mtc0_context();
3320
            rn = "Context";
3321
            break;
3322
        case 1:
3323
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3324
            rn = "ContextConfig";
3325
//            break;
3326
        default:
3327
            goto die;
3328
        }
3329
        break;
3330
    case 5:
3331
        switch (sel) {
3332
        case 0:
3333
            gen_op_mtc0_pagemask();
3334
            rn = "PageMask";
3335
            break;
3336
        case 1:
3337
            check_insn(env, ctx, ISA_MIPS32R2);
3338
            gen_op_mtc0_pagegrain();
3339
            rn = "PageGrain";
3340
            break;
3341
        default:
3342
            goto die;
3343
        }
3344
        break;
3345
    case 6:
3346
        switch (sel) {
3347
        case 0:
3348
            gen_op_mtc0_wired();
3349
            rn = "Wired";
3350
            break;
3351
        case 1:
3352
            check_insn(env, ctx, ISA_MIPS32R2);
3353
            gen_op_mtc0_srsconf0();
3354
            rn = "SRSConf0";
3355
            break;
3356
        case 2:
3357
            check_insn(env, ctx, ISA_MIPS32R2);
3358
            gen_op_mtc0_srsconf1();
3359
            rn = "SRSConf1";
3360
            break;
3361
        case 3:
3362
            check_insn(env, ctx, ISA_MIPS32R2);
3363
            gen_op_mtc0_srsconf2();
3364
            rn = "SRSConf2";
3365
            break;
3366
        case 4:
3367
            check_insn(env, ctx, ISA_MIPS32R2);
3368
            gen_op_mtc0_srsconf3();
3369
            rn = "SRSConf3";
3370
            break;
3371
        case 5:
3372
            check_insn(env, ctx, ISA_MIPS32R2);
3373
            gen_op_mtc0_srsconf4();
3374
            rn = "SRSConf4";
3375
            break;
3376
        default:
3377
            goto die;
3378
        }
3379
        break;
3380
    case 7:
3381
        switch (sel) {
3382
        case 0:
3383
            check_insn(env, ctx, ISA_MIPS32R2);
3384
            gen_op_mtc0_hwrena();
3385
            rn = "HWREna";
3386
            break;
3387
        default:
3388
            goto die;
3389
        }
3390
        break;
3391
    case 8:
3392
        /* ignored */
3393
        rn = "BadVAddr";
3394
        break;
3395
    case 9:
3396
        switch (sel) {
3397
        case 0:
3398
            gen_op_mtc0_count();
3399
            rn = "Count";
3400
            break;
3401
        /* 6,7 are implementation dependent */
3402
        default:
3403
            goto die;
3404
        }
3405
        /* Stop translation as we may have switched the execution mode */
3406
        ctx->bstate = BS_STOP;
3407
        break;
3408
    case 10:
3409
        switch (sel) {
3410
        case 0:
3411
            gen_op_mtc0_entryhi();
3412
            rn = "EntryHi";
3413
            break;
3414
        default:
3415
            goto die;
3416
        }
3417
        break;
3418
    case 11:
3419
        switch (sel) {
3420
        case 0:
3421
            gen_op_mtc0_compare();
3422
            rn = "Compare";
3423
            break;
3424
        /* 6,7 are implementation dependent */
3425
        default:
3426
            goto die;
3427
        }
3428
        /* Stop translation as we may have switched the execution mode */
3429
        ctx->bstate = BS_STOP;
3430
        break;
3431
    case 12:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_op_mtc0_status();
3435
            /* BS_STOP isn't good enough here, hflags may have changed. */
3436
            gen_save_pc(ctx->pc + 4);
3437
            ctx->bstate = BS_EXCP;
3438
            rn = "Status";
3439
            break;
3440
        case 1:
3441
            check_insn(env, ctx, ISA_MIPS32R2);
3442
            gen_op_mtc0_intctl();
3443
            /* Stop translation as we may have switched the execution mode */
3444
            ctx->bstate = BS_STOP;
3445
            rn = "IntCtl";
3446
            break;
3447
        case 2:
3448
            check_insn(env, ctx, ISA_MIPS32R2);
3449
            gen_op_mtc0_srsctl();
3450
            /* Stop translation as we may have switched the execution mode */
3451
            ctx->bstate = BS_STOP;
3452
            rn = "SRSCtl";
3453
            break;
3454
        case 3:
3455
            check_insn(env, ctx, ISA_MIPS32R2);
3456
            gen_op_mtc0_srsmap();
3457
            /* Stop translation as we may have switched the execution mode */
3458
            ctx->bstate = BS_STOP;
3459
            rn = "SRSMap";
3460
            break;
3461
        default:
3462
            goto die;
3463
        }
3464
        break;
3465
    case 13:
3466
        switch (sel) {
3467
        case 0:
3468
            gen_op_mtc0_cause();
3469
            rn = "Cause";
3470
            break;
3471
        default:
3472
            goto die;
3473
        }
3474
        /* Stop translation as we may have switched the execution mode */
3475
        ctx->bstate = BS_STOP;
3476
        break;
3477
    case 14:
3478
        switch (sel) {
3479
        case 0:
3480
            gen_op_mtc0_epc();
3481
            rn = "EPC";
3482
            break;
3483
        default:
3484
            goto die;
3485
        }
3486
        break;
3487
    case 15:
3488
        switch (sel) {
3489
        case 0:
3490
            /* ignored */
3491
            rn = "PRid";
3492
            break;
3493
        case 1:
3494
            check_insn(env, ctx, ISA_MIPS32R2);
3495
            gen_op_mtc0_ebase();
3496
            rn = "EBase";
3497
            break;
3498
        default:
3499
            goto die;
3500
        }
3501
        break;
3502
    case 16:
3503
        switch (sel) {
3504
        case 0:
3505
            gen_op_mtc0_config0();
3506
            rn = "Config";
3507
            /* Stop translation as we may have switched the execution mode */
3508
            ctx->bstate = BS_STOP;
3509
            break;
3510
        case 1:
3511
            /* ignored, read only */
3512
            rn = "Config1";
3513
            break;
3514
        case 2:
3515
            gen_op_mtc0_config2();
3516
            rn = "Config2";
3517
            /* Stop translation as we may have switched the execution mode */
3518
            ctx->bstate = BS_STOP;
3519
            break;
3520
        case 3:
3521
            /* ignored, read only */
3522
            rn = "Config3";
3523
            break;
3524
        /* 4,5 are reserved */
3525
        /* 6,7 are implementation dependent */
3526
        case 6:
3527
            /* ignored */
3528
            rn = "Config6";
3529
            break;
3530
        case 7:
3531
            /* ignored */
3532
            rn = "Config7";
3533
            break;
3534
        default:
3535
            rn = "Invalid config selector";
3536
            goto die;
3537
        }
3538
        break;
3539
    case 17:
3540
        switch (sel) {
3541
        case 0:
3542
            /* ignored */
3543
            rn = "LLAddr";
3544
            break;
3545
        default:
3546
            goto die;
3547
        }
3548
        break;
3549
    case 18:
3550
        switch (sel) {
3551
        case 0 ... 7:
3552
            gen_op_mtc0_watchlo(sel);
3553
            rn = "WatchLo";
3554
            break;
3555
        default:
3556
            goto die;
3557
        }
3558
        break;
3559
    case 19:
3560
        switch (sel) {
3561
        case 0 ... 7:
3562
            gen_op_mtc0_watchhi(sel);
3563
            rn = "WatchHi";
3564
            break;
3565
        default:
3566
            goto die;
3567
        }
3568
        break;
3569
    case 20:
3570
        switch (sel) {
3571
        case 0:
3572
#if defined(TARGET_MIPS64)
3573
            check_insn(env, ctx, ISA_MIPS3);
3574
            gen_op_mtc0_xcontext();
3575
            rn = "XContext";
3576
            break;
3577
#endif
3578
        default:
3579
            goto die;
3580
        }
3581
        break;
3582
    case 21:
3583
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3584
        switch (sel) {
3585
        case 0:
3586
            gen_op_mtc0_framemask();
3587
            rn = "Framemask";
3588
            break;
3589
        default:
3590
            goto die;
3591
        }
3592
        break;
3593
    case 22:
3594
        /* ignored */
3595
        rn = "Diagnostic"; /* implementation dependent */
3596
        break;
3597
    case 23:
3598
        switch (sel) {
3599
        case 0:
3600
            gen_op_mtc0_debug(); /* EJTAG support */
3601
            /* BS_STOP isn't good enough here, hflags may have changed. */
3602
            gen_save_pc(ctx->pc + 4);
3603
            ctx->bstate = BS_EXCP;
3604
            rn = "Debug";
3605
            break;
3606
        case 1:
3607
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3608
            rn = "TraceControl";
3609
            /* Stop translation as we may have switched the execution mode */
3610
            ctx->bstate = BS_STOP;
3611
//            break;
3612
        case 2:
3613
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3614
            rn = "TraceControl2";
3615
            /* Stop translation as we may have switched the execution mode */
3616
            ctx->bstate = BS_STOP;
3617
//            break;
3618
        case 3:
3619
            /* Stop translation as we may have switched the execution mode */
3620
            ctx->bstate = BS_STOP;
3621
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3622
            rn = "UserTraceData";
3623
            /* Stop translation as we may have switched the execution mode */
3624
            ctx->bstate = BS_STOP;
3625
//            break;
3626
        case 4:
3627
//            gen_op_mtc0_debug(); /* PDtrace support */
3628
            /* Stop translation as we may have switched the execution mode */
3629
            ctx->bstate = BS_STOP;
3630
            rn = "TraceBPC";
3631
//            break;
3632
        default:
3633
            goto die;
3634
        }
3635
        break;
3636
    case 24:
3637
        switch (sel) {
3638
        case 0:
3639
            gen_op_mtc0_depc(); /* EJTAG support */
3640
            rn = "DEPC";
3641
            break;
3642
        default:
3643
            goto die;
3644
        }
3645
        break;
3646
    case 25:
3647
        switch (sel) {
3648
        case 0:
3649
            gen_op_mtc0_performance0();
3650
            rn = "Performance0";
3651
            break;
3652
        case 1:
3653
//            gen_op_mtc0_performance1();
3654
            rn = "Performance1";
3655
//            break;
3656
        case 2:
3657
//            gen_op_mtc0_performance2();
3658
            rn = "Performance2";
3659
//            break;
3660
        case 3:
3661
//            gen_op_mtc0_performance3();
3662
            rn = "Performance3";
3663
//            break;
3664
        case 4:
3665
//            gen_op_mtc0_performance4();
3666
            rn = "Performance4";
3667
//            break;
3668
        case 5:
3669
//            gen_op_mtc0_performance5();
3670
            rn = "Performance5";
3671
//            break;
3672
        case 6:
3673
//            gen_op_mtc0_performance6();
3674
            rn = "Performance6";
3675
//            break;
3676
        case 7:
3677
//            gen_op_mtc0_performance7();
3678
            rn = "Performance7";
3679
//            break;
3680
        default:
3681
            goto die;
3682
        }
3683
       break;
3684
    case 26:
3685
        /* ignored */
3686
        rn = "ECC";
3687
        break;
3688
    case 27:
3689
        switch (sel) {
3690
        case 0 ... 3:
3691
            /* ignored */
3692
            rn = "CacheErr";
3693
            break;
3694
        default:
3695
            goto die;
3696
        }
3697
       break;
3698
    case 28:
3699
        switch (sel) {
3700
        case 0:
3701
        case 2:
3702
        case 4:
3703
        case 6:
3704
            gen_op_mtc0_taglo();
3705
            rn = "TagLo";
3706
            break;
3707
        case 1:
3708
        case 3:
3709
        case 5:
3710
        case 7:
3711
            gen_op_mtc0_datalo();
3712
            rn = "DataLo";
3713
            break;
3714
        default:
3715
            goto die;
3716
        }
3717
        break;
3718
    case 29:
3719
        switch (sel) {
3720
        case 0:
3721
        case 2:
3722
        case 4:
3723
        case 6:
3724
            gen_op_mtc0_taghi();
3725
            rn = "TagHi";
3726
            break;
3727
        case 1:
3728
        case 3:
3729
        case 5:
3730
        case 7:
3731
            gen_op_mtc0_datahi();
3732
            rn = "DataHi";
3733
            break;
3734
        default:
3735
            rn = "invalid sel";
3736
            goto die;
3737
        }
3738
       break;
3739
    case 30:
3740
        switch (sel) {
3741
        case 0:
3742
            gen_op_mtc0_errorepc();
3743
            rn = "ErrorEPC";
3744
            break;
3745
        default:
3746
            goto die;
3747
        }
3748
        break;
3749
    case 31:
3750
        switch (sel) {
3751
        case 0:
3752
            gen_op_mtc0_desave(); /* EJTAG support */
3753
            rn = "DESAVE";
3754
            break;
3755
        default:
3756
            goto die;
3757
        }
3758
        /* Stop translation as we may have switched the execution mode */
3759
        ctx->bstate = BS_STOP;
3760
        break;
3761
    default:
3762
       goto die;
3763
    }
3764
#if defined MIPS_DEBUG_DISAS
3765
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3766
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3767
                rn, reg, sel);
3768
    }
3769
#endif
3770
    return;
3771

    
3772
die:
3773
#if defined MIPS_DEBUG_DISAS
3774
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3775
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3776
                rn, reg, sel);
3777
    }
3778
#endif
3779
    generate_exception(ctx, EXCP_RI);
3780
}
3781

    
3782
#if defined(TARGET_MIPS64)
3783
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3784
{
3785
    const char *rn = "invalid";
3786

    
3787
    if (sel != 0)
3788
        check_insn(env, ctx, ISA_MIPS64);
3789

    
3790
    switch (reg) {
3791
    case 0:
3792
        switch (sel) {
3793
        case 0:
3794
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Index));
3795
            rn = "Index";
3796
            break;
3797
        case 1:
3798
            check_insn(env, ctx, ASE_MT);
3799
            gen_op_mfc0_mvpcontrol();
3800
            rn = "MVPControl";
3801
            break;
3802
        case 2:
3803
            check_insn(env, ctx, ASE_MT);
3804
            gen_op_mfc0_mvpconf0();
3805
            rn = "MVPConf0";
3806
            break;
3807
        case 3:
3808
            check_insn(env, ctx, ASE_MT);
3809
            gen_op_mfc0_mvpconf1();
3810
            rn = "MVPConf1";
3811
            break;
3812
        default:
3813
            goto die;
3814
        }
3815
        break;
3816
    case 1:
3817
        switch (sel) {
3818
        case 0:
3819
            gen_op_mfc0_random();
3820
            rn = "Random";
3821
            break;
3822
        case 1:
3823
            check_insn(env, ctx, ASE_MT);
3824
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEControl));
3825
            rn = "VPEControl";
3826
            break;
3827
        case 2:
3828
            check_insn(env, ctx, ASE_MT);
3829
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf0));
3830
            rn = "VPEConf0";
3831
            break;
3832
        case 3:
3833
            check_insn(env, ctx, ASE_MT);
3834
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEConf1));
3835
            rn = "VPEConf1";
3836
            break;
3837
        case 4:
3838
            check_insn(env, ctx, ASE_MT);
3839
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3840
            rn = "YQMask";
3841
            break;
3842
        case 5:
3843
            check_insn(env, ctx, ASE_MT);
3844
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3845
            rn = "VPESchedule";
3846
            break;
3847
        case 6:
3848
            check_insn(env, ctx, ASE_MT);
3849
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3850
            rn = "VPEScheFBack";
3851
            break;
3852
        case 7:
3853
            check_insn(env, ctx, ASE_MT);
3854
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_VPEOpt));
3855
            rn = "VPEOpt";
3856
            break;
3857
        default:
3858
            goto die;
3859
        }
3860
        break;
3861
    case 2:
3862
        switch (sel) {
3863
        case 0:
3864
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3865
            rn = "EntryLo0";
3866
            break;
3867
        case 1:
3868
            check_insn(env, ctx, ASE_MT);
3869
            gen_op_mfc0_tcstatus();
3870
            rn = "TCStatus";
3871
            break;
3872
        case 2:
3873
            check_insn(env, ctx, ASE_MT);
3874
            gen_op_mfc0_tcbind();
3875
            rn = "TCBind";
3876
            break;
3877
        case 3:
3878
            check_insn(env, ctx, ASE_MT);
3879
            gen_op_dmfc0_tcrestart();
3880
            rn = "TCRestart";
3881
            break;
3882
        case 4:
3883
            check_insn(env, ctx, ASE_MT);
3884
            gen_op_dmfc0_tchalt();
3885
            rn = "TCHalt";
3886
            break;
3887
        case 5:
3888
            check_insn(env, ctx, ASE_MT);
3889
            gen_op_dmfc0_tccontext();
3890
            rn = "TCContext";
3891
            break;
3892
        case 6:
3893
            check_insn(env, ctx, ASE_MT);
3894
            gen_op_dmfc0_tcschedule();
3895
            rn = "TCSchedule";
3896
            break;
3897
        case 7:
3898
            check_insn(env, ctx, ASE_MT);
3899
            gen_op_dmfc0_tcschefback();
3900
            rn = "TCScheFBack";
3901
            break;
3902
        default:
3903
            goto die;
3904
        }
3905
        break;
3906
    case 3:
3907
        switch (sel) {
3908
        case 0:
3909
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3910
            rn = "EntryLo1";
3911
            break;
3912
        default:
3913
            goto die;
3914
        }
3915
        break;
3916
    case 4:
3917
        switch (sel) {
3918
        case 0:
3919
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3920
            rn = "Context";
3921
            break;
3922
        case 1:
3923
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3924
            rn = "ContextConfig";
3925
//            break;
3926
        default:
3927
            goto die;
3928
        }
3929
        break;
3930
    case 5:
3931
        switch (sel) {
3932
        case 0:
3933
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageMask));
3934
            rn = "PageMask";
3935
            break;
3936
        case 1:
3937
            check_insn(env, ctx, ISA_MIPS32R2);
3938
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PageGrain));
3939
            rn = "PageGrain";
3940
            break;
3941
        default:
3942
            goto die;
3943
        }
3944
        break;
3945
    case 6:
3946
        switch (sel) {
3947
        case 0:
3948
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Wired));
3949
            rn = "Wired";
3950
            break;
3951
        case 1:
3952
            check_insn(env, ctx, ISA_MIPS32R2);
3953
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf0));
3954
            rn = "SRSConf0";
3955
            break;
3956
        case 2:
3957
            check_insn(env, ctx, ISA_MIPS32R2);
3958
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf1));
3959
            rn = "SRSConf1";
3960
            break;
3961
        case 3:
3962
            check_insn(env, ctx, ISA_MIPS32R2);
3963
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf2));
3964
            rn = "SRSConf2";
3965
            break;
3966
        case 4:
3967
            check_insn(env, ctx, ISA_MIPS32R2);
3968
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf3));
3969
            rn = "SRSConf3";
3970
            break;
3971
        case 5:
3972
            check_insn(env, ctx, ISA_MIPS32R2);
3973
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSConf4));
3974
            rn = "SRSConf4";
3975
            break;
3976
        default:
3977
            goto die;
3978
        }
3979
        break;
3980
    case 7:
3981
        switch (sel) {
3982
        case 0:
3983
            check_insn(env, ctx, ISA_MIPS32R2);
3984
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_HWREna));
3985
            rn = "HWREna";
3986
            break;
3987
        default:
3988
            goto die;
3989
        }
3990
        break;
3991
    case 8:
3992
        switch (sel) {
3993
        case 0:
3994
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
3995
            rn = "BadVAddr";
3996
            break;
3997
        default:
3998
            goto die;
3999
        }
4000
        break;
4001
    case 9:
4002
        switch (sel) {
4003
        case 0:
4004
            gen_op_mfc0_count();
4005
            rn = "Count";
4006
            break;
4007
        /* 6,7 are implementation dependent */
4008
        default:
4009
            goto die;
4010
        }
4011
        break;
4012
    case 10:
4013
        switch (sel) {
4014
        case 0:
4015
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4016
            rn = "EntryHi";
4017
            break;
4018
        default:
4019
            goto die;
4020
        }
4021
        break;
4022
    case 11:
4023
        switch (sel) {
4024
        case 0:
4025
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Compare));
4026
            rn = "Compare";
4027
            break;
4028
        /* 6,7 are implementation dependent */
4029
        default:
4030
            goto die;
4031
        }
4032
        break;
4033
    case 12:
4034
        switch (sel) {
4035
        case 0:
4036
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Status));
4037
            rn = "Status";
4038
            break;
4039
        case 1:
4040
            check_insn(env, ctx, ISA_MIPS32R2);
4041
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_IntCtl));
4042
            rn = "IntCtl";
4043
            break;
4044
        case 2:
4045
            check_insn(env, ctx, ISA_MIPS32R2);
4046
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSCtl));
4047
            rn = "SRSCtl";
4048
            break;
4049
        case 3:
4050
            check_insn(env, ctx, ISA_MIPS32R2);
4051
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_SRSMap));
4052
            rn = "SRSMap";
4053
            break;
4054
        default:
4055
            goto die;
4056
        }
4057
        break;
4058
    case 13:
4059
        switch (sel) {
4060
        case 0:
4061
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Cause));
4062
            rn = "Cause";
4063
            break;
4064
        default:
4065
            goto die;
4066
        }
4067
        break;
4068
    case 14:
4069
        switch (sel) {
4070
        case 0:
4071
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4072
            rn = "EPC";
4073
            break;
4074
        default:
4075
            goto die;
4076
        }
4077
        break;
4078
    case 15:
4079
        switch (sel) {
4080
        case 0:
4081
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_PRid));
4082
            rn = "PRid";
4083
            break;
4084
        case 1:
4085
            check_insn(env, ctx, ISA_MIPS32R2);
4086
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_EBase));
4087
            rn = "EBase";
4088
            break;
4089
        default:
4090
            goto die;
4091
        }
4092
        break;
4093
    case 16:
4094
        switch (sel) {
4095
        case 0:
4096
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config0));
4097
            rn = "Config";
4098
            break;
4099
        case 1:
4100
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config1));
4101
            rn = "Config1";
4102
            break;
4103
        case 2:
4104
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config2));
4105
            rn = "Config2";
4106
            break;
4107
        case 3:
4108
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config3));
4109
            rn = "Config3";
4110
            break;
4111
       /* 6,7 are implementation dependent */
4112
        case 6:
4113
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config6));
4114
            rn = "Config6";
4115
            break;
4116
        case 7:
4117
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Config7));
4118
            rn = "Config7";
4119
            break;
4120
        default:
4121
            goto die;
4122
        }
4123
        break;
4124
    case 17:
4125
        switch (sel) {
4126
        case 0:
4127
            gen_op_dmfc0_lladdr();
4128
            rn = "LLAddr";
4129
            break;
4130
        default:
4131
            goto die;
4132
        }
4133
        break;
4134
    case 18:
4135
        switch (sel) {
4136
        case 0 ... 7:
4137
            gen_op_dmfc0_watchlo(sel);
4138
            rn = "WatchLo";
4139
            break;
4140
        default:
4141
            goto die;
4142
        }
4143
        break;
4144
    case 19:
4145
        switch (sel) {
4146
        case 0 ... 7:
4147
            gen_op_mfc0_watchhi(sel);
4148
            rn = "WatchHi";
4149
            break;
4150
        default:
4151
            goto die;
4152
        }
4153
        break;
4154
    case 20:
4155
        switch (sel) {
4156
        case 0:
4157
            check_insn(env, ctx, ISA_MIPS3);
4158
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4159
            rn = "XContext";
4160
            break;
4161
        default:
4162
            goto die;
4163
        }
4164
        break;
4165
    case 21:
4166
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4167
        switch (sel) {
4168
        case 0:
4169
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Framemask));
4170
            rn = "Framemask";
4171
            break;
4172
        default:
4173
            goto die;
4174
        }
4175
        break;
4176
    case 22:
4177
        /* ignored */
4178
        rn = "'Diagnostic"; /* implementation dependent */
4179
        break;
4180
    case 23:
4181
        switch (sel) {
4182
        case 0:
4183
            gen_op_mfc0_debug(); /* EJTAG support */
4184
            rn = "Debug";
4185
            break;
4186
        case 1:
4187
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4188
            rn = "TraceControl";
4189
//            break;
4190
        case 2:
4191
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4192
            rn = "TraceControl2";
4193
//            break;
4194
        case 3:
4195
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4196
            rn = "UserTraceData";
4197
//            break;
4198
        case 4:
4199
//            gen_op_dmfc0_debug(); /* PDtrace support */
4200
            rn = "TraceBPC";
4201
//            break;
4202
        default:
4203
            goto die;
4204
        }
4205
        break;
4206
    case 24:
4207
        switch (sel) {
4208
        case 0:
4209
            /* EJTAG support */
4210
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4211
            rn = "DEPC";
4212
            break;
4213
        default:
4214
            goto die;
4215
        }
4216
        break;
4217
    case 25:
4218
        switch (sel) {
4219
        case 0:
4220
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_Performance0));
4221
            rn = "Performance0";
4222
            break;
4223
        case 1:
4224
//            gen_op_dmfc0_performance1();
4225
            rn = "Performance1";
4226
//            break;
4227
        case 2:
4228
//            gen_op_dmfc0_performance2();
4229
            rn = "Performance2";
4230
//            break;
4231
        case 3:
4232
//            gen_op_dmfc0_performance3();
4233
            rn = "Performance3";
4234
//            break;
4235
        case 4:
4236
//            gen_op_dmfc0_performance4();
4237
            rn = "Performance4";
4238
//            break;
4239
        case 5:
4240
//            gen_op_dmfc0_performance5();
4241
            rn = "Performance5";
4242
//            break;
4243
        case 6:
4244
//            gen_op_dmfc0_performance6();
4245
            rn = "Performance6";
4246
//            break;
4247
        case 7:
4248
//            gen_op_dmfc0_performance7();
4249
            rn = "Performance7";
4250
//            break;
4251
        default:
4252
            goto die;
4253
        }
4254
        break;
4255
    case 26:
4256
       rn = "ECC";
4257
       break;
4258
    case 27:
4259
        switch (sel) {
4260
        /* ignored */
4261
        case 0 ... 3:
4262
            rn = "CacheErr";
4263
            break;
4264
        default:
4265
            goto die;
4266
        }
4267
        break;
4268
    case 28:
4269
        switch (sel) {
4270
        case 0:
4271
        case 2:
4272
        case 4:
4273
        case 6:
4274
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagLo));
4275
            rn = "TagLo";
4276
            break;
4277
        case 1:
4278
        case 3:
4279
        case 5:
4280
        case 7:
4281
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataLo));
4282
            rn = "DataLo";
4283
            break;
4284
        default:
4285
            goto die;
4286
        }
4287
        break;
4288
    case 29:
4289
        switch (sel) {
4290
        case 0:
4291
        case 2:
4292
        case 4:
4293
        case 6:
4294
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_TagHi));
4295
            rn = "TagHi";
4296
            break;
4297
        case 1:
4298
        case 3:
4299
        case 5:
4300
        case 7:
4301
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DataHi));
4302
            rn = "DataHi";
4303
            break;
4304
        default:
4305
            goto die;
4306
        }
4307
        break;
4308
    case 30:
4309
        switch (sel) {
4310
        case 0:
4311
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4312
            rn = "ErrorEPC";
4313
            break;
4314
        default:
4315
            goto die;
4316
        }
4317
        break;
4318
    case 31:
4319
        switch (sel) {
4320
        case 0:
4321
            /* EJTAG support */
4322
            gen_mfc0_load32(cpu_T[0], offsetof(CPUState, CP0_DESAVE));
4323
            rn = "DESAVE";
4324
            break;
4325
        default:
4326
            goto die;
4327
        }
4328
        break;
4329
    default:
4330
        goto die;
4331
    }
4332
#if defined MIPS_DEBUG_DISAS
4333
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4334
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4335
                rn, reg, sel);
4336
    }
4337
#endif
4338
    return;
4339

    
4340
die:
4341
#if defined MIPS_DEBUG_DISAS
4342
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4343
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4344
                rn, reg, sel);
4345
    }
4346
#endif
4347
    generate_exception(ctx, EXCP_RI);
4348
}
4349

    
4350
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4351
{
4352
    const char *rn = "invalid";
4353

    
4354
    if (sel != 0)
4355
        check_insn(env, ctx, ISA_MIPS64);
4356

    
4357
    switch (reg) {
4358
    case 0:
4359
        switch (sel) {
4360
        case 0:
4361
            gen_op_mtc0_index();
4362
            rn = "Index";
4363
            break;
4364
        case 1:
4365
            check_insn(env, ctx, ASE_MT);
4366
            gen_op_mtc0_mvpcontrol();
4367
            rn = "MVPControl";
4368
            break;
4369
        case 2:
4370
            check_insn(env, ctx, ASE_MT);
4371
            /* ignored */
4372
            rn = "MVPConf0";
4373
            break;
4374
        case 3:
4375
            check_insn(env, ctx, ASE_MT);
4376
            /* ignored */
4377
            rn = "MVPConf1";
4378
            break;
4379
        default:
4380
            goto die;
4381
        }
4382
        break;
4383
    case 1:
4384
        switch (sel) {
4385
        case 0:
4386
            /* ignored */
4387
            rn = "Random";
4388
            break;
4389
        case 1:
4390
            check_insn(env, ctx, ASE_MT);
4391
            gen_op_mtc0_vpecontrol();
4392
            rn = "VPEControl";
4393
            break;
4394
        case 2:
4395
            check_insn(env, ctx, ASE_MT);
4396
            gen_op_mtc0_vpeconf0();
4397
            rn = "VPEConf0";
4398
            break;
4399
        case 3:
4400
            check_insn(env, ctx, ASE_MT);
4401
            gen_op_mtc0_vpeconf1();
4402
            rn = "VPEConf1";
4403
            break;
4404
        case 4:
4405
            check_insn(env, ctx, ASE_MT);
4406
            gen_op_mtc0_yqmask();
4407
            rn = "YQMask";
4408
            break;
4409
        case 5:
4410
            check_insn(env, ctx, ASE_MT);
4411
            gen_op_mtc0_vpeschedule();
4412
            rn = "VPESchedule";
4413
            break;
4414
        case 6:
4415
            check_insn(env, ctx, ASE_MT);
4416
            gen_op_mtc0_vpeschefback();
4417
            rn = "VPEScheFBack";
4418
            break;
4419
        case 7:
4420
            check_insn(env, ctx, ASE_MT);
4421
            gen_op_mtc0_vpeopt();
4422
            rn = "VPEOpt";
4423
            break;
4424
        default:
4425
            goto die;
4426
        }
4427
        break;
4428
    case 2:
4429
        switch (sel) {
4430
        case 0:
4431
            gen_op_mtc0_entrylo0();
4432
            rn = "EntryLo0";
4433
            break;
4434
        case 1:
4435
            check_insn(env, ctx, ASE_MT);
4436
            gen_op_mtc0_tcstatus();
4437
            rn = "TCStatus";
4438
            break;
4439
        case 2:
4440
            check_insn(env, ctx, ASE_MT);
4441
            gen_op_mtc0_tcbind();
4442
            rn = "TCBind";
4443
            break;
4444
        case 3:
4445
            check_insn(env, ctx, ASE_MT);
4446
            gen_op_mtc0_tcrestart();
4447
            rn = "TCRestart";
4448
            break;
4449
        case 4:
4450
            check_insn(env, ctx, ASE_MT);
4451
            gen_op_mtc0_tchalt();
4452
            rn = "TCHalt";
4453
            break;
4454
        case 5:
4455
            check_insn(env, ctx, ASE_MT);
4456
            gen_op_mtc0_tccontext();
4457
            rn = "TCContext";
4458
            break;
4459
        case 6:
4460
            check_insn(env, ctx, ASE_MT);
4461
            gen_op_mtc0_tcschedule();
4462
            rn = "TCSchedule";
4463
            break;
4464
        case 7:
4465
            check_insn(env, ctx, ASE_MT);
4466
            gen_op_mtc0_tcschefback();
4467
            rn = "TCScheFBack";
4468
            break;
4469
        default:
4470
            goto die;
4471
        }
4472
        break;
4473
    case 3:
4474
        switch (sel) {
4475
        case 0:
4476
            gen_op_mtc0_entrylo1();
4477
            rn = "EntryLo1";
4478
            break;
4479
        default:
4480
            goto die;
4481
        }
4482
        break;
4483
    case 4:
4484
        switch (sel) {
4485
        case 0:
4486
            gen_op_mtc0_context();
4487
            rn = "Context";
4488
            break;
4489
        case 1:
4490
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4491
            rn = "ContextConfig";
4492
//           break;
4493
        default:
4494
            goto die;
4495
        }
4496
        break;
4497
    case 5:
4498
        switch (sel) {
4499
        case 0:
4500
            gen_op_mtc0_pagemask();
4501
            rn = "PageMask";
4502
            break;
4503
        case 1:
4504
            check_insn(env, ctx, ISA_MIPS32R2);
4505
            gen_op_mtc0_pagegrain();
4506
            rn = "PageGrain";
4507
            break;
4508
        default:
4509
            goto die;
4510
        }
4511
        break;
4512
    case 6:
4513
        switch (sel) {
4514
        case 0:
4515
            gen_op_mtc0_wired();
4516
            rn = "Wired";
4517
            break;
4518
        case 1:
4519
            check_insn(env, ctx, ISA_MIPS32R2);
4520
            gen_op_mtc0_srsconf0();
4521
            rn = "SRSConf0";
4522
            break;
4523
        case 2:
4524
            check_insn(env, ctx, ISA_MIPS32R2);
4525
            gen_op_mtc0_srsconf1();
4526
            rn = "SRSConf1";
4527
            break;
4528
        case 3:
4529
            check_insn(env, ctx, ISA_MIPS32R2);
4530
            gen_op_mtc0_srsconf2();
4531
            rn = "SRSConf2";
4532
            break;
4533
        case 4:
4534
            check_insn(env, ctx, ISA_MIPS32R2);
4535
            gen_op_mtc0_srsconf3();
4536
            rn = "SRSConf3";
4537
            break;
4538
        case 5:
4539
            check_insn(env, ctx, ISA_MIPS32R2);
4540
            gen_op_mtc0_srsconf4();
4541
            rn = "SRSConf4";
4542
            break;
4543
        default:
4544
            goto die;
4545
        }
4546
        break;
4547
    case 7:
4548
        switch (sel) {
4549
        case 0:
4550
            check_insn(env, ctx, ISA_MIPS32R2);
4551
            gen_op_mtc0_hwrena();
4552
            rn = "HWREna";
4553
            break;
4554
        default:
4555
            goto die;
4556
        }
4557
        break;
4558
    case 8:
4559
        /* ignored */
4560
        rn = "BadVAddr";
4561
        break;
4562
    case 9:
4563
        switch (sel) {
4564
        case 0:
4565
            gen_op_mtc0_count();
4566
            rn = "Count";
4567
            break;
4568
        /* 6,7 are implementation dependent */
4569
        default:
4570
            goto die;
4571
        }
4572
        /* Stop translation as we may have switched the execution mode */
4573
        ctx->bstate = BS_STOP;
4574
        break;
4575
    case 10:
4576
        switch (sel) {
4577
        case 0:
4578
            gen_op_mtc0_entryhi();
4579
            rn = "EntryHi";
4580
            break;
4581
        default:
4582
            goto die;
4583
        }
4584
        break;
4585
    case 11:
4586
        switch (sel) {
4587
        case 0:
4588
            gen_op_mtc0_compare();
4589
            rn = "Compare";
4590
            break;
4591
        /* 6,7 are implementation dependent */
4592
        default:
4593
            goto die;
4594
        }
4595
        /* Stop translation as we may have switched the execution mode */
4596
        ctx->bstate = BS_STOP;
4597
        break;
4598
    case 12:
4599
        switch (sel) {
4600
        case 0:
4601
            gen_op_mtc0_status();
4602
            /* BS_STOP isn't good enough here, hflags may have changed. */
4603
            gen_save_pc(ctx->pc + 4);
4604
            ctx->bstate = BS_EXCP;
4605
            rn = "Status";
4606
            break;
4607
        case 1:
4608
            check_insn(env, ctx, ISA_MIPS32R2);
4609
            gen_op_mtc0_intctl();
4610
            /* Stop translation as we may have switched the execution mode */
4611
            ctx->bstate = BS_STOP;
4612
            rn = "IntCtl";
4613
            break;
4614
        case 2:
4615
            check_insn(env, ctx, ISA_MIPS32R2);
4616
            gen_op_mtc0_srsctl();
4617
            /* Stop translation as we may have switched the execution mode */
4618
            ctx->bstate = BS_STOP;
4619
            rn = "SRSCtl";
4620
            break;
4621
        case 3:
4622
            check_insn(env, ctx, ISA_MIPS32R2);
4623
            gen_op_mtc0_srsmap();
4624
            /* Stop translation as we may have switched the execution mode */
4625
            ctx->bstate = BS_STOP;
4626
            rn = "SRSMap";
4627
            break;
4628
        default:
4629
            goto die;
4630
        }
4631
        break;
4632
    case 13:
4633
        switch (sel) {
4634
        case 0:
4635
            gen_op_mtc0_cause();
4636
            rn = "Cause";
4637
            break;
4638
        default:
4639
            goto die;
4640
        }
4641
        /* Stop translation as we may have switched the execution mode */
4642
        ctx->bstate = BS_STOP;
4643
        break;
4644
    case 14:
4645
        switch (sel) {
4646
        case 0:
4647
            gen_op_mtc0_epc();
4648
            rn = "EPC";
4649
            break;
4650
        default:
4651
            goto die;
4652
        }
4653
        break;
4654
    case 15:
4655
        switch (sel) {
4656
        case 0:
4657
            /* ignored */
4658
            rn = "PRid";
4659
            break;
4660
        case 1:
4661
            check_insn(env, ctx, ISA_MIPS32R2);
4662
            gen_op_mtc0_ebase();
4663
            rn = "EBase";
4664
            break;
4665
        default:
4666
            goto die;
4667
        }
4668
        break;
4669
    case 16:
4670
        switch (sel) {
4671
        case 0:
4672
            gen_op_mtc0_config0();
4673
            rn = "Config";
4674
            /* Stop translation as we may have switched the execution mode */
4675
            ctx->bstate = BS_STOP;
4676
            break;
4677
        case 1:
4678
            /* ignored */
4679
            rn = "Config1";
4680
            break;
4681
        case 2:
4682
            gen_op_mtc0_config2();
4683
            rn = "Config2";
4684
            /* Stop translation as we may have switched the execution mode */
4685
            ctx->bstate = BS_STOP;
4686
            break;
4687
        case 3:
4688
            /* ignored */
4689
            rn = "Config3";
4690
            break;
4691
        /* 6,7 are implementation dependent */
4692
        default:
4693
            rn = "Invalid config selector";
4694
            goto die;
4695
        }
4696
        break;
4697
    case 17:
4698
        switch (sel) {
4699
        case 0:
4700
            /* ignored */
4701
            rn = "LLAddr";
4702
            break;
4703
        default:
4704
            goto die;
4705
        }
4706
        break;
4707
    case 18:
4708
        switch (sel) {
4709
        case 0 ... 7:
4710
            gen_op_mtc0_watchlo(sel);
4711
            rn = "WatchLo";
4712
            break;
4713
        default:
4714
            goto die;
4715
        }
4716
        break;
4717
    case 19:
4718
        switch (sel) {
4719
        case 0 ... 7:
4720
            gen_op_mtc0_watchhi(sel);
4721
            rn = "WatchHi";
4722
            break;
4723
        default:
4724
            goto die;
4725
        }
4726
        break;
4727
    case 20:
4728
        switch (sel) {
4729
        case 0:
4730
            check_insn(env, ctx, ISA_MIPS3);
4731
            gen_op_mtc0_xcontext();
4732
            rn = "XContext";
4733
            break;
4734
        default:
4735
            goto die;
4736
        }
4737
        break;
4738
    case 21:
4739
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4740
        switch (sel) {
4741
        case 0:
4742
            gen_op_mtc0_framemask();
4743
            rn = "Framemask";
4744
            break;
4745
        default:
4746
            goto die;
4747
        }
4748
        break;
4749
    case 22:
4750
        /* ignored */
4751
        rn = "Diagnostic"; /* implementation dependent */
4752
        break;
4753
    case 23:
4754
        switch (sel) {
4755
        case 0:
4756
            gen_op_mtc0_debug(); /* EJTAG support */
4757
            /* BS_STOP isn't good enough here, hflags may have changed. */
4758
            gen_save_pc(ctx->pc + 4);
4759
            ctx->bstate = BS_EXCP;
4760
            rn = "Debug";
4761
            break;
4762
        case 1:
4763
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
4764
            /* Stop translation as we may have switched the execution mode */
4765
            ctx->bstate = BS_STOP;
4766
            rn = "TraceControl";
4767
//            break;
4768
        case 2:
4769
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
4770
            /* Stop translation as we may have switched the execution mode */
4771
            ctx->bstate = BS_STOP;
4772
            rn = "TraceControl2";
4773
//            break;
4774
        case 3:
4775
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
4776
            /* Stop translation as we may have switched the execution mode */
4777
            ctx->bstate = BS_STOP;
4778
            rn = "UserTraceData";
4779
//            break;
4780
        case 4:
4781
//            gen_op_mtc0_debug(); /* PDtrace support */
4782
            /* Stop translation as we may have switched the execution mode */
4783
            ctx->bstate = BS_STOP;
4784
            rn = "TraceBPC";
4785
//            break;
4786
        default:
4787
            goto die;
4788
        }
4789
        break;
4790
    case 24:
4791
        switch (sel) {
4792
        case 0:
4793
            gen_op_mtc0_depc(); /* EJTAG support */
4794
            rn = "DEPC";
4795
            break;
4796
        default:
4797
            goto die;
4798
        }
4799
        break;
4800
    case 25:
4801
        switch (sel) {
4802
        case 0:
4803
            gen_op_mtc0_performance0();
4804
            rn = "Performance0";
4805
            break;
4806
        case 1:
4807
//            gen_op_mtc0_performance1();
4808
            rn = "Performance1";
4809
//            break;
4810
        case 2:
4811
//            gen_op_mtc0_performance2();
4812
            rn = "Performance2";
4813
//            break;
4814
        case 3:
4815
//            gen_op_mtc0_performance3();
4816
            rn = "Performance3";
4817
//            break;
4818
        case 4:
4819
//            gen_op_mtc0_performance4();
4820
            rn = "Performance4";
4821
//            break;
4822
        case 5:
4823
//            gen_op_mtc0_performance5();
4824
            rn = "Performance5";
4825
//            break;
4826
        case 6:
4827
//            gen_op_mtc0_performance6();
4828
            rn = "Performance6";
4829
//            break;
4830
        case 7:
4831
//            gen_op_mtc0_performance7();
4832
            rn = "Performance7";
4833
//            break;
4834
        default:
4835
            goto die;
4836
        }
4837
        break;
4838
    case 26:
4839
        /* ignored */
4840
        rn = "ECC";
4841
        break;
4842
    case 27:
4843
        switch (sel) {
4844
        case 0 ... 3:
4845
            /* ignored */
4846
            rn = "CacheErr";
4847
            break;
4848
        default:
4849
            goto die;
4850
        }
4851
        break;
4852
    case 28:
4853
        switch (sel) {
4854
        case 0:
4855
        case 2:
4856
        case 4:
4857
        case 6:
4858
            gen_op_mtc0_taglo();
4859
            rn = "TagLo";
4860
            break;
4861
        case 1:
4862
        case 3:
4863
        case 5:
4864
        case 7:
4865
            gen_op_mtc0_datalo();
4866
            rn = "DataLo";
4867
            break;
4868
        default:
4869
            goto die;
4870
        }
4871
        break;
4872
    case 29:
4873
        switch (sel) {
4874
        case 0:
4875
        case 2:
4876
        case 4:
4877
        case 6:
4878
            gen_op_mtc0_taghi();
4879
            rn = "TagHi";
4880
            break;
4881
        case 1:
4882
        case 3:
4883
        case 5:
4884
        case 7:
4885
            gen_op_mtc0_datahi();
4886
            rn = "DataHi";
4887
            break;
4888
        default:
4889
            rn = "invalid sel";
4890
            goto die;
4891
        }
4892
        break;
4893
    case 30:
4894
        switch (sel) {
4895
        case 0:
4896
            gen_op_mtc0_errorepc();
4897
            rn = "ErrorEPC";
4898
            break;
4899
        default:
4900
            goto die;
4901
        }
4902
        break;
4903
    case 31:
4904
        switch (sel) {
4905
        case 0:
4906
            gen_op_mtc0_desave(); /* EJTAG support */
4907
            rn = "DESAVE";
4908
            break;
4909
        default:
4910
            goto die;
4911
        }
4912
        /* Stop translation as we may have switched the execution mode */
4913
        ctx->bstate = BS_STOP;
4914
        break;
4915
    default:
4916
        goto die;
4917
    }
4918
#if defined MIPS_DEBUG_DISAS
4919
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4920
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4921
                rn, reg, sel);
4922
    }
4923
#endif
4924
    return;
4925

    
4926
die:
4927
#if defined MIPS_DEBUG_DISAS
4928
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4929
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4930
                rn, reg, sel);
4931
    }
4932
#endif
4933
    generate_exception(ctx, EXCP_RI);
4934
}
4935
#endif /* TARGET_MIPS64 */
4936

    
4937
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4938
                     int u, int sel, int h)
4939
{
4940
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4941

    
4942
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4943
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4944
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4945
        tcg_gen_movi_tl(cpu_T[0], -1);
4946
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4947
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4948
        tcg_gen_movi_tl(cpu_T[0], -1);
4949
    else if (u == 0) {
4950
        switch (rt) {
4951
        case 2:
4952
            switch (sel) {
4953
            case 1:
4954
                gen_op_mftc0_tcstatus();
4955
                break;
4956
            case 2:
4957
                gen_op_mftc0_tcbind();
4958
                break;
4959
            case 3:
4960
                gen_op_mftc0_tcrestart();
4961
                break;
4962
            case 4:
4963
                gen_op_mftc0_tchalt();
4964
                break;
4965
            case 5:
4966
                gen_op_mftc0_tccontext();
4967
                break;
4968
            case 6:
4969
                gen_op_mftc0_tcschedule();
4970
                break;
4971
            case 7:
4972
                gen_op_mftc0_tcschefback();
4973
                break;
4974
            default:
4975
                gen_mfc0(env, ctx, rt, sel);
4976
                break;
4977
            }
4978
            break;
4979
        case 10:
4980
            switch (sel) {
4981
            case 0:
4982
                gen_op_mftc0_entryhi();
4983
                break;
4984
            default:
4985
                gen_mfc0(env, ctx, rt, sel);
4986
                break;
4987
            }
4988
        case 12:
4989
            switch (sel) {
4990
            case 0:
4991
                gen_op_mftc0_status();
4992
                break;
4993
            default:
4994
                gen_mfc0(env, ctx, rt, sel);
4995
                break;
4996
            }
4997
        case 23:
4998
            switch (sel) {
4999
            case 0:
5000
                gen_op_mftc0_debug();
5001
                break;
5002
            default:
5003
                gen_mfc0(env, ctx, rt, sel);
5004
                break;
5005
            }
5006
            break;
5007
        default:
5008
            gen_mfc0(env, ctx, rt, sel);
5009
        }
5010
    } else switch (sel) {
5011
    /* GPR registers. */
5012
    case 0:
5013
        gen_op_mftgpr(rt);
5014
        break;
5015
    /* Auxiliary CPU registers */
5016
    case 1:
5017
        switch (rt) {
5018
        case 0:
5019
            gen_op_mftlo(0);
5020
            break;
5021
        case 1:
5022
            gen_op_mfthi(0);
5023
            break;
5024
        case 2:
5025
            gen_op_mftacx(0);
5026
            break;
5027
        case 4:
5028
            gen_op_mftlo(1);
5029
            break;
5030
        case 5:
5031
            gen_op_mfthi(1);
5032
            break;
5033
        case 6:
5034
            gen_op_mftacx(1);
5035
            break;
5036
        case 8:
5037
            gen_op_mftlo(2);
5038
            break;
5039
        case 9:
5040
            gen_op_mfthi(2);
5041
            break;
5042
        case 10:
5043
            gen_op_mftacx(2);
5044
            break;
5045
        case 12:
5046
            gen_op_mftlo(3);
5047
            break;
5048
        case 13:
5049
            gen_op_mfthi(3);
5050
            break;
5051
        case 14:
5052
            gen_op_mftacx(3);
5053
            break;
5054
        case 16:
5055
            gen_op_mftdsp();
5056
            break;
5057
        default:
5058
            goto die;
5059
        }
5060
        break;
5061
    /* Floating point (COP1). */
5062
    case 2:
5063
        /* XXX: For now we support only a single FPU context. */
5064
        if (h == 0) {
5065
            GEN_LOAD_FREG_FTN(WT0, rt);
5066
            gen_op_mfc1();
5067
        } else {
5068
            GEN_LOAD_FREG_FTN(WTH0, rt);
5069
            gen_op_mfhc1();
5070
        }
5071
        break;
5072
    case 3:
5073
        /* XXX: For now we support only a single FPU context. */
5074
        gen_op_cfc1(rt);
5075
        break;
5076
    /* COP2: Not implemented. */
5077
    case 4:
5078
    case 5:
5079
        /* fall through */
5080
    default:
5081
        goto die;
5082
    }
5083
#if defined MIPS_DEBUG_DISAS
5084
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5085
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5086
                rt, u, sel, h);
5087
    }
5088
#endif
5089
    return;
5090

    
5091
die:
5092
#if defined MIPS_DEBUG_DISAS
5093
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5094
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5095
                rt, u, sel, h);
5096
    }
5097
#endif
5098
    generate_exception(ctx, EXCP_RI);
5099
}
5100

    
5101
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5102
                     int u, int sel, int h)
5103
{
5104
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5105

    
5106
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5107
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5108
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5109
        /* NOP */ ;
5110
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5111
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5112
        /* NOP */ ;
5113
    else if (u == 0) {
5114
        switch (rd) {
5115
        case 2:
5116
            switch (sel) {
5117
            case 1:
5118
                gen_op_mttc0_tcstatus();
5119
                break;
5120
            case 2:
5121
                gen_op_mttc0_tcbind();
5122
                break;
5123
            case 3:
5124
                gen_op_mttc0_tcrestart();
5125
                break;
5126
            case 4:
5127
                gen_op_mttc0_tchalt();
5128
                break;
5129
            case 5:
5130
                gen_op_mttc0_tccontext();
5131
                break;
5132
            case 6:
5133
                gen_op_mttc0_tcschedule();
5134
                break;
5135
            case 7:
5136
                gen_op_mttc0_tcschefback();
5137
                break;
5138
            default:
5139
                gen_mtc0(env, ctx, rd, sel);
5140
                break;
5141
            }
5142
            break;
5143
        case 10:
5144
            switch (sel) {
5145
            case 0:
5146
                gen_op_mttc0_entryhi();
5147
                break;
5148
            default:
5149
                gen_mtc0(env, ctx, rd, sel);
5150
                break;
5151
            }
5152
        case 12:
5153
            switch (sel) {
5154
            case 0:
5155
                gen_op_mttc0_status();
5156
                break;
5157
            default:
5158
                gen_mtc0(env, ctx, rd, sel);
5159
                break;
5160
            }
5161
        case 23:
5162
            switch (sel) {
5163
            case 0:
5164
                gen_op_mttc0_debug();
5165
                break;
5166
            default:
5167
                gen_mtc0(env, ctx, rd, sel);
5168
                break;
5169
            }
5170
            break;
5171
        default:
5172
            gen_mtc0(env, ctx, rd, sel);
5173
        }
5174
    } else switch (sel) {
5175
    /* GPR registers. */
5176
    case 0:
5177
        gen_op_mttgpr(rd);
5178
        break;
5179
    /* Auxiliary CPU registers */
5180
    case 1:
5181
        switch (rd) {
5182
        case 0:
5183
            gen_op_mttlo(0);
5184
            break;
5185
        case 1:
5186
            gen_op_mtthi(0);
5187
            break;
5188
        case 2:
5189
            gen_op_mttacx(0);
5190
            break;
5191
        case 4:
5192
            gen_op_mttlo(1);
5193
            break;
5194
        case 5:
5195
            gen_op_mtthi(1);
5196
            break;
5197
        case 6:
5198
            gen_op_mttacx(1);
5199
            break;
5200
        case 8:
5201
            gen_op_mttlo(2);
5202
            break;
5203
        case 9:
5204
            gen_op_mtthi(2);
5205
            break;
5206
        case 10:
5207
            gen_op_mttacx(2);
5208
            break;
5209
        case 12:
5210
            gen_op_mttlo(3);
5211
            break;
5212
        case 13:
5213
            gen_op_mtthi(3);
5214
            break;
5215
        case 14:
5216
            gen_op_mttacx(3);
5217
            break;
5218
        case 16:
5219
            gen_op_mttdsp();
5220
            break;
5221
        default:
5222
            goto die;
5223
        }
5224
        break;
5225
    /* Floating point (COP1). */
5226
    case 2:
5227
        /* XXX: For now we support only a single FPU context. */
5228
        if (h == 0) {
5229
            gen_op_mtc1();
5230
            GEN_STORE_FTN_FREG(rd, WT0);
5231
        } else {
5232
            gen_op_mthc1();
5233
            GEN_STORE_FTN_FREG(rd, WTH0);
5234
        }
5235
        break;
5236
    case 3:
5237
        /* XXX: For now we support only a single FPU context. */
5238
        gen_op_ctc1(rd);
5239
        break;
5240
    /* COP2: Not implemented. */
5241
    case 4:
5242
    case 5:
5243
        /* fall through */
5244
    default:
5245
        goto die;
5246
    }
5247
#if defined MIPS_DEBUG_DISAS
5248
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5249
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5250
                rd, u, sel, h);
5251
    }
5252
#endif
5253
    return;
5254

    
5255
die:
5256
#if defined MIPS_DEBUG_DISAS
5257
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5258
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5259
                rd, u, sel, h);
5260
    }
5261
#endif
5262
    generate_exception(ctx, EXCP_RI);
5263
}
5264

    
5265
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5266
{
5267
    const char *opn = "ldst";
5268

    
5269
    switch (opc) {
5270
    case OPC_MFC0:
5271
        if (rt == 0) {
5272
            /* Treat as NOP. */
5273
            return;
5274
        }
5275
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5276
        gen_store_gpr(cpu_T[0], rt);
5277
        opn = "mfc0";
5278
        break;
5279
    case OPC_MTC0:
5280
        gen_load_gpr(cpu_T[0], rt);
5281
        save_cpu_state(ctx, 1);
5282
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5283
        opn = "mtc0";
5284
        break;
5285
#if defined(TARGET_MIPS64)
5286
    case OPC_DMFC0:
5287
        check_insn(env, ctx, ISA_MIPS3);
5288
        if (rt == 0) {
5289
            /* Treat as NOP. */
5290
            return;
5291
        }
5292
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5293
        gen_store_gpr(cpu_T[0], rt);
5294
        opn = "dmfc0";
5295
        break;
5296
    case OPC_DMTC0:
5297
        check_insn(env, ctx, ISA_MIPS3);
5298
        gen_load_gpr(cpu_T[0], rt);
5299
        save_cpu_state(ctx, 1);
5300
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5301
        opn = "dmtc0";
5302
        break;
5303
#endif
5304
    case OPC_MFTR:
5305
        check_insn(env, ctx, ASE_MT);
5306
        if (rd == 0) {
5307
            /* Treat as NOP. */
5308
            return;
5309
        }
5310
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5311
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5312
        gen_store_gpr(cpu_T[0], rd);
5313
        opn = "mftr";
5314
        break;
5315
    case OPC_MTTR:
5316
        check_insn(env, ctx, ASE_MT);
5317
        gen_load_gpr(cpu_T[0], rt);
5318
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5319
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5320
        opn = "mttr";
5321
        break;
5322
    case OPC_TLBWI:
5323
        opn = "tlbwi";
5324
        if (!env->tlb->do_tlbwi)
5325
            goto die;
5326
        gen_op_tlbwi();
5327
        break;
5328
    case OPC_TLBWR:
5329
        opn = "tlbwr";
5330
        if (!env->tlb->do_tlbwr)
5331
            goto die;
5332
        gen_op_tlbwr();
5333
        break;
5334
    case OPC_TLBP:
5335
        opn = "tlbp";
5336
        if (!env->tlb->do_tlbp)
5337
            goto die;
5338
        gen_op_tlbp();
5339
        break;
5340
    case OPC_TLBR:
5341
        opn = "tlbr";
5342
        if (!env->tlb->do_tlbr)
5343
            goto die;
5344
        gen_op_tlbr();
5345
        break;
5346
    case OPC_ERET:
5347
        opn = "eret";
5348
        check_insn(env, ctx, ISA_MIPS2);
5349
        save_cpu_state(ctx, 1);
5350
        gen_op_eret();
5351
        ctx->bstate = BS_EXCP;
5352
        break;
5353
    case OPC_DERET:
5354
        opn = "deret";
5355
        check_insn(env, ctx, ISA_MIPS32);
5356
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5357
            MIPS_INVAL(opn);
5358
            generate_exception(ctx, EXCP_RI);
5359
        } else {
5360
            save_cpu_state(ctx, 1);
5361
            gen_op_deret();
5362
            ctx->bstate = BS_EXCP;
5363
        }
5364
        break;
5365
    case OPC_WAIT:
5366
        opn = "wait";
5367
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5368
        /* If we get an exception, we want to restart at next instruction */
5369
        ctx->pc += 4;
5370
        save_cpu_state(ctx, 1);
5371
        ctx->pc -= 4;
5372
        gen_op_wait();
5373
        ctx->bstate = BS_EXCP;
5374
        break;
5375
    default:
5376
 die:
5377
        MIPS_INVAL(opn);
5378
        generate_exception(ctx, EXCP_RI);
5379
        return;
5380
    }
5381
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5382
}
5383

    
5384
/* CP1 Branches (before delay slot) */
5385
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5386
                                 int32_t cc, int32_t offset)
5387
{
5388
    target_ulong btarget;
5389
    const char *opn = "cp1 cond branch";
5390

    
5391
    if (cc != 0)
5392
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5393

    
5394
    btarget = ctx->pc + 4 + offset;
5395

    
5396
    switch (op) {
5397
    case OPC_BC1F:
5398
        gen_op_bc1f(cc);
5399
        opn = "bc1f";
5400
        goto not_likely;
5401
    case OPC_BC1FL:
5402
        gen_op_bc1f(cc);
5403
        opn = "bc1fl";
5404
        goto likely;
5405
    case OPC_BC1T:
5406
        gen_op_bc1t(cc);
5407
        opn = "bc1t";
5408
        goto not_likely;
5409
    case OPC_BC1TL:
5410
        gen_op_bc1t(cc);
5411
        opn = "bc1tl";
5412
    likely:
5413
        ctx->hflags |= MIPS_HFLAG_BL;
5414
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5415
        break;
5416
    case OPC_BC1FANY2:
5417
        gen_op_bc1any2f(cc);
5418
        opn = "bc1any2f";
5419
        goto not_likely;
5420
    case OPC_BC1TANY2:
5421
        gen_op_bc1any2t(cc);
5422
        opn = "bc1any2t";
5423
        goto not_likely;
5424
    case OPC_BC1FANY4:
5425
        gen_op_bc1any4f(cc);
5426
        opn = "bc1any4f";
5427
        goto not_likely;
5428
    case OPC_BC1TANY4:
5429
        gen_op_bc1any4t(cc);
5430
        opn = "bc1any4t";
5431
    not_likely:
5432
        ctx->hflags |= MIPS_HFLAG_BC;
5433
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5434
        break;
5435
    default:
5436
        MIPS_INVAL(opn);
5437
        generate_exception (ctx, EXCP_RI);
5438
        return;
5439
    }
5440
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5441
               ctx->hflags, btarget);
5442
    ctx->btarget = btarget;
5443
}
5444

    
5445
/* Coprocessor 1 (FPU) */
5446

    
5447
#define FOP(func, fmt) (((fmt) << 21) | (func))
5448

    
5449
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5450
{
5451
    const char *opn = "cp1 move";
5452

    
5453
    switch (opc) {
5454
    case OPC_MFC1:
5455
        GEN_LOAD_FREG_FTN(WT0, fs);
5456
        gen_op_mfc1();
5457
        gen_store_gpr(cpu_T[0], rt);
5458
        opn = "mfc1";
5459
        break;
5460
    case OPC_MTC1:
5461
        gen_load_gpr(cpu_T[0], rt);
5462
        gen_op_mtc1();
5463
        GEN_STORE_FTN_FREG(fs, WT0);
5464
        opn = "mtc1";
5465
        break;
5466
    case OPC_CFC1:
5467
        gen_op_cfc1(fs);
5468
        gen_store_gpr(cpu_T[0], rt);
5469
        opn = "cfc1";
5470
        break;
5471
    case OPC_CTC1:
5472
        gen_load_gpr(cpu_T[0], rt);
5473
        gen_op_ctc1(fs);
5474
        opn = "ctc1";
5475
        break;
5476
    case OPC_DMFC1:
5477
        GEN_LOAD_FREG_FTN(DT0, fs);
5478
        gen_op_dmfc1();
5479
        gen_store_gpr(cpu_T[0], rt);
5480
        opn = "dmfc1";
5481
        break;
5482
    case OPC_DMTC1:
5483
        gen_load_gpr(cpu_T[0], rt);
5484
        gen_op_dmtc1();
5485
        GEN_STORE_FTN_FREG(fs, DT0);
5486
        opn = "dmtc1";
5487
        break;
5488
    case OPC_MFHC1:
5489
        GEN_LOAD_FREG_FTN(WTH0, fs);
5490
        gen_op_mfhc1();
5491
        gen_store_gpr(cpu_T[0], rt);
5492
        opn = "mfhc1";
5493
        break;
5494
    case OPC_MTHC1:
5495
        gen_load_gpr(cpu_T[0], rt);
5496
        gen_op_mthc1();
5497
        GEN_STORE_FTN_FREG(fs, WTH0);
5498
        opn = "mthc1";
5499
        break;
5500
    default:
5501
        MIPS_INVAL(opn);
5502
        generate_exception (ctx, EXCP_RI);
5503
        return;
5504
    }
5505
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5506
}
5507

    
5508
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5509
{
5510
    int l1 = gen_new_label();
5511
    uint32_t ccbit;
5512
    TCGCond cond;
5513

    
5514
    if (cc)
5515
        ccbit = 1 << (24 + cc);
5516
    else
5517
        ccbit = 1 << 23;
5518
    if (tf)
5519
        cond = TCG_COND_EQ;
5520
    else
5521
        cond = TCG_COND_NE;
5522

    
5523
    gen_load_gpr(cpu_T[0], rd);
5524
    gen_load_gpr(cpu_T[1], rs);
5525
    {
5526
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5527
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
5528

    
5529
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5530
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5531
        tcg_temp_free(r_ptr);
5532
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5533
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5534
    }
5535
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5536

    
5537
    gen_set_label(l1);
5538
    gen_store_gpr(cpu_T[0], rd);
5539
}
5540

    
5541
#define GEN_MOVCF(fmt)                                                \
5542
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5543
{                                                                     \
5544
    uint32_t ccbit;                                                   \
5545
                                                                      \
5546
    if (cc) {                                                         \
5547
        ccbit = 1 << (24 + cc);                                       \
5548
    } else                                                            \
5549
        ccbit = 1 << 23;                                              \
5550
    if (!tf)                                                          \
5551
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5552
    else                                                              \
5553
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5554
}
5555
GEN_MOVCF(d);
5556
GEN_MOVCF(s);
5557
#undef GEN_MOVCF
5558

    
5559
static void gen_farith (DisasContext *ctx, uint32_t op1,
5560
                        int ft, int fs, int fd, int cc)
5561
{
5562
    const char *opn = "farith";
5563
    const char *condnames[] = {
5564
            "c.f",
5565
            "c.un",
5566
            "c.eq",
5567
            "c.ueq",
5568
            "c.olt",
5569
            "c.ult",
5570
            "c.ole",
5571
            "c.ule",
5572
            "c.sf",
5573
            "c.ngle",
5574
            "c.seq",
5575
            "c.ngl",
5576
            "c.lt",
5577
            "c.nge",
5578
            "c.le",
5579
            "c.ngt",
5580
    };
5581
    const char *condnames_abs[] = {
5582
            "cabs.f",
5583
            "cabs.un",
5584
            "cabs.eq",
5585
            "cabs.ueq",
5586
            "cabs.olt",
5587
            "cabs.ult",
5588
            "cabs.ole",
5589
            "cabs.ule",
5590
            "cabs.sf",
5591
            "cabs.ngle",
5592
            "cabs.seq",
5593
            "cabs.ngl",
5594
            "cabs.lt",
5595
            "cabs.nge",
5596
            "cabs.le",
5597
            "cabs.ngt",
5598
    };
5599
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5600
    uint32_t func = ctx->opcode & 0x3f;
5601

    
5602
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5603
    case FOP(0, 16):
5604
        GEN_LOAD_FREG_FTN(WT0, fs);
5605
        GEN_LOAD_FREG_FTN(WT1, ft);
5606
        gen_op_float_add_s();
5607
        GEN_STORE_FTN_FREG(fd, WT2);
5608
        opn = "add.s";
5609
        optype = BINOP;
5610
        break;
5611
    case FOP(1, 16):
5612
        GEN_LOAD_FREG_FTN(WT0, fs);
5613
        GEN_LOAD_FREG_FTN(WT1, ft);
5614
        gen_op_float_sub_s();
5615
        GEN_STORE_FTN_FREG(fd, WT2);
5616
        opn = "sub.s";
5617
        optype = BINOP;
5618
        break;
5619
    case FOP(2, 16):
5620
        GEN_LOAD_FREG_FTN(WT0, fs);
5621
        GEN_LOAD_FREG_FTN(WT1, ft);
5622
        gen_op_float_mul_s();
5623
        GEN_STORE_FTN_FREG(fd, WT2);
5624
        opn = "mul.s";
5625
        optype = BINOP;
5626
        break;
5627
    case FOP(3, 16):
5628
        GEN_LOAD_FREG_FTN(WT0, fs);
5629
        GEN_LOAD_FREG_FTN(WT1, ft);
5630
        gen_op_float_div_s();
5631
        GEN_STORE_FTN_FREG(fd, WT2);
5632
        opn = "div.s";
5633
        optype = BINOP;
5634
        break;
5635
    case FOP(4, 16):
5636
        GEN_LOAD_FREG_FTN(WT0, fs);
5637
        gen_op_float_sqrt_s();
5638
        GEN_STORE_FTN_FREG(fd, WT2);
5639
        opn = "sqrt.s";
5640
        break;
5641
    case FOP(5, 16):
5642
        GEN_LOAD_FREG_FTN(WT0, fs);
5643
        gen_op_float_abs_s();
5644
        GEN_STORE_FTN_FREG(fd, WT2);
5645
        opn = "abs.s";
5646
        break;
5647
    case FOP(6, 16):
5648
        GEN_LOAD_FREG_FTN(WT0, fs);
5649
        gen_op_float_mov_s();
5650
        GEN_STORE_FTN_FREG(fd, WT2);
5651
        opn = "mov.s";
5652
        break;
5653
    case FOP(7, 16):
5654
        GEN_LOAD_FREG_FTN(WT0, fs);
5655
        gen_op_float_chs_s();
5656
        GEN_STORE_FTN_FREG(fd, WT2);
5657
        opn = "neg.s";
5658
        break;
5659
    case FOP(8, 16):
5660
        check_cp1_64bitmode(ctx);
5661
        GEN_LOAD_FREG_FTN(WT0, fs);
5662
        gen_op_float_roundl_s();
5663
        GEN_STORE_FTN_FREG(fd, DT2);
5664
        opn = "round.l.s";
5665
        break;
5666
    case FOP(9, 16):
5667
        check_cp1_64bitmode(ctx);
5668
        GEN_LOAD_FREG_FTN(WT0, fs);
5669
        gen_op_float_truncl_s();
5670
        GEN_STORE_FTN_FREG(fd, DT2);
5671
        opn = "trunc.l.s";
5672
        break;
5673
    case FOP(10, 16):
5674
        check_cp1_64bitmode(ctx);
5675
        GEN_LOAD_FREG_FTN(WT0, fs);
5676
        gen_op_float_ceill_s();
5677
        GEN_STORE_FTN_FREG(fd, DT2);
5678
        opn = "ceil.l.s";
5679
        break;
5680
    case FOP(11, 16):
5681
        check_cp1_64bitmode(ctx);
5682
        GEN_LOAD_FREG_FTN(WT0, fs);
5683
        gen_op_float_floorl_s();
5684
        GEN_STORE_FTN_FREG(fd, DT2);
5685
        opn = "floor.l.s";
5686
        break;
5687
    case FOP(12, 16):
5688
        GEN_LOAD_FREG_FTN(WT0, fs);
5689
        gen_op_float_roundw_s();
5690
        GEN_STORE_FTN_FREG(fd, WT2);
5691
        opn = "round.w.s";
5692
        break;
5693
    case FOP(13, 16):
5694
        GEN_LOAD_FREG_FTN(WT0, fs);
5695
        gen_op_float_truncw_s();
5696
        GEN_STORE_FTN_FREG(fd, WT2);
5697
        opn = "trunc.w.s";
5698
        break;
5699
    case FOP(14, 16):
5700
        GEN_LOAD_FREG_FTN(WT0, fs);
5701
        gen_op_float_ceilw_s();
5702
        GEN_STORE_FTN_FREG(fd, WT2);
5703
        opn = "ceil.w.s";
5704
        break;
5705
    case FOP(15, 16):
5706
        GEN_LOAD_FREG_FTN(WT0, fs);
5707
        gen_op_float_floorw_s();
5708
        GEN_STORE_FTN_FREG(fd, WT2);
5709
        opn = "floor.w.s";
5710
        break;
5711
    case FOP(17, 16):
5712
        gen_load_gpr(cpu_T[0], ft);
5713
        GEN_LOAD_FREG_FTN(WT0, fs);
5714
        GEN_LOAD_FREG_FTN(WT2, fd);
5715
        gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
5716
        GEN_STORE_FTN_FREG(fd, WT2);
5717
        opn = "movcf.s";
5718
        break;
5719
    case FOP(18, 16):
5720
        gen_load_gpr(cpu_T[0], ft);
5721
        GEN_LOAD_FREG_FTN(WT0, fs);
5722
        GEN_LOAD_FREG_FTN(WT2, fd);
5723
        gen_op_float_movz_s();
5724
        GEN_STORE_FTN_FREG(fd, WT2);
5725
        opn = "movz.s";
5726
        break;
5727
    case FOP(19, 16):
5728
        gen_load_gpr(cpu_T[0], ft);
5729
        GEN_LOAD_FREG_FTN(WT0, fs);
5730
        GEN_LOAD_FREG_FTN(WT2, fd);
5731
        gen_op_float_movn_s();
5732
        GEN_STORE_FTN_FREG(fd, WT2);
5733
        opn = "movn.s";
5734
        break;
5735
    case FOP(21, 16):
5736
        check_cop1x(ctx);
5737
        GEN_LOAD_FREG_FTN(WT0, fs);
5738
        gen_op_float_recip_s();
5739
        GEN_STORE_FTN_FREG(fd, WT2);
5740
        opn = "recip.s";
5741
        break;
5742
    case FOP(22, 16):
5743
        check_cop1x(ctx);
5744
        GEN_LOAD_FREG_FTN(WT0, fs);
5745
        gen_op_float_rsqrt_s();
5746
        GEN_STORE_FTN_FREG(fd, WT2);
5747
        opn = "rsqrt.s";
5748
        break;
5749
    case FOP(28, 16):
5750
        check_cp1_64bitmode(ctx);
5751
        GEN_LOAD_FREG_FTN(WT0, fs);
5752
        GEN_LOAD_FREG_FTN(WT2, fd);
5753
        gen_op_float_recip2_s();
5754
        GEN_STORE_FTN_FREG(fd, WT2);
5755
        opn = "recip2.s";
5756
        break;
5757
    case FOP(29, 16):
5758
        check_cp1_64bitmode(ctx);
5759
        GEN_LOAD_FREG_FTN(WT0, fs);
5760
        gen_op_float_recip1_s();
5761
        GEN_STORE_FTN_FREG(fd, WT2);
5762
        opn = "recip1.s";
5763
        break;
5764
    case FOP(30, 16):
5765
        check_cp1_64bitmode(ctx);
5766
        GEN_LOAD_FREG_FTN(WT0, fs);
5767
        gen_op_float_rsqrt1_s();
5768
        GEN_STORE_FTN_FREG(fd, WT2);
5769
        opn = "rsqrt1.s";
5770
        break;
5771
    case FOP(31, 16):
5772
        check_cp1_64bitmode(ctx);
5773
        GEN_LOAD_FREG_FTN(WT0, fs);
5774
        GEN_LOAD_FREG_FTN(WT2, ft);
5775
        gen_op_float_rsqrt2_s();
5776
        GEN_STORE_FTN_FREG(fd, WT2);
5777
        opn = "rsqrt2.s";
5778
        break;
5779
    case FOP(33, 16):
5780
        check_cp1_registers(ctx, fd);
5781
        GEN_LOAD_FREG_FTN(WT0, fs);
5782
        gen_op_float_cvtd_s();
5783
        GEN_STORE_FTN_FREG(fd, DT2);
5784
        opn = "cvt.d.s";
5785
        break;
5786
    case FOP(36, 16):
5787
        GEN_LOAD_FREG_FTN(WT0, fs);
5788
        gen_op_float_cvtw_s();
5789
        GEN_STORE_FTN_FREG(fd, WT2);
5790
        opn = "cvt.w.s";
5791
        break;
5792
    case FOP(37, 16):
5793
        check_cp1_64bitmode(ctx);
5794
        GEN_LOAD_FREG_FTN(WT0, fs);
5795
        gen_op_float_cvtl_s();
5796
        GEN_STORE_FTN_FREG(fd, DT2);
5797
        opn = "cvt.l.s";
5798
        break;
5799
    case FOP(38, 16):
5800
        check_cp1_64bitmode(ctx);
5801
        GEN_LOAD_FREG_FTN(WT1, fs);
5802
        GEN_LOAD_FREG_FTN(WT0, ft);
5803
        gen_op_float_cvtps_s();
5804
        GEN_STORE_FTN_FREG(fd, DT2);
5805
        opn = "cvt.ps.s";
5806
        break;
5807
    case FOP(48, 16):
5808
    case FOP(49, 16):
5809
    case FOP(50, 16):
5810
    case FOP(51, 16):
5811
    case FOP(52, 16):
5812
    case FOP(53, 16):
5813
    case FOP(54, 16):
5814
    case FOP(55, 16):
5815
    case FOP(56, 16):
5816
    case FOP(57, 16):
5817
    case FOP(58, 16):
5818
    case FOP(59, 16):
5819
    case FOP(60, 16):
5820
    case FOP(61, 16):
5821
    case FOP(62, 16):
5822
    case FOP(63, 16):
5823
        GEN_LOAD_FREG_FTN(WT0, fs);
5824
        GEN_LOAD_FREG_FTN(WT1, ft);
5825
        if (ctx->opcode & (1 << 6)) {
5826
            check_cop1x(ctx);
5827
            gen_cmpabs_s(func-48, cc);
5828
            opn = condnames_abs[func-48];
5829
        } else {
5830
            gen_cmp_s(func-48, cc);
5831
            opn = condnames[func-48];
5832
        }
5833
        break;
5834
    case FOP(0, 17):
5835
        check_cp1_registers(ctx, fs | ft | fd);
5836
        GEN_LOAD_FREG_FTN(DT0, fs);
5837
        GEN_LOAD_FREG_FTN(DT1, ft);
5838
        gen_op_float_add_d();
5839
        GEN_STORE_FTN_FREG(fd, DT2);
5840
        opn = "add.d";
5841
        optype = BINOP;
5842
        break;
5843
    case FOP(1, 17):
5844
        check_cp1_registers(ctx, fs | ft | fd);
5845
        GEN_LOAD_FREG_FTN(DT0, fs);
5846
        GEN_LOAD_FREG_FTN(DT1, ft);
5847
        gen_op_float_sub_d();
5848
        GEN_STORE_FTN_FREG(fd, DT2);
5849
        opn = "sub.d";
5850
        optype = BINOP;
5851
        break;
5852
    case FOP(2, 17):
5853
        check_cp1_registers(ctx, fs | ft | fd);
5854
        GEN_LOAD_FREG_FTN(DT0, fs);
5855
        GEN_LOAD_FREG_FTN(DT1, ft);
5856
        gen_op_float_mul_d();
5857
        GEN_STORE_FTN_FREG(fd, DT2);
5858
        opn = "mul.d";
5859
        optype = BINOP;
5860
        break;
5861
    case FOP(3, 17):
5862
        check_cp1_registers(ctx, fs | ft | fd);
5863
        GEN_LOAD_FREG_FTN(DT0, fs);
5864
        GEN_LOAD_FREG_FTN(DT1, ft);
5865
        gen_op_float_div_d();
5866
        GEN_STORE_FTN_FREG(fd, DT2);
5867
        opn = "div.d";
5868
        optype = BINOP;
5869
        break;
5870
    case FOP(4, 17):
5871
        check_cp1_registers(ctx, fs | fd);
5872
        GEN_LOAD_FREG_FTN(DT0, fs);
5873
        gen_op_float_sqrt_d();
5874
        GEN_STORE_FTN_FREG(fd, DT2);
5875
        opn = "sqrt.d";
5876
        break;
5877
    case FOP(5, 17):
5878
        check_cp1_registers(ctx, fs | fd);
5879
        GEN_LOAD_FREG_FTN(DT0, fs);
5880
        gen_op_float_abs_d();
5881
        GEN_STORE_FTN_FREG(fd, DT2);
5882
        opn = "abs.d";
5883
        break;
5884
    case FOP(6, 17):
5885
        check_cp1_registers(ctx, fs | fd);
5886
        GEN_LOAD_FREG_FTN(DT0, fs);
5887
        gen_op_float_mov_d();
5888
        GEN_STORE_FTN_FREG(fd, DT2);
5889
        opn = "mov.d";
5890
        break;
5891
    case FOP(7, 17):
5892
        check_cp1_registers(ctx, fs | fd);
5893
        GEN_LOAD_FREG_FTN(DT0, fs);
5894
        gen_op_float_chs_d();
5895
        GEN_STORE_FTN_FREG(fd, DT2);
5896
        opn = "neg.d";
5897
        break;
5898
    case FOP(8, 17):
5899
        check_cp1_64bitmode(ctx);
5900
        GEN_LOAD_FREG_FTN(DT0, fs);
5901
        gen_op_float_roundl_d();
5902
        GEN_STORE_FTN_FREG(fd, DT2);
5903
        opn = "round.l.d";
5904
        break;
5905
    case FOP(9, 17):
5906
        check_cp1_64bitmode(ctx);
5907
        GEN_LOAD_FREG_FTN(DT0, fs);
5908
        gen_op_float_truncl_d();
5909
        GEN_STORE_FTN_FREG(fd, DT2);
5910
        opn = "trunc.l.d";
5911
        break;
5912
    case FOP(10, 17):
5913
        check_cp1_64bitmode(ctx);
5914
        GEN_LOAD_FREG_FTN(DT0, fs);
5915
        gen_op_float_ceill_d();
5916
        GEN_STORE_FTN_FREG(fd, DT2);
5917
        opn = "ceil.l.d";
5918
        break;
5919
    case FOP(11, 17):
5920
        check_cp1_64bitmode(ctx);
5921
        GEN_LOAD_FREG_FTN(DT0, fs);
5922
        gen_op_float_floorl_d();
5923
        GEN_STORE_FTN_FREG(fd, DT2);
5924
        opn = "floor.l.d";
5925
        break;
5926
    case FOP(12, 17):
5927
        check_cp1_registers(ctx, fs);
5928
        GEN_LOAD_FREG_FTN(DT0, fs);
5929
        gen_op_float_roundw_d();
5930
        GEN_STORE_FTN_FREG(fd, WT2);
5931
        opn = "round.w.d";
5932
        break;
5933
    case FOP(13, 17):
5934
        check_cp1_registers(ctx, fs);
5935
        GEN_LOAD_FREG_FTN(DT0, fs);
5936
        gen_op_float_truncw_d();
5937
        GEN_STORE_FTN_FREG(fd, WT2);
5938
        opn = "trunc.w.d";
5939
        break;
5940
    case FOP(14, 17):
5941
        check_cp1_registers(ctx, fs);
5942
        GEN_LOAD_FREG_FTN(DT0, fs);
5943
        gen_op_float_ceilw_d();
5944
        GEN_STORE_FTN_FREG(fd, WT2);
5945
        opn = "ceil.w.d";
5946
        break;
5947
    case FOP(15, 17):
5948
        check_cp1_registers(ctx, fs);
5949
        GEN_LOAD_FREG_FTN(DT0, fs);
5950
        gen_op_float_floorw_d();
5951
        GEN_STORE_FTN_FREG(fd, WT2);
5952
        opn = "floor.w.d";
5953
        break;
5954
    case FOP(17, 17):
5955
        gen_load_gpr(cpu_T[0], ft);
5956
        GEN_LOAD_FREG_FTN(DT0, fs);
5957
        GEN_LOAD_FREG_FTN(DT2, fd);
5958
        gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
5959
        GEN_STORE_FTN_FREG(fd, DT2);
5960
        opn = "movcf.d";
5961
        break;
5962
    case FOP(18, 17):
5963
        gen_load_gpr(cpu_T[0], ft);
5964
        GEN_LOAD_FREG_FTN(DT0, fs);
5965
        GEN_LOAD_FREG_FTN(DT2, fd);
5966
        gen_op_float_movz_d();
5967
        GEN_STORE_FTN_FREG(fd, DT2);
5968
        opn = "movz.d";
5969
        break;
5970
    case FOP(19, 17):
5971
        gen_load_gpr(cpu_T[0], ft);
5972
        GEN_LOAD_FREG_FTN(DT0, fs);
5973
        GEN_LOAD_FREG_FTN(DT2, fd);
5974
        gen_op_float_movn_d();
5975
        GEN_STORE_FTN_FREG(fd, DT2);
5976
        opn = "movn.d";
5977
        break;
5978
    case FOP(21, 17):
5979
        check_cp1_64bitmode(ctx);
5980
        GEN_LOAD_FREG_FTN(DT0, fs);
5981
        gen_op_float_recip_d();
5982
        GEN_STORE_FTN_FREG(fd, DT2);
5983
        opn = "recip.d";
5984
        break;
5985
    case FOP(22, 17):
5986
        check_cp1_64bitmode(ctx);
5987
        GEN_LOAD_FREG_FTN(DT0, fs);
5988
        gen_op_float_rsqrt_d();
5989
        GEN_STORE_FTN_FREG(fd, DT2);
5990
        opn = "rsqrt.d";
5991
        break;
5992
    case FOP(28, 17):
5993
        check_cp1_64bitmode(ctx);
5994
        GEN_LOAD_FREG_FTN(DT0, fs);
5995
        GEN_LOAD_FREG_FTN(DT2, ft);
5996
        gen_op_float_recip2_d();
5997
        GEN_STORE_FTN_FREG(fd, DT2);
5998
        opn = "recip2.d";
5999
        break;
6000
    case FOP(29, 17):
6001
        check_cp1_64bitmode(ctx);
6002
        GEN_LOAD_FREG_FTN(DT0, fs);
6003
        gen_op_float_recip1_d();
6004
        GEN_STORE_FTN_FREG(fd, DT2);
6005
        opn = "recip1.d";
6006
        break;
6007
    case FOP(30, 17):
6008
        check_cp1_64bitmode(ctx);
6009
        GEN_LOAD_FREG_FTN(DT0, fs);
6010
        gen_op_float_rsqrt1_d();
6011
        GEN_STORE_FTN_FREG(fd, DT2);
6012
        opn = "rsqrt1.d";
6013
        break;
6014
    case FOP(31, 17):
6015
        check_cp1_64bitmode(ctx);
6016
        GEN_LOAD_FREG_FTN(DT0, fs);
6017
        GEN_LOAD_FREG_FTN(DT2, ft);
6018
        gen_op_float_rsqrt2_d();
6019
        GEN_STORE_FTN_FREG(fd, DT2);
6020
        opn = "rsqrt2.d";
6021
        break;
6022
    case FOP(48, 17):
6023
    case FOP(49, 17):
6024
    case FOP(50, 17):
6025
    case FOP(51, 17):
6026
    case FOP(52, 17):
6027
    case FOP(53, 17):
6028
    case FOP(54, 17):
6029
    case FOP(55, 17):
6030
    case FOP(56, 17):
6031
    case FOP(57, 17):
6032
    case FOP(58, 17):
6033
    case FOP(59, 17):
6034
    case FOP(60, 17):
6035
    case FOP(61, 17):
6036
    case FOP(62, 17):
6037
    case FOP(63, 17):
6038
        GEN_LOAD_FREG_FTN(DT0, fs);
6039
        GEN_LOAD_FREG_FTN(DT1, ft);
6040
        if (ctx->opcode & (1 << 6)) {
6041
            check_cop1x(ctx);
6042
            check_cp1_registers(ctx, fs | ft);
6043
            gen_cmpabs_d(func-48, cc);
6044
            opn = condnames_abs[func-48];
6045
        } else {
6046
            check_cp1_registers(ctx, fs | ft);
6047
            gen_cmp_d(func-48, cc);
6048
            opn = condnames[func-48];
6049
        }
6050
        break;
6051
    case FOP(32, 17):
6052
        check_cp1_registers(ctx, fs);
6053
        GEN_LOAD_FREG_FTN(DT0, fs);
6054
        gen_op_float_cvts_d();
6055
        GEN_STORE_FTN_FREG(fd, WT2);
6056
        opn = "cvt.s.d";
6057
        break;
6058
    case FOP(36, 17):
6059
        check_cp1_registers(ctx, fs);
6060
        GEN_LOAD_FREG_FTN(DT0, fs);
6061
        gen_op_float_cvtw_d();
6062
        GEN_STORE_FTN_FREG(fd, WT2);
6063
        opn = "cvt.w.d";
6064
        break;
6065
    case FOP(37, 17):
6066
        check_cp1_64bitmode(ctx);
6067
        GEN_LOAD_FREG_FTN(DT0, fs);
6068
        gen_op_float_cvtl_d();
6069
        GEN_STORE_FTN_FREG(fd, DT2);
6070
        opn = "cvt.l.d";
6071
        break;
6072
    case FOP(32, 20):
6073
        GEN_LOAD_FREG_FTN(WT0, fs);
6074
        gen_op_float_cvts_w();
6075
        GEN_STORE_FTN_FREG(fd, WT2);
6076
        opn = "cvt.s.w";
6077
        break;
6078
    case FOP(33, 20):
6079
        check_cp1_registers(ctx, fd);
6080
        GEN_LOAD_FREG_FTN(WT0, fs);
6081
        gen_op_float_cvtd_w();
6082
        GEN_STORE_FTN_FREG(fd, DT2);
6083
        opn = "cvt.d.w";
6084
        break;
6085
    case FOP(32, 21):
6086
        check_cp1_64bitmode(ctx);
6087
        GEN_LOAD_FREG_FTN(DT0, fs);
6088
        gen_op_float_cvts_l();
6089
        GEN_STORE_FTN_FREG(fd, WT2);
6090
        opn = "cvt.s.l";
6091
        break;
6092
    case FOP(33, 21):
6093
        check_cp1_64bitmode(ctx);
6094
        GEN_LOAD_FREG_FTN(DT0, fs);
6095
        gen_op_float_cvtd_l();
6096
        GEN_STORE_FTN_FREG(fd, DT2);
6097
        opn = "cvt.d.l";
6098
        break;
6099
    case FOP(38, 20):
6100
        check_cp1_64bitmode(ctx);
6101
        GEN_LOAD_FREG_FTN(WT0, fs);
6102
        GEN_LOAD_FREG_FTN(WTH0, fs);
6103
        gen_op_float_cvtps_pw();
6104
        GEN_STORE_FTN_FREG(fd, WT2);
6105
        GEN_STORE_FTN_FREG(fd, WTH2);
6106
        opn = "cvt.ps.pw";
6107
        break;
6108
    case FOP(0, 22):
6109
        check_cp1_64bitmode(ctx);
6110
        GEN_LOAD_FREG_FTN(WT0, fs);
6111
        GEN_LOAD_FREG_FTN(WTH0, fs);
6112
        GEN_LOAD_FREG_FTN(WT1, ft);
6113
        GEN_LOAD_FREG_FTN(WTH1, ft);
6114
        gen_op_float_add_ps();
6115
        GEN_STORE_FTN_FREG(fd, WT2);
6116
        GEN_STORE_FTN_FREG(fd, WTH2);
6117
        opn = "add.ps";
6118
        break;
6119
    case FOP(1, 22):
6120
        check_cp1_64bitmode(ctx);
6121
        GEN_LOAD_FREG_FTN(WT0, fs);
6122
        GEN_LOAD_FREG_FTN(WTH0, fs);
6123
        GEN_LOAD_FREG_FTN(WT1, ft);
6124
        GEN_LOAD_FREG_FTN(WTH1, ft);
6125
        gen_op_float_sub_ps();
6126
        GEN_STORE_FTN_FREG(fd, WT2);
6127
        GEN_STORE_FTN_FREG(fd, WTH2);
6128
        opn = "sub.ps";
6129
        break;
6130
    case FOP(2, 22):
6131
        check_cp1_64bitmode(ctx);
6132
        GEN_LOAD_FREG_FTN(WT0, fs);
6133
        GEN_LOAD_FREG_FTN(WTH0, fs);
6134
        GEN_LOAD_FREG_FTN(WT1, ft);
6135
        GEN_LOAD_FREG_FTN(WTH1, ft);
6136
        gen_op_float_mul_ps();
6137
        GEN_STORE_FTN_FREG(fd, WT2);
6138
        GEN_STORE_FTN_FREG(fd, WTH2);
6139
        opn = "mul.ps";
6140
        break;
6141
    case FOP(5, 22):
6142
        check_cp1_64bitmode(ctx);
6143
        GEN_LOAD_FREG_FTN(WT0, fs);
6144
        GEN_LOAD_FREG_FTN(WTH0, fs);
6145
        gen_op_float_abs_ps();
6146
        GEN_STORE_FTN_FREG(fd, WT2);
6147
        GEN_STORE_FTN_FREG(fd, WTH2);
6148
        opn = "abs.ps";
6149
        break;
6150
    case FOP(6, 22):
6151
        check_cp1_64bitmode(ctx);
6152
        GEN_LOAD_FREG_FTN(WT0, fs);
6153
        GEN_LOAD_FREG_FTN(WTH0, fs);
6154
        gen_op_float_mov_ps();
6155
        GEN_STORE_FTN_FREG(fd, WT2);
6156
        GEN_STORE_FTN_FREG(fd, WTH2);
6157
        opn = "mov.ps";
6158
        break;
6159
    case FOP(7, 22):
6160
        check_cp1_64bitmode(ctx);
6161
        GEN_LOAD_FREG_FTN(WT0, fs);
6162
        GEN_LOAD_FREG_FTN(WTH0, fs);
6163
        gen_op_float_chs_ps();
6164
        GEN_STORE_FTN_FREG(fd, WT2);
6165
        GEN_STORE_FTN_FREG(fd, WTH2);
6166
        opn = "neg.ps";
6167
        break;
6168
    case FOP(17, 22):
6169
        check_cp1_64bitmode(ctx);
6170
        gen_load_gpr(cpu_T[0], ft);
6171
        GEN_LOAD_FREG_FTN(WT0, fs);
6172
        GEN_LOAD_FREG_FTN(WTH0, fs);
6173
        GEN_LOAD_FREG_FTN(WT2, fd);
6174
        GEN_LOAD_FREG_FTN(WTH2, fd);
6175
        if (ft & 0x1)
6176
            gen_op_float_movt_ps ((ft >> 2) & 0x7);
6177
        else
6178
            gen_op_float_movf_ps ((ft >> 2) & 0x7);
6179
        GEN_STORE_FTN_FREG(fd, WT2);
6180
        GEN_STORE_FTN_FREG(fd, WTH2);
6181
        opn = "movcf.ps";
6182
        break;
6183
    case FOP(18, 22):
6184
        check_cp1_64bitmode(ctx);
6185
        gen_load_gpr(cpu_T[0], ft);
6186
        GEN_LOAD_FREG_FTN(WT0, fs);
6187
        GEN_LOAD_FREG_FTN(WTH0, fs);
6188
        GEN_LOAD_FREG_FTN(WT2, fd);
6189
        GEN_LOAD_FREG_FTN(WTH2, fd);
6190
        gen_op_float_movz_ps();
6191
        GEN_STORE_FTN_FREG(fd, WT2);
6192
        GEN_STORE_FTN_FREG(fd, WTH2);
6193
        opn = "movz.ps";
6194
        break;
6195
    case FOP(19, 22):
6196
        check_cp1_64bitmode(ctx);
6197
        gen_load_gpr(cpu_T[0], ft);
6198
        GEN_LOAD_FREG_FTN(WT0, fs);
6199
        GEN_LOAD_FREG_FTN(WTH0, fs);
6200
        GEN_LOAD_FREG_FTN(WT2, fd);
6201
        GEN_LOAD_FREG_FTN(WTH2, fd);
6202
        gen_op_float_movn_ps();
6203
        GEN_STORE_FTN_FREG(fd, WT2);
6204
        GEN_STORE_FTN_FREG(fd, WTH2);
6205
        opn = "movn.ps";
6206
        break;
6207
    case FOP(24, 22):
6208
        check_cp1_64bitmode(ctx);
6209
        GEN_LOAD_FREG_FTN(WT0, ft);
6210
        GEN_LOAD_FREG_FTN(WTH0, ft);
6211
        GEN_LOAD_FREG_FTN(WT1, fs);
6212
        GEN_LOAD_FREG_FTN(WTH1, fs);
6213
        gen_op_float_addr_ps();
6214
        GEN_STORE_FTN_FREG(fd, WT2);
6215
        GEN_STORE_FTN_FREG(fd, WTH2);
6216
        opn = "addr.ps";
6217
        break;
6218
    case FOP(26, 22):
6219
        check_cp1_64bitmode(ctx);
6220
        GEN_LOAD_FREG_FTN(WT0, ft);
6221
        GEN_LOAD_FREG_FTN(WTH0, ft);
6222
        GEN_LOAD_FREG_FTN(WT1, fs);
6223
        GEN_LOAD_FREG_FTN(WTH1, fs);
6224
        gen_op_float_mulr_ps();
6225
        GEN_STORE_FTN_FREG(fd, WT2);
6226
        GEN_STORE_FTN_FREG(fd, WTH2);
6227
        opn = "mulr.ps";
6228
        break;
6229
    case FOP(28, 22):
6230
        check_cp1_64bitmode(ctx);
6231
        GEN_LOAD_FREG_FTN(WT0, fs);
6232
        GEN_LOAD_FREG_FTN(WTH0, fs);
6233
        GEN_LOAD_FREG_FTN(WT2, fd);
6234
        GEN_LOAD_FREG_FTN(WTH2, fd);
6235
        gen_op_float_recip2_ps();
6236
        GEN_STORE_FTN_FREG(fd, WT2);
6237
        GEN_STORE_FTN_FREG(fd, WTH2);
6238
        opn = "recip2.ps";
6239
        break;
6240
    case FOP(29, 22):
6241
        check_cp1_64bitmode(ctx);
6242
        GEN_LOAD_FREG_FTN(WT0, fs);
6243
        GEN_LOAD_FREG_FTN(WTH0, fs);
6244
        gen_op_float_recip1_ps();
6245
        GEN_STORE_FTN_FREG(fd, WT2);
6246
        GEN_STORE_FTN_FREG(fd, WTH2);
6247
        opn = "recip1.ps";
6248
        break;
6249
    case FOP(30, 22):
6250
        check_cp1_64bitmode(ctx);
6251
        GEN_LOAD_FREG_FTN(WT0, fs);
6252
        GEN_LOAD_FREG_FTN(WTH0, fs);
6253
        gen_op_float_rsqrt1_ps();
6254
        GEN_STORE_FTN_FREG(fd, WT2);
6255
        GEN_STORE_FTN_FREG(fd, WTH2);
6256
        opn = "rsqrt1.ps";
6257
        break;
6258
    case FOP(31, 22):
6259
        check_cp1_64bitmode(ctx);
6260
        GEN_LOAD_FREG_FTN(WT0, fs);
6261
        GEN_LOAD_FREG_FTN(WTH0, fs);
6262
        GEN_LOAD_FREG_FTN(WT2, ft);
6263
        GEN_LOAD_FREG_FTN(WTH2, ft);
6264
        gen_op_float_rsqrt2_ps();
6265
        GEN_STORE_FTN_FREG(fd, WT2);
6266
        GEN_STORE_FTN_FREG(fd, WTH2);
6267
        opn = "rsqrt2.ps";
6268
        break;
6269
    case FOP(32, 22):
6270
        check_cp1_64bitmode(ctx);
6271
        GEN_LOAD_FREG_FTN(WTH0, fs);
6272
        gen_op_float_cvts_pu();
6273
        GEN_STORE_FTN_FREG(fd, WT2);
6274
        opn = "cvt.s.pu";
6275
        break;
6276
    case FOP(36, 22):
6277
        check_cp1_64bitmode(ctx);
6278
        GEN_LOAD_FREG_FTN(WT0, fs);
6279
        GEN_LOAD_FREG_FTN(WTH0, fs);
6280
        gen_op_float_cvtpw_ps();
6281
        GEN_STORE_FTN_FREG(fd, WT2);
6282
        GEN_STORE_FTN_FREG(fd, WTH2);
6283
        opn = "cvt.pw.ps";
6284
        break;
6285
    case FOP(40, 22):
6286
        check_cp1_64bitmode(ctx);
6287
        GEN_LOAD_FREG_FTN(WT0, fs);
6288
        gen_op_float_cvts_pl();
6289
        GEN_STORE_FTN_FREG(fd, WT2);
6290
        opn = "cvt.s.pl";
6291
        break;
6292
    case FOP(44, 22):
6293
        check_cp1_64bitmode(ctx);
6294
        GEN_LOAD_FREG_FTN(WT0, fs);
6295
        GEN_LOAD_FREG_FTN(WT1, ft);
6296
        gen_op_float_pll_ps();
6297
        GEN_STORE_FTN_FREG(fd, DT2);
6298
        opn = "pll.ps";
6299
        break;
6300
    case FOP(45, 22):
6301
        check_cp1_64bitmode(ctx);
6302
        GEN_LOAD_FREG_FTN(WT0, fs);
6303
        GEN_LOAD_FREG_FTN(WTH1, ft);
6304
        gen_op_float_plu_ps();
6305
        GEN_STORE_FTN_FREG(fd, DT2);
6306
        opn = "plu.ps";
6307
        break;
6308
    case FOP(46, 22):
6309
        check_cp1_64bitmode(ctx);
6310
        GEN_LOAD_FREG_FTN(WTH0, fs);
6311
        GEN_LOAD_FREG_FTN(WT1, ft);
6312
        gen_op_float_pul_ps();
6313
        GEN_STORE_FTN_FREG(fd, DT2);
6314
        opn = "pul.ps";
6315
        break;
6316
    case FOP(47, 22):
6317
        check_cp1_64bitmode(ctx);
6318
        GEN_LOAD_FREG_FTN(WTH0, fs);
6319
        GEN_LOAD_FREG_FTN(WTH1, ft);
6320
        gen_op_float_puu_ps();
6321
        GEN_STORE_FTN_FREG(fd, DT2);
6322
        opn = "puu.ps";
6323
        break;
6324
    case FOP(48, 22):
6325
    case FOP(49, 22):
6326
    case FOP(50, 22):
6327
    case FOP(51, 22):
6328
    case FOP(52, 22):
6329
    case FOP(53, 22):
6330
    case FOP(54, 22):
6331
    case FOP(55, 22):
6332
    case FOP(56, 22):
6333
    case FOP(57, 22):
6334
    case FOP(58, 22):
6335
    case FOP(59, 22):
6336
    case FOP(60, 22):
6337
    case FOP(61, 22):
6338
    case FOP(62, 22):
6339
    case FOP(63, 22):
6340
        check_cp1_64bitmode(ctx);
6341
        GEN_LOAD_FREG_FTN(WT0, fs);
6342
        GEN_LOAD_FREG_FTN(WTH0, fs);
6343
        GEN_LOAD_FREG_FTN(WT1, ft);
6344
        GEN_LOAD_FREG_FTN(WTH1, ft);
6345
        if (ctx->opcode & (1 << 6)) {
6346
            gen_cmpabs_ps(func-48, cc);
6347
            opn = condnames_abs[func-48];
6348
        } else {
6349
            gen_cmp_ps(func-48, cc);
6350
            opn = condnames[func-48];
6351
        }
6352
        break;
6353
    default:
6354
        MIPS_INVAL(opn);
6355
        generate_exception (ctx, EXCP_RI);
6356
        return;
6357
    }
6358
    switch (optype) {
6359
    case BINOP:
6360
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6361
        break;
6362
    case CMPOP:
6363
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6364
        break;
6365
    default:
6366
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6367
        break;
6368
    }
6369
}
6370

    
6371
/* Coprocessor 3 (FPU) */
6372
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6373
                           int fd, int fs, int base, int index)
6374
{
6375
    const char *opn = "extended float load/store";
6376
    int store = 0;
6377

    
6378
    if (base == 0) {
6379
        gen_load_gpr(cpu_T[0], index);
6380
    } else if (index == 0) {
6381
        gen_load_gpr(cpu_T[0], base);
6382
    } else {
6383
        gen_load_gpr(cpu_T[0], base);
6384
        gen_load_gpr(cpu_T[1], index);
6385
        gen_op_addr_add();
6386
    }
6387
    /* Don't do NOP if destination is zero: we must perform the actual
6388
       memory access. */
6389
    switch (opc) {
6390
    case OPC_LWXC1:
6391
        check_cop1x(ctx);
6392
        op_ldst_lwc1(ctx);
6393
        GEN_STORE_FTN_FREG(fd, WT0);
6394
        opn = "lwxc1";
6395
        break;
6396
    case OPC_LDXC1:
6397
        check_cop1x(ctx);
6398
        check_cp1_registers(ctx, fd);
6399
        op_ldst_ldc1(ctx);
6400
        GEN_STORE_FTN_FREG(fd, DT0);
6401
        opn = "ldxc1";
6402
        break;
6403
    case OPC_LUXC1:
6404
        check_cp1_64bitmode(ctx);
6405
        op_ldst(luxc1);
6406
        GEN_STORE_FTN_FREG(fd, DT0);
6407
        opn = "luxc1";
6408
        break;
6409
    case OPC_SWXC1:
6410
        check_cop1x(ctx);
6411
        GEN_LOAD_FREG_FTN(WT0, fs);
6412
        op_ldst_swc1(ctx);
6413
        opn = "swxc1";
6414
        store = 1;
6415
        break;
6416
    case OPC_SDXC1:
6417
        check_cop1x(ctx);
6418
        check_cp1_registers(ctx, fs);
6419
        GEN_LOAD_FREG_FTN(DT0, fs);
6420
        op_ldst_sdc1(ctx);
6421
        opn = "sdxc1";
6422
        store = 1;
6423
        break;
6424
    case OPC_SUXC1:
6425
        check_cp1_64bitmode(ctx);
6426
        GEN_LOAD_FREG_FTN(DT0, fs);
6427
        op_ldst(suxc1);
6428
        opn = "suxc1";
6429
        store = 1;
6430
        break;
6431
    default:
6432
        MIPS_INVAL(opn);
6433
        generate_exception(ctx, EXCP_RI);
6434
        return;
6435
    }
6436
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6437
               regnames[index], regnames[base]);
6438
}
6439

    
6440
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6441
                            int fd, int fr, int fs, int ft)
6442
{
6443
    const char *opn = "flt3_arith";
6444

    
6445
    switch (opc) {
6446
    case OPC_ALNV_PS:
6447
        check_cp1_64bitmode(ctx);
6448
        gen_load_gpr(cpu_T[0], fr);
6449
        GEN_LOAD_FREG_FTN(DT0, fs);
6450
        GEN_LOAD_FREG_FTN(DT1, ft);
6451
        gen_op_float_alnv_ps();
6452
        GEN_STORE_FTN_FREG(fd, DT2);
6453
        opn = "alnv.ps";
6454
        break;
6455
    case OPC_MADD_S:
6456
        check_cop1x(ctx);
6457
        GEN_LOAD_FREG_FTN(WT0, fs);
6458
        GEN_LOAD_FREG_FTN(WT1, ft);
6459
        GEN_LOAD_FREG_FTN(WT2, fr);
6460
        gen_op_float_muladd_s();
6461
        GEN_STORE_FTN_FREG(fd, WT2);
6462
        opn = "madd.s";
6463
        break;
6464
    case OPC_MADD_D:
6465
        check_cop1x(ctx);
6466
        check_cp1_registers(ctx, fd | fs | ft | fr);
6467
        GEN_LOAD_FREG_FTN(DT0, fs);
6468
        GEN_LOAD_FREG_FTN(DT1, ft);
6469
        GEN_LOAD_FREG_FTN(DT2, fr);
6470
        gen_op_float_muladd_d();
6471
        GEN_STORE_FTN_FREG(fd, DT2);
6472
        opn = "madd.d";
6473
        break;
6474
    case OPC_MADD_PS:
6475
        check_cp1_64bitmode(ctx);
6476
        GEN_LOAD_FREG_FTN(WT0, fs);
6477
        GEN_LOAD_FREG_FTN(WTH0, fs);
6478
        GEN_LOAD_FREG_FTN(WT1, ft);
6479
        GEN_LOAD_FREG_FTN(WTH1, ft);
6480
        GEN_LOAD_FREG_FTN(WT2, fr);
6481
        GEN_LOAD_FREG_FTN(WTH2, fr);
6482
        gen_op_float_muladd_ps();
6483
        GEN_STORE_FTN_FREG(fd, WT2);
6484
        GEN_STORE_FTN_FREG(fd, WTH2);
6485
        opn = "madd.ps";
6486
        break;
6487
    case OPC_MSUB_S:
6488
        check_cop1x(ctx);
6489
        GEN_LOAD_FREG_FTN(WT0, fs);
6490
        GEN_LOAD_FREG_FTN(WT1, ft);
6491
        GEN_LOAD_FREG_FTN(WT2, fr);
6492
        gen_op_float_mulsub_s();
6493
        GEN_STORE_FTN_FREG(fd, WT2);
6494
        opn = "msub.s";
6495
        break;
6496
    case OPC_MSUB_D:
6497
        check_cop1x(ctx);
6498
        check_cp1_registers(ctx, fd | fs | ft | fr);
6499
        GEN_LOAD_FREG_FTN(DT0, fs);
6500
        GEN_LOAD_FREG_FTN(DT1, ft);
6501
        GEN_LOAD_FREG_FTN(DT2, fr);
6502
        gen_op_float_mulsub_d();
6503
        GEN_STORE_FTN_FREG(fd, DT2);
6504
        opn = "msub.d";
6505
        break;
6506
    case OPC_MSUB_PS:
6507
        check_cp1_64bitmode(ctx);
6508
        GEN_LOAD_FREG_FTN(WT0, fs);
6509
        GEN_LOAD_FREG_FTN(WTH0, fs);
6510
        GEN_LOAD_FREG_FTN(WT1, ft);
6511
        GEN_LOAD_FREG_FTN(WTH1, ft);
6512
        GEN_LOAD_FREG_FTN(WT2, fr);
6513
        GEN_LOAD_FREG_FTN(WTH2, fr);
6514
        gen_op_float_mulsub_ps();
6515
        GEN_STORE_FTN_FREG(fd, WT2);
6516
        GEN_STORE_FTN_FREG(fd, WTH2);
6517
        opn = "msub.ps";
6518
        break;
6519
    case OPC_NMADD_S:
6520
        check_cop1x(ctx);
6521
        GEN_LOAD_FREG_FTN(WT0, fs);
6522
        GEN_LOAD_FREG_FTN(WT1, ft);
6523
        GEN_LOAD_FREG_FTN(WT2, fr);
6524
        gen_op_float_nmuladd_s();
6525
        GEN_STORE_FTN_FREG(fd, WT2);
6526
        opn = "nmadd.s";
6527
        break;
6528
    case OPC_NMADD_D:
6529
        check_cop1x(ctx);
6530
        check_cp1_registers(ctx, fd | fs | ft | fr);
6531
        GEN_LOAD_FREG_FTN(DT0, fs);
6532
        GEN_LOAD_FREG_FTN(DT1, ft);
6533
        GEN_LOAD_FREG_FTN(DT2, fr);
6534
        gen_op_float_nmuladd_d();
6535
        GEN_STORE_FTN_FREG(fd, DT2);
6536
        opn = "nmadd.d";
6537
        break;
6538
    case OPC_NMADD_PS:
6539
        check_cp1_64bitmode(ctx);
6540
        GEN_LOAD_FREG_FTN(WT0, fs);
6541
        GEN_LOAD_FREG_FTN(WTH0, fs);
6542
        GEN_LOAD_FREG_FTN(WT1, ft);
6543
        GEN_LOAD_FREG_FTN(WTH1, ft);
6544
        GEN_LOAD_FREG_FTN(WT2, fr);
6545
        GEN_LOAD_FREG_FTN(WTH2, fr);
6546
        gen_op_float_nmuladd_ps();
6547
        GEN_STORE_FTN_FREG(fd, WT2);
6548
        GEN_STORE_FTN_FREG(fd, WTH2);
6549
        opn = "nmadd.ps";
6550
        break;
6551
    case OPC_NMSUB_S:
6552
        check_cop1x(ctx);
6553
        GEN_LOAD_FREG_FTN(WT0, fs);
6554
        GEN_LOAD_FREG_FTN(WT1, ft);
6555
        GEN_LOAD_FREG_FTN(WT2, fr);
6556
        gen_op_float_nmulsub_s();
6557
        GEN_STORE_FTN_FREG(fd, WT2);
6558
        opn = "nmsub.s";
6559
        break;
6560
    case OPC_NMSUB_D:
6561
        check_cop1x(ctx);
6562
        check_cp1_registers(ctx, fd | fs | ft | fr);
6563
        GEN_LOAD_FREG_FTN(DT0, fs);
6564
        GEN_LOAD_FREG_FTN(DT1, ft);
6565
        GEN_LOAD_FREG_FTN(DT2, fr);
6566
        gen_op_float_nmulsub_d();
6567
        GEN_STORE_FTN_FREG(fd, DT2);
6568
        opn = "nmsub.d";
6569
        break;
6570
    case OPC_NMSUB_PS:
6571
        check_cp1_64bitmode(ctx);
6572
        GEN_LOAD_FREG_FTN(WT0, fs);
6573
        GEN_LOAD_FREG_FTN(WTH0, fs);
6574
        GEN_LOAD_FREG_FTN(WT1, ft);
6575
        GEN_LOAD_FREG_FTN(WTH1, ft);
6576
        GEN_LOAD_FREG_FTN(WT2, fr);
6577
        GEN_LOAD_FREG_FTN(WTH2, fr);
6578
        gen_op_float_nmulsub_ps();
6579
        GEN_STORE_FTN_FREG(fd, WT2);
6580
        GEN_STORE_FTN_FREG(fd, WTH2);
6581
        opn = "nmsub.ps";
6582
        break;
6583
    default:
6584
        MIPS_INVAL(opn);
6585
        generate_exception (ctx, EXCP_RI);
6586
        return;
6587
    }
6588
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6589
               fregnames[fs], fregnames[ft]);
6590
}
6591

    
6592
/* ISA extensions (ASEs) */
6593
/* MIPS16 extension to MIPS32 */
6594
/* SmartMIPS extension to MIPS32 */
6595

    
6596
#if defined(TARGET_MIPS64)
6597

    
6598
/* MDMX extension to MIPS64 */
6599

    
6600
#endif
6601

    
6602
static void decode_opc (CPUState *env, DisasContext *ctx)
6603
{
6604
    int32_t offset;
6605
    int rs, rt, rd, sa;
6606
    uint32_t op, op1, op2;
6607
    int16_t imm;
6608

    
6609
    /* make sure instructions are on a word boundary */
6610
    if (ctx->pc & 0x3) {
6611
        env->CP0_BadVAddr = ctx->pc;
6612
        generate_exception(ctx, EXCP_AdEL);
6613
        return;
6614
    }
6615

    
6616
    /* Handle blikely not taken case */
6617
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6618
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
6619
        int l1 = gen_new_label();
6620

    
6621
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6622
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6623
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6624
        tcg_temp_free(r_tmp);
6625
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6626
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6627
        gen_set_label(l1);
6628
    }
6629
    op = MASK_OP_MAJOR(ctx->opcode);
6630
    rs = (ctx->opcode >> 21) & 0x1f;
6631
    rt = (ctx->opcode >> 16) & 0x1f;
6632
    rd = (ctx->opcode >> 11) & 0x1f;
6633
    sa = (ctx->opcode >> 6) & 0x1f;
6634
    imm = (int16_t)ctx->opcode;
6635
    switch (op) {
6636
    case OPC_SPECIAL:
6637
        op1 = MASK_SPECIAL(ctx->opcode);
6638
        switch (op1) {
6639
        case OPC_SLL:          /* Arithmetic with immediate */
6640
        case OPC_SRL ... OPC_SRA:
6641
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6642
            break;
6643
        case OPC_MOVZ ... OPC_MOVN:
6644
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6645
        case OPC_SLLV:         /* Arithmetic */
6646
        case OPC_SRLV ... OPC_SRAV:
6647
        case OPC_ADD ... OPC_NOR:
6648
        case OPC_SLT ... OPC_SLTU:
6649
            gen_arith(env, ctx, op1, rd, rs, rt);
6650
            break;
6651
        case OPC_MULT ... OPC_DIVU:
6652
            if (sa) {
6653
                check_insn(env, ctx, INSN_VR54XX);
6654
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6655
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6656
            } else
6657
                gen_muldiv(ctx, op1, rs, rt);
6658
            break;
6659
        case OPC_JR ... OPC_JALR:
6660
            gen_compute_branch(ctx, op1, rs, rd, sa);
6661
            return;
6662
        case OPC_TGE ... OPC_TEQ: /* Traps */
6663
        case OPC_TNE:
6664
            gen_trap(ctx, op1, rs, rt, -1);
6665
            break;
6666
        case OPC_MFHI:          /* Move from HI/LO */
6667
        case OPC_MFLO:
6668
            gen_HILO(ctx, op1, rd);
6669
            break;
6670
        case OPC_MTHI:
6671
        case OPC_MTLO:          /* Move to HI/LO */
6672
            gen_HILO(ctx, op1, rs);
6673
            break;
6674
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6675
#ifdef MIPS_STRICT_STANDARD
6676
            MIPS_INVAL("PMON / selsl");
6677
            generate_exception(ctx, EXCP_RI);
6678
#else
6679
            gen_op_pmon(sa);
6680
#endif
6681
            break;
6682
        case OPC_SYSCALL:
6683
            generate_exception(ctx, EXCP_SYSCALL);
6684
            break;
6685
        case OPC_BREAK:
6686
            generate_exception(ctx, EXCP_BREAK);
6687
            break;
6688
        case OPC_SPIM:
6689
#ifdef MIPS_STRICT_STANDARD
6690
            MIPS_INVAL("SPIM");
6691
            generate_exception(ctx, EXCP_RI);
6692
#else
6693
           /* Implemented as RI exception for now. */
6694
            MIPS_INVAL("spim (unofficial)");
6695
            generate_exception(ctx, EXCP_RI);
6696
#endif
6697
            break;
6698
        case OPC_SYNC:
6699
            /* Treat as NOP. */
6700
            break;
6701

    
6702
        case OPC_MOVCI:
6703
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6704
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6705
                save_cpu_state(ctx, 1);
6706
                check_cp1_enabled(ctx);
6707
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6708
                          (ctx->opcode >> 16) & 1);
6709
            } else {
6710
                generate_exception_err(ctx, EXCP_CpU, 1);
6711
            }
6712
            break;
6713

    
6714
#if defined(TARGET_MIPS64)
6715
       /* MIPS64 specific opcodes */
6716
        case OPC_DSLL:
6717
        case OPC_DSRL ... OPC_DSRA:
6718
        case OPC_DSLL32:
6719
        case OPC_DSRL32 ... OPC_DSRA32:
6720
            check_insn(env, ctx, ISA_MIPS3);
6721
            check_mips_64(ctx);
6722
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6723
            break;
6724
        case OPC_DSLLV:
6725
        case OPC_DSRLV ... OPC_DSRAV:
6726
        case OPC_DADD ... OPC_DSUBU:
6727
            check_insn(env, ctx, ISA_MIPS3);
6728
            check_mips_64(ctx);
6729
            gen_arith(env, ctx, op1, rd, rs, rt);
6730
            break;
6731
        case OPC_DMULT ... OPC_DDIVU:
6732
            check_insn(env, ctx, ISA_MIPS3);
6733
            check_mips_64(ctx);
6734
            gen_muldiv(ctx, op1, rs, rt);
6735
            break;
6736
#endif
6737
        default:            /* Invalid */
6738
            MIPS_INVAL("special");
6739
            generate_exception(ctx, EXCP_RI);
6740
            break;
6741
        }
6742
        break;
6743
    case OPC_SPECIAL2:
6744
        op1 = MASK_SPECIAL2(ctx->opcode);
6745
        switch (op1) {
6746
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
6747
        case OPC_MSUB ... OPC_MSUBU:
6748
            check_insn(env, ctx, ISA_MIPS32);
6749
            gen_muldiv(ctx, op1, rs, rt);
6750
            break;
6751
        case OPC_MUL:
6752
            gen_arith(env, ctx, op1, rd, rs, rt);
6753
            break;
6754
        case OPC_CLZ ... OPC_CLO:
6755
            check_insn(env, ctx, ISA_MIPS32);
6756
            gen_cl(ctx, op1, rd, rs);
6757
            break;
6758
        case OPC_SDBBP:
6759
            /* XXX: not clear which exception should be raised
6760
             *      when in debug mode...
6761
             */
6762
            check_insn(env, ctx, ISA_MIPS32);
6763
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6764
                generate_exception(ctx, EXCP_DBp);
6765
            } else {
6766
                generate_exception(ctx, EXCP_DBp);
6767
            }
6768
            /* Treat as NOP. */
6769
            break;
6770
#if defined(TARGET_MIPS64)
6771
        case OPC_DCLZ ... OPC_DCLO:
6772
            check_insn(env, ctx, ISA_MIPS64);
6773
            check_mips_64(ctx);
6774
            gen_cl(ctx, op1, rd, rs);
6775
            break;
6776
#endif
6777
        default:            /* Invalid */
6778
            MIPS_INVAL("special2");
6779
            generate_exception(ctx, EXCP_RI);
6780
            break;
6781
        }
6782
        break;
6783
    case OPC_SPECIAL3:
6784
         op1 = MASK_SPECIAL3(ctx->opcode);
6785
         switch (op1) {
6786
         case OPC_EXT:
6787
         case OPC_INS:
6788
             check_insn(env, ctx, ISA_MIPS32R2);
6789
             gen_bitops(ctx, op1, rt, rs, sa, rd);
6790
             break;
6791
         case OPC_BSHFL:
6792
             check_insn(env, ctx, ISA_MIPS32R2);
6793
             op2 = MASK_BSHFL(ctx->opcode);
6794
             switch (op2) {
6795
             case OPC_WSBH:
6796
                 gen_load_gpr(cpu_T[1], rt);
6797
                 gen_op_wsbh();
6798
                 break;
6799
             case OPC_SEB:
6800
                 gen_load_gpr(cpu_T[1], rt);
6801
                 tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6802
                 break;
6803
             case OPC_SEH:
6804
                 gen_load_gpr(cpu_T[1], rt);
6805
                 tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6806
                 break;
6807
             default:            /* Invalid */
6808
                 MIPS_INVAL("bshfl");
6809
                 generate_exception(ctx, EXCP_RI);
6810
                 break;
6811
            }
6812
            gen_store_gpr(cpu_T[0], rd);
6813
            break;
6814
        case OPC_RDHWR:
6815
            check_insn(env, ctx, ISA_MIPS32R2);
6816
            switch (rd) {
6817
            case 0:
6818
                save_cpu_state(ctx, 1);
6819
                gen_op_rdhwr_cpunum();
6820
                break;
6821
            case 1:
6822
                save_cpu_state(ctx, 1);
6823
                gen_op_rdhwr_synci_step();
6824
                break;
6825
            case 2:
6826
                save_cpu_state(ctx, 1);
6827
                gen_op_rdhwr_cc();
6828
                break;
6829
            case 3:
6830
                save_cpu_state(ctx, 1);
6831
                gen_op_rdhwr_ccres();
6832
                break;
6833
            case 29:
6834
#if defined (CONFIG_USER_ONLY)
6835
                gen_op_tls_value();
6836
                break;
6837
#endif
6838
            default:            /* Invalid */
6839
                MIPS_INVAL("rdhwr");
6840
                generate_exception(ctx, EXCP_RI);
6841
                break;
6842
            }
6843
            gen_store_gpr(cpu_T[0], rt);
6844
            break;
6845
        case OPC_FORK:
6846
            check_insn(env, ctx, ASE_MT);
6847
            gen_load_gpr(cpu_T[0], rt);
6848
            gen_load_gpr(cpu_T[1], rs);
6849
            gen_op_fork();
6850
            break;
6851
        case OPC_YIELD:
6852
            check_insn(env, ctx, ASE_MT);
6853
            gen_load_gpr(cpu_T[0], rs);
6854
            gen_op_yield();
6855
            gen_store_gpr(cpu_T[0], rd);
6856
            break;
6857
#if defined(TARGET_MIPS64)
6858
        case OPC_DEXTM ... OPC_DEXT:
6859
        case OPC_DINSM ... OPC_DINS:
6860
            check_insn(env, ctx, ISA_MIPS64R2);
6861
            check_mips_64(ctx);
6862
            gen_bitops(ctx, op1, rt, rs, sa, rd);
6863
            break;
6864
        case OPC_DBSHFL:
6865
            check_insn(env, ctx, ISA_MIPS64R2);
6866
            check_mips_64(ctx);
6867
            op2 = MASK_DBSHFL(ctx->opcode);
6868
            switch (op2) {
6869
            case OPC_DSBH:
6870
                gen_load_gpr(cpu_T[1], rt);
6871
                gen_op_dsbh();
6872
                break;
6873
            case OPC_DSHD:
6874
                gen_load_gpr(cpu_T[1], rt);
6875
                gen_op_dshd();
6876
                break;
6877
            default:            /* Invalid */
6878
                MIPS_INVAL("dbshfl");
6879
                generate_exception(ctx, EXCP_RI);
6880
                break;
6881
            }
6882
            gen_store_gpr(cpu_T[0], rd);
6883
            break;
6884
#endif
6885
        default:            /* Invalid */
6886
            MIPS_INVAL("special3");
6887
            generate_exception(ctx, EXCP_RI);
6888
            break;
6889
        }
6890
        break;
6891
    case OPC_REGIMM:
6892
        op1 = MASK_REGIMM(ctx->opcode);
6893
        switch (op1) {
6894
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
6895
        case OPC_BLTZAL ... OPC_BGEZALL:
6896
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
6897
            return;
6898
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
6899
        case OPC_TNEI:
6900
            gen_trap(ctx, op1, rs, -1, imm);
6901
            break;
6902
        case OPC_SYNCI:
6903
            check_insn(env, ctx, ISA_MIPS32R2);
6904
            /* Treat as NOP. */
6905
            break;
6906
        default:            /* Invalid */
6907
            MIPS_INVAL("regimm");
6908
            generate_exception(ctx, EXCP_RI);
6909
            break;
6910
        }
6911
        break;
6912
    case OPC_CP0:
6913
        check_cp0_enabled(ctx);
6914
        op1 = MASK_CP0(ctx->opcode);
6915
        switch (op1) {
6916
        case OPC_MFC0:
6917
        case OPC_MTC0:
6918
        case OPC_MFTR:
6919
        case OPC_MTTR:
6920
#if defined(TARGET_MIPS64)
6921
        case OPC_DMFC0:
6922
        case OPC_DMTC0:
6923
#endif
6924
            gen_cp0(env, ctx, op1, rt, rd);
6925
            break;
6926
        case OPC_C0_FIRST ... OPC_C0_LAST:
6927
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
6928
            break;
6929
        case OPC_MFMC0:
6930
            op2 = MASK_MFMC0(ctx->opcode);
6931
            switch (op2) {
6932
            case OPC_DMT:
6933
                check_insn(env, ctx, ASE_MT);
6934
                gen_op_dmt();
6935
                break;
6936
            case OPC_EMT:
6937
                check_insn(env, ctx, ASE_MT);
6938
                gen_op_emt();
6939
                break;
6940
            case OPC_DVPE:
6941
                check_insn(env, ctx, ASE_MT);
6942
                gen_op_dvpe();
6943
                break;
6944
            case OPC_EVPE:
6945
                check_insn(env, ctx, ASE_MT);
6946
                gen_op_evpe();
6947
                break;
6948
            case OPC_DI:
6949
                check_insn(env, ctx, ISA_MIPS32R2);
6950
                save_cpu_state(ctx, 1);
6951
                gen_op_di();
6952
                /* Stop translation as we may have switched the execution mode */
6953
                ctx->bstate = BS_STOP;
6954
                break;
6955
            case OPC_EI:
6956
                check_insn(env, ctx, ISA_MIPS32R2);
6957
                save_cpu_state(ctx, 1);
6958
                gen_op_ei();
6959
                /* Stop translation as we may have switched the execution mode */
6960
                ctx->bstate = BS_STOP;
6961
                break;
6962
            default:            /* Invalid */
6963
                MIPS_INVAL("mfmc0");
6964
                generate_exception(ctx, EXCP_RI);
6965
                break;
6966
            }
6967
            gen_store_gpr(cpu_T[0], rt);
6968
            break;
6969
        case OPC_RDPGPR:
6970
            check_insn(env, ctx, ISA_MIPS32R2);
6971
            gen_load_srsgpr(cpu_T[0], rt);
6972
            gen_store_gpr(cpu_T[0], rd);
6973
            break;
6974
        case OPC_WRPGPR:
6975
            check_insn(env, ctx, ISA_MIPS32R2);
6976
            gen_load_gpr(cpu_T[0], rt);
6977
            gen_store_srsgpr(cpu_T[0], rd);
6978
            break;
6979
        default:
6980
            MIPS_INVAL("cp0");
6981
            generate_exception(ctx, EXCP_RI);
6982
            break;
6983
        }
6984
        break;
6985
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
6986
         gen_arith_imm(env, ctx, op, rt, rs, imm);
6987
         break;
6988
    case OPC_J ... OPC_JAL: /* Jump */
6989
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
6990
         gen_compute_branch(ctx, op, rs, rt, offset);
6991
         return;
6992
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
6993
    case OPC_BEQL ... OPC_BGTZL:
6994
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
6995
         return;
6996
    case OPC_LB ... OPC_LWR: /* Load and stores */
6997
    case OPC_SB ... OPC_SW:
6998
    case OPC_SWR:
6999
    case OPC_LL:
7000
    case OPC_SC:
7001
         gen_ldst(ctx, op, rt, rs, imm);
7002
         break;
7003
    case OPC_CACHE:
7004
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7005
        /* Treat as NOP. */
7006
        break;
7007
    case OPC_PREF:
7008
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7009
        /* Treat as NOP. */
7010
        break;
7011

    
7012
    /* Floating point (COP1). */
7013
    case OPC_LWC1:
7014
    case OPC_LDC1:
7015
    case OPC_SWC1:
7016
    case OPC_SDC1:
7017
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7018
            save_cpu_state(ctx, 1);
7019
            check_cp1_enabled(ctx);
7020
            gen_flt_ldst(ctx, op, rt, rs, imm);
7021
        } else {
7022
            generate_exception_err(ctx, EXCP_CpU, 1);
7023
        }
7024
        break;
7025

    
7026
    case OPC_CP1:
7027
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7028
            save_cpu_state(ctx, 1);
7029
            check_cp1_enabled(ctx);
7030
            op1 = MASK_CP1(ctx->opcode);
7031
            switch (op1) {
7032
            case OPC_MFHC1:
7033
            case OPC_MTHC1:
7034
                check_insn(env, ctx, ISA_MIPS32R2);
7035
            case OPC_MFC1:
7036
            case OPC_CFC1:
7037
            case OPC_MTC1:
7038
            case OPC_CTC1:
7039
                gen_cp1(ctx, op1, rt, rd);
7040
                break;
7041
#if defined(TARGET_MIPS64)
7042
            case OPC_DMFC1:
7043
            case OPC_DMTC1:
7044
                check_insn(env, ctx, ISA_MIPS3);
7045
                gen_cp1(ctx, op1, rt, rd);
7046
                break;
7047
#endif
7048
            case OPC_BC1ANY2:
7049
            case OPC_BC1ANY4:
7050
                check_cop1x(ctx);
7051
                check_insn(env, ctx, ASE_MIPS3D);
7052
                /* fall through */
7053
            case OPC_BC1:
7054
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7055
                                    (rt >> 2) & 0x7, imm << 2);
7056
                return;
7057
            case OPC_S_FMT:
7058
            case OPC_D_FMT:
7059
            case OPC_W_FMT:
7060
            case OPC_L_FMT:
7061
            case OPC_PS_FMT:
7062
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7063
                           (imm >> 8) & 0x7);
7064
                break;
7065
            default:
7066
                MIPS_INVAL("cp1");
7067
                generate_exception (ctx, EXCP_RI);
7068
                break;
7069
            }
7070
        } else {
7071
            generate_exception_err(ctx, EXCP_CpU, 1);
7072
        }
7073
        break;
7074

    
7075
    /* COP2.  */
7076
    case OPC_LWC2:
7077
    case OPC_LDC2:
7078
    case OPC_SWC2:
7079
    case OPC_SDC2:
7080
    case OPC_CP2:
7081
        /* COP2: Not implemented. */
7082
        generate_exception_err(ctx, EXCP_CpU, 2);
7083
        break;
7084

    
7085
    case OPC_CP3:
7086
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7087
            save_cpu_state(ctx, 1);
7088
            check_cp1_enabled(ctx);
7089
            op1 = MASK_CP3(ctx->opcode);
7090
            switch (op1) {
7091
            case OPC_LWXC1:
7092
            case OPC_LDXC1:
7093
            case OPC_LUXC1:
7094
            case OPC_SWXC1:
7095
            case OPC_SDXC1:
7096
            case OPC_SUXC1:
7097
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7098
                break;
7099
            case OPC_PREFX:
7100
                /* Treat as NOP. */
7101
                break;
7102
            case OPC_ALNV_PS:
7103
            case OPC_MADD_S:
7104
            case OPC_MADD_D:
7105
            case OPC_MADD_PS:
7106
            case OPC_MSUB_S:
7107
            case OPC_MSUB_D:
7108
            case OPC_MSUB_PS:
7109
            case OPC_NMADD_S:
7110
            case OPC_NMADD_D:
7111
            case OPC_NMADD_PS:
7112
            case OPC_NMSUB_S:
7113
            case OPC_NMSUB_D:
7114
            case OPC_NMSUB_PS:
7115
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7116
                break;
7117
            default:
7118
                MIPS_INVAL("cp3");
7119
                generate_exception (ctx, EXCP_RI);
7120
                break;
7121
            }
7122
        } else {
7123
            generate_exception_err(ctx, EXCP_CpU, 1);
7124
        }
7125
        break;
7126

    
7127
#if defined(TARGET_MIPS64)
7128
    /* MIPS64 opcodes */
7129
    case OPC_LWU:
7130
    case OPC_LDL ... OPC_LDR:
7131
    case OPC_SDL ... OPC_SDR:
7132
    case OPC_LLD:
7133
    case OPC_LD:
7134
    case OPC_SCD:
7135
    case OPC_SD:
7136
        check_insn(env, ctx, ISA_MIPS3);
7137
        check_mips_64(ctx);
7138
        gen_ldst(ctx, op, rt, rs, imm);
7139
        break;
7140
    case OPC_DADDI ... OPC_DADDIU:
7141
        check_insn(env, ctx, ISA_MIPS3);
7142
        check_mips_64(ctx);
7143
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7144
        break;
7145
#endif
7146
    case OPC_JALX:
7147
        check_insn(env, ctx, ASE_MIPS16);
7148
        /* MIPS16: Not implemented. */
7149
    case OPC_MDMX:
7150
        check_insn(env, ctx, ASE_MDMX);
7151
        /* MDMX: Not implemented. */
7152
    default:            /* Invalid */
7153
        MIPS_INVAL("major opcode");
7154
        generate_exception(ctx, EXCP_RI);
7155
        break;
7156
    }
7157
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7158
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7159
        /* Branches completion */
7160
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7161
        ctx->bstate = BS_BRANCH;
7162
        save_cpu_state(ctx, 0);
7163
        switch (hflags) {
7164
        case MIPS_HFLAG_B:
7165
            /* unconditional branch */
7166
            MIPS_DEBUG("unconditional branch");
7167
            gen_goto_tb(ctx, 0, ctx->btarget);
7168
            break;
7169
        case MIPS_HFLAG_BL:
7170
            /* blikely taken case */
7171
            MIPS_DEBUG("blikely branch taken");
7172
            gen_goto_tb(ctx, 0, ctx->btarget);
7173
            break;
7174
        case MIPS_HFLAG_BC:
7175
            /* Conditional branch */
7176
            MIPS_DEBUG("conditional branch");
7177
            {
7178
                TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
7179
                int l1 = gen_new_label();
7180

    
7181
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7182
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7183
                tcg_temp_free(r_tmp);
7184
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7185
                gen_set_label(l1);
7186
                gen_goto_tb(ctx, 0, ctx->btarget);
7187
            }
7188
            break;
7189
        case MIPS_HFLAG_BR:
7190
            /* unconditional branch to register */
7191
            MIPS_DEBUG("branch to register");
7192
            gen_breg_pc();
7193
            tcg_gen_exit_tb(0);
7194
            break;
7195
        default:
7196
            MIPS_DEBUG("unknown branch");
7197
            break;
7198
        }
7199
    }
7200
}
7201

    
7202
static always_inline int
7203
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7204
                                int search_pc)
7205
{
7206
    DisasContext ctx;
7207
    target_ulong pc_start;
7208
    uint16_t *gen_opc_end;
7209
    int j, lj = -1;
7210

    
7211
    if (search_pc && loglevel)
7212
        fprintf (logfile, "search pc %d\n", search_pc);
7213

    
7214
    pc_start = tb->pc;
7215
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7216
    ctx.pc = pc_start;
7217
    ctx.saved_pc = -1;
7218
    ctx.tb = tb;
7219
    ctx.bstate = BS_NONE;
7220
    /* Restore delay slot state from the tb context.  */
7221
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7222
    restore_cpu_state(env, &ctx);
7223
#if defined(CONFIG_USER_ONLY)
7224
    ctx.mem_idx = MIPS_HFLAG_UM;
7225
#else
7226
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7227
#endif
7228
#ifdef DEBUG_DISAS
7229
    if (loglevel & CPU_LOG_TB_CPU) {
7230
        fprintf(logfile, "------------------------------------------------\n");
7231
        /* FIXME: This may print out stale hflags from env... */
7232
        cpu_dump_state(env, logfile, fprintf, 0);
7233
    }
7234
#endif
7235
#ifdef MIPS_DEBUG_DISAS
7236
    if (loglevel & CPU_LOG_TB_IN_ASM)
7237
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7238
                tb, ctx.mem_idx, ctx.hflags);
7239
#endif
7240
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7241
        if (env->nb_breakpoints > 0) {
7242
            for(j = 0; j < env->nb_breakpoints; j++) {
7243
                if (env->breakpoints[j] == ctx.pc) {
7244
                    save_cpu_state(&ctx, 1);
7245
                    ctx.bstate = BS_BRANCH;
7246
                    gen_op_debug();
7247
                    /* Include the breakpoint location or the tb won't
7248
                     * be flushed when it must be.  */
7249
                    ctx.pc += 4;
7250
                    goto done_generating;
7251
                }
7252
            }
7253
        }
7254

    
7255
        if (search_pc) {
7256
            j = gen_opc_ptr - gen_opc_buf;
7257
            if (lj < j) {
7258
                lj++;
7259
                while (lj < j)
7260
                    gen_opc_instr_start[lj++] = 0;
7261
            }
7262
            gen_opc_pc[lj] = ctx.pc;
7263
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7264
            gen_opc_instr_start[lj] = 1;
7265
        }
7266
        ctx.opcode = ldl_code(ctx.pc);
7267
        decode_opc(env, &ctx);
7268
        ctx.pc += 4;
7269

    
7270
        if (env->singlestep_enabled)
7271
            break;
7272

    
7273
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7274
            break;
7275

    
7276
#if defined (MIPS_SINGLE_STEP)
7277
        break;
7278
#endif
7279
    }
7280
    if (env->singlestep_enabled) {
7281
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7282
        gen_op_debug();
7283
    } else {
7284
        switch (ctx.bstate) {
7285
        case BS_STOP:
7286
            tcg_gen_helper_0_0(do_interrupt_restart);
7287
            gen_goto_tb(&ctx, 0, ctx.pc);
7288
            break;
7289
        case BS_NONE:
7290
            save_cpu_state(&ctx, 0);
7291
            gen_goto_tb(&ctx, 0, ctx.pc);
7292
            break;
7293
        case BS_EXCP:
7294
            tcg_gen_helper_0_0(do_interrupt_restart);
7295
            tcg_gen_exit_tb(0);
7296
            break;
7297
        case BS_BRANCH:
7298
        default:
7299
            break;
7300
        }
7301
    }
7302
done_generating:
7303
    *gen_opc_ptr = INDEX_op_end;
7304
    if (search_pc) {
7305
        j = gen_opc_ptr - gen_opc_buf;
7306
        lj++;
7307
        while (lj <= j)
7308
            gen_opc_instr_start[lj++] = 0;
7309
    } else {
7310
        tb->size = ctx.pc - pc_start;
7311
    }
7312
#ifdef DEBUG_DISAS
7313
#if defined MIPS_DEBUG_DISAS
7314
    if (loglevel & CPU_LOG_TB_IN_ASM)
7315
        fprintf(logfile, "\n");
7316
#endif
7317
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7318
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7319
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7320
        fprintf(logfile, "\n");
7321
    }
7322
    if (loglevel & CPU_LOG_TB_CPU) {
7323
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7324
    }
7325
#endif
7326

    
7327
    return 0;
7328
}
7329

    
7330
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7331
{
7332
    return gen_intermediate_code_internal(env, tb, 0);
7333
}
7334

    
7335
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7336
{
7337
    return gen_intermediate_code_internal(env, tb, 1);
7338
}
7339

    
7340
void fpu_dump_state(CPUState *env, FILE *f,
7341
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7342
                    int flags)
7343
{
7344
    int i;
7345
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7346

    
7347
#define printfpr(fp)                                                        \
7348
    do {                                                                    \
7349
        if (is_fpu64)                                                       \
7350
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7351
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7352
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7353
        else {                                                              \
7354
            fpr_t tmp;                                                      \
7355
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7356
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7357
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7358
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7359
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7360
        }                                                                   \
7361
    } while(0)
7362

    
7363

    
7364
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7365
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7366
                get_float_exception_flags(&env->fpu->fp_status));
7367
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7368
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7369
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7370
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7371
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7372
        printfpr(&env->fpu->fpr[i]);
7373
    }
7374

    
7375
#undef printfpr
7376
}
7377

    
7378
void dump_fpu (CPUState *env)
7379
{
7380
    if (loglevel) {
7381
        fprintf(logfile,
7382
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7383
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7384
                " %04x\n",
7385
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7386
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7387
                env->bcond);
7388
       fpu_dump_state(env, logfile, fprintf, 0);
7389
    }
7390
}
7391

    
7392
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7393
/* Debug help: The architecture requires 32bit code to maintain proper
7394
   sign-extened values on 64bit machines.  */
7395

    
7396
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7397

    
7398
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7399
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7400
                     int flags)
7401
{
7402
    int i;
7403

    
7404
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7405
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7406
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7407
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7408
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7409
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7410
    if (!SIGN_EXT_P(env->btarget))
7411
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7412

    
7413
    for (i = 0; i < 32; i++) {
7414
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7415
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7416
    }
7417

    
7418
    if (!SIGN_EXT_P(env->CP0_EPC))
7419
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7420
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7421
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7422
}
7423
#endif
7424

    
7425
void cpu_dump_state (CPUState *env, FILE *f,
7426
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7427
                     int flags)
7428
{
7429
    int i;
7430

    
7431
    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
7432
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7433
    for (i = 0; i < 32; i++) {
7434
        if ((i & 3) == 0)
7435
            cpu_fprintf(f, "GPR%02d:", i);
7436
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7437
        if ((i & 3) == 3)
7438
            cpu_fprintf(f, "\n");
7439
    }
7440

    
7441
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7442
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7443
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7444
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7445
    if (env->hflags & MIPS_HFLAG_FPU)
7446
        fpu_dump_state(env, f, cpu_fprintf, flags);
7447
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7448
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7449
#endif
7450
}
7451

    
7452
static void mips_tcg_init(void)
7453
{
7454
    static int inited;
7455

    
7456
    /* Initialize various static tables. */
7457
    if (inited)
7458
        return;
7459

    
7460
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7461
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7462
                                         TCG_AREG0,
7463
                                         offsetof(CPUState, current_tc_gprs),
7464
                                         "current_tc_gprs");
7465
    current_tc_hi = tcg_global_mem_new(TCG_TYPE_PTR,
7466
                                       TCG_AREG0,
7467
                                       offsetof(CPUState, current_tc_hi),
7468
                                       "current_tc_hi");
7469
#if TARGET_LONG_BITS > HOST_LONG_BITS
7470
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7471
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7472
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7473
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7474
#else
7475
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7476
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7477
#endif
7478

    
7479
    inited = 1;
7480
}
7481

    
7482
#include "translate_init.c"
7483

    
7484
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7485
{
7486
    CPUMIPSState *env;
7487
    const mips_def_t *def;
7488

    
7489
    def = cpu_mips_find_by_name(cpu_model);
7490
    if (!def)
7491
        return NULL;
7492
    env = qemu_mallocz(sizeof(CPUMIPSState));
7493
    if (!env)
7494
        return NULL;
7495
    env->cpu_model = def;
7496

    
7497
    cpu_exec_init(env);
7498
    env->cpu_model_str = cpu_model;
7499
    mips_tcg_init();
7500
    cpu_reset(env);
7501
    return env;
7502
}
7503

    
7504
void cpu_reset (CPUMIPSState *env)
7505
{
7506
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7507

    
7508
    tlb_flush(env, 1);
7509

    
7510
    /* Minimal init */
7511
#if !defined(CONFIG_USER_ONLY)
7512
    if (env->hflags & MIPS_HFLAG_BMASK) {
7513
        /* If the exception was raised from a delay slot,
7514
         * come back to the jump.  */
7515
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7516
    } else {
7517
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7518
    }
7519
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7520
    env->CP0_Wired = 0;
7521
    /* SMP not implemented */
7522
    env->CP0_EBase = 0x80000000;
7523
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7524
    /* vectored interrupts not implemented, timer on int 7,
7525
       no performance counters. */
7526
    env->CP0_IntCtl = 0xe0000000;
7527
    {
7528
        int i;
7529

    
7530
        for (i = 0; i < 7; i++) {
7531
            env->CP0_WatchLo[i] = 0;
7532
            env->CP0_WatchHi[i] = 0x80000000;
7533
        }
7534
        env->CP0_WatchLo[7] = 0;
7535
        env->CP0_WatchHi[7] = 0;
7536
    }
7537
    /* Count register increments in debug mode, EJTAG version 1 */
7538
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7539
#endif
7540
    env->exception_index = EXCP_NONE;
7541
#if defined(CONFIG_USER_ONLY)
7542
    env->hflags = MIPS_HFLAG_UM;
7543
    env->user_mode_only = 1;
7544
#else
7545
    env->hflags = MIPS_HFLAG_CP0;
7546
#endif
7547
    cpu_mips_register(env, env->cpu_model);
7548
}
7549

    
7550
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7551
                unsigned long searched_pc, int pc_pos, void *puc)
7552
{
7553
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7554
    env->hflags &= ~MIPS_HFLAG_BMASK;
7555
    env->hflags |= gen_opc_hflags[pc_pos];
7556
}