Statistics
| Branch: | Revision:

root / target-mips / translate.c @ e6bb7d7e

History | View | Annotate | Download (221 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, cpu_T[2];
427

    
428
/* The code generator doesn't like lots of temporaries, so maintain our own
429
   cache for reuse within a function.  */
430
#define MAX_TEMPS 4
431
static int num_temps;
432
static TCGv temps[MAX_TEMPS];
433

    
434
/* Allocate a temporary variable.  */
435
static TCGv new_tmp(void)
436
{
437
    TCGv tmp;
438
    if (num_temps == MAX_TEMPS)
439
        abort();
440

    
441
    if (GET_TCGV(temps[num_temps]))
442
      return temps[num_temps++];
443

    
444
    tmp = tcg_temp_new(TCG_TYPE_I32);
445
    temps[num_temps++] = tmp;
446
    return tmp;
447
}
448

    
449
/* Release a temporary variable.  */
450
static void dead_tmp(TCGv tmp)
451
{
452
    int i;
453
    num_temps--;
454
    i = num_temps;
455
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
456
        return;
457

    
458
    /* Shuffle this temp to the last slot.  */
459
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
460
        i--;
461
    while (i < num_temps) {
462
        temps[i] = temps[i + 1];
463
        i++;
464
    }
465
    temps[i] = tmp;
466
}
467

    
468
typedef struct DisasContext {
469
    struct TranslationBlock *tb;
470
    target_ulong pc, saved_pc;
471
    uint32_t opcode;
472
    uint32_t fp_status;
473
    /* Routine used to access memory */
474
    int mem_idx;
475
    uint32_t hflags, saved_hflags;
476
    int bstate;
477
    target_ulong btarget;
478
} DisasContext;
479

    
480
enum {
481
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
482
                      * exception condition
483
                      */
484
    BS_STOP     = 1, /* We want to stop translation for any reason */
485
    BS_BRANCH   = 2, /* We reached a branch condition     */
486
    BS_EXCP     = 3, /* We reached an exception condition */
487
};
488

    
489
static const char *regnames[] =
490
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
491
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
492
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
493
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
494

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

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

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

    
519
/* General purpose registers moves. */
520
static inline void gen_load_gpr (TCGv t, int reg)
521
{
522
    if (reg == 0)
523
        tcg_gen_movi_tl(t, 0);
524
    else
525
        tcg_gen_ld_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
526
}
527

    
528
static inline void gen_store_gpr (TCGv t, int reg)
529
{
530
    if (reg != 0)
531
        tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
532
}
533

    
534
/* Moves to/from shadow registers. */
535
static inline void gen_load_srsgpr (TCGv t, int reg)
536
{
537
    if (reg == 0)
538
        tcg_gen_movi_tl(t, 0);
539
    else {
540
        TCGv r_tmp = new_tmp();
541

    
542
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
543
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
544
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
545
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
546
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
547

    
548
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
549
        dead_tmp(r_tmp);
550
    }
551
}
552

    
553
static inline void gen_store_srsgpr (TCGv t, int reg)
554
{
555
    if (reg != 0) {
556
        TCGv r_tmp = new_tmp();
557

    
558
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
559
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
560
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
561
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
562
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
563

    
564
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
565
        dead_tmp(r_tmp);
566
    }
567
}
568

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

    
586
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
587
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
588

    
589
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
590
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
591

    
592
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
593
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
594

    
595
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
596
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
597

    
598
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
599
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
600

    
601
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
602
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
603

    
604
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
605
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
606

    
607
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
608
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
609

    
610
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
611
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
612

    
613
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
614
do {                                                                          \
615
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
616
} while (0)
617

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

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

    
647
FOP_CONDS(, d)
648
FOP_CONDS(abs, d)
649
FOP_CONDS(, s)
650
FOP_CONDS(abs, s)
651
FOP_CONDS(, ps)
652
FOP_CONDS(abs, ps)
653

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

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

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

    
712
static inline void gen_save_pc(target_ulong pc)
713
{
714
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
715
    TCGv r_tc_off = new_tmp();
716
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
717
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
718

    
719
    tcg_gen_movi_tl(r_tmp, pc);
720
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
721
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
722
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
723
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
724
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
725
    dead_tmp(r_tc_off);
726
}
727

    
728
static inline void gen_breg_pc(void)
729
{
730
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
731
    TCGv r_tc_off = new_tmp();
732
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
733
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
734

    
735
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
736
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
737
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
738
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
739
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
740
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
741
    dead_tmp(r_tc_off);
742
}
743

    
744
static inline void gen_save_btarget(target_ulong btarget)
745
{
746
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
747

    
748
    tcg_gen_movi_tl(r_tmp, btarget);
749
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
750
}
751

    
752
static always_inline void gen_save_breg_target(int reg)
753
{
754
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
755

    
756
    gen_load_gpr(r_tmp, reg);
757
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
758
}
759

    
760
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
761
{
762
#if defined MIPS_DEBUG_DISAS
763
    if (loglevel & CPU_LOG_TB_IN_ASM) {
764
            fprintf(logfile, "hflags %08x saved %08x\n",
765
                    ctx->hflags, ctx->saved_hflags);
766
    }
767
#endif
768
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
769
        gen_save_pc(ctx->pc);
770
        ctx->saved_pc = ctx->pc;
771
    }
772
    if (ctx->hflags != ctx->saved_hflags) {
773
        gen_op_save_state(ctx->hflags);
774
        ctx->saved_hflags = ctx->hflags;
775
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
776
        case MIPS_HFLAG_BR:
777
            break;
778
        case MIPS_HFLAG_BC:
779
        case MIPS_HFLAG_BL:
780
        case MIPS_HFLAG_B:
781
            gen_save_btarget(ctx->btarget);
782
            break;
783
        }
784
    }
785
}
786

    
787
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
788
{
789
    ctx->saved_hflags = ctx->hflags;
790
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
791
    case MIPS_HFLAG_BR:
792
        break;
793
    case MIPS_HFLAG_BC:
794
    case MIPS_HFLAG_BL:
795
    case MIPS_HFLAG_B:
796
        ctx->btarget = env->btarget;
797
        break;
798
    }
799
}
800

    
801
static always_inline void
802
generate_exception_err (DisasContext *ctx, int excp, int err)
803
{
804
    save_cpu_state(ctx, 1);
805
    tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
806
    tcg_gen_helper_0_0(do_interrupt_restart);
807
    tcg_gen_exit_tb(0);
808
}
809

    
810
static always_inline void
811
generate_exception (DisasContext *ctx, int excp)
812
{
813
    save_cpu_state(ctx, 1);
814
    tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
815
    tcg_gen_helper_0_0(do_interrupt_restart);
816
    tcg_gen_exit_tb(0);
817
}
818

    
819
/* Addresses computation */
820
static inline void gen_op_addr_add (void)
821
{
822
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
823

    
824
#if defined(TARGET_MIPS64)
825
    /* For compatibility with 32-bit code, data reference in user mode
826
       with Status_UX = 0 should be casted to 32-bit and sign extended.
827
       See the MIPS64 PRA manual, section 4.10. */
828
    {
829
        TCGv r_tmp = new_tmp();
830
        int l1 = gen_new_label();
831

    
832
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
833
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
834
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
835
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
836
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
837
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
838
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
839
        gen_set_label(l1);
840
        dead_tmp(r_tmp);
841
    }
842
#endif
843
}
844

    
845
static always_inline void check_cp0_enabled(DisasContext *ctx)
846
{
847
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
848
        generate_exception_err(ctx, EXCP_CpU, 1);
849
}
850

    
851
static always_inline void check_cp1_enabled(DisasContext *ctx)
852
{
853
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
854
        generate_exception_err(ctx, EXCP_CpU, 1);
855
}
856

    
857
/* Verify that the processor is running with COP1X instructions enabled.
858
   This is associated with the nabla symbol in the MIPS32 and MIPS64
859
   opcode tables.  */
860

    
861
static always_inline void check_cop1x(DisasContext *ctx)
862
{
863
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
864
        generate_exception(ctx, EXCP_RI);
865
}
866

    
867
/* Verify that the processor is running with 64-bit floating-point
868
   operations enabled.  */
869

    
870
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
871
{
872
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
873
        generate_exception(ctx, EXCP_RI);
874
}
875

    
876
/*
877
 * Verify if floating point register is valid; an operation is not defined
878
 * if bit 0 of any register specification is set and the FR bit in the
879
 * Status register equals zero, since the register numbers specify an
880
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
881
 * in the Status register equals one, both even and odd register numbers
882
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
883
 *
884
 * Multiple 64 bit wide registers can be checked by calling
885
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
886
 */
887
void check_cp1_registers(DisasContext *ctx, int regs)
888
{
889
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
890
        generate_exception(ctx, EXCP_RI);
891
}
892

    
893
/* This code generates a "reserved instruction" exception if the
894
   CPU does not support the instruction set corresponding to flags. */
895
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
896
{
897
    if (unlikely(!(env->insn_flags & flags)))
898
        generate_exception(ctx, EXCP_RI);
899
}
900

    
901
/* This code generates a "reserved instruction" exception if 64-bit
902
   instructions are not enabled. */
903
static always_inline void check_mips_64(DisasContext *ctx)
904
{
905
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
906
        generate_exception(ctx, EXCP_RI);
907
}
908

    
909
/* load/store instructions. */
910
#if defined(CONFIG_USER_ONLY)
911
#define op_ldst(name)        gen_op_##name##_raw()
912
#define OP_LD_TABLE(width)
913
#define OP_ST_TABLE(width)
914
#else
915
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
916
#define OP_LD_TABLE(width)                                                    \
917
static GenOpFunc *gen_op_l##width[] = {                                       \
918
    &gen_op_l##width##_kernel,                                                \
919
    &gen_op_l##width##_super,                                                 \
920
    &gen_op_l##width##_user,                                                  \
921
}
922
#define OP_ST_TABLE(width)                                                    \
923
static GenOpFunc *gen_op_s##width[] = {                                       \
924
    &gen_op_s##width##_kernel,                                                \
925
    &gen_op_s##width##_super,                                                 \
926
    &gen_op_s##width##_user,                                                  \
927
}
928
#endif
929

    
930
#if defined(TARGET_MIPS64)
931
OP_LD_TABLE(dl);
932
OP_LD_TABLE(dr);
933
OP_ST_TABLE(dl);
934
OP_ST_TABLE(dr);
935
#endif
936
OP_LD_TABLE(wl);
937
OP_LD_TABLE(wr);
938
OP_ST_TABLE(wl);
939
OP_ST_TABLE(wr);
940
OP_LD_TABLE(wc1);
941
OP_ST_TABLE(wc1);
942
OP_LD_TABLE(dc1);
943
OP_ST_TABLE(dc1);
944
OP_LD_TABLE(uxc1);
945
OP_ST_TABLE(uxc1);
946

    
947
#define OP_LD(insn,fname)                                        \
948
void inline op_ldst_##insn(DisasContext *ctx)                    \
949
{                                                                \
950
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
951
}
952
OP_LD(lb,ld8s);
953
OP_LD(lbu,ld8u);
954
OP_LD(lh,ld16s);
955
OP_LD(lhu,ld16u);
956
OP_LD(lw,ld32s);
957
#if defined(TARGET_MIPS64)
958
OP_LD(lwu,ld32u);
959
OP_LD(ld,ld64);
960
#endif
961
#undef OP_LD
962

    
963
#define OP_ST(insn,fname)                                        \
964
void inline op_ldst_##insn(DisasContext *ctx)                    \
965
{                                                                \
966
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
967
}
968
OP_ST(sb,st8);
969
OP_ST(sh,st16);
970
OP_ST(sw,st32);
971
#if defined(TARGET_MIPS64)
972
OP_ST(sd,st64);
973
#endif
974
#undef OP_ST
975

    
976
#define OP_LD_ATOMIC(insn,fname)                                        \
977
void inline op_ldst_##insn(DisasContext *ctx)                           \
978
{                                                                       \
979
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
980
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
981
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
982
}
983
OP_LD_ATOMIC(ll,ld32s);
984
#if defined(TARGET_MIPS64)
985
OP_LD_ATOMIC(lld,ld64);
986
#endif
987
#undef OP_LD_ATOMIC
988

    
989
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
990
void inline op_ldst_##insn(DisasContext *ctx)                           \
991
{                                                                       \
992
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);                             \
993
    int l1 = gen_new_label();                                           \
994
    int l2 = gen_new_label();                                           \
995
    int l3 = gen_new_label();                                           \
996
                                                                        \
997
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
998
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
999
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1000
    generate_exception(ctx, EXCP_AdES);                                 \
1001
    gen_set_label(l1);                                                  \
1002
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1003
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1004
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1005
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1006
    tcg_gen_br(l3);                                                     \
1007
    gen_set_label(l2);                                                  \
1008
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1009
    gen_set_label(l3);                                                  \
1010
}
1011
OP_ST_ATOMIC(sc,st32,0x3);
1012
#if defined(TARGET_MIPS64)
1013
OP_ST_ATOMIC(scd,st64,0x7);
1014
#endif
1015
#undef OP_ST_ATOMIC
1016

    
1017
void inline op_ldst_lwc1(DisasContext *ctx)
1018
{
1019
    op_ldst(lwc1);
1020
}
1021

    
1022
void inline op_ldst_ldc1(DisasContext *ctx)
1023
{
1024
    op_ldst(ldc1);
1025
}
1026

    
1027
void inline op_ldst_swc1(DisasContext *ctx)
1028
{
1029
    op_ldst(swc1);
1030
}
1031

    
1032
void inline op_ldst_sdc1(DisasContext *ctx)
1033
{
1034
    op_ldst(sdc1);
1035
}
1036

    
1037
/* Load and store */
1038
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1039
                      int base, int16_t offset)
1040
{
1041
    const char *opn = "ldst";
1042

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

    
1188
/* Load and store */
1189
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1190
                      int base, int16_t offset)
1191
{
1192
    const char *opn = "flt_ldst";
1193

    
1194
    if (base == 0) {
1195
        tcg_gen_movi_tl(cpu_T[0], offset);
1196
    } else if (offset == 0) {
1197
        gen_load_gpr(cpu_T[0], base);
1198
    } else {
1199
        gen_load_gpr(cpu_T[0], base);
1200
        tcg_gen_movi_tl(cpu_T[1], offset);
1201
        gen_op_addr_add();
1202
    }
1203
    /* Don't do NOP if destination is zero: we must perform the actual
1204
       memory access. */
1205
    switch (opc) {
1206
    case OPC_LWC1:
1207
        op_ldst_lwc1(ctx);
1208
        GEN_STORE_FTN_FREG(ft, WT0);
1209
        opn = "lwc1";
1210
        break;
1211
    case OPC_SWC1:
1212
        GEN_LOAD_FREG_FTN(WT0, ft);
1213
        op_ldst_swc1(ctx);
1214
        opn = "swc1";
1215
        break;
1216
    case OPC_LDC1:
1217
        op_ldst_ldc1(ctx);
1218
        GEN_STORE_FTN_FREG(ft, DT0);
1219
        opn = "ldc1";
1220
        break;
1221
    case OPC_SDC1:
1222
        GEN_LOAD_FREG_FTN(DT0, ft);
1223
        op_ldst_sdc1(ctx);
1224
        opn = "sdc1";
1225
        break;
1226
    default:
1227
        MIPS_INVAL(opn);
1228
        generate_exception(ctx, EXCP_RI);
1229
        return;
1230
    }
1231
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1232
}
1233

    
1234
/* Arithmetic with immediate operand */
1235
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1236
                           int rt, int rs, int16_t imm)
1237
{
1238
    target_ulong uimm;
1239
    const char *opn = "imm arith";
1240

    
1241
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1242
        /* If no destination, treat it as a NOP.
1243
           For addi, we must generate the overflow exception when needed. */
1244
        MIPS_DEBUG("NOP");
1245
        return;
1246
    }
1247
    uimm = (uint16_t)imm;
1248
    switch (opc) {
1249
    case OPC_ADDI:
1250
    case OPC_ADDIU:
1251
#if defined(TARGET_MIPS64)
1252
    case OPC_DADDI:
1253
    case OPC_DADDIU:
1254
#endif
1255
    case OPC_SLTI:
1256
    case OPC_SLTIU:
1257
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1258
        tcg_gen_movi_tl(cpu_T[1], uimm);
1259
        /* Fall through. */
1260
    case OPC_ANDI:
1261
    case OPC_ORI:
1262
    case OPC_XORI:
1263
        gen_load_gpr(cpu_T[0], rs);
1264
        break;
1265
    case OPC_LUI:
1266
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1267
        break;
1268
    case OPC_SLL:
1269
    case OPC_SRA:
1270
    case OPC_SRL:
1271
#if defined(TARGET_MIPS64)
1272
    case OPC_DSLL:
1273
    case OPC_DSRA:
1274
    case OPC_DSRL:
1275
    case OPC_DSLL32:
1276
    case OPC_DSRA32:
1277
    case OPC_DSRL32:
1278
#endif
1279
        uimm &= 0x1f;
1280
        gen_load_gpr(cpu_T[0], rs);
1281
        break;
1282
    }
1283
    switch (opc) {
1284
    case OPC_ADDI:
1285
        {
1286
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1287
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1288
            int l1 = gen_new_label();
1289

    
1290
            save_cpu_state(ctx, 1);
1291
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1292
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1293

    
1294
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1295
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1296
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1297
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1298
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1299
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1300
            /* operands of same sign, result different sign */
1301
            generate_exception(ctx, EXCP_OVERFLOW);
1302
            gen_set_label(l1);
1303

    
1304
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1305
        }
1306
        opn = "addi";
1307
        break;
1308
    case OPC_ADDIU:
1309
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1310
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1311
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1312
        opn = "addiu";
1313
        break;
1314
#if defined(TARGET_MIPS64)
1315
    case OPC_DADDI:
1316
        {
1317
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1318
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1319
            int l1 = gen_new_label();
1320

    
1321
            save_cpu_state(ctx, 1);
1322
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1323
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1324

    
1325
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1326
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1327
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1328
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1329
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1330
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1331
            /* operands of same sign, result different sign */
1332
            generate_exception(ctx, EXCP_OVERFLOW);
1333
            gen_set_label(l1);
1334
        }
1335
        opn = "daddi";
1336
        break;
1337
    case OPC_DADDIU:
1338
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1339
        opn = "daddiu";
1340
        break;
1341
#endif
1342
    case OPC_SLTI:
1343
        gen_op_lti(uimm);
1344
        opn = "slti";
1345
        break;
1346
    case OPC_SLTIU:
1347
        gen_op_ltiu(uimm);
1348
        opn = "sltiu";
1349
        break;
1350
    case OPC_ANDI:
1351
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1352
        opn = "andi";
1353
        break;
1354
    case OPC_ORI:
1355
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1356
        opn = "ori";
1357
        break;
1358
    case OPC_XORI:
1359
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1360
        opn = "xori";
1361
        break;
1362
    case OPC_LUI:
1363
        opn = "lui";
1364
        break;
1365
    case OPC_SLL:
1366
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1367
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1368
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1369
        opn = "sll";
1370
        break;
1371
    case OPC_SRA:
1372
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1373
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1374
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1375
        opn = "sra";
1376
        break;
1377
    case OPC_SRL:
1378
        switch ((ctx->opcode >> 21) & 0x1f) {
1379
        case 0:
1380
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1381
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1382
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1383
            opn = "srl";
1384
            break;
1385
        case 1:
1386
            /* rotr is decoded as srl on non-R2 CPUs */
1387
            if (env->insn_flags & ISA_MIPS32R2) {
1388
                if (uimm != 0) {
1389
                    TCGv r_tmp1 = new_tmp();
1390
                    TCGv r_tmp2 = new_tmp();
1391

    
1392
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1393
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1394
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1395
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1396
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1397
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1398
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1399
                    dead_tmp(r_tmp1);
1400
                    dead_tmp(r_tmp2);
1401
                }
1402
                opn = "rotr";
1403
            } else {
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
            }
1409
            break;
1410
        default:
1411
            MIPS_INVAL("invalid srl flag");
1412
            generate_exception(ctx, EXCP_RI);
1413
            break;
1414
        }
1415
        break;
1416
#if defined(TARGET_MIPS64)
1417
    case OPC_DSLL:
1418
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1419
        opn = "dsll";
1420
        break;
1421
    case OPC_DSRA:
1422
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1423
        opn = "dsra";
1424
        break;
1425
    case OPC_DSRL:
1426
        switch ((ctx->opcode >> 21) & 0x1f) {
1427
        case 0:
1428
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1429
            opn = "dsrl";
1430
            break;
1431
        case 1:
1432
            /* drotr is decoded as dsrl on non-R2 CPUs */
1433
            if (env->insn_flags & ISA_MIPS32R2) {
1434
                if (uimm != 0) {
1435
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1436

    
1437
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1438
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1439
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1440
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1441
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1442
                }
1443
                opn = "drotr";
1444
            } else {
1445
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1446
                opn = "dsrl";
1447
            }
1448
            break;
1449
        default:
1450
            MIPS_INVAL("invalid dsrl flag");
1451
            generate_exception(ctx, EXCP_RI);
1452
            break;
1453
        }
1454
        break;
1455
    case OPC_DSLL32:
1456
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1457
        opn = "dsll32";
1458
        break;
1459
    case OPC_DSRA32:
1460
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1461
        opn = "dsra32";
1462
        break;
1463
    case OPC_DSRL32:
1464
        switch ((ctx->opcode >> 21) & 0x1f) {
1465
        case 0:
1466
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1467
            opn = "dsrl32";
1468
            break;
1469
        case 1:
1470
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1471
            if (env->insn_flags & ISA_MIPS32R2) {
1472
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1473
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1474

    
1475
                tcg_gen_movi_tl(r_tmp1, 0x40);
1476
                tcg_gen_movi_tl(r_tmp2, 32);
1477
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1478
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1479
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1480
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1481
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1482
                opn = "drotr32";
1483
            } else {
1484
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1485
                opn = "dsrl32";
1486
            }
1487
            break;
1488
        default:
1489
            MIPS_INVAL("invalid dsrl32 flag");
1490
            generate_exception(ctx, EXCP_RI);
1491
            break;
1492
        }
1493
        break;
1494
#endif
1495
    default:
1496
        MIPS_INVAL(opn);
1497
        generate_exception(ctx, EXCP_RI);
1498
        return;
1499
    }
1500
    gen_store_gpr(cpu_T[0], rt);
1501
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1502
}
1503

    
1504
/* Arithmetic */
1505
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1506
                       int rd, int rs, int rt)
1507
{
1508
    const char *opn = "arith";
1509

    
1510
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1511
       && opc != OPC_DADD && opc != OPC_DSUB) {
1512
        /* If no destination, treat it as a NOP.
1513
           For add & sub, we must generate the overflow exception when needed. */
1514
        MIPS_DEBUG("NOP");
1515
        return;
1516
    }
1517
    gen_load_gpr(cpu_T[0], rs);
1518
    /* Specialcase the conventional move operation. */
1519
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1520
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1521
        gen_store_gpr(cpu_T[0], rd);
1522
        return;
1523
    }
1524
    gen_load_gpr(cpu_T[1], rt);
1525
    switch (opc) {
1526
    case OPC_ADD:
1527
        {
1528
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1529
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1530
            int l1 = gen_new_label();
1531

    
1532
            save_cpu_state(ctx, 1);
1533
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1534
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1535
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1536

    
1537
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1538
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1539
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1540
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1541
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1542
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1543
            /* operands of same sign, result different sign */
1544
            generate_exception(ctx, EXCP_OVERFLOW);
1545
            gen_set_label(l1);
1546

    
1547
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1548
        }
1549
        opn = "add";
1550
        break;
1551
    case OPC_ADDU:
1552
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1553
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1554
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1555
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1556
        opn = "addu";
1557
        break;
1558
    case OPC_SUB:
1559
        {
1560
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1561
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1562
            int l1 = gen_new_label();
1563

    
1564
            save_cpu_state(ctx, 1);
1565
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1566
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1567
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1568

    
1569
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1570
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1571
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1572
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1573
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1574
            /* operands of different sign, first operand and result different sign */
1575
            generate_exception(ctx, EXCP_OVERFLOW);
1576
            gen_set_label(l1);
1577

    
1578
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1579
        }
1580
        opn = "sub";
1581
        break;
1582
    case OPC_SUBU:
1583
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1584
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1585
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1586
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1587
        opn = "subu";
1588
        break;
1589
#if defined(TARGET_MIPS64)
1590
    case OPC_DADD:
1591
        {
1592
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1593
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1594
            int l1 = gen_new_label();
1595

    
1596
            save_cpu_state(ctx, 1);
1597
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1598
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1599

    
1600
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1601
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1602
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1603
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1604
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1605
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1606
            /* operands of same sign, result different sign */
1607
            generate_exception(ctx, EXCP_OVERFLOW);
1608
            gen_set_label(l1);
1609
        }
1610
        opn = "dadd";
1611
        break;
1612
    case OPC_DADDU:
1613
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1614
        opn = "daddu";
1615
        break;
1616
    case OPC_DSUB:
1617
        {
1618
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1619
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1620
            int l1 = gen_new_label();
1621

    
1622
            save_cpu_state(ctx, 1);
1623
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1624
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1625

    
1626
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1627
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1628
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1629
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1630
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1631
            /* operands of different sign, first operand and result different sign */
1632
            generate_exception(ctx, EXCP_OVERFLOW);
1633
            gen_set_label(l1);
1634
        }
1635
        opn = "dsub";
1636
        break;
1637
    case OPC_DSUBU:
1638
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1639
        opn = "dsubu";
1640
        break;
1641
#endif
1642
    case OPC_SLT:
1643
        gen_op_lt();
1644
        opn = "slt";
1645
        break;
1646
    case OPC_SLTU:
1647
        gen_op_ltu();
1648
        opn = "sltu";
1649
        break;
1650
    case OPC_AND:
1651
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1652
        opn = "and";
1653
        break;
1654
    case OPC_NOR:
1655
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1656
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1657
        opn = "nor";
1658
        break;
1659
    case OPC_OR:
1660
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1661
        opn = "or";
1662
        break;
1663
    case OPC_XOR:
1664
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1665
        opn = "xor";
1666
        break;
1667
    case OPC_MUL:
1668
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1669
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1670
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1671
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1672
        opn = "mul";
1673
        break;
1674
    case OPC_MOVN:
1675
        {
1676
            int l1 = gen_new_label();
1677

    
1678
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1679
            gen_store_gpr(cpu_T[0], rd);
1680
            gen_set_label(l1);
1681
        }
1682
        opn = "movn";
1683
        goto print;
1684
    case OPC_MOVZ:
1685
        {
1686
            int l1 = gen_new_label();
1687

    
1688
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1689
            gen_store_gpr(cpu_T[0], rd);
1690
            gen_set_label(l1);
1691
        }
1692
        opn = "movz";
1693
        goto print;
1694
    case OPC_SLLV:
1695
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1696
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1697
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1698
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1699
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1700
        opn = "sllv";
1701
        break;
1702
    case OPC_SRAV:
1703
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1704
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1705
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1706
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1707
        opn = "srav";
1708
        break;
1709
    case OPC_SRLV:
1710
        switch ((ctx->opcode >> 6) & 0x1f) {
1711
        case 0:
1712
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1713
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1714
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1715
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1716
            opn = "srlv";
1717
            break;
1718
        case 1:
1719
            /* rotrv is decoded as srlv on non-R2 CPUs */
1720
            if (env->insn_flags & ISA_MIPS32R2) {
1721
                int l1 = gen_new_label();
1722
                int l2 = gen_new_label();
1723

    
1724
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1725
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1726
                {
1727
                    TCGv r_tmp1 = new_tmp();
1728
                    TCGv r_tmp2 = new_tmp();
1729
                    TCGv r_tmp3 = new_tmp();
1730

    
1731
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1732
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1733
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1734
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1735
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1736
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1737
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1738
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1739
                    dead_tmp(r_tmp1);
1740
                    dead_tmp(r_tmp2);
1741
                    dead_tmp(r_tmp3);
1742
                    tcg_gen_br(l2);
1743
                }
1744
                gen_set_label(l1);
1745
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1746
                gen_set_label(l2);
1747
                opn = "rotrv";
1748
            } else {
1749
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1750
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1751
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1752
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1753
                opn = "srlv";
1754
            }
1755
            break;
1756
        default:
1757
            MIPS_INVAL("invalid srlv flag");
1758
            generate_exception(ctx, EXCP_RI);
1759
            break;
1760
        }
1761
        break;
1762
#if defined(TARGET_MIPS64)
1763
    case OPC_DSLLV:
1764
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1765
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1766
        opn = "dsllv";
1767
        break;
1768
    case OPC_DSRAV:
1769
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1770
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1771
        opn = "dsrav";
1772
        break;
1773
    case OPC_DSRLV:
1774
        switch ((ctx->opcode >> 6) & 0x1f) {
1775
        case 0:
1776
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1777
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1778
            opn = "dsrlv";
1779
            break;
1780
        case 1:
1781
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1782
            if (env->insn_flags & ISA_MIPS32R2) {
1783
                int l1 = gen_new_label();
1784
                int l2 = gen_new_label();
1785

    
1786
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1787
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1788
                {
1789
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1790

    
1791
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1792
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1793
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1794
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1795
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1796
                    tcg_gen_br(l2);
1797
                }
1798
                gen_set_label(l1);
1799
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1800
                gen_set_label(l2);
1801
                opn = "drotrv";
1802
            } else {
1803
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1804
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1805
                opn = "dsrlv";
1806
            }
1807
            break;
1808
        default:
1809
            MIPS_INVAL("invalid dsrlv flag");
1810
            generate_exception(ctx, EXCP_RI);
1811
            break;
1812
        }
1813
        break;
1814
#endif
1815
    default:
1816
        MIPS_INVAL(opn);
1817
        generate_exception(ctx, EXCP_RI);
1818
        return;
1819
    }
1820
    gen_store_gpr(cpu_T[0], rd);
1821
 print:
1822
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1823
}
1824

    
1825
/* Arithmetic on HI/LO registers */
1826
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1827
{
1828
    const char *opn = "hilo";
1829

    
1830
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1831
        /* Treat as NOP. */
1832
        MIPS_DEBUG("NOP");
1833
        return;
1834
    }
1835
    switch (opc) {
1836
    case OPC_MFHI:
1837
        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0]));
1838
        gen_store_gpr(cpu_T[0], reg);
1839
        opn = "mfhi";
1840
        break;
1841
    case OPC_MFLO:
1842
        tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0]));
1843
        gen_store_gpr(cpu_T[0], reg);
1844
        opn = "mflo";
1845
        break;
1846
    case OPC_MTHI:
1847
        gen_load_gpr(cpu_T[0], reg);
1848
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[0]));
1849
        opn = "mthi";
1850
        break;
1851
    case OPC_MTLO:
1852
        gen_load_gpr(cpu_T[0], reg);
1853
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[0]));
1854
        opn = "mtlo";
1855
        break;
1856
    default:
1857
        MIPS_INVAL(opn);
1858
        generate_exception(ctx, EXCP_RI);
1859
        return;
1860
    }
1861
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1862
}
1863

    
1864
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1865
                        int rs, int rt)
1866
{
1867
    const char *opn = "mul/div";
1868

    
1869
    gen_load_gpr(cpu_T[0], rs);
1870
    gen_load_gpr(cpu_T[1], rt);
1871
    switch (opc) {
1872
    case OPC_DIV:
1873
        {
1874
            int l1 = gen_new_label();
1875

    
1876
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1877
            {
1878
                TCGv r_tmp1 = new_tmp();
1879
                TCGv r_tmp2 = new_tmp();
1880
                TCGv r_tmp3 = new_tmp();
1881
                TCGv r_tc_off = new_tmp();
1882
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1883
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1884

    
1885
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1886
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
1887
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1888
                tcg_gen_rem_i32(r_tmp1, r_tmp1, r_tmp2);
1889
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
1890
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
1891
                dead_tmp(r_tmp1);
1892
                dead_tmp(r_tmp2);
1893
                dead_tmp(r_tmp3);
1894
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1895
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1896
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1897
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1898
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1899
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1900
                dead_tmp(r_tc_off);
1901
            }
1902
            gen_set_label(l1);
1903
        }
1904
        opn = "div";
1905
        break;
1906
    case OPC_DIVU:
1907
        {
1908
            int l1 = gen_new_label();
1909

    
1910
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1911
            {
1912
                TCGv r_tmp1 = new_tmp();
1913
                TCGv r_tmp2 = new_tmp();
1914
                TCGv r_tmp3 = new_tmp();
1915
                TCGv r_tc_off = new_tmp();
1916
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1917
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1918

    
1919
                tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1920
                tcg_gen_ext_i32_tl(r_tmp2, cpu_T[1]);
1921
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1922
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1923
                tcg_gen_trunc_tl_i32(cpu_T[0], r_tmp3);
1924
                tcg_gen_trunc_tl_i32(cpu_T[1], r_tmp1);
1925
                dead_tmp(r_tmp1);
1926
                dead_tmp(r_tmp2);
1927
                dead_tmp(r_tmp3);
1928
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1929
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1930
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1931
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1932
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1933
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1934
                dead_tmp(r_tc_off);
1935
            }
1936
            gen_set_label(l1);
1937
        }
1938
        opn = "divu";
1939
        break;
1940
    case OPC_MULT:
1941
        gen_op_mult();
1942
        opn = "mult";
1943
        break;
1944
    case OPC_MULTU:
1945
        gen_op_multu();
1946
        opn = "multu";
1947
        break;
1948
#if defined(TARGET_MIPS64)
1949
    case OPC_DDIV:
1950
        {
1951
            int l1 = gen_new_label();
1952

    
1953
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1954
            {
1955
                TCGv r_tc_off = new_tmp();
1956
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1957
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1958
                int l2 = gen_new_label();
1959
                int l3 = gen_new_label();
1960

    
1961
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1962
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2);
1963
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1964
                tcg_gen_movi_tl(cpu_T[1], 0);
1965
                tcg_gen_br(l3);
1966
                gen_set_label(l2);
1967
                tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
1968
                tcg_gen_rem_i64(cpu_T[1], cpu_T[0], cpu_T[1]);
1969
                gen_set_label(l3);
1970

    
1971
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1972
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1973
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
1974
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
1975
                tcg_gen_st_tl(cpu_T[0], r_ptr, offsetof(CPUState, LO));
1976
                tcg_gen_st_tl(cpu_T[1], r_ptr, offsetof(CPUState, HI));
1977
                dead_tmp(r_tc_off);
1978
            }
1979
            gen_set_label(l1);
1980
        }
1981
        opn = "ddiv";
1982
        break;
1983
    case OPC_DDIVU:
1984
        {
1985
            int l1 = gen_new_label();
1986

    
1987
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1988
            {
1989
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1990
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1991
                TCGv r_tc_off = new_tmp();
1992
                TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
1993
                TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
1994

    
1995
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1996
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1997
                tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
1998
                tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
1999
                tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
2000
                tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
2001
                tcg_gen_st_tl(r_tmp1, r_ptr, offsetof(CPUState, LO));
2002
                tcg_gen_st_tl(r_tmp2, r_ptr, offsetof(CPUState, HI));
2003
                dead_tmp(r_tc_off);
2004
            }
2005
            gen_set_label(l1);
2006
        }
2007
        opn = "ddivu";
2008
        break;
2009
    case OPC_DMULT:
2010
        gen_op_dmult();
2011
        opn = "dmult";
2012
        break;
2013
    case OPC_DMULTU:
2014
        gen_op_dmultu();
2015
        opn = "dmultu";
2016
        break;
2017
#endif
2018
    case OPC_MADD:
2019
        gen_op_madd();
2020
        opn = "madd";
2021
        break;
2022
    case OPC_MADDU:
2023
        gen_op_maddu();
2024
        opn = "maddu";
2025
        break;
2026
    case OPC_MSUB:
2027
        gen_op_msub();
2028
        opn = "msub";
2029
        break;
2030
    case OPC_MSUBU:
2031
        gen_op_msubu();
2032
        opn = "msubu";
2033
        break;
2034
    default:
2035
        MIPS_INVAL(opn);
2036
        generate_exception(ctx, EXCP_RI);
2037
        return;
2038
    }
2039
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2040
}
2041

    
2042
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2043
                            int rd, int rs, int rt)
2044
{
2045
    const char *opn = "mul vr54xx";
2046

    
2047
    gen_load_gpr(cpu_T[0], rs);
2048
    gen_load_gpr(cpu_T[1], rt);
2049

    
2050
    switch (opc) {
2051
    case OPC_VR54XX_MULS:
2052
        gen_op_muls();
2053
        opn = "muls";
2054
        break;
2055
    case OPC_VR54XX_MULSU:
2056
        gen_op_mulsu();
2057
        opn = "mulsu";
2058
        break;
2059
    case OPC_VR54XX_MACC:
2060
        gen_op_macc();
2061
        opn = "macc";
2062
        break;
2063
    case OPC_VR54XX_MACCU:
2064
        gen_op_maccu();
2065
        opn = "maccu";
2066
        break;
2067
    case OPC_VR54XX_MSAC:
2068
        gen_op_msac();
2069
        opn = "msac";
2070
        break;
2071
    case OPC_VR54XX_MSACU:
2072
        gen_op_msacu();
2073
        opn = "msacu";
2074
        break;
2075
    case OPC_VR54XX_MULHI:
2076
        gen_op_mulhi();
2077
        opn = "mulhi";
2078
        break;
2079
    case OPC_VR54XX_MULHIU:
2080
        gen_op_mulhiu();
2081
        opn = "mulhiu";
2082
        break;
2083
    case OPC_VR54XX_MULSHI:
2084
        gen_op_mulshi();
2085
        opn = "mulshi";
2086
        break;
2087
    case OPC_VR54XX_MULSHIU:
2088
        gen_op_mulshiu();
2089
        opn = "mulshiu";
2090
        break;
2091
    case OPC_VR54XX_MACCHI:
2092
        gen_op_macchi();
2093
        opn = "macchi";
2094
        break;
2095
    case OPC_VR54XX_MACCHIU:
2096
        gen_op_macchiu();
2097
        opn = "macchiu";
2098
        break;
2099
    case OPC_VR54XX_MSACHI:
2100
        gen_op_msachi();
2101
        opn = "msachi";
2102
        break;
2103
    case OPC_VR54XX_MSACHIU:
2104
        gen_op_msachiu();
2105
        opn = "msachiu";
2106
        break;
2107
    default:
2108
        MIPS_INVAL("mul vr54xx");
2109
        generate_exception(ctx, EXCP_RI);
2110
        return;
2111
    }
2112
    gen_store_gpr(cpu_T[0], rd);
2113
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2114
}
2115

    
2116
static void gen_cl (DisasContext *ctx, uint32_t opc,
2117
                    int rd, int rs)
2118
{
2119
    const char *opn = "CLx";
2120
    if (rd == 0) {
2121
        /* Treat as NOP. */
2122
        MIPS_DEBUG("NOP");
2123
        return;
2124
    }
2125
    gen_load_gpr(cpu_T[0], rs);
2126
    switch (opc) {
2127
    case OPC_CLO:
2128
        tcg_gen_helper_0_0(do_clo);
2129
        opn = "clo";
2130
        break;
2131
    case OPC_CLZ:
2132
        tcg_gen_helper_0_0(do_clz);
2133
        opn = "clz";
2134
        break;
2135
#if defined(TARGET_MIPS64)
2136
    case OPC_DCLO:
2137
        tcg_gen_helper_0_0(do_dclo);
2138
        opn = "dclo";
2139
        break;
2140
    case OPC_DCLZ:
2141
        tcg_gen_helper_0_0(do_dclz);
2142
        opn = "dclz";
2143
        break;
2144
#endif
2145
    default:
2146
        MIPS_INVAL(opn);
2147
        generate_exception(ctx, EXCP_RI);
2148
        return;
2149
    }
2150
    gen_store_gpr(cpu_T[0], rd);
2151
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2152
}
2153

    
2154
/* Traps */
2155
static void gen_trap (DisasContext *ctx, uint32_t opc,
2156
                      int rs, int rt, int16_t imm)
2157
{
2158
    int cond;
2159

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

    
2251
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2252
{
2253
    TranslationBlock *tb;
2254
    tb = ctx->tb;
2255
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2256
        tcg_gen_goto_tb(n);
2257
        gen_save_pc(dest);
2258
        tcg_gen_exit_tb((long)tb + n);
2259
    } else {
2260
        gen_save_pc(dest);
2261
        tcg_gen_exit_tb(0);
2262
    }
2263
}
2264

    
2265
/* Branches (before delay slot) */
2266
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2267
                                int rs, int rt, int32_t offset)
2268
{
2269
    target_ulong btarget = -1;
2270
    int blink = 0;
2271
    int bcond = 0;
2272

    
2273
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2274
#ifdef MIPS_DEBUG_DISAS
2275
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2276
            fprintf(logfile,
2277
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2278
                    ctx->pc);
2279
        }
2280
#endif
2281
        generate_exception(ctx, EXCP_RI);
2282
        return;
2283
    }
2284

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

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

    
2504
/* special3 bitfield operations */
2505
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2506
                       int rs, int lsb, int msb)
2507
{
2508
    gen_load_gpr(cpu_T[1], rs);
2509
    switch (opc) {
2510
    case OPC_EXT:
2511
        if (lsb + msb > 31)
2512
            goto fail;
2513
        gen_op_ext(lsb, msb + 1);
2514
        break;
2515
#if defined(TARGET_MIPS64)
2516
    case OPC_DEXTM:
2517
        if (lsb + msb > 63)
2518
            goto fail;
2519
        gen_op_dext(lsb, msb + 1 + 32);
2520
        break;
2521
    case OPC_DEXTU:
2522
        if (lsb + msb > 63)
2523
            goto fail;
2524
        gen_op_dext(lsb + 32, msb + 1);
2525
        break;
2526
    case OPC_DEXT:
2527
        if (lsb + msb > 63)
2528
            goto fail;
2529
        gen_op_dext(lsb, msb + 1);
2530
        break;
2531
#endif
2532
    case OPC_INS:
2533
        if (lsb > msb)
2534
            goto fail;
2535
        gen_load_gpr(cpu_T[0], rt);
2536
        gen_op_ins(lsb, msb - lsb + 1);
2537
        break;
2538
#if defined(TARGET_MIPS64)
2539
    case OPC_DINSM:
2540
        if (lsb > msb)
2541
            goto fail;
2542
        gen_load_gpr(cpu_T[0], rt);
2543
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2544
        break;
2545
    case OPC_DINSU:
2546
        if (lsb > msb)
2547
            goto fail;
2548
        gen_load_gpr(cpu_T[0], rt);
2549
        gen_op_dins(lsb + 32, msb - lsb + 1);
2550
        break;
2551
    case OPC_DINS:
2552
        if (lsb > msb)
2553
            goto fail;
2554
        gen_load_gpr(cpu_T[0], rt);
2555
        gen_op_dins(lsb, msb - lsb + 1);
2556
        break;
2557
#endif
2558
    default:
2559
fail:
2560
        MIPS_INVAL("bitops");
2561
        generate_exception(ctx, EXCP_RI);
2562
        return;
2563
    }
2564
    gen_store_gpr(cpu_T[0], rt);
2565
}
2566

    
2567
/* CP0 (MMU and control) */
2568
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2569
{
2570
    const char *rn = "invalid";
2571
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2572
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2573

    
2574
    if (sel != 0)
2575
        check_insn(env, ctx, ISA_MIPS32);
2576

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

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

    
3187
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3188
{
3189
    const char *rn = "invalid";
3190

    
3191
    if (sel != 0)
3192
        check_insn(env, ctx, ISA_MIPS32);
3193

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

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

    
3786
#if defined(TARGET_MIPS64)
3787
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3788
{
3789
    const char *rn = "invalid";
3790
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3791

    
3792
    if (sel != 0)
3793
        check_insn(env, ctx, ISA_MIPS64);
3794

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

    
4380
die:
4381
#if defined MIPS_DEBUG_DISAS
4382
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4383
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4384
                rn, reg, sel);
4385
    }
4386
#endif
4387
    generate_exception(ctx, EXCP_RI);
4388
}
4389

    
4390
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4391
{
4392
    const char *rn = "invalid";
4393

    
4394
    if (sel != 0)
4395
        check_insn(env, ctx, ISA_MIPS64);
4396

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

    
4966
die:
4967
#if defined MIPS_DEBUG_DISAS
4968
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4969
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4970
                rn, reg, sel);
4971
    }
4972
#endif
4973
    generate_exception(ctx, EXCP_RI);
4974
}
4975
#endif /* TARGET_MIPS64 */
4976

    
4977
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
4978
                     int u, int sel, int h)
4979
{
4980
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
4981

    
4982
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
4983
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
4984
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
4985
        tcg_gen_movi_tl(cpu_T[0], -1);
4986
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
4987
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
4988
        tcg_gen_movi_tl(cpu_T[0], -1);
4989
    else if (u == 0) {
4990
        switch (rt) {
4991
        case 2:
4992
            switch (sel) {
4993
            case 1:
4994
                gen_op_mftc0_tcstatus();
4995
                break;
4996
            case 2:
4997
                gen_op_mftc0_tcbind();
4998
                break;
4999
            case 3:
5000
                gen_op_mftc0_tcrestart();
5001
                break;
5002
            case 4:
5003
                gen_op_mftc0_tchalt();
5004
                break;
5005
            case 5:
5006
                gen_op_mftc0_tccontext();
5007
                break;
5008
            case 6:
5009
                gen_op_mftc0_tcschedule();
5010
                break;
5011
            case 7:
5012
                gen_op_mftc0_tcschefback();
5013
                break;
5014
            default:
5015
                gen_mfc0(env, ctx, rt, sel);
5016
                break;
5017
            }
5018
            break;
5019
        case 10:
5020
            switch (sel) {
5021
            case 0:
5022
                gen_op_mftc0_entryhi();
5023
                break;
5024
            default:
5025
                gen_mfc0(env, ctx, rt, sel);
5026
                break;
5027
            }
5028
        case 12:
5029
            switch (sel) {
5030
            case 0:
5031
                gen_op_mftc0_status();
5032
                break;
5033
            default:
5034
                gen_mfc0(env, ctx, rt, sel);
5035
                break;
5036
            }
5037
        case 23:
5038
            switch (sel) {
5039
            case 0:
5040
                gen_op_mftc0_debug();
5041
                break;
5042
            default:
5043
                gen_mfc0(env, ctx, rt, sel);
5044
                break;
5045
            }
5046
            break;
5047
        default:
5048
            gen_mfc0(env, ctx, rt, sel);
5049
        }
5050
    } else switch (sel) {
5051
    /* GPR registers. */
5052
    case 0:
5053
        gen_op_mftgpr(rt);
5054
        break;
5055
    /* Auxiliary CPU registers */
5056
    case 1:
5057
        switch (rt) {
5058
        case 0:
5059
            gen_op_mftlo(0);
5060
            break;
5061
        case 1:
5062
            gen_op_mfthi(0);
5063
            break;
5064
        case 2:
5065
            gen_op_mftacx(0);
5066
            break;
5067
        case 4:
5068
            gen_op_mftlo(1);
5069
            break;
5070
        case 5:
5071
            gen_op_mfthi(1);
5072
            break;
5073
        case 6:
5074
            gen_op_mftacx(1);
5075
            break;
5076
        case 8:
5077
            gen_op_mftlo(2);
5078
            break;
5079
        case 9:
5080
            gen_op_mfthi(2);
5081
            break;
5082
        case 10:
5083
            gen_op_mftacx(2);
5084
            break;
5085
        case 12:
5086
            gen_op_mftlo(3);
5087
            break;
5088
        case 13:
5089
            gen_op_mfthi(3);
5090
            break;
5091
        case 14:
5092
            gen_op_mftacx(3);
5093
            break;
5094
        case 16:
5095
            gen_op_mftdsp();
5096
            break;
5097
        default:
5098
            goto die;
5099
        }
5100
        break;
5101
    /* Floating point (COP1). */
5102
    case 2:
5103
        /* XXX: For now we support only a single FPU context. */
5104
        if (h == 0) {
5105
            GEN_LOAD_FREG_FTN(WT0, rt);
5106
            gen_op_mfc1();
5107
        } else {
5108
            GEN_LOAD_FREG_FTN(WTH0, rt);
5109
            gen_op_mfhc1();
5110
        }
5111
        break;
5112
    case 3:
5113
        /* XXX: For now we support only a single FPU context. */
5114
        gen_op_cfc1(rt);
5115
        break;
5116
    /* COP2: Not implemented. */
5117
    case 4:
5118
    case 5:
5119
        /* fall through */
5120
    default:
5121
        goto die;
5122
    }
5123
#if defined MIPS_DEBUG_DISAS
5124
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5125
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5126
                rt, u, sel, h);
5127
    }
5128
#endif
5129
    return;
5130

    
5131
die:
5132
#if defined MIPS_DEBUG_DISAS
5133
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5134
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5135
                rt, u, sel, h);
5136
    }
5137
#endif
5138
    generate_exception(ctx, EXCP_RI);
5139
}
5140

    
5141
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
5142
                     int u, int sel, int h)
5143
{
5144
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5145

    
5146
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5147
        ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
5148
         (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
5149
        /* NOP */ ;
5150
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5151
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5152
        /* NOP */ ;
5153
    else if (u == 0) {
5154
        switch (rd) {
5155
        case 2:
5156
            switch (sel) {
5157
            case 1:
5158
                gen_op_mttc0_tcstatus();
5159
                break;
5160
            case 2:
5161
                gen_op_mttc0_tcbind();
5162
                break;
5163
            case 3:
5164
                gen_op_mttc0_tcrestart();
5165
                break;
5166
            case 4:
5167
                gen_op_mttc0_tchalt();
5168
                break;
5169
            case 5:
5170
                gen_op_mttc0_tccontext();
5171
                break;
5172
            case 6:
5173
                gen_op_mttc0_tcschedule();
5174
                break;
5175
            case 7:
5176
                gen_op_mttc0_tcschefback();
5177
                break;
5178
            default:
5179
                gen_mtc0(env, ctx, rd, sel);
5180
                break;
5181
            }
5182
            break;
5183
        case 10:
5184
            switch (sel) {
5185
            case 0:
5186
                gen_op_mttc0_entryhi();
5187
                break;
5188
            default:
5189
                gen_mtc0(env, ctx, rd, sel);
5190
                break;
5191
            }
5192
        case 12:
5193
            switch (sel) {
5194
            case 0:
5195
                gen_op_mttc0_status();
5196
                break;
5197
            default:
5198
                gen_mtc0(env, ctx, rd, sel);
5199
                break;
5200
            }
5201
        case 23:
5202
            switch (sel) {
5203
            case 0:
5204
                gen_op_mttc0_debug();
5205
                break;
5206
            default:
5207
                gen_mtc0(env, ctx, rd, sel);
5208
                break;
5209
            }
5210
            break;
5211
        default:
5212
            gen_mtc0(env, ctx, rd, sel);
5213
        }
5214
    } else switch (sel) {
5215
    /* GPR registers. */
5216
    case 0:
5217
        gen_op_mttgpr(rd);
5218
        break;
5219
    /* Auxiliary CPU registers */
5220
    case 1:
5221
        switch (rd) {
5222
        case 0:
5223
            gen_op_mttlo(0);
5224
            break;
5225
        case 1:
5226
            gen_op_mtthi(0);
5227
            break;
5228
        case 2:
5229
            gen_op_mttacx(0);
5230
            break;
5231
        case 4:
5232
            gen_op_mttlo(1);
5233
            break;
5234
        case 5:
5235
            gen_op_mtthi(1);
5236
            break;
5237
        case 6:
5238
            gen_op_mttacx(1);
5239
            break;
5240
        case 8:
5241
            gen_op_mttlo(2);
5242
            break;
5243
        case 9:
5244
            gen_op_mtthi(2);
5245
            break;
5246
        case 10:
5247
            gen_op_mttacx(2);
5248
            break;
5249
        case 12:
5250
            gen_op_mttlo(3);
5251
            break;
5252
        case 13:
5253
            gen_op_mtthi(3);
5254
            break;
5255
        case 14:
5256
            gen_op_mttacx(3);
5257
            break;
5258
        case 16:
5259
            gen_op_mttdsp();
5260
            break;
5261
        default:
5262
            goto die;
5263
        }
5264
        break;
5265
    /* Floating point (COP1). */
5266
    case 2:
5267
        /* XXX: For now we support only a single FPU context. */
5268
        if (h == 0) {
5269
            gen_op_mtc1();
5270
            GEN_STORE_FTN_FREG(rd, WT0);
5271
        } else {
5272
            gen_op_mthc1();
5273
            GEN_STORE_FTN_FREG(rd, WTH0);
5274
        }
5275
        break;
5276
    case 3:
5277
        /* XXX: For now we support only a single FPU context. */
5278
        gen_op_ctc1(rd);
5279
        break;
5280
    /* COP2: Not implemented. */
5281
    case 4:
5282
    case 5:
5283
        /* fall through */
5284
    default:
5285
        goto die;
5286
    }
5287
#if defined MIPS_DEBUG_DISAS
5288
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5289
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5290
                rd, u, sel, h);
5291
    }
5292
#endif
5293
    return;
5294

    
5295
die:
5296
#if defined MIPS_DEBUG_DISAS
5297
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5298
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5299
                rd, u, sel, h);
5300
    }
5301
#endif
5302
    generate_exception(ctx, EXCP_RI);
5303
}
5304

    
5305
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5306
{
5307
    const char *opn = "ldst";
5308

    
5309
    switch (opc) {
5310
    case OPC_MFC0:
5311
        if (rt == 0) {
5312
            /* Treat as NOP. */
5313
            return;
5314
        }
5315
        gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
5316
        gen_store_gpr(cpu_T[0], rt);
5317
        opn = "mfc0";
5318
        break;
5319
    case OPC_MTC0:
5320
        gen_load_gpr(cpu_T[0], rt);
5321
        save_cpu_state(ctx, 1);
5322
        gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
5323
        opn = "mtc0";
5324
        break;
5325
#if defined(TARGET_MIPS64)
5326
    case OPC_DMFC0:
5327
        check_insn(env, ctx, ISA_MIPS3);
5328
        if (rt == 0) {
5329
            /* Treat as NOP. */
5330
            return;
5331
        }
5332
        gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
5333
        gen_store_gpr(cpu_T[0], rt);
5334
        opn = "dmfc0";
5335
        break;
5336
    case OPC_DMTC0:
5337
        check_insn(env, ctx, ISA_MIPS3);
5338
        gen_load_gpr(cpu_T[0], rt);
5339
        save_cpu_state(ctx, 1);
5340
        gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
5341
        opn = "dmtc0";
5342
        break;
5343
#endif
5344
    case OPC_MFTR:
5345
        check_insn(env, ctx, ASE_MT);
5346
        if (rd == 0) {
5347
            /* Treat as NOP. */
5348
            return;
5349
        }
5350
        gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
5351
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5352
        gen_store_gpr(cpu_T[0], rd);
5353
        opn = "mftr";
5354
        break;
5355
    case OPC_MTTR:
5356
        check_insn(env, ctx, ASE_MT);
5357
        gen_load_gpr(cpu_T[0], rt);
5358
        gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
5359
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5360
        opn = "mttr";
5361
        break;
5362
    case OPC_TLBWI:
5363
        opn = "tlbwi";
5364
        if (!env->tlb->do_tlbwi)
5365
            goto die;
5366
        gen_op_tlbwi();
5367
        break;
5368
    case OPC_TLBWR:
5369
        opn = "tlbwr";
5370
        if (!env->tlb->do_tlbwr)
5371
            goto die;
5372
        gen_op_tlbwr();
5373
        break;
5374
    case OPC_TLBP:
5375
        opn = "tlbp";
5376
        if (!env->tlb->do_tlbp)
5377
            goto die;
5378
        gen_op_tlbp();
5379
        break;
5380
    case OPC_TLBR:
5381
        opn = "tlbr";
5382
        if (!env->tlb->do_tlbr)
5383
            goto die;
5384
        gen_op_tlbr();
5385
        break;
5386
    case OPC_ERET:
5387
        opn = "eret";
5388
        check_insn(env, ctx, ISA_MIPS2);
5389
        save_cpu_state(ctx, 1);
5390
        gen_op_eret();
5391
        ctx->bstate = BS_EXCP;
5392
        break;
5393
    case OPC_DERET:
5394
        opn = "deret";
5395
        check_insn(env, ctx, ISA_MIPS32);
5396
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5397
            MIPS_INVAL(opn);
5398
            generate_exception(ctx, EXCP_RI);
5399
        } else {
5400
            save_cpu_state(ctx, 1);
5401
            gen_op_deret();
5402
            ctx->bstate = BS_EXCP;
5403
        }
5404
        break;
5405
    case OPC_WAIT:
5406
        opn = "wait";
5407
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5408
        /* If we get an exception, we want to restart at next instruction */
5409
        ctx->pc += 4;
5410
        save_cpu_state(ctx, 1);
5411
        ctx->pc -= 4;
5412
        gen_op_wait();
5413
        ctx->bstate = BS_EXCP;
5414
        break;
5415
    default:
5416
 die:
5417
        MIPS_INVAL(opn);
5418
        generate_exception(ctx, EXCP_RI);
5419
        return;
5420
    }
5421
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5422
}
5423

    
5424
/* CP1 Branches (before delay slot) */
5425
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5426
                                 int32_t cc, int32_t offset)
5427
{
5428
    target_ulong btarget;
5429
    const char *opn = "cp1 cond branch";
5430

    
5431
    if (cc != 0)
5432
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5433

    
5434
    btarget = ctx->pc + 4 + offset;
5435

    
5436
    switch (op) {
5437
    case OPC_BC1F:
5438
        gen_op_bc1f(cc);
5439
        opn = "bc1f";
5440
        goto not_likely;
5441
    case OPC_BC1FL:
5442
        gen_op_bc1f(cc);
5443
        opn = "bc1fl";
5444
        goto likely;
5445
    case OPC_BC1T:
5446
        gen_op_bc1t(cc);
5447
        opn = "bc1t";
5448
        goto not_likely;
5449
    case OPC_BC1TL:
5450
        gen_op_bc1t(cc);
5451
        opn = "bc1tl";
5452
    likely:
5453
        ctx->hflags |= MIPS_HFLAG_BL;
5454
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5455
        break;
5456
    case OPC_BC1FANY2:
5457
        gen_op_bc1any2f(cc);
5458
        opn = "bc1any2f";
5459
        goto not_likely;
5460
    case OPC_BC1TANY2:
5461
        gen_op_bc1any2t(cc);
5462
        opn = "bc1any2t";
5463
        goto not_likely;
5464
    case OPC_BC1FANY4:
5465
        gen_op_bc1any4f(cc);
5466
        opn = "bc1any4f";
5467
        goto not_likely;
5468
    case OPC_BC1TANY4:
5469
        gen_op_bc1any4t(cc);
5470
        opn = "bc1any4t";
5471
    not_likely:
5472
        ctx->hflags |= MIPS_HFLAG_BC;
5473
        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond));
5474
        break;
5475
    default:
5476
        MIPS_INVAL(opn);
5477
        generate_exception (ctx, EXCP_RI);
5478
        return;
5479
    }
5480
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5481
               ctx->hflags, btarget);
5482
    ctx->btarget = btarget;
5483
}
5484

    
5485
/* Coprocessor 1 (FPU) */
5486

    
5487
#define FOP(func, fmt) (((fmt) << 21) | (func))
5488

    
5489
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5490
{
5491
    const char *opn = "cp1 move";
5492

    
5493
    switch (opc) {
5494
    case OPC_MFC1:
5495
        GEN_LOAD_FREG_FTN(WT0, fs);
5496
        gen_op_mfc1();
5497
        gen_store_gpr(cpu_T[0], rt);
5498
        opn = "mfc1";
5499
        break;
5500
    case OPC_MTC1:
5501
        gen_load_gpr(cpu_T[0], rt);
5502
        gen_op_mtc1();
5503
        GEN_STORE_FTN_FREG(fs, WT0);
5504
        opn = "mtc1";
5505
        break;
5506
    case OPC_CFC1:
5507
        gen_op_cfc1(fs);
5508
        gen_store_gpr(cpu_T[0], rt);
5509
        opn = "cfc1";
5510
        break;
5511
    case OPC_CTC1:
5512
        gen_load_gpr(cpu_T[0], rt);
5513
        gen_op_ctc1(fs);
5514
        opn = "ctc1";
5515
        break;
5516
    case OPC_DMFC1:
5517
        GEN_LOAD_FREG_FTN(DT0, fs);
5518
        gen_op_dmfc1();
5519
        gen_store_gpr(cpu_T[0], rt);
5520
        opn = "dmfc1";
5521
        break;
5522
    case OPC_DMTC1:
5523
        gen_load_gpr(cpu_T[0], rt);
5524
        gen_op_dmtc1();
5525
        GEN_STORE_FTN_FREG(fs, DT0);
5526
        opn = "dmtc1";
5527
        break;
5528
    case OPC_MFHC1:
5529
        GEN_LOAD_FREG_FTN(WTH0, fs);
5530
        gen_op_mfhc1();
5531
        gen_store_gpr(cpu_T[0], rt);
5532
        opn = "mfhc1";
5533
        break;
5534
    case OPC_MTHC1:
5535
        gen_load_gpr(cpu_T[0], rt);
5536
        gen_op_mthc1();
5537
        GEN_STORE_FTN_FREG(fs, WTH0);
5538
        opn = "mthc1";
5539
        break;
5540
    default:
5541
        MIPS_INVAL(opn);
5542
        generate_exception (ctx, EXCP_RI);
5543
        return;
5544
    }
5545
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5546
}
5547

    
5548
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5549
{
5550
    int l1 = gen_new_label();
5551
    uint32_t ccbit;
5552
    TCGCond cond;
5553

    
5554
    if (cc)
5555
        ccbit = 1 << (24 + cc);
5556
    else
5557
        ccbit = 1 << 23;
5558
    if (tf)
5559
        cond = TCG_COND_EQ;
5560
    else
5561
        cond = TCG_COND_NE;
5562

    
5563
    gen_load_gpr(cpu_T[0], rd);
5564
    gen_load_gpr(cpu_T[1], rs);
5565
    {
5566
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5567
        TCGv r_tmp = new_tmp();
5568

    
5569
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5570
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5571
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5572
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5573
        dead_tmp(r_tmp);
5574
    }
5575
    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
5576

    
5577
    gen_set_label(l1);
5578
    gen_store_gpr(cpu_T[0], rd);
5579
}
5580

    
5581
#define GEN_MOVCF(fmt)                                                \
5582
static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
5583
{                                                                     \
5584
    uint32_t ccbit;                                                   \
5585
                                                                      \
5586
    if (cc) {                                                         \
5587
        ccbit = 1 << (24 + cc);                                       \
5588
    } else                                                            \
5589
        ccbit = 1 << 23;                                              \
5590
    if (!tf)                                                          \
5591
        glue(gen_op_float_movf_, fmt)(ccbit);                         \
5592
    else                                                              \
5593
        glue(gen_op_float_movt_, fmt)(ccbit);                         \
5594
}
5595
GEN_MOVCF(d);
5596
GEN_MOVCF(s);
5597
#undef GEN_MOVCF
5598

    
5599
static void gen_farith (DisasContext *ctx, uint32_t op1,
5600
                        int ft, int fs, int fd, int cc)
5601
{
5602
    const char *opn = "farith";
5603
    const char *condnames[] = {
5604
            "c.f",
5605
            "c.un",
5606
            "c.eq",
5607
            "c.ueq",
5608
            "c.olt",
5609
            "c.ult",
5610
            "c.ole",
5611
            "c.ule",
5612
            "c.sf",
5613
            "c.ngle",
5614
            "c.seq",
5615
            "c.ngl",
5616
            "c.lt",
5617
            "c.nge",
5618
            "c.le",
5619
            "c.ngt",
5620
    };
5621
    const char *condnames_abs[] = {
5622
            "cabs.f",
5623
            "cabs.un",
5624
            "cabs.eq",
5625
            "cabs.ueq",
5626
            "cabs.olt",
5627
            "cabs.ult",
5628
            "cabs.ole",
5629
            "cabs.ule",
5630
            "cabs.sf",
5631
            "cabs.ngle",
5632
            "cabs.seq",
5633
            "cabs.ngl",
5634
            "cabs.lt",
5635
            "cabs.nge",
5636
            "cabs.le",
5637
            "cabs.ngt",
5638
    };
5639
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5640
    uint32_t func = ctx->opcode & 0x3f;
5641

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

    
6411
/* Coprocessor 3 (FPU) */
6412
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6413
                           int fd, int fs, int base, int index)
6414
{
6415
    const char *opn = "extended float load/store";
6416
    int store = 0;
6417

    
6418
    if (base == 0) {
6419
        gen_load_gpr(cpu_T[0], index);
6420
    } else if (index == 0) {
6421
        gen_load_gpr(cpu_T[0], base);
6422
    } else {
6423
        gen_load_gpr(cpu_T[0], base);
6424
        gen_load_gpr(cpu_T[1], index);
6425
        gen_op_addr_add();
6426
    }
6427
    /* Don't do NOP if destination is zero: we must perform the actual
6428
       memory access. */
6429
    switch (opc) {
6430
    case OPC_LWXC1:
6431
        check_cop1x(ctx);
6432
        op_ldst_lwc1(ctx);
6433
        GEN_STORE_FTN_FREG(fd, WT0);
6434
        opn = "lwxc1";
6435
        break;
6436
    case OPC_LDXC1:
6437
        check_cop1x(ctx);
6438
        check_cp1_registers(ctx, fd);
6439
        op_ldst_ldc1(ctx);
6440
        GEN_STORE_FTN_FREG(fd, DT0);
6441
        opn = "ldxc1";
6442
        break;
6443
    case OPC_LUXC1:
6444
        check_cp1_64bitmode(ctx);
6445
        op_ldst(luxc1);
6446
        GEN_STORE_FTN_FREG(fd, DT0);
6447
        opn = "luxc1";
6448
        break;
6449
    case OPC_SWXC1:
6450
        check_cop1x(ctx);
6451
        GEN_LOAD_FREG_FTN(WT0, fs);
6452
        op_ldst_swc1(ctx);
6453
        opn = "swxc1";
6454
        store = 1;
6455
        break;
6456
    case OPC_SDXC1:
6457
        check_cop1x(ctx);
6458
        check_cp1_registers(ctx, fs);
6459
        GEN_LOAD_FREG_FTN(DT0, fs);
6460
        op_ldst_sdc1(ctx);
6461
        opn = "sdxc1";
6462
        store = 1;
6463
        break;
6464
    case OPC_SUXC1:
6465
        check_cp1_64bitmode(ctx);
6466
        GEN_LOAD_FREG_FTN(DT0, fs);
6467
        op_ldst(suxc1);
6468
        opn = "suxc1";
6469
        store = 1;
6470
        break;
6471
    default:
6472
        MIPS_INVAL(opn);
6473
        generate_exception(ctx, EXCP_RI);
6474
        return;
6475
    }
6476
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6477
               regnames[index], regnames[base]);
6478
}
6479

    
6480
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6481
                            int fd, int fr, int fs, int ft)
6482
{
6483
    const char *opn = "flt3_arith";
6484

    
6485
    switch (opc) {
6486
    case OPC_ALNV_PS:
6487
        check_cp1_64bitmode(ctx);
6488
        gen_load_gpr(cpu_T[0], fr);
6489
        GEN_LOAD_FREG_FTN(DT0, fs);
6490
        GEN_LOAD_FREG_FTN(DT1, ft);
6491
        gen_op_float_alnv_ps();
6492
        GEN_STORE_FTN_FREG(fd, DT2);
6493
        opn = "alnv.ps";
6494
        break;
6495
    case OPC_MADD_S:
6496
        check_cop1x(ctx);
6497
        GEN_LOAD_FREG_FTN(WT0, fs);
6498
        GEN_LOAD_FREG_FTN(WT1, ft);
6499
        GEN_LOAD_FREG_FTN(WT2, fr);
6500
        gen_op_float_muladd_s();
6501
        GEN_STORE_FTN_FREG(fd, WT2);
6502
        opn = "madd.s";
6503
        break;
6504
    case OPC_MADD_D:
6505
        check_cop1x(ctx);
6506
        check_cp1_registers(ctx, fd | fs | ft | fr);
6507
        GEN_LOAD_FREG_FTN(DT0, fs);
6508
        GEN_LOAD_FREG_FTN(DT1, ft);
6509
        GEN_LOAD_FREG_FTN(DT2, fr);
6510
        gen_op_float_muladd_d();
6511
        GEN_STORE_FTN_FREG(fd, DT2);
6512
        opn = "madd.d";
6513
        break;
6514
    case OPC_MADD_PS:
6515
        check_cp1_64bitmode(ctx);
6516
        GEN_LOAD_FREG_FTN(WT0, fs);
6517
        GEN_LOAD_FREG_FTN(WTH0, fs);
6518
        GEN_LOAD_FREG_FTN(WT1, ft);
6519
        GEN_LOAD_FREG_FTN(WTH1, ft);
6520
        GEN_LOAD_FREG_FTN(WT2, fr);
6521
        GEN_LOAD_FREG_FTN(WTH2, fr);
6522
        gen_op_float_muladd_ps();
6523
        GEN_STORE_FTN_FREG(fd, WT2);
6524
        GEN_STORE_FTN_FREG(fd, WTH2);
6525
        opn = "madd.ps";
6526
        break;
6527
    case OPC_MSUB_S:
6528
        check_cop1x(ctx);
6529
        GEN_LOAD_FREG_FTN(WT0, fs);
6530
        GEN_LOAD_FREG_FTN(WT1, ft);
6531
        GEN_LOAD_FREG_FTN(WT2, fr);
6532
        gen_op_float_mulsub_s();
6533
        GEN_STORE_FTN_FREG(fd, WT2);
6534
        opn = "msub.s";
6535
        break;
6536
    case OPC_MSUB_D:
6537
        check_cop1x(ctx);
6538
        check_cp1_registers(ctx, fd | fs | ft | fr);
6539
        GEN_LOAD_FREG_FTN(DT0, fs);
6540
        GEN_LOAD_FREG_FTN(DT1, ft);
6541
        GEN_LOAD_FREG_FTN(DT2, fr);
6542
        gen_op_float_mulsub_d();
6543
        GEN_STORE_FTN_FREG(fd, DT2);
6544
        opn = "msub.d";
6545
        break;
6546
    case OPC_MSUB_PS:
6547
        check_cp1_64bitmode(ctx);
6548
        GEN_LOAD_FREG_FTN(WT0, fs);
6549
        GEN_LOAD_FREG_FTN(WTH0, fs);
6550
        GEN_LOAD_FREG_FTN(WT1, ft);
6551
        GEN_LOAD_FREG_FTN(WTH1, ft);
6552
        GEN_LOAD_FREG_FTN(WT2, fr);
6553
        GEN_LOAD_FREG_FTN(WTH2, fr);
6554
        gen_op_float_mulsub_ps();
6555
        GEN_STORE_FTN_FREG(fd, WT2);
6556
        GEN_STORE_FTN_FREG(fd, WTH2);
6557
        opn = "msub.ps";
6558
        break;
6559
    case OPC_NMADD_S:
6560
        check_cop1x(ctx);
6561
        GEN_LOAD_FREG_FTN(WT0, fs);
6562
        GEN_LOAD_FREG_FTN(WT1, ft);
6563
        GEN_LOAD_FREG_FTN(WT2, fr);
6564
        gen_op_float_nmuladd_s();
6565
        GEN_STORE_FTN_FREG(fd, WT2);
6566
        opn = "nmadd.s";
6567
        break;
6568
    case OPC_NMADD_D:
6569
        check_cop1x(ctx);
6570
        check_cp1_registers(ctx, fd | fs | ft | fr);
6571
        GEN_LOAD_FREG_FTN(DT0, fs);
6572
        GEN_LOAD_FREG_FTN(DT1, ft);
6573
        GEN_LOAD_FREG_FTN(DT2, fr);
6574
        gen_op_float_nmuladd_d();
6575
        GEN_STORE_FTN_FREG(fd, DT2);
6576
        opn = "nmadd.d";
6577
        break;
6578
    case OPC_NMADD_PS:
6579
        check_cp1_64bitmode(ctx);
6580
        GEN_LOAD_FREG_FTN(WT0, fs);
6581
        GEN_LOAD_FREG_FTN(WTH0, fs);
6582
        GEN_LOAD_FREG_FTN(WT1, ft);
6583
        GEN_LOAD_FREG_FTN(WTH1, ft);
6584
        GEN_LOAD_FREG_FTN(WT2, fr);
6585
        GEN_LOAD_FREG_FTN(WTH2, fr);
6586
        gen_op_float_nmuladd_ps();
6587
        GEN_STORE_FTN_FREG(fd, WT2);
6588
        GEN_STORE_FTN_FREG(fd, WTH2);
6589
        opn = "nmadd.ps";
6590
        break;
6591
    case OPC_NMSUB_S:
6592
        check_cop1x(ctx);
6593
        GEN_LOAD_FREG_FTN(WT0, fs);
6594
        GEN_LOAD_FREG_FTN(WT1, ft);
6595
        GEN_LOAD_FREG_FTN(WT2, fr);
6596
        gen_op_float_nmulsub_s();
6597
        GEN_STORE_FTN_FREG(fd, WT2);
6598
        opn = "nmsub.s";
6599
        break;
6600
    case OPC_NMSUB_D:
6601
        check_cop1x(ctx);
6602
        check_cp1_registers(ctx, fd | fs | ft | fr);
6603
        GEN_LOAD_FREG_FTN(DT0, fs);
6604
        GEN_LOAD_FREG_FTN(DT1, ft);
6605
        GEN_LOAD_FREG_FTN(DT2, fr);
6606
        gen_op_float_nmulsub_d();
6607
        GEN_STORE_FTN_FREG(fd, DT2);
6608
        opn = "nmsub.d";
6609
        break;
6610
    case OPC_NMSUB_PS:
6611
        check_cp1_64bitmode(ctx);
6612
        GEN_LOAD_FREG_FTN(WT0, fs);
6613
        GEN_LOAD_FREG_FTN(WTH0, fs);
6614
        GEN_LOAD_FREG_FTN(WT1, ft);
6615
        GEN_LOAD_FREG_FTN(WTH1, ft);
6616
        GEN_LOAD_FREG_FTN(WT2, fr);
6617
        GEN_LOAD_FREG_FTN(WTH2, fr);
6618
        gen_op_float_nmulsub_ps();
6619
        GEN_STORE_FTN_FREG(fd, WT2);
6620
        GEN_STORE_FTN_FREG(fd, WTH2);
6621
        opn = "nmsub.ps";
6622
        break;
6623
    default:
6624
        MIPS_INVAL(opn);
6625
        generate_exception (ctx, EXCP_RI);
6626
        return;
6627
    }
6628
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
6629
               fregnames[fs], fregnames[ft]);
6630
}
6631

    
6632
/* ISA extensions (ASEs) */
6633
/* MIPS16 extension to MIPS32 */
6634
/* SmartMIPS extension to MIPS32 */
6635

    
6636
#if defined(TARGET_MIPS64)
6637

    
6638
/* MDMX extension to MIPS64 */
6639

    
6640
#endif
6641

    
6642
static void decode_opc (CPUState *env, DisasContext *ctx)
6643
{
6644
    int32_t offset;
6645
    int rs, rt, rd, sa;
6646
    uint32_t op, op1, op2;
6647
    int16_t imm;
6648

    
6649
    /* make sure instructions are on a word boundary */
6650
    if (ctx->pc & 0x3) {
6651
        env->CP0_BadVAddr = ctx->pc;
6652
        generate_exception(ctx, EXCP_AdEL);
6653
        return;
6654
    }
6655

    
6656
    /* Handle blikely not taken case */
6657
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
6658
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
6659
        int l1 = gen_new_label();
6660

    
6661
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
6662
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
6663
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
6664
        gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
6665
        gen_goto_tb(ctx, 1, ctx->pc + 4);
6666
        gen_set_label(l1);
6667
    }
6668
    op = MASK_OP_MAJOR(ctx->opcode);
6669
    rs = (ctx->opcode >> 21) & 0x1f;
6670
    rt = (ctx->opcode >> 16) & 0x1f;
6671
    rd = (ctx->opcode >> 11) & 0x1f;
6672
    sa = (ctx->opcode >> 6) & 0x1f;
6673
    imm = (int16_t)ctx->opcode;
6674
    switch (op) {
6675
    case OPC_SPECIAL:
6676
        op1 = MASK_SPECIAL(ctx->opcode);
6677
        switch (op1) {
6678
        case OPC_SLL:          /* Arithmetic with immediate */
6679
        case OPC_SRL ... OPC_SRA:
6680
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
6681
            break;
6682
        case OPC_MOVZ ... OPC_MOVN:
6683
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6684
        case OPC_SLLV:         /* Arithmetic */
6685
        case OPC_SRLV ... OPC_SRAV:
6686
        case OPC_ADD ... OPC_NOR:
6687
        case OPC_SLT ... OPC_SLTU:
6688
            gen_arith(env, ctx, op1, rd, rs, rt);
6689
            break;
6690
        case OPC_MULT ... OPC_DIVU:
6691
            if (sa) {
6692
                check_insn(env, ctx, INSN_VR54XX);
6693
                op1 = MASK_MUL_VR54XX(ctx->opcode);
6694
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
6695
            } else
6696
                gen_muldiv(ctx, op1, rs, rt);
6697
            break;
6698
        case OPC_JR ... OPC_JALR:
6699
            gen_compute_branch(ctx, op1, rs, rd, sa);
6700
            return;
6701
        case OPC_TGE ... OPC_TEQ: /* Traps */
6702
        case OPC_TNE:
6703
            gen_trap(ctx, op1, rs, rt, -1);
6704
            break;
6705
        case OPC_MFHI:          /* Move from HI/LO */
6706
        case OPC_MFLO:
6707
            gen_HILO(ctx, op1, rd);
6708
            break;
6709
        case OPC_MTHI:
6710
        case OPC_MTLO:          /* Move to HI/LO */
6711
            gen_HILO(ctx, op1, rs);
6712
            break;
6713
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
6714
#ifdef MIPS_STRICT_STANDARD
6715
            MIPS_INVAL("PMON / selsl");
6716
            generate_exception(ctx, EXCP_RI);
6717
#else
6718
            gen_op_pmon(sa);
6719
#endif
6720
            break;
6721
        case OPC_SYSCALL:
6722
            generate_exception(ctx, EXCP_SYSCALL);
6723
            break;
6724
        case OPC_BREAK:
6725
            generate_exception(ctx, EXCP_BREAK);
6726
            break;
6727
        case OPC_SPIM:
6728
#ifdef MIPS_STRICT_STANDARD
6729
            MIPS_INVAL("SPIM");
6730
            generate_exception(ctx, EXCP_RI);
6731
#else
6732
           /* Implemented as RI exception for now. */
6733
            MIPS_INVAL("spim (unofficial)");
6734
            generate_exception(ctx, EXCP_RI);
6735
#endif
6736
            break;
6737
        case OPC_SYNC:
6738
            /* Treat as NOP. */
6739
            break;
6740

    
6741
        case OPC_MOVCI:
6742
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6743
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
6744
                save_cpu_state(ctx, 1);
6745
                check_cp1_enabled(ctx);
6746
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
6747
                          (ctx->opcode >> 16) & 1);
6748
            } else {
6749
                generate_exception_err(ctx, EXCP_CpU, 1);
6750
            }
6751
            break;
6752

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

    
7051
    /* Floating point (COP1). */
7052
    case OPC_LWC1:
7053
    case OPC_LDC1:
7054
    case OPC_SWC1:
7055
    case OPC_SDC1:
7056
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7057
            save_cpu_state(ctx, 1);
7058
            check_cp1_enabled(ctx);
7059
            gen_flt_ldst(ctx, op, rt, rs, imm);
7060
        } else {
7061
            generate_exception_err(ctx, EXCP_CpU, 1);
7062
        }
7063
        break;
7064

    
7065
    case OPC_CP1:
7066
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7067
            save_cpu_state(ctx, 1);
7068
            check_cp1_enabled(ctx);
7069
            op1 = MASK_CP1(ctx->opcode);
7070
            switch (op1) {
7071
            case OPC_MFHC1:
7072
            case OPC_MTHC1:
7073
                check_insn(env, ctx, ISA_MIPS32R2);
7074
            case OPC_MFC1:
7075
            case OPC_CFC1:
7076
            case OPC_MTC1:
7077
            case OPC_CTC1:
7078
                gen_cp1(ctx, op1, rt, rd);
7079
                break;
7080
#if defined(TARGET_MIPS64)
7081
            case OPC_DMFC1:
7082
            case OPC_DMTC1:
7083
                check_insn(env, ctx, ISA_MIPS3);
7084
                gen_cp1(ctx, op1, rt, rd);
7085
                break;
7086
#endif
7087
            case OPC_BC1ANY2:
7088
            case OPC_BC1ANY4:
7089
                check_cop1x(ctx);
7090
                check_insn(env, ctx, ASE_MIPS3D);
7091
                /* fall through */
7092
            case OPC_BC1:
7093
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7094
                                    (rt >> 2) & 0x7, imm << 2);
7095
                return;
7096
            case OPC_S_FMT:
7097
            case OPC_D_FMT:
7098
            case OPC_W_FMT:
7099
            case OPC_L_FMT:
7100
            case OPC_PS_FMT:
7101
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7102
                           (imm >> 8) & 0x7);
7103
                break;
7104
            default:
7105
                MIPS_INVAL("cp1");
7106
                generate_exception (ctx, EXCP_RI);
7107
                break;
7108
            }
7109
        } else {
7110
            generate_exception_err(ctx, EXCP_CpU, 1);
7111
        }
7112
        break;
7113

    
7114
    /* COP2.  */
7115
    case OPC_LWC2:
7116
    case OPC_LDC2:
7117
    case OPC_SWC2:
7118
    case OPC_SDC2:
7119
    case OPC_CP2:
7120
        /* COP2: Not implemented. */
7121
        generate_exception_err(ctx, EXCP_CpU, 2);
7122
        break;
7123

    
7124
    case OPC_CP3:
7125
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7126
            save_cpu_state(ctx, 1);
7127
            check_cp1_enabled(ctx);
7128
            op1 = MASK_CP3(ctx->opcode);
7129
            switch (op1) {
7130
            case OPC_LWXC1:
7131
            case OPC_LDXC1:
7132
            case OPC_LUXC1:
7133
            case OPC_SWXC1:
7134
            case OPC_SDXC1:
7135
            case OPC_SUXC1:
7136
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7137
                break;
7138
            case OPC_PREFX:
7139
                /* Treat as NOP. */
7140
                break;
7141
            case OPC_ALNV_PS:
7142
            case OPC_MADD_S:
7143
            case OPC_MADD_D:
7144
            case OPC_MADD_PS:
7145
            case OPC_MSUB_S:
7146
            case OPC_MSUB_D:
7147
            case OPC_MSUB_PS:
7148
            case OPC_NMADD_S:
7149
            case OPC_NMADD_D:
7150
            case OPC_NMADD_PS:
7151
            case OPC_NMSUB_S:
7152
            case OPC_NMSUB_D:
7153
            case OPC_NMSUB_PS:
7154
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7155
                break;
7156
            default:
7157
                MIPS_INVAL("cp3");
7158
                generate_exception (ctx, EXCP_RI);
7159
                break;
7160
            }
7161
        } else {
7162
            generate_exception_err(ctx, EXCP_CpU, 1);
7163
        }
7164
        break;
7165

    
7166
#if defined(TARGET_MIPS64)
7167
    /* MIPS64 opcodes */
7168
    case OPC_LWU:
7169
    case OPC_LDL ... OPC_LDR:
7170
    case OPC_SDL ... OPC_SDR:
7171
    case OPC_LLD:
7172
    case OPC_LD:
7173
    case OPC_SCD:
7174
    case OPC_SD:
7175
        check_insn(env, ctx, ISA_MIPS3);
7176
        check_mips_64(ctx);
7177
        gen_ldst(ctx, op, rt, rs, imm);
7178
        break;
7179
    case OPC_DADDI ... OPC_DADDIU:
7180
        check_insn(env, ctx, ISA_MIPS3);
7181
        check_mips_64(ctx);
7182
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7183
        break;
7184
#endif
7185
    case OPC_JALX:
7186
        check_insn(env, ctx, ASE_MIPS16);
7187
        /* MIPS16: Not implemented. */
7188
    case OPC_MDMX:
7189
        check_insn(env, ctx, ASE_MDMX);
7190
        /* MDMX: Not implemented. */
7191
    default:            /* Invalid */
7192
        MIPS_INVAL("major opcode");
7193
        generate_exception(ctx, EXCP_RI);
7194
        break;
7195
    }
7196
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7197
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7198
        /* Branches completion */
7199
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7200
        ctx->bstate = BS_BRANCH;
7201
        save_cpu_state(ctx, 0);
7202
        switch (hflags) {
7203
        case MIPS_HFLAG_B:
7204
            /* unconditional branch */
7205
            MIPS_DEBUG("unconditional branch");
7206
            gen_goto_tb(ctx, 0, ctx->btarget);
7207
            break;
7208
        case MIPS_HFLAG_BL:
7209
            /* blikely taken case */
7210
            MIPS_DEBUG("blikely branch taken");
7211
            gen_goto_tb(ctx, 0, ctx->btarget);
7212
            break;
7213
        case MIPS_HFLAG_BC:
7214
            /* Conditional branch */
7215
            MIPS_DEBUG("conditional branch");
7216
            {
7217
                TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
7218
                int l1 = gen_new_label();
7219

    
7220
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7221
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7222
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7223
                gen_set_label(l1);
7224
                gen_goto_tb(ctx, 0, ctx->btarget);
7225
            }
7226
            break;
7227
        case MIPS_HFLAG_BR:
7228
            /* unconditional branch to register */
7229
            MIPS_DEBUG("branch to register");
7230
            gen_breg_pc();
7231
            tcg_gen_exit_tb(0);
7232
            break;
7233
        default:
7234
            MIPS_DEBUG("unknown branch");
7235
            break;
7236
        }
7237
    }
7238
}
7239

    
7240
static always_inline int
7241
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7242
                                int search_pc)
7243
{
7244
    DisasContext ctx;
7245
    target_ulong pc_start;
7246
    uint16_t *gen_opc_end;
7247
    int j, lj = -1;
7248

    
7249
    if (search_pc && loglevel)
7250
        fprintf (logfile, "search pc %d\n", search_pc);
7251

    
7252
    num_temps = 0;
7253
    memset(temps, 0, sizeof(temps));
7254

    
7255
    num_temps = 0;
7256
    memset(temps, 0, sizeof(temps));
7257

    
7258
    pc_start = tb->pc;
7259
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
7260
    ctx.pc = pc_start;
7261
    ctx.saved_pc = -1;
7262
    ctx.tb = tb;
7263
    ctx.bstate = BS_NONE;
7264
    /* Restore delay slot state from the tb context.  */
7265
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7266
    restore_cpu_state(env, &ctx);
7267
#if defined(CONFIG_USER_ONLY)
7268
    ctx.mem_idx = MIPS_HFLAG_UM;
7269
#else
7270
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7271
#endif
7272
#ifdef DEBUG_DISAS
7273
    if (loglevel & CPU_LOG_TB_CPU) {
7274
        fprintf(logfile, "------------------------------------------------\n");
7275
        /* FIXME: This may print out stale hflags from env... */
7276
        cpu_dump_state(env, logfile, fprintf, 0);
7277
    }
7278
#endif
7279
#ifdef MIPS_DEBUG_DISAS
7280
    if (loglevel & CPU_LOG_TB_IN_ASM)
7281
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7282
                tb, ctx.mem_idx, ctx.hflags);
7283
#endif
7284
    while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
7285
        if (env->nb_breakpoints > 0) {
7286
            for(j = 0; j < env->nb_breakpoints; j++) {
7287
                if (env->breakpoints[j] == ctx.pc) {
7288
                    save_cpu_state(&ctx, 1);
7289
                    ctx.bstate = BS_BRANCH;
7290
                    gen_op_debug();
7291
                    /* Include the breakpoint location or the tb won't
7292
                     * be flushed when it must be.  */
7293
                    ctx.pc += 4;
7294
                    goto done_generating;
7295
                }
7296
            }
7297
        }
7298

    
7299
        if (search_pc) {
7300
            j = gen_opc_ptr - gen_opc_buf;
7301
            if (lj < j) {
7302
                lj++;
7303
                while (lj < j)
7304
                    gen_opc_instr_start[lj++] = 0;
7305
            }
7306
            gen_opc_pc[lj] = ctx.pc;
7307
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7308
            gen_opc_instr_start[lj] = 1;
7309
        }
7310
        ctx.opcode = ldl_code(ctx.pc);
7311
        decode_opc(env, &ctx);
7312
        if (num_temps) {
7313
            fprintf(stderr,
7314
                    "Internal resource leak before " TARGET_FMT_lx "\n",
7315
                    ctx.pc);
7316
            num_temps = 0;
7317
        }
7318
        ctx.pc += 4;
7319

    
7320
        if (env->singlestep_enabled)
7321
            break;
7322

    
7323
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7324
            break;
7325

    
7326
#if defined (MIPS_SINGLE_STEP)
7327
        break;
7328
#endif
7329
    }
7330
    if (env->singlestep_enabled) {
7331
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7332
        gen_op_debug();
7333
    } else {
7334
        switch (ctx.bstate) {
7335
        case BS_STOP:
7336
            tcg_gen_helper_0_0(do_interrupt_restart);
7337
            gen_goto_tb(&ctx, 0, ctx.pc);
7338
            break;
7339
        case BS_NONE:
7340
            save_cpu_state(&ctx, 0);
7341
            gen_goto_tb(&ctx, 0, ctx.pc);
7342
            break;
7343
        case BS_EXCP:
7344
            tcg_gen_helper_0_0(do_interrupt_restart);
7345
            tcg_gen_exit_tb(0);
7346
            break;
7347
        case BS_BRANCH:
7348
        default:
7349
            break;
7350
        }
7351
    }
7352
done_generating:
7353
    *gen_opc_ptr = INDEX_op_end;
7354
    if (search_pc) {
7355
        j = gen_opc_ptr - gen_opc_buf;
7356
        lj++;
7357
        while (lj <= j)
7358
            gen_opc_instr_start[lj++] = 0;
7359
    } else {
7360
        tb->size = ctx.pc - pc_start;
7361
    }
7362
#ifdef DEBUG_DISAS
7363
#if defined MIPS_DEBUG_DISAS
7364
    if (loglevel & CPU_LOG_TB_IN_ASM)
7365
        fprintf(logfile, "\n");
7366
#endif
7367
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7368
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7369
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7370
        fprintf(logfile, "\n");
7371
    }
7372
    if (loglevel & CPU_LOG_TB_CPU) {
7373
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7374
    }
7375
#endif
7376

    
7377
    return 0;
7378
}
7379

    
7380
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7381
{
7382
    return gen_intermediate_code_internal(env, tb, 0);
7383
}
7384

    
7385
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7386
{
7387
    return gen_intermediate_code_internal(env, tb, 1);
7388
}
7389

    
7390
void fpu_dump_state(CPUState *env, FILE *f,
7391
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7392
                    int flags)
7393
{
7394
    int i;
7395
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7396

    
7397
#define printfpr(fp)                                                        \
7398
    do {                                                                    \
7399
        if (is_fpu64)                                                       \
7400
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7401
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7402
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7403
        else {                                                              \
7404
            fpr_t tmp;                                                      \
7405
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7406
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7407
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7408
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7409
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7410
        }                                                                   \
7411
    } while(0)
7412

    
7413

    
7414
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7415
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7416
                get_float_exception_flags(&env->fpu->fp_status));
7417
    fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
7418
    fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
7419
    fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
7420
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
7421
        fpu_fprintf(f, "%3s: ", fregnames[i]);
7422
        printfpr(&env->fpu->fpr[i]);
7423
    }
7424

    
7425
#undef printfpr
7426
}
7427

    
7428
void dump_fpu (CPUState *env)
7429
{
7430
    if (loglevel) {
7431
        fprintf(logfile,
7432
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
7433
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
7434
                " %04x\n",
7435
                env->PC[env->current_tc], env->HI[env->current_tc][0],
7436
                env->LO[env->current_tc][0], env->hflags, env->btarget,
7437
                env->bcond);
7438
       fpu_dump_state(env, logfile, fprintf, 0);
7439
    }
7440
}
7441

    
7442
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7443
/* Debug help: The architecture requires 32bit code to maintain proper
7444
   sign-extened values on 64bit machines.  */
7445

    
7446
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
7447

    
7448
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
7449
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7450
                     int flags)
7451
{
7452
    int i;
7453

    
7454
    if (!SIGN_EXT_P(env->PC[env->current_tc]))
7455
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
7456
    if (!SIGN_EXT_P(env->HI[env->current_tc][0]))
7457
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[env->current_tc][0]);
7458
    if (!SIGN_EXT_P(env->LO[env->current_tc][0]))
7459
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[env->current_tc][0]);
7460
    if (!SIGN_EXT_P(env->btarget))
7461
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
7462

    
7463
    for (i = 0; i < 32; i++) {
7464
        if (!SIGN_EXT_P(env->gpr[env->current_tc][i]))
7465
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[env->current_tc][i]);
7466
    }
7467

    
7468
    if (!SIGN_EXT_P(env->CP0_EPC))
7469
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
7470
    if (!SIGN_EXT_P(env->CP0_LLAddr))
7471
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
7472
}
7473
#endif
7474

    
7475
void cpu_dump_state (CPUState *env, FILE *f,
7476
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
7477
                     int flags)
7478
{
7479
    int i;
7480

    
7481
    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",
7482
                env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
7483
    for (i = 0; i < 32; i++) {
7484
        if ((i & 3) == 0)
7485
            cpu_fprintf(f, "GPR%02d:", i);
7486
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[env->current_tc][i]);
7487
        if ((i & 3) == 3)
7488
            cpu_fprintf(f, "\n");
7489
    }
7490

    
7491
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
7492
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
7493
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
7494
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
7495
    if (env->hflags & MIPS_HFLAG_FPU)
7496
        fpu_dump_state(env, f, cpu_fprintf, flags);
7497
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
7498
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
7499
#endif
7500
}
7501

    
7502
static void mips_tcg_init(void)
7503
{
7504
    static int inited;
7505

    
7506
    /* Initialize various static tables. */
7507
    if (inited)
7508
        return;
7509

    
7510
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
7511
    current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR,
7512
                                         TCG_AREG0,
7513
                                         offsetof(CPUState, current_tc_gprs),
7514
                                         "current_tc_gprs");
7515
#if TARGET_LONG_BITS > HOST_LONG_BITS
7516
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
7517
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
7518
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
7519
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
7520
#else
7521
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
7522
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
7523
#endif
7524

    
7525
    inited = 1;
7526
}
7527

    
7528
#include "translate_init.c"
7529

    
7530
CPUMIPSState *cpu_mips_init (const char *cpu_model)
7531
{
7532
    CPUMIPSState *env;
7533
    const mips_def_t *def;
7534

    
7535
    def = cpu_mips_find_by_name(cpu_model);
7536
    if (!def)
7537
        return NULL;
7538
    env = qemu_mallocz(sizeof(CPUMIPSState));
7539
    if (!env)
7540
        return NULL;
7541
    env->cpu_model = def;
7542

    
7543
    cpu_exec_init(env);
7544
    env->cpu_model_str = cpu_model;
7545
    mips_tcg_init();
7546
    cpu_reset(env);
7547
    return env;
7548
}
7549

    
7550
void cpu_reset (CPUMIPSState *env)
7551
{
7552
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
7553

    
7554
    tlb_flush(env, 1);
7555

    
7556
    /* Minimal init */
7557
#if !defined(CONFIG_USER_ONLY)
7558
    if (env->hflags & MIPS_HFLAG_BMASK) {
7559
        /* If the exception was raised from a delay slot,
7560
         * come back to the jump.  */
7561
        env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
7562
    } else {
7563
        env->CP0_ErrorEPC = env->PC[env->current_tc];
7564
    }
7565
    env->PC[env->current_tc] = (int32_t)0xBFC00000;
7566
    env->CP0_Wired = 0;
7567
    /* SMP not implemented */
7568
    env->CP0_EBase = 0x80000000;
7569
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
7570
    /* vectored interrupts not implemented, timer on int 7,
7571
       no performance counters. */
7572
    env->CP0_IntCtl = 0xe0000000;
7573
    {
7574
        int i;
7575

    
7576
        for (i = 0; i < 7; i++) {
7577
            env->CP0_WatchLo[i] = 0;
7578
            env->CP0_WatchHi[i] = 0x80000000;
7579
        }
7580
        env->CP0_WatchLo[7] = 0;
7581
        env->CP0_WatchHi[7] = 0;
7582
    }
7583
    /* Count register increments in debug mode, EJTAG version 1 */
7584
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
7585
#endif
7586
    env->exception_index = EXCP_NONE;
7587
#if defined(CONFIG_USER_ONLY)
7588
    env->hflags = MIPS_HFLAG_UM;
7589
    env->user_mode_only = 1;
7590
#else
7591
    env->hflags = MIPS_HFLAG_CP0;
7592
#endif
7593
    cpu_mips_register(env, env->cpu_model);
7594
}
7595

    
7596
void gen_pc_load(CPUState *env, TranslationBlock *tb,
7597
                unsigned long searched_pc, int pc_pos, void *puc)
7598
{
7599
    env->PC[env->current_tc] = gen_opc_pc[pc_pos];
7600
    env->hflags &= ~MIPS_HFLAG_BMASK;
7601
    env->hflags |= gen_opc_hflags[pc_pos];
7602
}