Statistics
| Branch: | Revision:

root / target-mips / translate.c @ c7e8a937

History | View | Annotate | Download (243.4 kB)

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

    
428
/* FPU TNs, global for now. */
429
static TCGv fpu32_T[3], fpu64_T[3], fpu32h_T[3];
430

    
431
#include "gen-icount.h"
432

    
433
static inline void tcg_gen_helper_0_i(void *func, TCGv arg)
434
{
435
    TCGv tmp = tcg_const_i32(arg);
436

    
437
    tcg_gen_helper_0_1(func, tmp);
438
    tcg_temp_free(tmp);
439
}
440

    
441
static inline void tcg_gen_helper_0_ii(void *func, TCGv arg1, TCGv arg2)
442
{
443
    TCGv tmp1 = tcg_const_i32(arg1);
444
    TCGv tmp2 = tcg_const_i32(arg2);
445

    
446
    tcg_gen_helper_0_2(func, tmp1, tmp2);
447
    tcg_temp_free(tmp1);
448
    tcg_temp_free(tmp2);
449
}
450

    
451
static inline void tcg_gen_helper_0_1i(void *func, TCGv arg1, TCGv arg2)
452
{
453
    TCGv tmp = tcg_const_i32(arg2);
454

    
455
    tcg_gen_helper_0_2(func, arg1, tmp);
456
    tcg_temp_free(tmp);
457
}
458

    
459
static inline void tcg_gen_helper_0_2i(void *func, TCGv arg1, TCGv arg2, TCGv arg3)
460
{
461
    TCGv tmp = tcg_const_i32(arg3);
462

    
463
    tcg_gen_helper_0_3(func, arg1, arg2, tmp);
464
    tcg_temp_free(tmp);
465
}
466

    
467
static inline void tcg_gen_helper_0_1ii(void *func, TCGv arg1, TCGv arg2, TCGv arg3)
468
{
469
    TCGv tmp1 = tcg_const_i32(arg2);
470
    TCGv tmp2 = tcg_const_i32(arg3);
471

    
472
    tcg_gen_helper_0_3(func, arg1, tmp1, tmp2);
473
    tcg_temp_free(tmp1);
474
    tcg_temp_free(tmp2);
475
}
476

    
477
static inline void tcg_gen_helper_1_i(void *func, TCGv ret, TCGv arg)
478
{
479
    TCGv tmp = tcg_const_i32(arg);
480

    
481
    tcg_gen_helper_1_1(func, ret, tmp);
482
    tcg_temp_free(tmp);
483
}
484

    
485
static inline void tcg_gen_helper_1_1i(void *func, TCGv ret, TCGv arg1, TCGv arg2)
486
{
487
    TCGv tmp = tcg_const_i32(arg2);
488

    
489
    tcg_gen_helper_1_2(func, ret, arg1, tmp);
490
    tcg_temp_free(tmp);
491
}
492

    
493
static inline void tcg_gen_helper_1_1ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
494
{
495
    TCGv tmp1 = tcg_const_i32(arg2);
496
    TCGv tmp2 = tcg_const_i32(arg3);
497

    
498
    tcg_gen_helper_1_3(func, ret, arg1, tmp1, tmp2);
499
    tcg_temp_free(tmp1);
500
    tcg_temp_free(tmp2);
501
}
502

    
503
static inline void tcg_gen_helper_1_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
504
{
505
    TCGv tmp = tcg_const_i32(arg3);
506

    
507
    tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp);
508
    tcg_temp_free(tmp);
509
}
510

    
511
static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4)
512
{
513
    TCGv tmp1 = tcg_const_i32(arg3);
514
    TCGv tmp2 = tcg_const_i32(arg4);
515

    
516
    tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2);
517
    tcg_temp_free(tmp1);
518
    tcg_temp_free(tmp2);
519
}
520

    
521
typedef struct DisasContext {
522
    struct TranslationBlock *tb;
523
    target_ulong pc, saved_pc;
524
    uint32_t opcode;
525
    uint32_t fp_status;
526
    /* Routine used to access memory */
527
    int mem_idx;
528
    uint32_t hflags, saved_hflags;
529
    int bstate;
530
    target_ulong btarget;
531
} DisasContext;
532

    
533
enum {
534
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
535
                      * exception condition */
536
    BS_STOP     = 1, /* We want to stop translation for any reason */
537
    BS_BRANCH   = 2, /* We reached a branch condition     */
538
    BS_EXCP     = 3, /* We reached an exception condition */
539
};
540

    
541
static const char *regnames[] =
542
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
543
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
544
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
545
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
546

    
547
static const char *fregnames[] =
548
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
549
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
550
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
551
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
552

    
553
#ifdef MIPS_DEBUG_DISAS
554
#define MIPS_DEBUG(fmt, args...)                                              \
555
do {                                                                          \
556
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
557
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
558
                ctx->pc, ctx->opcode , ##args);                               \
559
    }                                                                         \
560
} while (0)
561
#else
562
#define MIPS_DEBUG(fmt, args...) do { } while(0)
563
#endif
564

    
565
#define MIPS_INVAL(op)                                                        \
566
do {                                                                          \
567
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
568
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
569
} while (0)
570

    
571
/* General purpose registers moves. */
572
static inline void gen_load_gpr (TCGv t, int reg)
573
{
574
    if (reg == 0)
575
        tcg_gen_movi_tl(t, 0);
576
    else
577
        tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
578
                                  sizeof(target_ulong) * reg);
579
}
580

    
581
static inline void gen_store_gpr (TCGv t, int reg)
582
{
583
    if (reg != 0)
584
        tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
585
                                  sizeof(target_ulong) * reg);
586
}
587

    
588
/* Moves to/from HI and LO registers.  */
589
static inline void gen_load_LO (TCGv t, int reg)
590
{
591
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
592
                              sizeof(target_ulong) * reg);
593
}
594

    
595
static inline void gen_store_LO (TCGv t, int reg)
596
{
597
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
598
                              sizeof(target_ulong) * reg);
599
}
600

    
601
static inline void gen_load_HI (TCGv t, int reg)
602
{
603
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
604
                              sizeof(target_ulong) * reg);
605
}
606

    
607
static inline void gen_store_HI (TCGv t, int reg)
608
{
609
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
610
                              sizeof(target_ulong) * reg);
611
}
612

    
613
/* Moves to/from shadow registers. */
614
static inline void gen_load_srsgpr (int from, int to)
615
{
616
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
617

    
618
    if (from == 0)
619
        tcg_gen_movi_tl(r_tmp1, 0);
620
    else {
621
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
622

    
623
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
624
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
625
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
626
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
627
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
628

    
629
        tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from);
630
        tcg_temp_free(r_tmp2);
631
    }
632
    gen_store_gpr(r_tmp1, to);
633
    tcg_temp_free(r_tmp1);
634
}
635

    
636
static inline void gen_store_srsgpr (int from, int to)
637
{
638
    if (to != 0) {
639
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
640
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
641

    
642
        gen_load_gpr(r_tmp1, from);
643
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
644
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
645
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
646
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
647
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
648

    
649
        tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to);
650
        tcg_temp_free(r_tmp1);
651
        tcg_temp_free(r_tmp2);
652
    }
653
}
654

    
655
/* Floating point register moves. */
656
static inline void gen_load_fpr32 (TCGv t, int reg)
657
{
658
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
659
}
660

    
661
static inline void gen_store_fpr32 (TCGv t, int reg)
662
{
663
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
664
}
665

    
666
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
667
{
668
    if (ctx->hflags & MIPS_HFLAG_F64) {
669
        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
670
    } else {
671
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
672
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
673

    
674
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
675
        tcg_gen_extu_i32_i64(t, r_tmp1);
676
        tcg_gen_shli_i64(t, t, 32);
677
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
678
        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
679
        tcg_gen_or_i64(t, t, r_tmp2);
680
        tcg_temp_free(r_tmp1);
681
        tcg_temp_free(r_tmp2);
682
    }
683
}
684

    
685
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
686
{
687
    if (ctx->hflags & MIPS_HFLAG_F64) {
688
        tcg_gen_st_i64(t, current_fpu, 8 * reg);
689
    } else {
690
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
691

    
692
        tcg_gen_trunc_i64_i32(r_tmp, t);
693
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
694
        tcg_gen_shri_i64(t, t, 32);
695
        tcg_gen_trunc_i64_i32(r_tmp, t);
696
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
697
        tcg_temp_free(r_tmp);
698
    }
699
}
700

    
701
static inline void gen_load_fpr32h (TCGv t, int reg)
702
{
703
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
704
}
705

    
706
static inline void gen_store_fpr32h (TCGv t, int reg)
707
{
708
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
709
}
710

    
711
static inline void get_fp_cond (TCGv t)
712
{
713
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
714
    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
715

    
716
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
717
    tcg_gen_shri_i32(r_tmp2, r_tmp1, 24);
718
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
719
    tcg_gen_shri_i32(r_tmp1, r_tmp1, 23);
720
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
721
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
722
    tcg_temp_free(r_tmp1);
723
    tcg_temp_free(r_tmp2);
724
}
725

    
726
#define FOP_CONDS(type, fmt)                                              \
727
static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = {            \
728
    do_cmp ## type ## _ ## fmt ## _f,                                     \
729
    do_cmp ## type ## _ ## fmt ## _un,                                    \
730
    do_cmp ## type ## _ ## fmt ## _eq,                                    \
731
    do_cmp ## type ## _ ## fmt ## _ueq,                                   \
732
    do_cmp ## type ## _ ## fmt ## _olt,                                   \
733
    do_cmp ## type ## _ ## fmt ## _ult,                                   \
734
    do_cmp ## type ## _ ## fmt ## _ole,                                   \
735
    do_cmp ## type ## _ ## fmt ## _ule,                                   \
736
    do_cmp ## type ## _ ## fmt ## _sf,                                    \
737
    do_cmp ## type ## _ ## fmt ## _ngle,                                  \
738
    do_cmp ## type ## _ ## fmt ## _seq,                                   \
739
    do_cmp ## type ## _ ## fmt ## _ngl,                                   \
740
    do_cmp ## type ## _ ## fmt ## _lt,                                    \
741
    do_cmp ## type ## _ ## fmt ## _nge,                                   \
742
    do_cmp ## type ## _ ## fmt ## _le,                                    \
743
    do_cmp ## type ## _ ## fmt ## _ngt,                                   \
744
};                                                                        \
745
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)            \
746
{                                                                         \
747
    tcg_gen_helper_0_i(fcmp ## type ## _ ## fmt ## _table[n], cc);        \
748
}
749

    
750
FOP_CONDS(, d)
751
FOP_CONDS(abs, d)
752
FOP_CONDS(, s)
753
FOP_CONDS(abs, s)
754
FOP_CONDS(, ps)
755
FOP_CONDS(abs, ps)
756
#undef FOP_CONDS
757

    
758
/* Tests */
759
#define OP_COND(name, cond)                                   \
760
static inline void glue(gen_op_, name) (TCGv t0, TCGv t1)     \
761
{                                                             \
762
    int l1 = gen_new_label();                                 \
763
    int l2 = gen_new_label();                                 \
764
                                                              \
765
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
766
    tcg_gen_movi_tl(t0, 0);                                   \
767
    tcg_gen_br(l2);                                           \
768
    gen_set_label(l1);                                        \
769
    tcg_gen_movi_tl(t0, 1);                                   \
770
    gen_set_label(l2);                                        \
771
}
772
OP_COND(eq, TCG_COND_EQ);
773
OP_COND(ne, TCG_COND_NE);
774
OP_COND(ge, TCG_COND_GE);
775
OP_COND(geu, TCG_COND_GEU);
776
OP_COND(lt, TCG_COND_LT);
777
OP_COND(ltu, TCG_COND_LTU);
778
#undef OP_COND
779

    
780
#define OP_CONDI(name, cond)                                  \
781
static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
782
{                                                             \
783
    int l1 = gen_new_label();                                 \
784
    int l2 = gen_new_label();                                 \
785
                                                              \
786
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
787
    tcg_gen_movi_tl(t, 0);                                    \
788
    tcg_gen_br(l2);                                           \
789
    gen_set_label(l1);                                        \
790
    tcg_gen_movi_tl(t, 1);                                    \
791
    gen_set_label(l2);                                        \
792
}
793
OP_CONDI(lti, TCG_COND_LT);
794
OP_CONDI(ltiu, TCG_COND_LTU);
795
#undef OP_CONDI
796

    
797
#define OP_CONDZ(name, cond)                                  \
798
static inline void glue(gen_op_, name) (TCGv t)               \
799
{                                                             \
800
    int l1 = gen_new_label();                                 \
801
    int l2 = gen_new_label();                                 \
802
                                                              \
803
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
804
    tcg_gen_movi_tl(t, 0);                                    \
805
    tcg_gen_br(l2);                                           \
806
    gen_set_label(l1);                                        \
807
    tcg_gen_movi_tl(t, 1);                                    \
808
    gen_set_label(l2);                                        \
809
}
810
OP_CONDZ(gez, TCG_COND_GE);
811
OP_CONDZ(gtz, TCG_COND_GT);
812
OP_CONDZ(lez, TCG_COND_LE);
813
OP_CONDZ(ltz, TCG_COND_LT);
814
#undef OP_CONDZ
815

    
816
static inline void gen_save_pc(target_ulong pc)
817
{
818
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
819

    
820
    tcg_gen_movi_tl(r_tmp, pc);
821
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC));
822
    tcg_temp_free(r_tmp);
823
}
824

    
825
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
826
{
827
#if defined MIPS_DEBUG_DISAS
828
    if (loglevel & CPU_LOG_TB_IN_ASM) {
829
            fprintf(logfile, "hflags %08x saved %08x\n",
830
                    ctx->hflags, ctx->saved_hflags);
831
    }
832
#endif
833
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
834
        gen_save_pc(ctx->pc);
835
        ctx->saved_pc = ctx->pc;
836
    }
837
    if (ctx->hflags != ctx->saved_hflags) {
838
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
839

    
840
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
841
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
842
        tcg_temp_free(r_tmp);
843
        ctx->saved_hflags = ctx->hflags;
844
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
845
        case MIPS_HFLAG_BR:
846
            break;
847
        case MIPS_HFLAG_BC:
848
        case MIPS_HFLAG_BL:
849
        case MIPS_HFLAG_B:
850
            tcg_gen_movi_tl(btarget, ctx->btarget);
851
            break;
852
        }
853
    }
854
}
855

    
856
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
857
{
858
    ctx->saved_hflags = ctx->hflags;
859
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
860
    case MIPS_HFLAG_BR:
861
        break;
862
    case MIPS_HFLAG_BC:
863
    case MIPS_HFLAG_BL:
864
    case MIPS_HFLAG_B:
865
        ctx->btarget = env->btarget;
866
        break;
867
    }
868
}
869

    
870
static inline void
871
generate_exception_err (DisasContext *ctx, int excp, int err)
872
{
873
    save_cpu_state(ctx, 1);
874
    tcg_gen_helper_0_ii(do_raise_exception_err, excp, err);
875
    tcg_gen_helper_0_0(do_interrupt_restart);
876
    tcg_gen_exit_tb(0);
877
}
878

    
879
static inline void
880
generate_exception (DisasContext *ctx, int excp)
881
{
882
    save_cpu_state(ctx, 1);
883
    tcg_gen_helper_0_i(do_raise_exception, excp);
884
    tcg_gen_helper_0_0(do_interrupt_restart);
885
    tcg_gen_exit_tb(0);
886
}
887

    
888
/* Addresses computation */
889
static inline void gen_op_addr_add (TCGv t0, TCGv t1)
890
{
891
    tcg_gen_add_tl(t0, t0, t1);
892

    
893
#if defined(TARGET_MIPS64)
894
    /* For compatibility with 32-bit code, data reference in user mode
895
       with Status_UX = 0 should be casted to 32-bit and sign extended.
896
       See the MIPS64 PRA manual, section 4.10. */
897
    {
898
        int l1 = gen_new_label();
899
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
900

    
901
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
902
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
903
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
904
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
905
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
906
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
907
        tcg_temp_free(r_tmp);
908
        tcg_gen_ext32s_i64(t0, t0);
909
        gen_set_label(l1);
910
    }
911
#endif
912
}
913

    
914
static inline void check_cp0_enabled(DisasContext *ctx)
915
{
916
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
917
        generate_exception_err(ctx, EXCP_CpU, 1);
918
}
919

    
920
static inline void check_cp1_enabled(DisasContext *ctx)
921
{
922
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
923
        generate_exception_err(ctx, EXCP_CpU, 1);
924
}
925

    
926
/* Verify that the processor is running with COP1X instructions enabled.
927
   This is associated with the nabla symbol in the MIPS32 and MIPS64
928
   opcode tables.  */
929

    
930
static inline void check_cop1x(DisasContext *ctx)
931
{
932
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
933
        generate_exception(ctx, EXCP_RI);
934
}
935

    
936
/* Verify that the processor is running with 64-bit floating-point
937
   operations enabled.  */
938

    
939
static inline void check_cp1_64bitmode(DisasContext *ctx)
940
{
941
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
942
        generate_exception(ctx, EXCP_RI);
943
}
944

    
945
/*
946
 * Verify if floating point register is valid; an operation is not defined
947
 * if bit 0 of any register specification is set and the FR bit in the
948
 * Status register equals zero, since the register numbers specify an
949
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
950
 * in the Status register equals one, both even and odd register numbers
951
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
952
 *
953
 * Multiple 64 bit wide registers can be checked by calling
954
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
955
 */
956
static inline void check_cp1_registers(DisasContext *ctx, int regs)
957
{
958
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
959
        generate_exception(ctx, EXCP_RI);
960
}
961

    
962
/* This code generates a "reserved instruction" exception if the
963
   CPU does not support the instruction set corresponding to flags. */
964
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
965
{
966
    if (unlikely(!(env->insn_flags & flags)))
967
        generate_exception(ctx, EXCP_RI);
968
}
969

    
970
/* This code generates a "reserved instruction" exception if 64-bit
971
   instructions are not enabled. */
972
static inline void check_mips_64(DisasContext *ctx)
973
{
974
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
975
        generate_exception(ctx, EXCP_RI);
976
}
977

    
978
/* load/store instructions. */
979
#define OP_LD(insn,fname)                                        \
980
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
981
{                                                                \
982
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
983
}
984
OP_LD(lb,ld8s);
985
OP_LD(lbu,ld8u);
986
OP_LD(lh,ld16s);
987
OP_LD(lhu,ld16u);
988
OP_LD(lw,ld32s);
989
#if defined(TARGET_MIPS64)
990
OP_LD(lwu,ld32u);
991
OP_LD(ld,ld64);
992
#endif
993
#undef OP_LD
994

    
995
#define OP_ST(insn,fname)                                        \
996
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
997
{                                                                \
998
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
999
}
1000
OP_ST(sb,st8);
1001
OP_ST(sh,st16);
1002
OP_ST(sw,st32);
1003
#if defined(TARGET_MIPS64)
1004
OP_ST(sd,st64);
1005
#endif
1006
#undef OP_ST
1007

    
1008
#define OP_LD_ATOMIC(insn,fname)                                        \
1009
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1010
{                                                                       \
1011
    tcg_gen_mov_tl(t1, t0);                                             \
1012
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
1013
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
1014
}
1015
OP_LD_ATOMIC(ll,ld32s);
1016
#if defined(TARGET_MIPS64)
1017
OP_LD_ATOMIC(lld,ld64);
1018
#endif
1019
#undef OP_LD_ATOMIC
1020

    
1021
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1022
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1023
{                                                                       \
1024
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1025
    int l1 = gen_new_label();                                           \
1026
    int l2 = gen_new_label();                                           \
1027
    int l3 = gen_new_label();                                           \
1028
                                                                        \
1029
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
1030
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1031
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
1032
    generate_exception(ctx, EXCP_AdES);                                 \
1033
    gen_set_label(l1);                                                  \
1034
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1035
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
1036
    tcg_temp_free(r_tmp);                                               \
1037
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
1038
    tcg_gen_movi_tl(t0, 1);                                             \
1039
    tcg_gen_br(l3);                                                     \
1040
    gen_set_label(l2);                                                  \
1041
    tcg_gen_movi_tl(t0, 0);                                             \
1042
    gen_set_label(l3);                                                  \
1043
}
1044
OP_ST_ATOMIC(sc,st32,0x3);
1045
#if defined(TARGET_MIPS64)
1046
OP_ST_ATOMIC(scd,st64,0x7);
1047
#endif
1048
#undef OP_ST_ATOMIC
1049

    
1050
/* Load and store */
1051
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1052
                      int base, int16_t offset)
1053
{
1054
    const char *opn = "ldst";
1055
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1056
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1057

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

    
1214
/* Load and store */
1215
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1216
                          int base, int16_t offset)
1217
{
1218
    const char *opn = "flt_ldst";
1219
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1220

    
1221
    if (base == 0) {
1222
        tcg_gen_movi_tl(t0, offset);
1223
    } else if (offset == 0) {
1224
        gen_load_gpr(t0, base);
1225
    } else {
1226
        TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1227

    
1228
        gen_load_gpr(t0, base);
1229
        tcg_gen_movi_tl(t1, offset);
1230
        gen_op_addr_add(t0, t1);
1231
        tcg_temp_free(t1);
1232
    }
1233
    /* Don't do NOP if destination is zero: we must perform the actual
1234
       memory access. */
1235
    switch (opc) {
1236
    case OPC_LWC1:
1237
        tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx);
1238
        gen_store_fpr32(fpu32_T[0], ft);
1239
        opn = "lwc1";
1240
        break;
1241
    case OPC_SWC1:
1242
        gen_load_fpr32(fpu32_T[0], ft);
1243
        tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx);
1244
        opn = "swc1";
1245
        break;
1246
    case OPC_LDC1:
1247
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
1248
        gen_store_fpr64(ctx, fpu64_T[0], ft);
1249
        opn = "ldc1";
1250
        break;
1251
    case OPC_SDC1:
1252
        gen_load_fpr64(ctx, fpu64_T[0], ft);
1253
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
1254
        opn = "sdc1";
1255
        break;
1256
    default:
1257
        MIPS_INVAL(opn);
1258
        generate_exception(ctx, EXCP_RI);
1259
        goto out;
1260
    }
1261
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1262
 out:
1263
    tcg_temp_free(t0);
1264
}
1265

    
1266
/* Arithmetic with immediate operand */
1267
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1268
                           int rt, int rs, int16_t imm)
1269
{
1270
    target_ulong uimm;
1271
    const char *opn = "imm arith";
1272
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1273

    
1274
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1275
        /* If no destination, treat it as a NOP.
1276
           For addi, we must generate the overflow exception when needed. */
1277
        MIPS_DEBUG("NOP");
1278
        goto out;
1279
    }
1280
    uimm = (uint16_t)imm;
1281
    switch (opc) {
1282
    case OPC_ADDI:
1283
    case OPC_ADDIU:
1284
#if defined(TARGET_MIPS64)
1285
    case OPC_DADDI:
1286
    case OPC_DADDIU:
1287
#endif
1288
    case OPC_SLTI:
1289
    case OPC_SLTIU:
1290
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1291
        /* Fall through. */
1292
    case OPC_ANDI:
1293
    case OPC_ORI:
1294
    case OPC_XORI:
1295
        gen_load_gpr(t0, rs);
1296
        break;
1297
    case OPC_LUI:
1298
        tcg_gen_movi_tl(t0, imm << 16);
1299
        break;
1300
    case OPC_SLL:
1301
    case OPC_SRA:
1302
    case OPC_SRL:
1303
#if defined(TARGET_MIPS64)
1304
    case OPC_DSLL:
1305
    case OPC_DSRA:
1306
    case OPC_DSRL:
1307
    case OPC_DSLL32:
1308
    case OPC_DSRA32:
1309
    case OPC_DSRL32:
1310
#endif
1311
        uimm &= 0x1f;
1312
        gen_load_gpr(t0, rs);
1313
        break;
1314
    }
1315
    switch (opc) {
1316
    case OPC_ADDI:
1317
        {
1318
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1319
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1320
            int l1 = gen_new_label();
1321

    
1322
            save_cpu_state(ctx, 1);
1323
            tcg_gen_ext32s_tl(r_tmp1, t0);
1324
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1325

    
1326
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1327
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1328
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1329
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1330
            tcg_temp_free(r_tmp2);
1331
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1332
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1333
            tcg_temp_free(r_tmp1);
1334
            /* operands of same sign, result different sign */
1335
            generate_exception(ctx, EXCP_OVERFLOW);
1336
            gen_set_label(l1);
1337

    
1338
            tcg_gen_ext32s_tl(t0, t0);
1339
        }
1340
        opn = "addi";
1341
        break;
1342
    case OPC_ADDIU:
1343
        tcg_gen_ext32s_tl(t0, t0);
1344
        tcg_gen_addi_tl(t0, t0, uimm);
1345
        tcg_gen_ext32s_tl(t0, t0);
1346
        opn = "addiu";
1347
        break;
1348
#if defined(TARGET_MIPS64)
1349
    case OPC_DADDI:
1350
        {
1351
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1352
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1353
            int l1 = gen_new_label();
1354

    
1355
            save_cpu_state(ctx, 1);
1356
            tcg_gen_mov_tl(r_tmp1, t0);
1357
            tcg_gen_addi_tl(t0, t0, uimm);
1358

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

    
1428
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1429
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1430
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1431
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1432
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1433
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1434
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1435
                    tcg_temp_free(r_tmp1);
1436
                    tcg_temp_free(r_tmp2);
1437
                }
1438
                opn = "rotr";
1439
            } else {
1440
                tcg_gen_ext32u_tl(t0, t0);
1441
                tcg_gen_shri_tl(t0, t0, uimm);
1442
                tcg_gen_ext32s_tl(t0, t0);
1443
                opn = "srl";
1444
            }
1445
            break;
1446
        default:
1447
            MIPS_INVAL("invalid srl flag");
1448
            generate_exception(ctx, EXCP_RI);
1449
            break;
1450
        }
1451
        break;
1452
#if defined(TARGET_MIPS64)
1453
    case OPC_DSLL:
1454
        tcg_gen_shli_tl(t0, t0, uimm);
1455
        opn = "dsll";
1456
        break;
1457
    case OPC_DSRA:
1458
        tcg_gen_sari_tl(t0, t0, uimm);
1459
        opn = "dsra";
1460
        break;
1461
    case OPC_DSRL:
1462
        switch ((ctx->opcode >> 21) & 0x1f) {
1463
        case 0:
1464
            tcg_gen_shri_tl(t0, t0, uimm);
1465
            opn = "dsrl";
1466
            break;
1467
        case 1:
1468
            /* drotr is decoded as dsrl on non-R2 CPUs */
1469
            if (env->insn_flags & ISA_MIPS32R2) {
1470
                if (uimm != 0) {
1471
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1472

    
1473
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1474
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1475
                    tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1476
                    tcg_gen_shri_tl(t0, t0, uimm);
1477
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1478
                    tcg_temp_free(r_tmp1);
1479
                }
1480
                opn = "drotr";
1481
            } else {
1482
                tcg_gen_shri_tl(t0, t0, uimm);
1483
                opn = "dsrl";
1484
            }
1485
            break;
1486
        default:
1487
            MIPS_INVAL("invalid dsrl flag");
1488
            generate_exception(ctx, EXCP_RI);
1489
            break;
1490
        }
1491
        break;
1492
    case OPC_DSLL32:
1493
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1494
        opn = "dsll32";
1495
        break;
1496
    case OPC_DSRA32:
1497
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1498
        opn = "dsra32";
1499
        break;
1500
    case OPC_DSRL32:
1501
        switch ((ctx->opcode >> 21) & 0x1f) {
1502
        case 0:
1503
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1504
            opn = "dsrl32";
1505
            break;
1506
        case 1:
1507
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1508
            if (env->insn_flags & ISA_MIPS32R2) {
1509
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1510
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1511

    
1512
                tcg_gen_movi_tl(r_tmp1, 0x40);
1513
                tcg_gen_movi_tl(r_tmp2, 32);
1514
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1515
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1516
                tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1517
                tcg_gen_shr_tl(t0, t0, r_tmp2);
1518
                tcg_gen_or_tl(t0, t0, r_tmp1);
1519
                tcg_temp_free(r_tmp1);
1520
                tcg_temp_free(r_tmp2);
1521
                opn = "drotr32";
1522
            } else {
1523
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1524
                opn = "dsrl32";
1525
            }
1526
            break;
1527
        default:
1528
            MIPS_INVAL("invalid dsrl32 flag");
1529
            generate_exception(ctx, EXCP_RI);
1530
            break;
1531
        }
1532
        break;
1533
#endif
1534
    default:
1535
        MIPS_INVAL(opn);
1536
        generate_exception(ctx, EXCP_RI);
1537
        goto out;
1538
    }
1539
    gen_store_gpr(t0, rt);
1540
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1541
 out:
1542
    tcg_temp_free(t0);
1543
}
1544

    
1545
/* Arithmetic */
1546
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1547
                       int rd, int rs, int rt)
1548
{
1549
    const char *opn = "arith";
1550
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1551
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1552

    
1553
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1554
       && opc != OPC_DADD && opc != OPC_DSUB) {
1555
        /* If no destination, treat it as a NOP.
1556
           For add & sub, we must generate the overflow exception when needed. */
1557
        MIPS_DEBUG("NOP");
1558
        goto out;
1559
    }
1560
    gen_load_gpr(t0, rs);
1561
    /* Specialcase the conventional move operation. */
1562
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1563
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1564
        gen_store_gpr(t0, rd);
1565
        goto out;
1566
    }
1567
    gen_load_gpr(t1, rt);
1568
    switch (opc) {
1569
    case OPC_ADD:
1570
        {
1571
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1572
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1573
            int l1 = gen_new_label();
1574

    
1575
            save_cpu_state(ctx, 1);
1576
            tcg_gen_ext32s_tl(r_tmp1, t0);
1577
            tcg_gen_ext32s_tl(r_tmp2, t1);
1578
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1579

    
1580
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1581
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1582
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1583
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1584
            tcg_temp_free(r_tmp2);
1585
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1586
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1587
            tcg_temp_free(r_tmp1);
1588
            /* operands of same sign, result different sign */
1589
            generate_exception(ctx, EXCP_OVERFLOW);
1590
            gen_set_label(l1);
1591

    
1592
            tcg_gen_ext32s_tl(t0, t0);
1593
        }
1594
        opn = "add";
1595
        break;
1596
    case OPC_ADDU:
1597
        tcg_gen_ext32s_tl(t0, t0);
1598
        tcg_gen_ext32s_tl(t1, t1);
1599
        tcg_gen_add_tl(t0, t0, t1);
1600
        tcg_gen_ext32s_tl(t0, t0);
1601
        opn = "addu";
1602
        break;
1603
    case OPC_SUB:
1604
        {
1605
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1606
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1607
            int l1 = gen_new_label();
1608

    
1609
            save_cpu_state(ctx, 1);
1610
            tcg_gen_ext32s_tl(r_tmp1, t0);
1611
            tcg_gen_ext32s_tl(r_tmp2, t1);
1612
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1613

    
1614
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1615
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1616
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1617
            tcg_temp_free(r_tmp2);
1618
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1619
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1620
            tcg_temp_free(r_tmp1);
1621
            /* operands of different sign, first operand and result different sign */
1622
            generate_exception(ctx, EXCP_OVERFLOW);
1623
            gen_set_label(l1);
1624

    
1625
            tcg_gen_ext32s_tl(t0, t0);
1626
        }
1627
        opn = "sub";
1628
        break;
1629
    case OPC_SUBU:
1630
        tcg_gen_ext32s_tl(t0, t0);
1631
        tcg_gen_ext32s_tl(t1, t1);
1632
        tcg_gen_sub_tl(t0, t0, t1);
1633
        tcg_gen_ext32s_tl(t0, t0);
1634
        opn = "subu";
1635
        break;
1636
#if defined(TARGET_MIPS64)
1637
    case OPC_DADD:
1638
        {
1639
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1640
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1641
            int l1 = gen_new_label();
1642

    
1643
            save_cpu_state(ctx, 1);
1644
            tcg_gen_mov_tl(r_tmp1, t0);
1645
            tcg_gen_add_tl(t0, t0, t1);
1646

    
1647
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1648
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1649
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1650
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1651
            tcg_temp_free(r_tmp2);
1652
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1653
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1654
            tcg_temp_free(r_tmp1);
1655
            /* operands of same sign, result different sign */
1656
            generate_exception(ctx, EXCP_OVERFLOW);
1657
            gen_set_label(l1);
1658
        }
1659
        opn = "dadd";
1660
        break;
1661
    case OPC_DADDU:
1662
        tcg_gen_add_tl(t0, t0, t1);
1663
        opn = "daddu";
1664
        break;
1665
    case OPC_DSUB:
1666
        {
1667
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1668
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1669
            int l1 = gen_new_label();
1670

    
1671
            save_cpu_state(ctx, 1);
1672
            tcg_gen_mov_tl(r_tmp1, t0);
1673
            tcg_gen_sub_tl(t0, t0, t1);
1674

    
1675
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1676
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1677
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1678
            tcg_temp_free(r_tmp2);
1679
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1680
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1681
            tcg_temp_free(r_tmp1);
1682
            /* operands of different sign, first operand and result different sign */
1683
            generate_exception(ctx, EXCP_OVERFLOW);
1684
            gen_set_label(l1);
1685
        }
1686
        opn = "dsub";
1687
        break;
1688
    case OPC_DSUBU:
1689
        tcg_gen_sub_tl(t0, t0, t1);
1690
        opn = "dsubu";
1691
        break;
1692
#endif
1693
    case OPC_SLT:
1694
        gen_op_lt(t0, t1);
1695
        opn = "slt";
1696
        break;
1697
    case OPC_SLTU:
1698
        gen_op_ltu(t0, t1);
1699
        opn = "sltu";
1700
        break;
1701
    case OPC_AND:
1702
        tcg_gen_and_tl(t0, t0, t1);
1703
        opn = "and";
1704
        break;
1705
    case OPC_NOR:
1706
        tcg_gen_or_tl(t0, t0, t1);
1707
        tcg_gen_not_tl(t0, t0);
1708
        opn = "nor";
1709
        break;
1710
    case OPC_OR:
1711
        tcg_gen_or_tl(t0, t0, t1);
1712
        opn = "or";
1713
        break;
1714
    case OPC_XOR:
1715
        tcg_gen_xor_tl(t0, t0, t1);
1716
        opn = "xor";
1717
        break;
1718
    case OPC_MUL:
1719
        tcg_gen_ext32s_tl(t0, t0);
1720
        tcg_gen_ext32s_tl(t1, t1);
1721
        tcg_gen_mul_tl(t0, t0, t1);
1722
        tcg_gen_ext32s_tl(t0, t0);
1723
        opn = "mul";
1724
        break;
1725
    case OPC_MOVN:
1726
        {
1727
            int l1 = gen_new_label();
1728

    
1729
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1730
            gen_store_gpr(t0, rd);
1731
            gen_set_label(l1);
1732
        }
1733
        opn = "movn";
1734
        goto print;
1735
    case OPC_MOVZ:
1736
        {
1737
            int l1 = gen_new_label();
1738

    
1739
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1740
            gen_store_gpr(t0, rd);
1741
            gen_set_label(l1);
1742
        }
1743
        opn = "movz";
1744
        goto print;
1745
    case OPC_SLLV:
1746
        tcg_gen_ext32u_tl(t0, t0);
1747
        tcg_gen_ext32u_tl(t1, t1);
1748
        tcg_gen_andi_tl(t0, t0, 0x1f);
1749
        tcg_gen_shl_tl(t0, t1, t0);
1750
        tcg_gen_ext32s_tl(t0, t0);
1751
        opn = "sllv";
1752
        break;
1753
    case OPC_SRAV:
1754
        tcg_gen_ext32s_tl(t1, t1);
1755
        tcg_gen_andi_tl(t0, t0, 0x1f);
1756
        tcg_gen_sar_tl(t0, t1, t0);
1757
        tcg_gen_ext32s_tl(t0, t0);
1758
        opn = "srav";
1759
        break;
1760
    case OPC_SRLV:
1761
        switch ((ctx->opcode >> 6) & 0x1f) {
1762
        case 0:
1763
            tcg_gen_ext32u_tl(t1, t1);
1764
            tcg_gen_andi_tl(t0, t0, 0x1f);
1765
            tcg_gen_shr_tl(t0, t1, t0);
1766
            tcg_gen_ext32s_tl(t0, t0);
1767
            opn = "srlv";
1768
            break;
1769
        case 1:
1770
            /* rotrv is decoded as srlv on non-R2 CPUs */
1771
            if (env->insn_flags & ISA_MIPS32R2) {
1772
                int l1 = gen_new_label();
1773
                int l2 = gen_new_label();
1774

    
1775
                tcg_gen_andi_tl(t0, t0, 0x1f);
1776
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1777
                {
1778
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1779
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1780
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1781

    
1782
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1783
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1784
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1785
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1786
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1787
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1788
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1789
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1790
                    tcg_temp_free(r_tmp1);
1791
                    tcg_temp_free(r_tmp2);
1792
                    tcg_temp_free(r_tmp3);
1793
                    tcg_gen_br(l2);
1794
                }
1795
                gen_set_label(l1);
1796
                tcg_gen_mov_tl(t0, t1);
1797
                gen_set_label(l2);
1798
                opn = "rotrv";
1799
            } else {
1800
                tcg_gen_ext32u_tl(t1, t1);
1801
                tcg_gen_andi_tl(t0, t0, 0x1f);
1802
                tcg_gen_shr_tl(t0, t1, t0);
1803
                tcg_gen_ext32s_tl(t0, t0);
1804
                opn = "srlv";
1805
            }
1806
            break;
1807
        default:
1808
            MIPS_INVAL("invalid srlv flag");
1809
            generate_exception(ctx, EXCP_RI);
1810
            break;
1811
        }
1812
        break;
1813
#if defined(TARGET_MIPS64)
1814
    case OPC_DSLLV:
1815
        tcg_gen_andi_tl(t0, t0, 0x3f);
1816
        tcg_gen_shl_tl(t0, t1, t0);
1817
        opn = "dsllv";
1818
        break;
1819
    case OPC_DSRAV:
1820
        tcg_gen_andi_tl(t0, t0, 0x3f);
1821
        tcg_gen_sar_tl(t0, t1, t0);
1822
        opn = "dsrav";
1823
        break;
1824
    case OPC_DSRLV:
1825
        switch ((ctx->opcode >> 6) & 0x1f) {
1826
        case 0:
1827
            tcg_gen_andi_tl(t0, t0, 0x3f);
1828
            tcg_gen_shr_tl(t0, t1, t0);
1829
            opn = "dsrlv";
1830
            break;
1831
        case 1:
1832
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1833
            if (env->insn_flags & ISA_MIPS32R2) {
1834
                int l1 = gen_new_label();
1835
                int l2 = gen_new_label();
1836

    
1837
                tcg_gen_andi_tl(t0, t0, 0x3f);
1838
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1839
                {
1840
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1841

    
1842
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1843
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, t0);
1844
                    tcg_gen_shl_tl(r_tmp1, t1, r_tmp1);
1845
                    tcg_gen_shr_tl(t0, t1, t0);
1846
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1847
                    tcg_temp_free(r_tmp1);
1848
                    tcg_gen_br(l2);
1849
                }
1850
                gen_set_label(l1);
1851
                tcg_gen_mov_tl(t0, t1);
1852
                gen_set_label(l2);
1853
                opn = "drotrv";
1854
            } else {
1855
                tcg_gen_andi_tl(t0, t0, 0x3f);
1856
                tcg_gen_shr_tl(t0, t1, t0);
1857
                opn = "dsrlv";
1858
            }
1859
            break;
1860
        default:
1861
            MIPS_INVAL("invalid dsrlv flag");
1862
            generate_exception(ctx, EXCP_RI);
1863
            break;
1864
        }
1865
        break;
1866
#endif
1867
    default:
1868
        MIPS_INVAL(opn);
1869
        generate_exception(ctx, EXCP_RI);
1870
        goto out;
1871
    }
1872
    gen_store_gpr(t0, rd);
1873
 print:
1874
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1875
 out:
1876
    tcg_temp_free(t0);
1877
    tcg_temp_free(t1);
1878
}
1879

    
1880
/* Arithmetic on HI/LO registers */
1881
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1882
{
1883
    const char *opn = "hilo";
1884
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1885

    
1886
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1887
        /* Treat as NOP. */
1888
        MIPS_DEBUG("NOP");
1889
        goto out;
1890
    }
1891
    switch (opc) {
1892
    case OPC_MFHI:
1893
        gen_load_HI(t0, 0);
1894
        gen_store_gpr(t0, reg);
1895
        opn = "mfhi";
1896
        break;
1897
    case OPC_MFLO:
1898
        gen_load_LO(t0, 0);
1899
        gen_store_gpr(t0, reg);
1900
        opn = "mflo";
1901
        break;
1902
    case OPC_MTHI:
1903
        gen_load_gpr(t0, reg);
1904
        gen_store_HI(t0, 0);
1905
        opn = "mthi";
1906
        break;
1907
    case OPC_MTLO:
1908
        gen_load_gpr(t0, reg);
1909
        gen_store_LO(t0, 0);
1910
        opn = "mtlo";
1911
        break;
1912
    default:
1913
        MIPS_INVAL(opn);
1914
        generate_exception(ctx, EXCP_RI);
1915
        goto out;
1916
    }
1917
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1918
 out:
1919
    tcg_temp_free(t0);
1920
}
1921

    
1922
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1923
                        int rs, int rt)
1924
{
1925
    const char *opn = "mul/div";
1926
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1927
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1928

    
1929
    gen_load_gpr(t0, rs);
1930
    gen_load_gpr(t1, rt);
1931
    switch (opc) {
1932
    case OPC_DIV:
1933
        {
1934
            int l1 = gen_new_label();
1935

    
1936
            tcg_gen_ext32s_tl(t0, t0);
1937
            tcg_gen_ext32s_tl(t1, t1);
1938
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1939
            {
1940
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1941
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1942
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1943

    
1944
                tcg_gen_ext_tl_i64(r_tmp1, t0);
1945
                tcg_gen_ext_tl_i64(r_tmp2, t1);
1946
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1947
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1948
                tcg_gen_trunc_i64_tl(t0, r_tmp3);
1949
                tcg_gen_trunc_i64_tl(t1, r_tmp2);
1950
                tcg_temp_free(r_tmp1);
1951
                tcg_temp_free(r_tmp2);
1952
                tcg_temp_free(r_tmp3);
1953
                tcg_gen_ext32s_tl(t0, t0);
1954
                tcg_gen_ext32s_tl(t1, t1);
1955
                gen_store_LO(t0, 0);
1956
                gen_store_HI(t1, 0);
1957
            }
1958
            gen_set_label(l1);
1959
        }
1960
        opn = "div";
1961
        break;
1962
    case OPC_DIVU:
1963
        {
1964
            int l1 = gen_new_label();
1965

    
1966
            tcg_gen_ext32s_tl(t1, t1);
1967
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1968
            {
1969
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1970
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1971
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1972

    
1973
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1974
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1975
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1976
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1977
                tcg_gen_ext_i32_tl(t0, r_tmp3);
1978
                tcg_gen_ext_i32_tl(t1, r_tmp1);
1979
                tcg_temp_free(r_tmp1);
1980
                tcg_temp_free(r_tmp2);
1981
                tcg_temp_free(r_tmp3);
1982
                gen_store_LO(t0, 0);
1983
                gen_store_HI(t1, 0);
1984
            }
1985
            gen_set_label(l1);
1986
        }
1987
        opn = "divu";
1988
        break;
1989
    case OPC_MULT:
1990
        {
1991
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1992
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1993

    
1994
            tcg_gen_ext32s_tl(t0, t0);
1995
            tcg_gen_ext32s_tl(t1, t1);
1996
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1997
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1998
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1999
            tcg_temp_free(r_tmp2);
2000
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2001
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2002
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2003
            tcg_temp_free(r_tmp1);
2004
            tcg_gen_ext32s_tl(t0, t0);
2005
            tcg_gen_ext32s_tl(t1, t1);
2006
            gen_store_LO(t0, 0);
2007
            gen_store_HI(t1, 0);
2008
        }
2009
        opn = "mult";
2010
        break;
2011
    case OPC_MULTU:
2012
        {
2013
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2014
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2015

    
2016
            tcg_gen_ext32u_tl(t0, t0);
2017
            tcg_gen_ext32u_tl(t1, t1);
2018
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2019
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2020
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2021
            tcg_temp_free(r_tmp2);
2022
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2023
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2024
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2025
            tcg_temp_free(r_tmp1);
2026
            tcg_gen_ext32s_tl(t0, t0);
2027
            tcg_gen_ext32s_tl(t1, t1);
2028
            gen_store_LO(t0, 0);
2029
            gen_store_HI(t1, 0);
2030
        }
2031
        opn = "multu";
2032
        break;
2033
#if defined(TARGET_MIPS64)
2034
    case OPC_DDIV:
2035
        {
2036
            int l1 = gen_new_label();
2037

    
2038
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2039
            {
2040
                int l2 = gen_new_label();
2041

    
2042
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2043
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2044
                {
2045
                    tcg_gen_movi_tl(t1, 0);
2046
                    gen_store_LO(t0, 0);
2047
                    gen_store_HI(t1, 0);
2048
                    tcg_gen_br(l1);
2049
                }
2050
                gen_set_label(l2);
2051
                {
2052
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2053
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2054

    
2055
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2056
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2057
                    gen_store_LO(r_tmp1, 0);
2058
                    gen_store_HI(r_tmp2, 0);
2059
                    tcg_temp_free(r_tmp1);
2060
                    tcg_temp_free(r_tmp2);
2061
                }
2062
            }
2063
            gen_set_label(l1);
2064
        }
2065
        opn = "ddiv";
2066
        break;
2067
    case OPC_DDIVU:
2068
        {
2069
            int l1 = gen_new_label();
2070

    
2071
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2072
            {
2073
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2074
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2075

    
2076
                tcg_gen_divu_i64(r_tmp1, t0, t1);
2077
                tcg_gen_remu_i64(r_tmp2, t0, t1);
2078
                tcg_temp_free(r_tmp1);
2079
                tcg_temp_free(r_tmp2);
2080
                gen_store_LO(r_tmp1, 0);
2081
                gen_store_HI(r_tmp2, 0);
2082
            }
2083
            gen_set_label(l1);
2084
        }
2085
        opn = "ddivu";
2086
        break;
2087
    case OPC_DMULT:
2088
        tcg_gen_helper_0_2(do_dmult, t0, t1);
2089
        opn = "dmult";
2090
        break;
2091
    case OPC_DMULTU:
2092
        tcg_gen_helper_0_2(do_dmultu, t0, t1);
2093
        opn = "dmultu";
2094
        break;
2095
#endif
2096
    case OPC_MADD:
2097
        {
2098
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2099
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2100
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2101

    
2102
            tcg_gen_ext32s_tl(t0, t0);
2103
            tcg_gen_ext32s_tl(t1, t1);
2104
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2105
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2106
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2107
            gen_load_LO(t0, 0);
2108
            gen_load_HI(t1, 0);
2109
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2110
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2111
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2112
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2113
            tcg_temp_free(r_tmp3);
2114
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2115
            tcg_temp_free(r_tmp2);
2116
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2117
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2118
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2119
            tcg_temp_free(r_tmp1);
2120
            tcg_gen_ext32s_tl(t0, t0);
2121
            tcg_gen_ext32s_tl(t1, t1);
2122
            gen_store_LO(t0, 0);
2123
            gen_store_HI(t1, 0);
2124
        }
2125
        opn = "madd";
2126
        break;
2127
    case OPC_MADDU:
2128
       {
2129
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2130
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2131
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2132

    
2133
            tcg_gen_ext32u_tl(t0, t0);
2134
            tcg_gen_ext32u_tl(t1, t1);
2135
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2136
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2137
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2138
            gen_load_LO(t0, 0);
2139
            gen_load_HI(t1, 0);
2140
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2141
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2142
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2143
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2144
            tcg_temp_free(r_tmp3);
2145
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2146
            tcg_temp_free(r_tmp2);
2147
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2148
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2149
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2150
            tcg_temp_free(r_tmp1);
2151
            tcg_gen_ext32s_tl(t0, t0);
2152
            tcg_gen_ext32s_tl(t1, t1);
2153
            gen_store_LO(t0, 0);
2154
            gen_store_HI(t1, 0);
2155
        }
2156
        opn = "maddu";
2157
        break;
2158
    case OPC_MSUB:
2159
        {
2160
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2161
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2162
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2163

    
2164
            tcg_gen_ext32s_tl(t0, t0);
2165
            tcg_gen_ext32s_tl(t1, t1);
2166
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2167
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2168
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2169
            gen_load_LO(t0, 0);
2170
            gen_load_HI(t1, 0);
2171
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2172
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2173
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2174
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2175
            tcg_temp_free(r_tmp3);
2176
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2177
            tcg_temp_free(r_tmp2);
2178
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2179
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2180
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2181
            tcg_temp_free(r_tmp1);
2182
            tcg_gen_ext32s_tl(t0, t0);
2183
            tcg_gen_ext32s_tl(t1, t1);
2184
            gen_store_LO(t0, 0);
2185
            gen_store_HI(t1, 0);
2186
        }
2187
        opn = "msub";
2188
        break;
2189
    case OPC_MSUBU:
2190
        {
2191
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2192
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2193
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2194

    
2195
            tcg_gen_ext32u_tl(t0, t0);
2196
            tcg_gen_ext32u_tl(t1, t1);
2197
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2198
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2199
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2200
            gen_load_LO(t0, 0);
2201
            gen_load_HI(t1, 0);
2202
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2203
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2204
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2205
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2206
            tcg_temp_free(r_tmp3);
2207
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2208
            tcg_temp_free(r_tmp2);
2209
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2210
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2211
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2212
            tcg_temp_free(r_tmp1);
2213
            tcg_gen_ext32s_tl(t0, t0);
2214
            tcg_gen_ext32s_tl(t1, t1);
2215
            gen_store_LO(t0, 0);
2216
            gen_store_HI(t1, 0);
2217
        }
2218
        opn = "msubu";
2219
        break;
2220
    default:
2221
        MIPS_INVAL(opn);
2222
        generate_exception(ctx, EXCP_RI);
2223
        goto out;
2224
    }
2225
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2226
 out:
2227
    tcg_temp_free(t0);
2228
    tcg_temp_free(t1);
2229
}
2230

    
2231
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2232
                            int rd, int rs, int rt)
2233
{
2234
    const char *opn = "mul vr54xx";
2235
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2236
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2237

    
2238
    gen_load_gpr(t0, rs);
2239
    gen_load_gpr(t1, rt);
2240

    
2241
    switch (opc) {
2242
    case OPC_VR54XX_MULS:
2243
        tcg_gen_helper_1_2(do_muls, t0, t0, t1);
2244
        opn = "muls";
2245
        break;
2246
    case OPC_VR54XX_MULSU:
2247
        tcg_gen_helper_1_2(do_mulsu, t0, t0, t1);
2248
        opn = "mulsu";
2249
        break;
2250
    case OPC_VR54XX_MACC:
2251
        tcg_gen_helper_1_2(do_macc, t0, t0, t1);
2252
        opn = "macc";
2253
        break;
2254
    case OPC_VR54XX_MACCU:
2255
        tcg_gen_helper_1_2(do_maccu, t0, t0, t1);
2256
        opn = "maccu";
2257
        break;
2258
    case OPC_VR54XX_MSAC:
2259
        tcg_gen_helper_1_2(do_msac, t0, t0, t1);
2260
        opn = "msac";
2261
        break;
2262
    case OPC_VR54XX_MSACU:
2263
        tcg_gen_helper_1_2(do_msacu, t0, t0, t1);
2264
        opn = "msacu";
2265
        break;
2266
    case OPC_VR54XX_MULHI:
2267
        tcg_gen_helper_1_2(do_mulhi, t0, t0, t1);
2268
        opn = "mulhi";
2269
        break;
2270
    case OPC_VR54XX_MULHIU:
2271
        tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1);
2272
        opn = "mulhiu";
2273
        break;
2274
    case OPC_VR54XX_MULSHI:
2275
        tcg_gen_helper_1_2(do_mulshi, t0, t0, t1);
2276
        opn = "mulshi";
2277
        break;
2278
    case OPC_VR54XX_MULSHIU:
2279
        tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1);
2280
        opn = "mulshiu";
2281
        break;
2282
    case OPC_VR54XX_MACCHI:
2283
        tcg_gen_helper_1_2(do_macchi, t0, t0, t1);
2284
        opn = "macchi";
2285
        break;
2286
    case OPC_VR54XX_MACCHIU:
2287
        tcg_gen_helper_1_2(do_macchiu, t0, t0, t1);
2288
        opn = "macchiu";
2289
        break;
2290
    case OPC_VR54XX_MSACHI:
2291
        tcg_gen_helper_1_2(do_msachi, t0, t0, t1);
2292
        opn = "msachi";
2293
        break;
2294
    case OPC_VR54XX_MSACHIU:
2295
        tcg_gen_helper_1_2(do_msachiu, t0, t0, t1);
2296
        opn = "msachiu";
2297
        break;
2298
    default:
2299
        MIPS_INVAL("mul vr54xx");
2300
        generate_exception(ctx, EXCP_RI);
2301
        goto out;
2302
    }
2303
    gen_store_gpr(t0, rd);
2304
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2305

    
2306
 out:
2307
    tcg_temp_free(t0);
2308
    tcg_temp_free(t1);
2309
}
2310

    
2311
static void gen_cl (DisasContext *ctx, uint32_t opc,
2312
                    int rd, int rs)
2313
{
2314
    const char *opn = "CLx";
2315
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2316

    
2317
    if (rd == 0) {
2318
        /* Treat as NOP. */
2319
        MIPS_DEBUG("NOP");
2320
        goto out;
2321
    }
2322
    gen_load_gpr(t0, rs);
2323
    switch (opc) {
2324
    case OPC_CLO:
2325
        tcg_gen_helper_1_1(do_clo, t0, t0);
2326
        opn = "clo";
2327
        break;
2328
    case OPC_CLZ:
2329
        tcg_gen_helper_1_1(do_clz, t0, t0);
2330
        opn = "clz";
2331
        break;
2332
#if defined(TARGET_MIPS64)
2333
    case OPC_DCLO:
2334
        tcg_gen_helper_1_1(do_dclo, t0, t0);
2335
        opn = "dclo";
2336
        break;
2337
    case OPC_DCLZ:
2338
        tcg_gen_helper_1_1(do_dclz, t0, t0);
2339
        opn = "dclz";
2340
        break;
2341
#endif
2342
    default:
2343
        MIPS_INVAL(opn);
2344
        generate_exception(ctx, EXCP_RI);
2345
        goto out;
2346
    }
2347
    gen_store_gpr(t0, rd);
2348
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2349

    
2350
 out:
2351
    tcg_temp_free(t0);
2352
}
2353

    
2354
/* Traps */
2355
static void gen_trap (DisasContext *ctx, uint32_t opc,
2356
                      int rs, int rt, int16_t imm)
2357
{
2358
    int cond;
2359
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2360
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2361

    
2362
    cond = 0;
2363
    /* Load needed operands */
2364
    switch (opc) {
2365
    case OPC_TEQ:
2366
    case OPC_TGE:
2367
    case OPC_TGEU:
2368
    case OPC_TLT:
2369
    case OPC_TLTU:
2370
    case OPC_TNE:
2371
        /* Compare two registers */
2372
        if (rs != rt) {
2373
            gen_load_gpr(t0, rs);
2374
            gen_load_gpr(t1, rt);
2375
            cond = 1;
2376
        }
2377
        break;
2378
    case OPC_TEQI:
2379
    case OPC_TGEI:
2380
    case OPC_TGEIU:
2381
    case OPC_TLTI:
2382
    case OPC_TLTIU:
2383
    case OPC_TNEI:
2384
        /* Compare register to immediate */
2385
        if (rs != 0 || imm != 0) {
2386
            gen_load_gpr(t0, rs);
2387
            tcg_gen_movi_tl(t1, (int32_t)imm);
2388
            cond = 1;
2389
        }
2390
        break;
2391
    }
2392
    if (cond == 0) {
2393
        switch (opc) {
2394
        case OPC_TEQ:   /* rs == rs */
2395
        case OPC_TEQI:  /* r0 == 0  */
2396
        case OPC_TGE:   /* rs >= rs */
2397
        case OPC_TGEI:  /* r0 >= 0  */
2398
        case OPC_TGEU:  /* rs >= rs unsigned */
2399
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2400
            /* Always trap */
2401
            tcg_gen_movi_tl(t0, 1);
2402
            break;
2403
        case OPC_TLT:   /* rs < rs           */
2404
        case OPC_TLTI:  /* r0 < 0            */
2405
        case OPC_TLTU:  /* rs < rs unsigned  */
2406
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2407
        case OPC_TNE:   /* rs != rs          */
2408
        case OPC_TNEI:  /* r0 != 0           */
2409
            /* Never trap: treat as NOP. */
2410
            goto out;
2411
        default:
2412
            MIPS_INVAL("trap");
2413
            generate_exception(ctx, EXCP_RI);
2414
            goto out;
2415
        }
2416
    } else {
2417
        switch (opc) {
2418
        case OPC_TEQ:
2419
        case OPC_TEQI:
2420
            gen_op_eq(t0, t1);
2421
            break;
2422
        case OPC_TGE:
2423
        case OPC_TGEI:
2424
            gen_op_ge(t0, t1);
2425
            break;
2426
        case OPC_TGEU:
2427
        case OPC_TGEIU:
2428
            gen_op_geu(t0, t1);
2429
            break;
2430
        case OPC_TLT:
2431
        case OPC_TLTI:
2432
            gen_op_lt(t0, t1);
2433
            break;
2434
        case OPC_TLTU:
2435
        case OPC_TLTIU:
2436
            gen_op_ltu(t0, t1);
2437
            break;
2438
        case OPC_TNE:
2439
        case OPC_TNEI:
2440
            gen_op_ne(t0, t1);
2441
            break;
2442
        default:
2443
            MIPS_INVAL("trap");
2444
            generate_exception(ctx, EXCP_RI);
2445
            goto out;
2446
        }
2447
    }
2448
    save_cpu_state(ctx, 1);
2449
    {
2450
        int l1 = gen_new_label();
2451

    
2452
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2453
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2454
        gen_set_label(l1);
2455
    }
2456
    ctx->bstate = BS_STOP;
2457
 out:
2458
    tcg_temp_free(t0);
2459
    tcg_temp_free(t1);
2460
}
2461

    
2462
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2463
{
2464
    TranslationBlock *tb;
2465
    tb = ctx->tb;
2466
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2467
        tcg_gen_goto_tb(n);
2468
        gen_save_pc(dest);
2469
        tcg_gen_exit_tb((long)tb + n);
2470
    } else {
2471
        gen_save_pc(dest);
2472
        tcg_gen_exit_tb(0);
2473
    }
2474
}
2475

    
2476
/* Branches (before delay slot) */
2477
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2478
                                int rs, int rt, int32_t offset)
2479
{
2480
    target_ulong btgt = -1;
2481
    int blink = 0;
2482
    int bcond = 0;
2483
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2484
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2485

    
2486
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2487
#ifdef MIPS_DEBUG_DISAS
2488
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2489
            fprintf(logfile,
2490
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2491
                    ctx->pc);
2492
        }
2493
#endif
2494
        generate_exception(ctx, EXCP_RI);
2495
        goto out;
2496
    }
2497

    
2498
    /* Load needed operands */
2499
    switch (opc) {
2500
    case OPC_BEQ:
2501
    case OPC_BEQL:
2502
    case OPC_BNE:
2503
    case OPC_BNEL:
2504
        /* Compare two registers */
2505
        if (rs != rt) {
2506
            gen_load_gpr(t0, rs);
2507
            gen_load_gpr(t1, rt);
2508
            bcond = 1;
2509
        }
2510
        btgt = ctx->pc + 4 + offset;
2511
        break;
2512
    case OPC_BGEZ:
2513
    case OPC_BGEZAL:
2514
    case OPC_BGEZALL:
2515
    case OPC_BGEZL:
2516
    case OPC_BGTZ:
2517
    case OPC_BGTZL:
2518
    case OPC_BLEZ:
2519
    case OPC_BLEZL:
2520
    case OPC_BLTZ:
2521
    case OPC_BLTZAL:
2522
    case OPC_BLTZALL:
2523
    case OPC_BLTZL:
2524
        /* Compare to zero */
2525
        if (rs != 0) {
2526
            gen_load_gpr(t0, rs);
2527
            bcond = 1;
2528
        }
2529
        btgt = ctx->pc + 4 + offset;
2530
        break;
2531
    case OPC_J:
2532
    case OPC_JAL:
2533
        /* Jump to immediate */
2534
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2535
        break;
2536
    case OPC_JR:
2537
    case OPC_JALR:
2538
        /* Jump to register */
2539
        if (offset != 0 && offset != 16) {
2540
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2541
               others are reserved. */
2542
            MIPS_INVAL("jump hint");
2543
            generate_exception(ctx, EXCP_RI);
2544
            goto out;
2545
        }
2546
        gen_load_gpr(btarget, rs);
2547
        break;
2548
    default:
2549
        MIPS_INVAL("branch/jump");
2550
        generate_exception(ctx, EXCP_RI);
2551
        goto out;
2552
    }
2553
    if (bcond == 0) {
2554
        /* No condition to be computed */
2555
        switch (opc) {
2556
        case OPC_BEQ:     /* rx == rx        */
2557
        case OPC_BEQL:    /* rx == rx likely */
2558
        case OPC_BGEZ:    /* 0 >= 0          */
2559
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2560
        case OPC_BLEZ:    /* 0 <= 0          */
2561
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2562
            /* Always take */
2563
            ctx->hflags |= MIPS_HFLAG_B;
2564
            MIPS_DEBUG("balways");
2565
            break;
2566
        case OPC_BGEZAL:  /* 0 >= 0          */
2567
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2568
            /* Always take and link */
2569
            blink = 31;
2570
            ctx->hflags |= MIPS_HFLAG_B;
2571
            MIPS_DEBUG("balways and link");
2572
            break;
2573
        case OPC_BNE:     /* rx != rx        */
2574
        case OPC_BGTZ:    /* 0 > 0           */
2575
        case OPC_BLTZ:    /* 0 < 0           */
2576
            /* Treat as NOP. */
2577
            MIPS_DEBUG("bnever (NOP)");
2578
            goto out;
2579
        case OPC_BLTZAL:  /* 0 < 0           */
2580
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2581
            gen_store_gpr(t0, 31);
2582
            MIPS_DEBUG("bnever and link");
2583
            goto out;
2584
        case OPC_BLTZALL: /* 0 < 0 likely */
2585
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2586
            gen_store_gpr(t0, 31);
2587
            /* Skip the instruction in the delay slot */
2588
            MIPS_DEBUG("bnever, link and skip");
2589
            ctx->pc += 4;
2590
            goto out;
2591
        case OPC_BNEL:    /* rx != rx likely */
2592
        case OPC_BGTZL:   /* 0 > 0 likely */
2593
        case OPC_BLTZL:   /* 0 < 0 likely */
2594
            /* Skip the instruction in the delay slot */
2595
            MIPS_DEBUG("bnever and skip");
2596
            ctx->pc += 4;
2597
            goto out;
2598
        case OPC_J:
2599
            ctx->hflags |= MIPS_HFLAG_B;
2600
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2601
            break;
2602
        case OPC_JAL:
2603
            blink = 31;
2604
            ctx->hflags |= MIPS_HFLAG_B;
2605
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2606
            break;
2607
        case OPC_JR:
2608
            ctx->hflags |= MIPS_HFLAG_BR;
2609
            MIPS_DEBUG("jr %s", regnames[rs]);
2610
            break;
2611
        case OPC_JALR:
2612
            blink = rt;
2613
            ctx->hflags |= MIPS_HFLAG_BR;
2614
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2615
            break;
2616
        default:
2617
            MIPS_INVAL("branch/jump");
2618
            generate_exception(ctx, EXCP_RI);
2619
            goto out;
2620
        }
2621
    } else {
2622
        switch (opc) {
2623
        case OPC_BEQ:
2624
            gen_op_eq(t0, t1);
2625
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2626
                       regnames[rs], regnames[rt], btgt);
2627
            goto not_likely;
2628
        case OPC_BEQL:
2629
            gen_op_eq(t0, t1);
2630
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2631
                       regnames[rs], regnames[rt], btgt);
2632
            goto likely;
2633
        case OPC_BNE:
2634
            gen_op_ne(t0, t1);
2635
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2636
                       regnames[rs], regnames[rt], btgt);
2637
            goto not_likely;
2638
        case OPC_BNEL:
2639
            gen_op_ne(t0, t1);
2640
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2641
                       regnames[rs], regnames[rt], btgt);
2642
            goto likely;
2643
        case OPC_BGEZ:
2644
            gen_op_gez(t0);
2645
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2646
            goto not_likely;
2647
        case OPC_BGEZL:
2648
            gen_op_gez(t0);
2649
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2650
            goto likely;
2651
        case OPC_BGEZAL:
2652
            gen_op_gez(t0);
2653
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2654
            blink = 31;
2655
            goto not_likely;
2656
        case OPC_BGEZALL:
2657
            gen_op_gez(t0);
2658
            blink = 31;
2659
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2660
            goto likely;
2661
        case OPC_BGTZ:
2662
            gen_op_gtz(t0);
2663
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2664
            goto not_likely;
2665
        case OPC_BGTZL:
2666
            gen_op_gtz(t0);
2667
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2668
            goto likely;
2669
        case OPC_BLEZ:
2670
            gen_op_lez(t0);
2671
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2672
            goto not_likely;
2673
        case OPC_BLEZL:
2674
            gen_op_lez(t0);
2675
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2676
            goto likely;
2677
        case OPC_BLTZ:
2678
            gen_op_ltz(t0);
2679
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2680
            goto not_likely;
2681
        case OPC_BLTZL:
2682
            gen_op_ltz(t0);
2683
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2684
            goto likely;
2685
        case OPC_BLTZAL:
2686
            gen_op_ltz(t0);
2687
            blink = 31;
2688
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2689
        not_likely:
2690
            ctx->hflags |= MIPS_HFLAG_BC;
2691
            tcg_gen_trunc_tl_i32(bcond, t0);
2692
            break;
2693
        case OPC_BLTZALL:
2694
            gen_op_ltz(t0);
2695
            blink = 31;
2696
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2697
        likely:
2698
            ctx->hflags |= MIPS_HFLAG_BL;
2699
            tcg_gen_trunc_tl_i32(bcond, t0);
2700
            break;
2701
        default:
2702
            MIPS_INVAL("conditional branch/jump");
2703
            generate_exception(ctx, EXCP_RI);
2704
            goto out;
2705
        }
2706
    }
2707
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2708
               blink, ctx->hflags, btgt);
2709

    
2710
    ctx->btarget = btgt;
2711
    if (blink > 0) {
2712
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2713
        gen_store_gpr(t0, blink);
2714
    }
2715

    
2716
 out:
2717
    tcg_temp_free(t0);
2718
    tcg_temp_free(t1);
2719
}
2720

    
2721
/* special3 bitfield operations */
2722
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2723
                        int rs, int lsb, int msb)
2724
{
2725
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2726
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2727

    
2728
    gen_load_gpr(t1, rs);
2729
    switch (opc) {
2730
    case OPC_EXT:
2731
        if (lsb + msb > 31)
2732
            goto fail;
2733
        tcg_gen_helper_1_1ii(do_ext, t0, t1, lsb, msb + 1);
2734
        break;
2735
#if defined(TARGET_MIPS64)
2736
    case OPC_DEXTM:
2737
        if (lsb + msb > 63)
2738
            goto fail;
2739
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1 + 32);
2740
        break;
2741
    case OPC_DEXTU:
2742
        if (lsb + msb > 63)
2743
            goto fail;
2744
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb + 32, msb + 1);
2745
        break;
2746
    case OPC_DEXT:
2747
        if (lsb + msb > 63)
2748
            goto fail;
2749
        tcg_gen_helper_1_1ii(do_dext, t0, t1, lsb, msb + 1);
2750
        break;
2751
#endif
2752
    case OPC_INS:
2753
        if (lsb > msb)
2754
            goto fail;
2755
        gen_load_gpr(t0, rt);
2756
        tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
2757
        break;
2758
#if defined(TARGET_MIPS64)
2759
    case OPC_DINSM:
2760
        if (lsb > msb)
2761
            goto fail;
2762
        gen_load_gpr(t0, rt);
2763
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
2764
        break;
2765
    case OPC_DINSU:
2766
        if (lsb > msb)
2767
            goto fail;
2768
        gen_load_gpr(t0, rt);
2769
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
2770
        break;
2771
    case OPC_DINS:
2772
        if (lsb > msb)
2773
            goto fail;
2774
        gen_load_gpr(t0, rt);
2775
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
2776
        break;
2777
#endif
2778
    default:
2779
fail:
2780
        MIPS_INVAL("bitops");
2781
        generate_exception(ctx, EXCP_RI);
2782
        tcg_temp_free(t0);
2783
        tcg_temp_free(t1);
2784
        return;
2785
    }
2786
    gen_store_gpr(t0, rt);
2787
    tcg_temp_free(t0);
2788
    tcg_temp_free(t1);
2789
}
2790

    
2791
/* CP0 (MMU and control) */
2792
#ifndef CONFIG_USER_ONLY
2793
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2794
{
2795
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2796

    
2797
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2798
    tcg_gen_ext_i32_tl(t, r_tmp);
2799
    tcg_temp_free(r_tmp);
2800
}
2801

    
2802
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2803
{
2804
    tcg_gen_ld_tl(t, cpu_env, off);
2805
    tcg_gen_ext32s_tl(t, t);
2806
}
2807

    
2808
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2809
{
2810
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2811

    
2812
    tcg_gen_trunc_tl_i32(r_tmp, t);
2813
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2814
    tcg_temp_free(r_tmp);
2815
}
2816

    
2817
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2818
{
2819
    tcg_gen_ext32s_tl(t, t);
2820
    tcg_gen_st_tl(t, cpu_env, off);
2821
}
2822

    
2823
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2824
{
2825
    const char *rn = "invalid";
2826

    
2827
    if (sel != 0)
2828
        check_insn(env, ctx, ISA_MIPS32);
2829

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

    
3399
die:
3400
#if defined MIPS_DEBUG_DISAS
3401
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3402
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3403
                rn, reg, sel);
3404
    }
3405
#endif
3406
    generate_exception(ctx, EXCP_RI);
3407
}
3408

    
3409
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3410
{
3411
    const char *rn = "invalid";
3412

    
3413
    if (sel != 0)
3414
        check_insn(env, ctx, ISA_MIPS32);
3415

    
3416
    if (use_icount)
3417
        gen_io_start();
3418

    
3419
    switch (reg) {
3420
    case 0:
3421
        switch (sel) {
3422
        case 0:
3423
            tcg_gen_helper_0_1(do_mtc0_index, t0);
3424
            rn = "Index";
3425
            break;
3426
        case 1:
3427
            check_insn(env, ctx, ASE_MT);
3428
            tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0);
3429
            rn = "MVPControl";
3430
            break;
3431
        case 2:
3432
            check_insn(env, ctx, ASE_MT);
3433
            /* ignored */
3434
            rn = "MVPConf0";
3435
            break;
3436
        case 3:
3437
            check_insn(env, ctx, ASE_MT);
3438
            /* ignored */
3439
            rn = "MVPConf1";
3440
            break;
3441
        default:
3442
            goto die;
3443
        }
3444
        break;
3445
    case 1:
3446
        switch (sel) {
3447
        case 0:
3448
            /* ignored */
3449
            rn = "Random";
3450
            break;
3451
        case 1:
3452
            check_insn(env, ctx, ASE_MT);
3453
            tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0);
3454
            rn = "VPEControl";
3455
            break;
3456
        case 2:
3457
            check_insn(env, ctx, ASE_MT);
3458
            tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0);
3459
            rn = "VPEConf0";
3460
            break;
3461
        case 3:
3462
            check_insn(env, ctx, ASE_MT);
3463
            tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0);
3464
            rn = "VPEConf1";
3465
            break;
3466
        case 4:
3467
            check_insn(env, ctx, ASE_MT);
3468
            tcg_gen_helper_0_1(do_mtc0_yqmask, t0);
3469
            rn = "YQMask";
3470
            break;
3471
        case 5:
3472
            check_insn(env, ctx, ASE_MT);
3473
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
3474
            rn = "VPESchedule";
3475
            break;
3476
        case 6:
3477
            check_insn(env, ctx, ASE_MT);
3478
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
3479
            rn = "VPEScheFBack";
3480
            break;
3481
        case 7:
3482
            check_insn(env, ctx, ASE_MT);
3483
            tcg_gen_helper_0_1(do_mtc0_vpeopt, t0);
3484
            rn = "VPEOpt";
3485
            break;
3486
        default:
3487
            goto die;
3488
        }
3489
        break;
3490
    case 2:
3491
        switch (sel) {
3492
        case 0:
3493
            tcg_gen_helper_0_1(do_mtc0_entrylo0, t0);
3494
            rn = "EntryLo0";
3495
            break;
3496
        case 1:
3497
            check_insn(env, ctx, ASE_MT);
3498
            tcg_gen_helper_0_1(do_mtc0_tcstatus, t0);
3499
            rn = "TCStatus";
3500
            break;
3501
        case 2:
3502
            check_insn(env, ctx, ASE_MT);
3503
            tcg_gen_helper_0_1(do_mtc0_tcbind, t0);
3504
            rn = "TCBind";
3505
            break;
3506
        case 3:
3507
            check_insn(env, ctx, ASE_MT);
3508
            tcg_gen_helper_0_1(do_mtc0_tcrestart, t0);
3509
            rn = "TCRestart";
3510
            break;
3511
        case 4:
3512
            check_insn(env, ctx, ASE_MT);
3513
            tcg_gen_helper_0_1(do_mtc0_tchalt, t0);
3514
            rn = "TCHalt";
3515
            break;
3516
        case 5:
3517
            check_insn(env, ctx, ASE_MT);
3518
            tcg_gen_helper_0_1(do_mtc0_tccontext, t0);
3519
            rn = "TCContext";
3520
            break;
3521
        case 6:
3522
            check_insn(env, ctx, ASE_MT);
3523
            tcg_gen_helper_0_1(do_mtc0_tcschedule, t0);
3524
            rn = "TCSchedule";
3525
            break;
3526
        case 7:
3527
            check_insn(env, ctx, ASE_MT);
3528
            tcg_gen_helper_0_1(do_mtc0_tcschefback, t0);
3529
            rn = "TCScheFBack";
3530
            break;
3531
        default:
3532
            goto die;
3533
        }
3534
        break;
3535
    case 3:
3536
        switch (sel) {
3537
        case 0:
3538
            tcg_gen_helper_0_1(do_mtc0_entrylo1, t0);
3539
            rn = "EntryLo1";
3540
            break;
3541
        default:
3542
            goto die;
3543
        }
3544
        break;
3545
    case 4:
3546
        switch (sel) {
3547
        case 0:
3548
            tcg_gen_helper_0_1(do_mtc0_context, t0);
3549
            rn = "Context";
3550
            break;
3551
        case 1:
3552
//            tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */
3553
            rn = "ContextConfig";
3554
//            break;
3555
        default:
3556
            goto die;
3557
        }
3558
        break;
3559
    case 5:
3560
        switch (sel) {
3561
        case 0:
3562
            tcg_gen_helper_0_1(do_mtc0_pagemask, t0);
3563
            rn = "PageMask";
3564
            break;
3565
        case 1:
3566
            check_insn(env, ctx, ISA_MIPS32R2);
3567
            tcg_gen_helper_0_1(do_mtc0_pagegrain, t0);
3568
            rn = "PageGrain";
3569
            break;
3570
        default:
3571
            goto die;
3572
        }
3573
        break;
3574
    case 6:
3575
        switch (sel) {
3576
        case 0:
3577
            tcg_gen_helper_0_1(do_mtc0_wired, t0);
3578
            rn = "Wired";
3579
            break;
3580
        case 1:
3581
            check_insn(env, ctx, ISA_MIPS32R2);
3582
            tcg_gen_helper_0_1(do_mtc0_srsconf0, t0);
3583
            rn = "SRSConf0";
3584
            break;
3585
        case 2:
3586
            check_insn(env, ctx, ISA_MIPS32R2);
3587
            tcg_gen_helper_0_1(do_mtc0_srsconf1, t0);
3588
            rn = "SRSConf1";
3589
            break;
3590
        case 3:
3591
            check_insn(env, ctx, ISA_MIPS32R2);
3592
            tcg_gen_helper_0_1(do_mtc0_srsconf2, t0);
3593
            rn = "SRSConf2";
3594
            break;
3595
        case 4:
3596
            check_insn(env, ctx, ISA_MIPS32R2);
3597
            tcg_gen_helper_0_1(do_mtc0_srsconf3, t0);
3598
            rn = "SRSConf3";
3599
            break;
3600
        case 5:
3601
            check_insn(env, ctx, ISA_MIPS32R2);
3602
            tcg_gen_helper_0_1(do_mtc0_srsconf4, t0);
3603
            rn = "SRSConf4";
3604
            break;
3605
        default:
3606
            goto die;
3607
        }
3608
        break;
3609
    case 7:
3610
        switch (sel) {
3611
        case 0:
3612
            check_insn(env, ctx, ISA_MIPS32R2);
3613
            tcg_gen_helper_0_1(do_mtc0_hwrena, t0);
3614
            rn = "HWREna";
3615
            break;
3616
        default:
3617
            goto die;
3618
        }
3619
        break;
3620
    case 8:
3621
        /* ignored */
3622
        rn = "BadVAddr";
3623
        break;
3624
    case 9:
3625
        switch (sel) {
3626
        case 0:
3627
            tcg_gen_helper_0_1(do_mtc0_count, t0);
3628
            rn = "Count";
3629
            break;
3630
        /* 6,7 are implementation dependent */
3631
        default:
3632
            goto die;
3633
        }
3634
        /* Stop translation as we may have switched the execution mode */
3635
        ctx->bstate = BS_STOP;
3636
        break;
3637
    case 10:
3638
        switch (sel) {
3639
        case 0:
3640
            tcg_gen_helper_0_1(do_mtc0_entryhi, t0);
3641
            rn = "EntryHi";
3642
            break;
3643
        default:
3644
            goto die;
3645
        }
3646
        break;
3647
    case 11:
3648
        switch (sel) {
3649
        case 0:
3650
            tcg_gen_helper_0_1(do_mtc0_compare, t0);
3651
            rn = "Compare";
3652
            break;
3653
        /* 6,7 are implementation dependent */
3654
        default:
3655
            goto die;
3656
        }
3657
        /* Stop translation as we may have switched the execution mode */
3658
        ctx->bstate = BS_STOP;
3659
        break;
3660
    case 12:
3661
        switch (sel) {
3662
        case 0:
3663
            tcg_gen_helper_0_1(do_mtc0_status, t0);
3664
            /* BS_STOP isn't good enough here, hflags may have changed. */
3665
            gen_save_pc(ctx->pc + 4);
3666
            ctx->bstate = BS_EXCP;
3667
            rn = "Status";
3668
            break;
3669
        case 1:
3670
            check_insn(env, ctx, ISA_MIPS32R2);
3671
            tcg_gen_helper_0_1(do_mtc0_intctl, t0);
3672
            /* Stop translation as we may have switched the execution mode */
3673
            ctx->bstate = BS_STOP;
3674
            rn = "IntCtl";
3675
            break;
3676
        case 2:
3677
            check_insn(env, ctx, ISA_MIPS32R2);
3678
            tcg_gen_helper_0_1(do_mtc0_srsctl, t0);
3679
            /* Stop translation as we may have switched the execution mode */
3680
            ctx->bstate = BS_STOP;
3681
            rn = "SRSCtl";
3682
            break;
3683
        case 3:
3684
            check_insn(env, ctx, ISA_MIPS32R2);
3685
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
3686
            /* Stop translation as we may have switched the execution mode */
3687
            ctx->bstate = BS_STOP;
3688
            rn = "SRSMap";
3689
            break;
3690
        default:
3691
            goto die;
3692
        }
3693
        break;
3694
    case 13:
3695
        switch (sel) {
3696
        case 0:
3697
            tcg_gen_helper_0_1(do_mtc0_cause, t0);
3698
            rn = "Cause";
3699
            break;
3700
        default:
3701
            goto die;
3702
        }
3703
        /* Stop translation as we may have switched the execution mode */
3704
        ctx->bstate = BS_STOP;
3705
        break;
3706
    case 14:
3707
        switch (sel) {
3708
        case 0:
3709
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
3710
            rn = "EPC";
3711
            break;
3712
        default:
3713
            goto die;
3714
        }
3715
        break;
3716
    case 15:
3717
        switch (sel) {
3718
        case 0:
3719
            /* ignored */
3720
            rn = "PRid";
3721
            break;
3722
        case 1:
3723
            check_insn(env, ctx, ISA_MIPS32R2);
3724
            tcg_gen_helper_0_1(do_mtc0_ebase, t0);
3725
            rn = "EBase";
3726
            break;
3727
        default:
3728
            goto die;
3729
        }
3730
        break;
3731
    case 16:
3732
        switch (sel) {
3733
        case 0:
3734
            tcg_gen_helper_0_1(do_mtc0_config0, t0);
3735
            rn = "Config";
3736
            /* Stop translation as we may have switched the execution mode */
3737
            ctx->bstate = BS_STOP;
3738
            break;
3739
        case 1:
3740
            /* ignored, read only */
3741
            rn = "Config1";
3742
            break;
3743
        case 2:
3744
            tcg_gen_helper_0_1(do_mtc0_config2, t0);
3745
            rn = "Config2";
3746
            /* Stop translation as we may have switched the execution mode */
3747
            ctx->bstate = BS_STOP;
3748
            break;
3749
        case 3:
3750
            /* ignored, read only */
3751
            rn = "Config3";
3752
            break;
3753
        /* 4,5 are reserved */
3754
        /* 6,7 are implementation dependent */
3755
        case 6:
3756
            /* ignored */
3757
            rn = "Config6";
3758
            break;
3759
        case 7:
3760
            /* ignored */
3761
            rn = "Config7";
3762
            break;
3763
        default:
3764
            rn = "Invalid config selector";
3765
            goto die;
3766
        }
3767
        break;
3768
    case 17:
3769
        switch (sel) {
3770
        case 0:
3771
            /* ignored */
3772
            rn = "LLAddr";
3773
            break;
3774
        default:
3775
            goto die;
3776
        }
3777
        break;
3778
    case 18:
3779
        switch (sel) {
3780
        case 0 ... 7:
3781
            tcg_gen_helper_0_1i(do_mtc0_watchlo, t0, sel);
3782
            rn = "WatchLo";
3783
            break;
3784
        default:
3785
            goto die;
3786
        }
3787
        break;
3788
    case 19:
3789
        switch (sel) {
3790
        case 0 ... 7:
3791
            tcg_gen_helper_0_1i(do_mtc0_watchhi, t0, sel);
3792
            rn = "WatchHi";
3793
            break;
3794
        default:
3795
            goto die;
3796
        }
3797
        break;
3798
    case 20:
3799
        switch (sel) {
3800
        case 0:
3801
#if defined(TARGET_MIPS64)
3802
            check_insn(env, ctx, ISA_MIPS3);
3803
            tcg_gen_helper_0_1(do_mtc0_xcontext, t0);
3804
            rn = "XContext";
3805
            break;
3806
#endif
3807
        default:
3808
            goto die;
3809
        }
3810
        break;
3811
    case 21:
3812
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3813
        switch (sel) {
3814
        case 0:
3815
            tcg_gen_helper_0_1(do_mtc0_framemask, t0);
3816
            rn = "Framemask";
3817
            break;
3818
        default:
3819
            goto die;
3820
        }
3821
        break;
3822
    case 22:
3823
        /* ignored */
3824
        rn = "Diagnostic"; /* implementation dependent */
3825
        break;
3826
    case 23:
3827
        switch (sel) {
3828
        case 0:
3829
            tcg_gen_helper_0_1(do_mtc0_debug, t0); /* EJTAG support */
3830
            /* BS_STOP isn't good enough here, hflags may have changed. */
3831
            gen_save_pc(ctx->pc + 4);
3832
            ctx->bstate = BS_EXCP;
3833
            rn = "Debug";
3834
            break;
3835
        case 1:
3836
//            tcg_gen_helper_0_1(do_mtc0_tracecontrol, t0); /* PDtrace support */
3837
            rn = "TraceControl";
3838
            /* Stop translation as we may have switched the execution mode */
3839
            ctx->bstate = BS_STOP;
3840
//            break;
3841
        case 2:
3842
//            tcg_gen_helper_0_1(do_mtc0_tracecontrol2, t0); /* PDtrace support */
3843
            rn = "TraceControl2";
3844
            /* Stop translation as we may have switched the execution mode */
3845
            ctx->bstate = BS_STOP;
3846
//            break;
3847
        case 3:
3848
            /* Stop translation as we may have switched the execution mode */
3849
            ctx->bstate = BS_STOP;
3850
//            tcg_gen_helper_0_1(do_mtc0_usertracedata, t0); /* PDtrace support */
3851
            rn = "UserTraceData";
3852
            /* Stop translation as we may have switched the execution mode */
3853
            ctx->bstate = BS_STOP;
3854
//            break;
3855
        case 4:
3856
//            tcg_gen_helper_0_1(do_mtc0_tracebpc, t0); /* PDtrace support */
3857
            /* Stop translation as we may have switched the execution mode */
3858
            ctx->bstate = BS_STOP;
3859
            rn = "TraceBPC";
3860
//            break;
3861
        default:
3862
            goto die;
3863
        }
3864
        break;
3865
    case 24:
3866
        switch (sel) {
3867
        case 0:
3868
            /* EJTAG support */
3869
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
3870
            rn = "DEPC";
3871
            break;
3872
        default:
3873
            goto die;
3874
        }
3875
        break;
3876
    case 25:
3877
        switch (sel) {
3878
        case 0:
3879
            tcg_gen_helper_0_1(do_mtc0_performance0, t0);
3880
            rn = "Performance0";
3881
            break;
3882
        case 1:
3883
//            tcg_gen_helper_0_1(do_mtc0_performance1, t0);
3884
            rn = "Performance1";
3885
//            break;
3886
        case 2:
3887
//            tcg_gen_helper_0_1(do_mtc0_performance2, t0);
3888
            rn = "Performance2";
3889
//            break;
3890
        case 3:
3891
//            tcg_gen_helper_0_1(do_mtc0_performance3, t0);
3892
            rn = "Performance3";
3893
//            break;
3894
        case 4:
3895
//            tcg_gen_helper_0_1(do_mtc0_performance4, t0);
3896
            rn = "Performance4";
3897
//            break;
3898
        case 5:
3899
//            tcg_gen_helper_0_1(do_mtc0_performance5, t0);
3900
            rn = "Performance5";
3901
//            break;
3902
        case 6:
3903
//            tcg_gen_helper_0_1(do_mtc0_performance6, t0);
3904
            rn = "Performance6";
3905
//            break;
3906
        case 7:
3907
//            tcg_gen_helper_0_1(do_mtc0_performance7, t0);
3908
            rn = "Performance7";
3909
//            break;
3910
        default:
3911
            goto die;
3912
        }
3913
       break;
3914
    case 26:
3915
        /* ignored */
3916
        rn = "ECC";
3917
        break;
3918
    case 27:
3919
        switch (sel) {
3920
        case 0 ... 3:
3921
            /* ignored */
3922
            rn = "CacheErr";
3923
            break;
3924
        default:
3925
            goto die;
3926
        }
3927
       break;
3928
    case 28:
3929
        switch (sel) {
3930
        case 0:
3931
        case 2:
3932
        case 4:
3933
        case 6:
3934
            tcg_gen_helper_0_1(do_mtc0_taglo, t0);
3935
            rn = "TagLo";
3936
            break;
3937
        case 1:
3938
        case 3:
3939
        case 5:
3940
        case 7:
3941
            tcg_gen_helper_0_1(do_mtc0_datalo, t0);
3942
            rn = "DataLo";
3943
            break;
3944
        default:
3945
            goto die;
3946
        }
3947
        break;
3948
    case 29:
3949
        switch (sel) {
3950
        case 0:
3951
        case 2:
3952
        case 4:
3953
        case 6:
3954
            tcg_gen_helper_0_1(do_mtc0_taghi, t0);
3955
            rn = "TagHi";
3956
            break;
3957
        case 1:
3958
        case 3:
3959
        case 5:
3960
        case 7:
3961
            tcg_gen_helper_0_1(do_mtc0_datahi, t0);
3962
            rn = "DataHi";
3963
            break;
3964
        default:
3965
            rn = "invalid sel";
3966
            goto die;
3967
        }
3968
       break;
3969
    case 30:
3970
        switch (sel) {
3971
        case 0:
3972
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
3973
            rn = "ErrorEPC";
3974
            break;
3975
        default:
3976
            goto die;
3977
        }
3978
        break;
3979
    case 31:
3980
        switch (sel) {
3981
        case 0:
3982
            /* EJTAG support */
3983
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
3984
            rn = "DESAVE";
3985
            break;
3986
        default:
3987
            goto die;
3988
        }
3989
        /* Stop translation as we may have switched the execution mode */
3990
        ctx->bstate = BS_STOP;
3991
        break;
3992
    default:
3993
       goto die;
3994
    }
3995
#if defined MIPS_DEBUG_DISAS
3996
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3997
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3998
                rn, reg, sel);
3999
    }
4000
#endif
4001
    /* For simplicity assume that all writes can cause interrupts.  */
4002
    if (use_icount) {
4003
        gen_io_end();
4004
        ctx->bstate = BS_STOP;
4005
    }
4006
    return;
4007

    
4008
die:
4009
#if defined MIPS_DEBUG_DISAS
4010
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4011
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
4012
                rn, reg, sel);
4013
    }
4014
#endif
4015
    generate_exception(ctx, EXCP_RI);
4016
}
4017

    
4018
#if defined(TARGET_MIPS64)
4019
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4020
{
4021
    const char *rn = "invalid";
4022

    
4023
    if (sel != 0)
4024
        check_insn(env, ctx, ISA_MIPS64);
4025

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

    
4583
die:
4584
#if defined MIPS_DEBUG_DISAS
4585
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4586
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4587
                rn, reg, sel);
4588
    }
4589
#endif
4590
    generate_exception(ctx, EXCP_RI);
4591
}
4592

    
4593
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4594
{
4595
    const char *rn = "invalid";
4596

    
4597
    if (sel != 0)
4598
        check_insn(env, ctx, ISA_MIPS64);
4599

    
4600
    if (use_icount)
4601
        gen_io_start();
4602

    
4603
    switch (reg) {
4604
    case 0:
4605
        switch (sel) {
4606
        case 0:
4607
            tcg_gen_helper_0_1(do_mtc0_index, t0);
4608
            rn = "Index";
4609
            break;
4610
        case 1:
4611
            check_insn(env, ctx, ASE_MT);
4612
            tcg_gen_helper_0_1(do_mtc0_mvpcontrol, t0);
4613
            rn = "MVPControl";
4614
            break;
4615
        case 2:
4616
            check_insn(env, ctx, ASE_MT);
4617
            /* ignored */
4618
            rn = "MVPConf0";
4619
            break;
4620
        case 3:
4621
            check_insn(env, ctx, ASE_MT);
4622
            /* ignored */
4623
            rn = "MVPConf1";
4624
            break;
4625
        default:
4626
            goto die;
4627
        }
4628
        break;
4629
    case 1:
4630
        switch (sel) {
4631
        case 0:
4632
            /* ignored */
4633
            rn = "Random";
4634
            break;
4635
        case 1:
4636
            check_insn(env, ctx, ASE_MT);
4637
            tcg_gen_helper_0_1(do_mtc0_vpecontrol, t0);
4638
            rn = "VPEControl";
4639
            break;
4640
        case 2:
4641
            check_insn(env, ctx, ASE_MT);
4642
            tcg_gen_helper_0_1(do_mtc0_vpeconf0, t0);
4643
            rn = "VPEConf0";
4644
            break;
4645
        case 3:
4646
            check_insn(env, ctx, ASE_MT);
4647
            tcg_gen_helper_0_1(do_mtc0_vpeconf1, t0);
4648
            rn = "VPEConf1";
4649
            break;
4650
        case 4:
4651
            check_insn(env, ctx, ASE_MT);
4652
            tcg_gen_helper_0_1(do_mtc0_yqmask, t0);
4653
            rn = "YQMask";
4654
            break;
4655
        case 5:
4656
            check_insn(env, ctx, ASE_MT);
4657
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4658
            rn = "VPESchedule";
4659
            break;
4660
        case 6:
4661
            check_insn(env, ctx, ASE_MT);
4662
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4663
            rn = "VPEScheFBack";
4664
            break;
4665
        case 7:
4666
            check_insn(env, ctx, ASE_MT);
4667
            tcg_gen_helper_0_1(do_mtc0_vpeopt, t0);
4668
            rn = "VPEOpt";
4669
            break;
4670
        default:
4671
            goto die;
4672
        }
4673
        break;
4674
    case 2:
4675
        switch (sel) {
4676
        case 0:
4677
            tcg_gen_helper_0_1(do_mtc0_entrylo0, t0);
4678
            rn = "EntryLo0";
4679
            break;
4680
        case 1:
4681
            check_insn(env, ctx, ASE_MT);
4682
            tcg_gen_helper_0_1(do_mtc0_tcstatus, t0);
4683
            rn = "TCStatus";
4684
            break;
4685
        case 2:
4686
            check_insn(env, ctx, ASE_MT);
4687
            tcg_gen_helper_0_1(do_mtc0_tcbind, t0);
4688
            rn = "TCBind";
4689
            break;
4690
        case 3:
4691
            check_insn(env, ctx, ASE_MT);
4692
            tcg_gen_helper_0_1(do_mtc0_tcrestart, t0);
4693
            rn = "TCRestart";
4694
            break;
4695
        case 4:
4696
            check_insn(env, ctx, ASE_MT);
4697
            tcg_gen_helper_0_1(do_mtc0_tchalt, t0);
4698
            rn = "TCHalt";
4699
            break;
4700
        case 5:
4701
            check_insn(env, ctx, ASE_MT);
4702
            tcg_gen_helper_0_1(do_mtc0_tccontext, t0);
4703
            rn = "TCContext";
4704
            break;
4705
        case 6:
4706
            check_insn(env, ctx, ASE_MT);
4707
            tcg_gen_helper_0_1(do_mtc0_tcschedule, t0);
4708
            rn = "TCSchedule";
4709
            break;
4710
        case 7:
4711
            check_insn(env, ctx, ASE_MT);
4712
            tcg_gen_helper_0_1(do_mtc0_tcschefback, t0);
4713
            rn = "TCScheFBack";
4714
            break;
4715
        default:
4716
            goto die;
4717
        }
4718
        break;
4719
    case 3:
4720
        switch (sel) {
4721
        case 0:
4722
            tcg_gen_helper_0_1(do_mtc0_entrylo1, t0);
4723
            rn = "EntryLo1";
4724
            break;
4725
        default:
4726
            goto die;
4727
        }
4728
        break;
4729
    case 4:
4730
        switch (sel) {
4731
        case 0:
4732
            tcg_gen_helper_0_1(do_mtc0_context, t0);
4733
            rn = "Context";
4734
            break;
4735
        case 1:
4736
//           tcg_gen_helper_0_1(do_mtc0_contextconfig, t0); /* SmartMIPS ASE */
4737
            rn = "ContextConfig";
4738
//           break;
4739
        default:
4740
            goto die;
4741
        }
4742
        break;
4743
    case 5:
4744
        switch (sel) {
4745
        case 0:
4746
            tcg_gen_helper_0_1(do_mtc0_pagemask, t0);
4747
            rn = "PageMask";
4748
            break;
4749
        case 1:
4750
            check_insn(env, ctx, ISA_MIPS32R2);
4751
            tcg_gen_helper_0_1(do_mtc0_pagegrain, t0);
4752
            rn = "PageGrain";
4753
            break;
4754
        default:
4755
            goto die;
4756
        }
4757
        break;
4758
    case 6:
4759
        switch (sel) {
4760
        case 0:
4761
            tcg_gen_helper_0_1(do_mtc0_wired, t0);
4762
            rn = "Wired";
4763
            break;
4764
        case 1:
4765
            check_insn(env, ctx, ISA_MIPS32R2);
4766
            tcg_gen_helper_0_1(do_mtc0_srsconf0, t0);
4767
            rn = "SRSConf0";
4768
            break;
4769
        case 2:
4770
            check_insn(env, ctx, ISA_MIPS32R2);
4771
            tcg_gen_helper_0_1(do_mtc0_srsconf1, t0);
4772
            rn = "SRSConf1";
4773
            break;
4774
        case 3:
4775
            check_insn(env, ctx, ISA_MIPS32R2);
4776
            tcg_gen_helper_0_1(do_mtc0_srsconf2, t0);
4777
            rn = "SRSConf2";
4778
            break;
4779
        case 4:
4780
            check_insn(env, ctx, ISA_MIPS32R2);
4781
            tcg_gen_helper_0_1(do_mtc0_srsconf3, t0);
4782
            rn = "SRSConf3";
4783
            break;
4784
        case 5:
4785
            check_insn(env, ctx, ISA_MIPS32R2);
4786
            tcg_gen_helper_0_1(do_mtc0_srsconf4, t0);
4787
            rn = "SRSConf4";
4788
            break;
4789
        default:
4790
            goto die;
4791
        }
4792
        break;
4793
    case 7:
4794
        switch (sel) {
4795
        case 0:
4796
            check_insn(env, ctx, ISA_MIPS32R2);
4797
            tcg_gen_helper_0_1(do_mtc0_hwrena, t0);
4798
            rn = "HWREna";
4799
            break;
4800
        default:
4801
            goto die;
4802
        }
4803
        break;
4804
    case 8:
4805
        /* ignored */
4806
        rn = "BadVAddr";
4807
        break;
4808
    case 9:
4809
        switch (sel) {
4810
        case 0:
4811
            tcg_gen_helper_0_1(do_mtc0_count, t0);
4812
            rn = "Count";
4813
            break;
4814
        /* 6,7 are implementation dependent */
4815
        default:
4816
            goto die;
4817
        }
4818
        /* Stop translation as we may have switched the execution mode */
4819
        ctx->bstate = BS_STOP;
4820
        break;
4821
    case 10:
4822
        switch (sel) {
4823
        case 0:
4824
            tcg_gen_helper_0_1(do_mtc0_entryhi, t0);
4825
            rn = "EntryHi";
4826
            break;
4827
        default:
4828
            goto die;
4829
        }
4830
        break;
4831
    case 11:
4832
        switch (sel) {
4833
        case 0:
4834
            tcg_gen_helper_0_1(do_mtc0_compare, t0);
4835
            rn = "Compare";
4836
            break;
4837
        /* 6,7 are implementation dependent */
4838
        default:
4839
            goto die;
4840
        }
4841
        /* Stop translation as we may have switched the execution mode */
4842
        ctx->bstate = BS_STOP;
4843
        break;
4844
    case 12:
4845
        switch (sel) {
4846
        case 0:
4847
            tcg_gen_helper_0_1(do_mtc0_status, t0);
4848
            /* BS_STOP isn't good enough here, hflags may have changed. */
4849
            gen_save_pc(ctx->pc + 4);
4850
            ctx->bstate = BS_EXCP;
4851
            rn = "Status";
4852
            break;
4853
        case 1:
4854
            check_insn(env, ctx, ISA_MIPS32R2);
4855
            tcg_gen_helper_0_1(do_mtc0_intctl, t0);
4856
            /* Stop translation as we may have switched the execution mode */
4857
            ctx->bstate = BS_STOP;
4858
            rn = "IntCtl";
4859
            break;
4860
        case 2:
4861
            check_insn(env, ctx, ISA_MIPS32R2);
4862
            tcg_gen_helper_0_1(do_mtc0_srsctl, t0);
4863
            /* Stop translation as we may have switched the execution mode */
4864
            ctx->bstate = BS_STOP;
4865
            rn = "SRSCtl";
4866
            break;
4867
        case 3:
4868
            check_insn(env, ctx, ISA_MIPS32R2);
4869
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
4870
            /* Stop translation as we may have switched the execution mode */
4871
            ctx->bstate = BS_STOP;
4872
            rn = "SRSMap";
4873
            break;
4874
        default:
4875
            goto die;
4876
        }
4877
        break;
4878
    case 13:
4879
        switch (sel) {
4880
        case 0:
4881
            tcg_gen_helper_0_1(do_mtc0_cause, t0);
4882
            rn = "Cause";
4883
            break;
4884
        default:
4885
            goto die;
4886
        }
4887
        /* Stop translation as we may have switched the execution mode */
4888
        ctx->bstate = BS_STOP;
4889
        break;
4890
    case 14:
4891
        switch (sel) {
4892
        case 0:
4893
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4894
            rn = "EPC";
4895
            break;
4896
        default:
4897
            goto die;
4898
        }
4899
        break;
4900
    case 15:
4901
        switch (sel) {
4902
        case 0:
4903
            /* ignored */
4904
            rn = "PRid";
4905
            break;
4906
        case 1:
4907
            check_insn(env, ctx, ISA_MIPS32R2);
4908
            tcg_gen_helper_0_1(do_mtc0_ebase, t0);
4909
            rn = "EBase";
4910
            break;
4911
        default:
4912
            goto die;
4913
        }
4914
        break;
4915
    case 16:
4916
        switch (sel) {
4917
        case 0:
4918
            tcg_gen_helper_0_1(do_mtc0_config0, t0);
4919
            rn = "Config";
4920
            /* Stop translation as we may have switched the execution mode */
4921
            ctx->bstate = BS_STOP;
4922
            break;
4923
        case 1:
4924
            /* ignored */
4925
            rn = "Config1";
4926
            break;
4927
        case 2:
4928
            tcg_gen_helper_0_1(do_mtc0_config2, t0);
4929
            rn = "Config2";
4930
            /* Stop translation as we may have switched the execution mode */
4931
            ctx->bstate = BS_STOP;
4932
            break;
4933
        case 3:
4934
            /* ignored */
4935
            rn = "Config3";
4936
            break;
4937
        /* 6,7 are implementation dependent */
4938
        default:
4939
            rn = "Invalid config selector";
4940
            goto die;
4941
        }
4942
        break;
4943
    case 17:
4944
        switch (sel) {
4945
        case 0:
4946
            /* ignored */
4947
            rn = "LLAddr";
4948
            break;
4949
        default:
4950
            goto die;
4951
        }
4952
        break;
4953
    case 18:
4954
        switch (sel) {
4955
        case 0 ... 7:
4956
            tcg_gen_helper_0_1i(do_mtc0_watchlo, t0, sel);
4957
            rn = "WatchLo";
4958
            break;
4959
        default:
4960
            goto die;
4961
        }
4962
        break;
4963
    case 19:
4964
        switch (sel) {
4965
        case 0 ... 7:
4966
            tcg_gen_helper_0_1i(do_mtc0_watchhi, t0, sel);
4967
            rn = "WatchHi";
4968
            break;
4969
        default:
4970
            goto die;
4971
        }
4972
        break;
4973
    case 20:
4974
        switch (sel) {
4975
        case 0:
4976
            check_insn(env, ctx, ISA_MIPS3);
4977
            tcg_gen_helper_0_1(do_mtc0_xcontext, t0);
4978
            rn = "XContext";
4979
            break;
4980
        default:
4981
            goto die;
4982
        }
4983
        break;
4984
    case 21:
4985
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4986
        switch (sel) {
4987
        case 0:
4988
            tcg_gen_helper_0_1(do_mtc0_framemask, t0);
4989
            rn = "Framemask";
4990
            break;
4991
        default:
4992
            goto die;
4993
        }
4994
        break;
4995
    case 22:
4996
        /* ignored */
4997
        rn = "Diagnostic"; /* implementation dependent */
4998
        break;
4999
    case 23:
5000
        switch (sel) {
5001
        case 0:
5002
            tcg_gen_helper_0_1(do_mtc0_debug, t0); /* EJTAG support */
5003
            /* BS_STOP isn't good enough here, hflags may have changed. */
5004
            gen_save_pc(ctx->pc + 4);
5005
            ctx->bstate = BS_EXCP;
5006
            rn = "Debug";
5007
            break;
5008
        case 1:
5009
//            tcg_gen_helper_0_1(do_mtc0_tracecontrol, t0); /* PDtrace support */
5010
            /* Stop translation as we may have switched the execution mode */
5011
            ctx->bstate = BS_STOP;
5012
            rn = "TraceControl";
5013
//            break;
5014
        case 2:
5015
//            tcg_gen_helper_0_1(do_mtc0_tracecontrol2, t0); /* PDtrace support */
5016
            /* Stop translation as we may have switched the execution mode */
5017
            ctx->bstate = BS_STOP;
5018
            rn = "TraceControl2";
5019
//            break;
5020
        case 3:
5021
//            tcg_gen_helper_0_1(do_mtc0_usertracedata, t0); /* PDtrace support */
5022
            /* Stop translation as we may have switched the execution mode */
5023
            ctx->bstate = BS_STOP;
5024
            rn = "UserTraceData";
5025
//            break;
5026
        case 4:
5027
//            tcg_gen_helper_0_1(do_mtc0_tracebpc, t0); /* PDtrace support */
5028
            /* Stop translation as we may have switched the execution mode */
5029
            ctx->bstate = BS_STOP;
5030
            rn = "TraceBPC";
5031
//            break;
5032
        default:
5033
            goto die;
5034
        }
5035
        break;
5036
    case 24:
5037
        switch (sel) {
5038
        case 0:
5039
            /* EJTAG support */
5040
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
5041
            rn = "DEPC";
5042
            break;
5043
        default:
5044
            goto die;
5045
        }
5046
        break;
5047
    case 25:
5048
        switch (sel) {
5049
        case 0:
5050
            tcg_gen_helper_0_1(do_mtc0_performance0, t0);
5051
            rn = "Performance0";
5052
            break;
5053
        case 1:
5054
//            tcg_gen_helper_0_1(do_mtc0_performance1, t0);
5055
            rn = "Performance1";
5056
//            break;
5057
        case 2:
5058
//            tcg_gen_helper_0_1(do_mtc0_performance2, t0);
5059
            rn = "Performance2";
5060
//            break;
5061
        case 3:
5062
//            tcg_gen_helper_0_1(do_mtc0_performance3, t0);
5063
            rn = "Performance3";
5064
//            break;
5065
        case 4:
5066
//            tcg_gen_helper_0_1(do_mtc0_performance4, t0);
5067
            rn = "Performance4";
5068
//            break;
5069
        case 5:
5070
//            tcg_gen_helper_0_1(do_mtc0_performance5, t0);
5071
            rn = "Performance5";
5072
//            break;
5073
        case 6:
5074
//            tcg_gen_helper_0_1(do_mtc0_performance6, t0);
5075
            rn = "Performance6";
5076
//            break;
5077
        case 7:
5078
//            tcg_gen_helper_0_1(do_mtc0_performance7, t0);
5079
            rn = "Performance7";
5080
//            break;
5081
        default:
5082
            goto die;
5083
        }
5084
        break;
5085
    case 26:
5086
        /* ignored */
5087
        rn = "ECC";
5088
        break;
5089
    case 27:
5090
        switch (sel) {
5091
        case 0 ... 3:
5092
            /* ignored */
5093
            rn = "CacheErr";
5094
            break;
5095
        default:
5096
            goto die;
5097
        }
5098
        break;
5099
    case 28:
5100
        switch (sel) {
5101
        case 0:
5102
        case 2:
5103
        case 4:
5104
        case 6:
5105
            tcg_gen_helper_0_1(do_mtc0_taglo, t0);
5106
            rn = "TagLo";
5107
            break;
5108
        case 1:
5109
        case 3:
5110
        case 5:
5111
        case 7:
5112
            tcg_gen_helper_0_1(do_mtc0_datalo, t0);
5113
            rn = "DataLo";
5114
            break;
5115
        default:
5116
            goto die;
5117
        }
5118
        break;
5119
    case 29:
5120
        switch (sel) {
5121
        case 0:
5122
        case 2:
5123
        case 4:
5124
        case 6:
5125
            tcg_gen_helper_0_1(do_mtc0_taghi, t0);
5126
            rn = "TagHi";
5127
            break;
5128
        case 1:
5129
        case 3:
5130
        case 5:
5131
        case 7:
5132
            tcg_gen_helper_0_1(do_mtc0_datahi, t0);
5133
            rn = "DataHi";
5134
            break;
5135
        default:
5136
            rn = "invalid sel";
5137
            goto die;
5138
        }
5139
        break;
5140
    case 30:
5141
        switch (sel) {
5142
        case 0:
5143
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5144
            rn = "ErrorEPC";
5145
            break;
5146
        default:
5147
            goto die;
5148
        }
5149
        break;
5150
    case 31:
5151
        switch (sel) {
5152
        case 0:
5153
            /* EJTAG support */
5154
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
5155
            rn = "DESAVE";
5156
            break;
5157
        default:
5158
            goto die;
5159
        }
5160
        /* Stop translation as we may have switched the execution mode */
5161
        ctx->bstate = BS_STOP;
5162
        break;
5163
    default:
5164
        goto die;
5165
    }
5166
#if defined MIPS_DEBUG_DISAS
5167
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5168
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5169
                rn, reg, sel);
5170
    }
5171
#endif
5172
    tcg_temp_free(t0);
5173
    /* For simplicity assume that all writes can cause interrupts.  */
5174
    if (use_icount) {
5175
        gen_io_end();
5176
        ctx->bstate = BS_STOP;
5177
    }
5178
    return;
5179

    
5180
die:
5181
    tcg_temp_free(t0);
5182
#if defined MIPS_DEBUG_DISAS
5183
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5184
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5185
                rn, reg, sel);
5186
    }
5187
#endif
5188
    generate_exception(ctx, EXCP_RI);
5189
}
5190
#endif /* TARGET_MIPS64 */
5191

    
5192
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5193
                     int u, int sel, int h)
5194
{
5195
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5196
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5197

    
5198
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5199
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5200
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5201
        tcg_gen_movi_tl(t0, -1);
5202
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5203
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5204
        tcg_gen_movi_tl(t0, -1);
5205
    else if (u == 0) {
5206
        switch (rt) {
5207
        case 2:
5208
            switch (sel) {
5209
            case 1:
5210
                tcg_gen_helper_1_1(do_mftc0_tcstatus, t0, t0);
5211
                break;
5212
            case 2:
5213
                tcg_gen_helper_1_1(do_mftc0_tcbind, t0, t0);
5214
                break;
5215
            case 3:
5216
                tcg_gen_helper_1_1(do_mftc0_tcrestart, t0, t0);
5217
                break;
5218
            case 4:
5219
                tcg_gen_helper_1_1(do_mftc0_tchalt, t0, t0);
5220
                break;
5221
            case 5:
5222
                tcg_gen_helper_1_1(do_mftc0_tccontext, t0, t0);
5223
                break;
5224
            case 6:
5225
                tcg_gen_helper_1_1(do_mftc0_tcschedule, t0, t0);
5226
                break;
5227
            case 7:
5228
                tcg_gen_helper_1_1(do_mftc0_tcschefback, t0, t0);
5229
                break;
5230
            default:
5231
                gen_mfc0(env, ctx, t0, rt, sel);
5232
                break;
5233
            }
5234
            break;
5235
        case 10:
5236
            switch (sel) {
5237
            case 0:
5238
                tcg_gen_helper_1_1(do_mftc0_entryhi, t0, t0);
5239
                break;
5240
            default:
5241
                gen_mfc0(env, ctx, t0, rt, sel);
5242
                break;
5243
            }
5244
        case 12:
5245
            switch (sel) {
5246
            case 0:
5247
                tcg_gen_helper_1_1(do_mftc0_status, t0, t0);
5248
                break;
5249
            default:
5250
                gen_mfc0(env, ctx, t0, rt, sel);
5251
                break;
5252
            }
5253
        case 23:
5254
            switch (sel) {
5255
            case 0:
5256
                tcg_gen_helper_1_1(do_mftc0_debug, t0, t0);
5257
                break;
5258
            default:
5259
                gen_mfc0(env, ctx, t0, rt, sel);
5260
                break;
5261
            }
5262
            break;
5263
        default:
5264
            gen_mfc0(env, ctx, t0, rt, sel);
5265
        }
5266
    } else switch (sel) {
5267
    /* GPR registers. */
5268
    case 0:
5269
        tcg_gen_helper_1_1i(do_mftgpr, t0, t0, rt);
5270
        break;
5271
    /* Auxiliary CPU registers */
5272
    case 1:
5273
        switch (rt) {
5274
        case 0:
5275
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 0);
5276
            break;
5277
        case 1:
5278
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 0);
5279
            break;
5280
        case 2:
5281
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 0);
5282
            break;
5283
        case 4:
5284
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 1);
5285
            break;
5286
        case 5:
5287
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 1);
5288
            break;
5289
        case 6:
5290
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 1);
5291
            break;
5292
        case 8:
5293
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 2);
5294
            break;
5295
        case 9:
5296
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 2);
5297
            break;
5298
        case 10:
5299
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 2);
5300
            break;
5301
        case 12:
5302
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 3);
5303
            break;
5304
        case 13:
5305
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 3);
5306
            break;
5307
        case 14:
5308
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 3);
5309
            break;
5310
        case 16:
5311
            tcg_gen_helper_1_1(do_mftdsp, t0, t0);
5312
            break;
5313
        default:
5314
            goto die;
5315
        }
5316
        break;
5317
    /* Floating point (COP1). */
5318
    case 2:
5319
        /* XXX: For now we support only a single FPU context. */
5320
        if (h == 0) {
5321
            gen_load_fpr32(fpu32_T[0], rt);
5322
            tcg_gen_ext_i32_tl(t0, fpu32_T[0]);
5323
        } else {
5324
            gen_load_fpr32h(fpu32h_T[0], rt);
5325
            tcg_gen_ext_i32_tl(t0, fpu32h_T[0]);
5326
        }
5327
        break;
5328
    case 3:
5329
        /* XXX: For now we support only a single FPU context. */
5330
        tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt);
5331
        break;
5332
    /* COP2: Not implemented. */
5333
    case 4:
5334
    case 5:
5335
        /* fall through */
5336
    default:
5337
        goto die;
5338
    }
5339
#if defined MIPS_DEBUG_DISAS
5340
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5341
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5342
                rt, u, sel, h);
5343
    }
5344
#endif
5345
    gen_store_gpr(t0, rd);
5346
    tcg_temp_free(t0);
5347
    return;
5348

    
5349
die:
5350
    tcg_temp_free(t0);
5351
#if defined MIPS_DEBUG_DISAS
5352
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5353
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5354
                rt, u, sel, h);
5355
    }
5356
#endif
5357
    generate_exception(ctx, EXCP_RI);
5358
}
5359

    
5360
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5361
                     int u, int sel, int h)
5362
{
5363
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5364
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5365

    
5366
    gen_load_gpr(t0, rt);
5367
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5368
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5369
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5370
        /* NOP */ ;
5371
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5372
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5373
        /* NOP */ ;
5374
    else if (u == 0) {
5375
        switch (rd) {
5376
        case 2:
5377
            switch (sel) {
5378
            case 1:
5379
                tcg_gen_helper_0_1(do_mttc0_tcstatus, t0);
5380
                break;
5381
            case 2:
5382
                tcg_gen_helper_0_1(do_mttc0_tcbind, t0);
5383
                break;
5384
            case 3:
5385
                tcg_gen_helper_0_1(do_mttc0_tcrestart, t0);
5386
                break;
5387
            case 4:
5388
                tcg_gen_helper_0_1(do_mttc0_tchalt, t0);
5389
                break;
5390
            case 5:
5391
                tcg_gen_helper_0_1(do_mttc0_tccontext, t0);
5392
                break;
5393
            case 6:
5394
                tcg_gen_helper_0_1(do_mttc0_tcschedule, t0);
5395
                break;
5396
            case 7:
5397
                tcg_gen_helper_0_1(do_mttc0_tcschefback, t0);
5398
                break;
5399
            default:
5400
                gen_mtc0(env, ctx, t0, rd, sel);
5401
                break;
5402
            }
5403
            break;
5404
        case 10:
5405
            switch (sel) {
5406
            case 0:
5407
                tcg_gen_helper_0_1(do_mttc0_entryhi, t0);
5408
                break;
5409
            default:
5410
                gen_mtc0(env, ctx, t0, rd, sel);
5411
                break;
5412
            }
5413
        case 12:
5414
            switch (sel) {
5415
            case 0:
5416
                tcg_gen_helper_0_1(do_mttc0_status, t0);
5417
                break;
5418
            default:
5419
                gen_mtc0(env, ctx, t0, rd, sel);
5420
                break;
5421
            }
5422
        case 23:
5423
            switch (sel) {
5424
            case 0:
5425
                tcg_gen_helper_0_1(do_mttc0_debug, t0);
5426
                break;
5427
            default:
5428
                gen_mtc0(env, ctx, t0, rd, sel);
5429
                break;
5430
            }
5431
            break;
5432
        default:
5433
            gen_mtc0(env, ctx, t0, rd, sel);
5434
        }
5435
    } else switch (sel) {
5436
    /* GPR registers. */
5437
    case 0:
5438
        tcg_gen_helper_0_1i(do_mttgpr, t0, rd);
5439
        break;
5440
    /* Auxiliary CPU registers */
5441
    case 1:
5442
        switch (rd) {
5443
        case 0:
5444
            tcg_gen_helper_0_1i(do_mttlo, t0, 0);
5445
            break;
5446
        case 1:
5447
            tcg_gen_helper_0_1i(do_mtthi, t0, 0);
5448
            break;
5449
        case 2:
5450
            tcg_gen_helper_0_1i(do_mttacx, t0, 0);
5451
            break;
5452
        case 4:
5453
            tcg_gen_helper_0_1i(do_mttlo, t0, 1);
5454
            break;
5455
        case 5:
5456
            tcg_gen_helper_0_1i(do_mtthi, t0, 1);
5457
            break;
5458
        case 6:
5459
            tcg_gen_helper_0_1i(do_mttacx, t0, 1);
5460
            break;
5461
        case 8:
5462
            tcg_gen_helper_0_1i(do_mttlo, t0, 2);
5463
            break;
5464
        case 9:
5465
            tcg_gen_helper_0_1i(do_mtthi, t0, 2);
5466
            break;
5467
        case 10:
5468
            tcg_gen_helper_0_1i(do_mttacx, t0, 2);
5469
            break;
5470
        case 12:
5471
            tcg_gen_helper_0_1i(do_mttlo, t0, 3);
5472
            break;
5473
        case 13:
5474
            tcg_gen_helper_0_1i(do_mtthi, t0, 3);
5475
            break;
5476
        case 14:
5477
            tcg_gen_helper_0_1i(do_mttacx, t0, 3);
5478
            break;
5479
        case 16:
5480
            tcg_gen_helper_0_1(do_mttdsp, t0);
5481
            break;
5482
        default:
5483
            goto die;
5484
        }
5485
        break;
5486
    /* Floating point (COP1). */
5487
    case 2:
5488
        /* XXX: For now we support only a single FPU context. */
5489
        if (h == 0) {
5490
            tcg_gen_trunc_tl_i32(fpu32_T[0], t0);
5491
            gen_store_fpr32(fpu32_T[0], rd);
5492
        } else {
5493
            tcg_gen_trunc_tl_i32(fpu32h_T[0], t0);
5494
            gen_store_fpr32h(fpu32h_T[0], rd);
5495
        }
5496
        break;
5497
    case 3:
5498
        /* XXX: For now we support only a single FPU context. */
5499
        tcg_gen_helper_0_1i(do_ctc1, t0, rd);
5500
        break;
5501
    /* COP2: Not implemented. */
5502
    case 4:
5503
    case 5:
5504
        /* fall through */
5505
    default:
5506
        goto die;
5507
    }
5508
#if defined MIPS_DEBUG_DISAS
5509
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5510
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5511
                rd, u, sel, h);
5512
    }
5513
#endif
5514
    tcg_temp_free(t0);
5515
    return;
5516

    
5517
die:
5518
    tcg_temp_free(t0);
5519
#if defined MIPS_DEBUG_DISAS
5520
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5521
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5522
                rd, u, sel, h);
5523
    }
5524
#endif
5525
    generate_exception(ctx, EXCP_RI);
5526
}
5527

    
5528
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5529
{
5530
    const char *opn = "ldst";
5531

    
5532
    switch (opc) {
5533
    case OPC_MFC0:
5534
        if (rt == 0) {
5535
            /* Treat as NOP. */
5536
            return;
5537
        }
5538
        {
5539
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5540

    
5541
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5542
            gen_store_gpr(t0, rt);
5543
            tcg_temp_free(t0);
5544
        }
5545
        opn = "mfc0";
5546
        break;
5547
    case OPC_MTC0:
5548
        {
5549
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5550

    
5551
            gen_load_gpr(t0, rt);
5552
            save_cpu_state(ctx, 1);
5553
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5554
            tcg_temp_free(t0);
5555
        }
5556
        opn = "mtc0";
5557
        break;
5558
#if defined(TARGET_MIPS64)
5559
    case OPC_DMFC0:
5560
        check_insn(env, ctx, ISA_MIPS3);
5561
        if (rt == 0) {
5562
            /* Treat as NOP. */
5563
            return;
5564
        }
5565
        {
5566
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5567

    
5568
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5569
            gen_store_gpr(t0, rt);
5570
            tcg_temp_free(t0);
5571
        }
5572
        opn = "dmfc0";
5573
        break;
5574
    case OPC_DMTC0:
5575
        check_insn(env, ctx, ISA_MIPS3);
5576
        {
5577
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5578

    
5579
            gen_load_gpr(t0, rt);
5580
            save_cpu_state(ctx, 1);
5581
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5582
            tcg_temp_free(t0);
5583
        }
5584
        opn = "dmtc0";
5585
        break;
5586
#endif
5587
    case OPC_MFTR:
5588
        check_insn(env, ctx, ASE_MT);
5589
        if (rd == 0) {
5590
            /* Treat as NOP. */
5591
            return;
5592
        }
5593
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5594
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5595
        opn = "mftr";
5596
        break;
5597
    case OPC_MTTR:
5598
        check_insn(env, ctx, ASE_MT);
5599
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5600
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5601
        opn = "mttr";
5602
        break;
5603
    case OPC_TLBWI:
5604
        opn = "tlbwi";
5605
        if (!env->tlb->do_tlbwi)
5606
            goto die;
5607
        tcg_gen_helper_0_0(env->tlb->do_tlbwi);
5608
        break;
5609
    case OPC_TLBWR:
5610
        opn = "tlbwr";
5611
        if (!env->tlb->do_tlbwr)
5612
            goto die;
5613
        tcg_gen_helper_0_0(env->tlb->do_tlbwr);
5614
        break;
5615
    case OPC_TLBP:
5616
        opn = "tlbp";
5617
        if (!env->tlb->do_tlbp)
5618
            goto die;
5619
        tcg_gen_helper_0_0(env->tlb->do_tlbp);
5620
        break;
5621
    case OPC_TLBR:
5622
        opn = "tlbr";
5623
        if (!env->tlb->do_tlbr)
5624
            goto die;
5625
        tcg_gen_helper_0_0(env->tlb->do_tlbr);
5626
        break;
5627
    case OPC_ERET:
5628
        opn = "eret";
5629
        check_insn(env, ctx, ISA_MIPS2);
5630
        save_cpu_state(ctx, 1);
5631
        tcg_gen_helper_0_0(do_eret);
5632
        ctx->bstate = BS_EXCP;
5633
        break;
5634
    case OPC_DERET:
5635
        opn = "deret";
5636
        check_insn(env, ctx, ISA_MIPS32);
5637
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5638
            MIPS_INVAL(opn);
5639
            generate_exception(ctx, EXCP_RI);
5640
        } else {
5641
            save_cpu_state(ctx, 1);
5642
            tcg_gen_helper_0_0(do_deret);
5643
            ctx->bstate = BS_EXCP;
5644
        }
5645
        break;
5646
    case OPC_WAIT:
5647
        opn = "wait";
5648
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5649
        /* If we get an exception, we want to restart at next instruction */
5650
        ctx->pc += 4;
5651
        save_cpu_state(ctx, 1);
5652
        ctx->pc -= 4;
5653
        tcg_gen_helper_0_0(do_wait);
5654
        ctx->bstate = BS_EXCP;
5655
        break;
5656
    default:
5657
 die:
5658
        MIPS_INVAL(opn);
5659
        generate_exception(ctx, EXCP_RI);
5660
        return;
5661
    }
5662
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5663
}
5664
#endif /* !CONFIG_USER_ONLY */
5665

    
5666
/* CP1 Branches (before delay slot) */
5667
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5668
                                 int32_t cc, int32_t offset)
5669
{
5670
    target_ulong btarget;
5671
    const char *opn = "cp1 cond branch";
5672
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5673
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5674

    
5675
    if (cc != 0)
5676
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5677

    
5678
    btarget = ctx->pc + 4 + offset;
5679

    
5680
    switch (op) {
5681
    case OPC_BC1F:
5682
        {
5683
            int l1 = gen_new_label();
5684
            int l2 = gen_new_label();
5685
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5686

    
5687
            get_fp_cond(r_tmp1);
5688
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5689
            tcg_temp_free(r_tmp1);
5690
            tcg_gen_not_tl(t0, t0);
5691
            tcg_gen_movi_tl(t1, 0x1 << cc);
5692
            tcg_gen_and_tl(t0, t0, t1);
5693
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5694
            tcg_gen_movi_tl(t0, 0);
5695
            tcg_gen_br(l2);
5696
            gen_set_label(l1);
5697
            tcg_gen_movi_tl(t0, 1);
5698
            gen_set_label(l2);
5699
        }
5700
        opn = "bc1f";
5701
        goto not_likely;
5702
    case OPC_BC1FL:
5703
        {
5704
            int l1 = gen_new_label();
5705
            int l2 = gen_new_label();
5706
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5707

    
5708
            get_fp_cond(r_tmp1);
5709
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5710
            tcg_temp_free(r_tmp1);
5711
            tcg_gen_not_tl(t0, t0);
5712
            tcg_gen_movi_tl(t1, 0x1 << cc);
5713
            tcg_gen_and_tl(t0, t0, t1);
5714
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5715
            tcg_gen_movi_tl(t0, 0);
5716
            tcg_gen_br(l2);
5717
            gen_set_label(l1);
5718
            tcg_gen_movi_tl(t0, 1);
5719
            gen_set_label(l2);
5720
        }
5721
        opn = "bc1fl";
5722
        goto likely;
5723
    case OPC_BC1T:
5724
        {
5725
            int l1 = gen_new_label();
5726
            int l2 = gen_new_label();
5727
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5728

    
5729
            get_fp_cond(r_tmp1);
5730
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5731
            tcg_temp_free(r_tmp1);
5732
            tcg_gen_movi_tl(t1, 0x1 << cc);
5733
            tcg_gen_and_tl(t0, t0, t1);
5734
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5735
            tcg_gen_movi_tl(t0, 0);
5736
            tcg_gen_br(l2);
5737
            gen_set_label(l1);
5738
            tcg_gen_movi_tl(t0, 1);
5739
            gen_set_label(l2);
5740
        }
5741
        opn = "bc1t";
5742
        goto not_likely;
5743
    case OPC_BC1TL:
5744
        {
5745
            int l1 = gen_new_label();
5746
            int l2 = gen_new_label();
5747
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5748

    
5749
            get_fp_cond(r_tmp1);
5750
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5751
            tcg_temp_free(r_tmp1);
5752
            tcg_gen_movi_tl(t1, 0x1 << cc);
5753
            tcg_gen_and_tl(t0, t0, t1);
5754
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5755
            tcg_gen_movi_tl(t0, 0);
5756
            tcg_gen_br(l2);
5757
            gen_set_label(l1);
5758
            tcg_gen_movi_tl(t0, 1);
5759
            gen_set_label(l2);
5760
        }
5761
        opn = "bc1tl";
5762
    likely:
5763
        ctx->hflags |= MIPS_HFLAG_BL;
5764
        tcg_gen_trunc_tl_i32(bcond, t0);
5765
        break;
5766
    case OPC_BC1FANY2:
5767
        {
5768
            int l1 = gen_new_label();
5769
            int l2 = gen_new_label();
5770
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5771

    
5772
            get_fp_cond(r_tmp1);
5773
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5774
            tcg_temp_free(r_tmp1);
5775
            tcg_gen_not_tl(t0, t0);
5776
            tcg_gen_movi_tl(t1, 0x3 << cc);
5777
            tcg_gen_and_tl(t0, t0, t1);
5778
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5779
            tcg_gen_movi_tl(t0, 0);
5780
            tcg_gen_br(l2);
5781
            gen_set_label(l1);
5782
            tcg_gen_movi_tl(t0, 1);
5783
            gen_set_label(l2);
5784
        }
5785
        opn = "bc1any2f";
5786
        goto not_likely;
5787
    case OPC_BC1TANY2:
5788
        {
5789
            int l1 = gen_new_label();
5790
            int l2 = gen_new_label();
5791
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5792

    
5793
            get_fp_cond(r_tmp1);
5794
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5795
            tcg_temp_free(r_tmp1);
5796
            tcg_gen_movi_tl(t1, 0x3 << cc);
5797
            tcg_gen_and_tl(t0, t0, t1);
5798
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5799
            tcg_gen_movi_tl(t0, 0);
5800
            tcg_gen_br(l2);
5801
            gen_set_label(l1);
5802
            tcg_gen_movi_tl(t0, 1);
5803
            gen_set_label(l2);
5804
        }
5805
        opn = "bc1any2t";
5806
        goto not_likely;
5807
    case OPC_BC1FANY4:
5808
        {
5809
            int l1 = gen_new_label();
5810
            int l2 = gen_new_label();
5811
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5812

    
5813
            get_fp_cond(r_tmp1);
5814
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5815
            tcg_temp_free(r_tmp1);
5816
            tcg_gen_not_tl(t0, t0);
5817
            tcg_gen_movi_tl(t1, 0xf << cc);
5818
            tcg_gen_and_tl(t0, t0, t1);
5819
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5820
            tcg_gen_movi_tl(t0, 0);
5821
            tcg_gen_br(l2);
5822
            gen_set_label(l1);
5823
            tcg_gen_movi_tl(t0, 1);
5824
            gen_set_label(l2);
5825
        }
5826
        opn = "bc1any4f";
5827
        goto not_likely;
5828
    case OPC_BC1TANY4:
5829
        {
5830
            int l1 = gen_new_label();
5831
            int l2 = gen_new_label();
5832
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5833

    
5834
            get_fp_cond(r_tmp1);
5835
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5836
            tcg_temp_free(r_tmp1);
5837
            tcg_gen_movi_tl(t1, 0xf << cc);
5838
            tcg_gen_and_tl(t0, t0, t1);
5839
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5840
            tcg_gen_movi_tl(t0, 0);
5841
            tcg_gen_br(l2);
5842
            gen_set_label(l1);
5843
            tcg_gen_movi_tl(t0, 1);
5844
            gen_set_label(l2);
5845
        }
5846
        opn = "bc1any4t";
5847
    not_likely:
5848
        ctx->hflags |= MIPS_HFLAG_BC;
5849
        tcg_gen_trunc_tl_i32(bcond, t0);
5850
        break;
5851
    default:
5852
        MIPS_INVAL(opn);
5853
        generate_exception (ctx, EXCP_RI);
5854
        goto out;
5855
    }
5856
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5857
               ctx->hflags, btarget);
5858
    ctx->btarget = btarget;
5859

    
5860
 out:
5861
    tcg_temp_free(t0);
5862
    tcg_temp_free(t1);
5863
}
5864

    
5865
/* Coprocessor 1 (FPU) */
5866

    
5867
#define FOP(func, fmt) (((fmt) << 21) | (func))
5868

    
5869
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5870
{
5871
    const char *opn = "cp1 move";
5872
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5873

    
5874
    switch (opc) {
5875
    case OPC_MFC1:
5876
        gen_load_fpr32(fpu32_T[0], fs);
5877
        tcg_gen_ext_i32_tl(t0, fpu32_T[0]);
5878
        gen_store_gpr(t0, rt);
5879
        opn = "mfc1";
5880
        break;
5881
    case OPC_MTC1:
5882
        gen_load_gpr(t0, rt);
5883
        tcg_gen_trunc_tl_i32(fpu32_T[0], t0);
5884
        gen_store_fpr32(fpu32_T[0], fs);
5885
        opn = "mtc1";
5886
        break;
5887
    case OPC_CFC1:
5888
        tcg_gen_helper_1_i(do_cfc1, t0, fs);
5889
        gen_store_gpr(t0, rt);
5890
        opn = "cfc1";
5891
        break;
5892
    case OPC_CTC1:
5893
        gen_load_gpr(t0, rt);
5894
        tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5895
        opn = "ctc1";
5896
        break;
5897
    case OPC_DMFC1:
5898
        gen_load_fpr64(ctx, fpu64_T[0], fs);
5899
        tcg_gen_mov_tl(t0, fpu64_T[0]);
5900
        gen_store_gpr(t0, rt);
5901
        opn = "dmfc1";
5902
        break;
5903
    case OPC_DMTC1:
5904
        gen_load_gpr(t0, rt);
5905
        tcg_gen_mov_tl(fpu64_T[0], t0);
5906
        gen_store_fpr64(ctx, fpu64_T[0], fs);
5907
        opn = "dmtc1";
5908
        break;
5909
    case OPC_MFHC1:
5910
        gen_load_fpr32h(fpu32h_T[0], fs);
5911
        tcg_gen_ext_i32_tl(t0, fpu32h_T[0]);
5912
        gen_store_gpr(t0, rt);
5913
        opn = "mfhc1";
5914
        break;
5915
    case OPC_MTHC1:
5916
        gen_load_gpr(t0, rt);
5917
        tcg_gen_trunc_tl_i32(fpu32h_T[0], t0);
5918
        gen_store_fpr32h(fpu32h_T[0], fs);
5919
        opn = "mthc1";
5920
        break;
5921
    default:
5922
        MIPS_INVAL(opn);
5923
        generate_exception (ctx, EXCP_RI);
5924
        goto out;
5925
    }
5926
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5927

    
5928
 out:
5929
    tcg_temp_free(t0);
5930
}
5931

    
5932
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5933
{
5934
    int l1 = gen_new_label();
5935
    uint32_t ccbit;
5936
    TCGCond cond;
5937
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5938
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5939

    
5940
    if (cc)
5941
        ccbit = 1 << (24 + cc);
5942
    else
5943
        ccbit = 1 << 23;
5944
    if (tf)
5945
        cond = TCG_COND_EQ;
5946
    else
5947
        cond = TCG_COND_NE;
5948

    
5949
    gen_load_gpr(t0, rd);
5950
    gen_load_gpr(t1, rs);
5951
    {
5952
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5953
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
5954

    
5955
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5956
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5957
        tcg_temp_free(r_ptr);
5958
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5959
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5960
        tcg_temp_free(r_tmp);
5961
    }
5962
    tcg_gen_mov_tl(t0, t1);
5963
    tcg_temp_free(t1);
5964

    
5965
    gen_set_label(l1);
5966
    gen_store_gpr(t0, rd);
5967
    tcg_temp_free(t0);
5968
}
5969

    
5970
static inline void gen_movcf_s (int cc, int tf)
5971
{
5972
    uint32_t ccbit;
5973
    int cond;
5974
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5975
    int l1 = gen_new_label();
5976

    
5977
    if (cc)
5978
        ccbit = 1 << (24 + cc);
5979
    else
5980
        ccbit = 1 << 23;
5981

    
5982
    if (tf)
5983
        cond = TCG_COND_EQ;
5984
    else
5985
        cond = TCG_COND_NE;
5986

    
5987
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
5988
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
5989
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5990
    tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]);
5991
    gen_set_label(l1);
5992
    tcg_temp_free(r_tmp1);
5993
}
5994

    
5995
static inline void gen_movcf_d (int cc, int tf)
5996
{
5997
    uint32_t ccbit;
5998
    int cond;
5999
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
6000
    int l1 = gen_new_label();
6001

    
6002
    if (cc)
6003
        ccbit = 1 << (24 + cc);
6004
    else
6005
        ccbit = 1 << 23;
6006

    
6007
    if (tf)
6008
        cond = TCG_COND_EQ;
6009
    else
6010
        cond = TCG_COND_NE;
6011

    
6012
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6013
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6014
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6015
    tcg_gen_movi_i64(fpu64_T[2], fpu64_T[0]);
6016
    gen_set_label(l1);
6017
    tcg_temp_free(r_tmp1);
6018
}
6019

    
6020
static inline void gen_movcf_ps (int cc, int tf)
6021
{
6022
    int cond;
6023
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6024
    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);
6025
    int l1 = gen_new_label();
6026
    int l2 = gen_new_label();
6027

    
6028
    if (tf)
6029
        cond = TCG_COND_EQ;
6030
    else
6031
        cond = TCG_COND_NE;
6032

    
6033
    get_fp_cond(r_tmp1);
6034
    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);
6035
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);
6036
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);
6037
    tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]);
6038
    gen_set_label(l1);
6039
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);
6040
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);
6041
    tcg_gen_movi_i32(fpu32h_T[2], fpu32h_T[0]);
6042
    gen_set_label(l2);
6043
    tcg_temp_free(r_tmp1);
6044
    tcg_temp_free(r_tmp2);
6045
}
6046

    
6047

    
6048
static void gen_farith (DisasContext *ctx, uint32_t op1,
6049
                        int ft, int fs, int fd, int cc)
6050
{
6051
    const char *opn = "farith";
6052
    const char *condnames[] = {
6053
            "c.f",
6054
            "c.un",
6055
            "c.eq",
6056
            "c.ueq",
6057
            "c.olt",
6058
            "c.ult",
6059
            "c.ole",
6060
            "c.ule",
6061
            "c.sf",
6062
            "c.ngle",
6063
            "c.seq",
6064
            "c.ngl",
6065
            "c.lt",
6066
            "c.nge",
6067
            "c.le",
6068
            "c.ngt",
6069
    };
6070
    const char *condnames_abs[] = {
6071
            "cabs.f",
6072
            "cabs.un",
6073
            "cabs.eq",
6074
            "cabs.ueq",
6075
            "cabs.olt",
6076
            "cabs.ult",
6077
            "cabs.ole",
6078
            "cabs.ule",
6079
            "cabs.sf",
6080
            "cabs.ngle",
6081
            "cabs.seq",
6082
            "cabs.ngl",
6083
            "cabs.lt",
6084
            "cabs.nge",
6085
            "cabs.le",
6086
            "cabs.ngt",
6087
    };
6088
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6089
    uint32_t func = ctx->opcode & 0x3f;
6090

    
6091
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6092
    case FOP(0, 16):
6093
        gen_load_fpr32(fpu32_T[0], fs);
6094
        gen_load_fpr32(fpu32_T[1], ft);
6095
        tcg_gen_helper_0_0(do_float_add_s);
6096
        gen_store_fpr32(fpu32_T[2], fd);
6097
        opn = "add.s";
6098
        optype = BINOP;
6099
        break;
6100
    case FOP(1, 16):
6101
        gen_load_fpr32(fpu32_T[0], fs);
6102
        gen_load_fpr32(fpu32_T[1], ft);
6103
        tcg_gen_helper_0_0(do_float_sub_s);
6104
        gen_store_fpr32(fpu32_T[2], fd);
6105
        opn = "sub.s";
6106
        optype = BINOP;
6107
        break;
6108
    case FOP(2, 16):
6109
        gen_load_fpr32(fpu32_T[0], fs);
6110
        gen_load_fpr32(fpu32_T[1], ft);
6111
        tcg_gen_helper_0_0(do_float_mul_s);
6112
        gen_store_fpr32(fpu32_T[2], fd);
6113
        opn = "mul.s";
6114
        optype = BINOP;
6115
        break;
6116
    case FOP(3, 16):
6117
        gen_load_fpr32(fpu32_T[0], fs);
6118
        gen_load_fpr32(fpu32_T[1], ft);
6119
        tcg_gen_helper_0_0(do_float_div_s);
6120
        gen_store_fpr32(fpu32_T[2], fd);
6121
        opn = "div.s";
6122
        optype = BINOP;
6123
        break;
6124
    case FOP(4, 16):
6125
        gen_load_fpr32(fpu32_T[0], fs);
6126
        tcg_gen_helper_0_0(do_float_sqrt_s);
6127
        gen_store_fpr32(fpu32_T[2], fd);
6128
        opn = "sqrt.s";
6129
        break;
6130
    case FOP(5, 16):
6131
        gen_load_fpr32(fpu32_T[0], fs);
6132
        tcg_gen_helper_0_0(do_float_abs_s);
6133
        gen_store_fpr32(fpu32_T[2], fd);
6134
        opn = "abs.s";
6135
        break;
6136
    case FOP(6, 16):
6137
        gen_load_fpr32(fpu32_T[0], fs);
6138
        gen_store_fpr32(fpu32_T[0], fd);
6139
        opn = "mov.s";
6140
        break;
6141
    case FOP(7, 16):
6142
        gen_load_fpr32(fpu32_T[0], fs);
6143
        tcg_gen_helper_0_0(do_float_chs_s);
6144
        gen_store_fpr32(fpu32_T[2], fd);
6145
        opn = "neg.s";
6146
        break;
6147
    case FOP(8, 16):
6148
        check_cp1_64bitmode(ctx);
6149
        gen_load_fpr32(fpu32_T[0], fs);
6150
        tcg_gen_helper_0_0(do_float_roundl_s);
6151
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6152
        opn = "round.l.s";
6153
        break;
6154
    case FOP(9, 16):
6155
        check_cp1_64bitmode(ctx);
6156
        gen_load_fpr32(fpu32_T[0], fs);
6157
        tcg_gen_helper_0_0(do_float_truncl_s);
6158
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6159
        opn = "trunc.l.s";
6160
        break;
6161
    case FOP(10, 16):
6162
        check_cp1_64bitmode(ctx);
6163
        gen_load_fpr32(fpu32_T[0], fs);
6164
        tcg_gen_helper_0_0(do_float_ceill_s);
6165
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6166
        opn = "ceil.l.s";
6167
        break;
6168
    case FOP(11, 16):
6169
        check_cp1_64bitmode(ctx);
6170
        gen_load_fpr32(fpu32_T[0], fs);
6171
        tcg_gen_helper_0_0(do_float_floorl_s);
6172
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6173
        opn = "floor.l.s";
6174
        break;
6175
    case FOP(12, 16):
6176
        gen_load_fpr32(fpu32_T[0], fs);
6177
        tcg_gen_helper_0_0(do_float_roundw_s);
6178
        gen_store_fpr32(fpu32_T[2], fd);
6179
        opn = "round.w.s";
6180
        break;
6181
    case FOP(13, 16):
6182
        gen_load_fpr32(fpu32_T[0], fs);
6183
        tcg_gen_helper_0_0(do_float_truncw_s);
6184
        gen_store_fpr32(fpu32_T[2], fd);
6185
        opn = "trunc.w.s";
6186
        break;
6187
    case FOP(14, 16):
6188
        gen_load_fpr32(fpu32_T[0], fs);
6189
        tcg_gen_helper_0_0(do_float_ceilw_s);
6190
        gen_store_fpr32(fpu32_T[2], fd);
6191
        opn = "ceil.w.s";
6192
        break;
6193
    case FOP(15, 16):
6194
        gen_load_fpr32(fpu32_T[0], fs);
6195
        tcg_gen_helper_0_0(do_float_floorw_s);
6196
        gen_store_fpr32(fpu32_T[2], fd);
6197
        opn = "floor.w.s";
6198
        break;
6199
    case FOP(17, 16):
6200
        gen_load_fpr32(fpu32_T[0], fs);
6201
        gen_load_fpr32(fpu32_T[2], fd);
6202
        gen_movcf_s((ft >> 2) & 0x7, ft & 0x1);
6203
        gen_store_fpr32(fpu32_T[2], fd);
6204
        opn = "movcf.s";
6205
        break;
6206
    case FOP(18, 16):
6207
        gen_load_fpr32(fpu32_T[0], fs);
6208
        gen_load_fpr32(fpu32_T[2], fd);
6209
        {
6210
            int l1 = gen_new_label();
6211
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6212

    
6213
            gen_load_gpr(t0, ft);
6214
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6215
            tcg_temp_free(t0);
6216
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
6217
            gen_set_label(l1);
6218
        }
6219
        gen_store_fpr32(fpu32_T[2], fd);
6220
        opn = "movz.s";
6221
        break;
6222
    case FOP(19, 16):
6223
        gen_load_fpr32(fpu32_T[0], fs);
6224
        gen_load_fpr32(fpu32_T[2], fd);
6225
        {
6226
            int l1 = gen_new_label();
6227
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6228

    
6229
            gen_load_gpr(t0, ft);
6230
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6231
            tcg_temp_free(t0);
6232
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
6233
            gen_set_label(l1);
6234
        }
6235
        gen_store_fpr32(fpu32_T[2], fd);
6236
        opn = "movn.s";
6237
        break;
6238
    case FOP(21, 16):
6239
        check_cop1x(ctx);
6240
        gen_load_fpr32(fpu32_T[0], fs);
6241
        tcg_gen_helper_0_0(do_float_recip_s);
6242
        gen_store_fpr32(fpu32_T[2], fd);
6243
        opn = "recip.s";
6244
        break;
6245
    case FOP(22, 16):
6246
        check_cop1x(ctx);
6247
        gen_load_fpr32(fpu32_T[0], fs);
6248
        tcg_gen_helper_0_0(do_float_rsqrt_s);
6249
        gen_store_fpr32(fpu32_T[2], fd);
6250
        opn = "rsqrt.s";
6251
        break;
6252
    case FOP(28, 16):
6253
        check_cp1_64bitmode(ctx);
6254
        gen_load_fpr32(fpu32_T[0], fs);
6255
        gen_load_fpr32(fpu32_T[2], fd);
6256
        tcg_gen_helper_0_0(do_float_recip2_s);
6257
        gen_store_fpr32(fpu32_T[2], fd);
6258
        opn = "recip2.s";
6259
        break;
6260
    case FOP(29, 16):
6261
        check_cp1_64bitmode(ctx);
6262
        gen_load_fpr32(fpu32_T[0], fs);
6263
        tcg_gen_helper_0_0(do_float_recip1_s);
6264
        gen_store_fpr32(fpu32_T[2], fd);
6265
        opn = "recip1.s";
6266
        break;
6267
    case FOP(30, 16):
6268
        check_cp1_64bitmode(ctx);
6269
        gen_load_fpr32(fpu32_T[0], fs);
6270
        tcg_gen_helper_0_0(do_float_rsqrt1_s);
6271
        gen_store_fpr32(fpu32_T[2], fd);
6272
        opn = "rsqrt1.s";
6273
        break;
6274
    case FOP(31, 16):
6275
        check_cp1_64bitmode(ctx);
6276
        gen_load_fpr32(fpu32_T[0], fs);
6277
        gen_load_fpr32(fpu32_T[2], ft);
6278
        tcg_gen_helper_0_0(do_float_rsqrt2_s);
6279
        gen_store_fpr32(fpu32_T[2], fd);
6280
        opn = "rsqrt2.s";
6281
        break;
6282
    case FOP(33, 16):
6283
        check_cp1_registers(ctx, fd);
6284
        gen_load_fpr32(fpu32_T[0], fs);
6285
        tcg_gen_helper_0_0(do_float_cvtd_s);
6286
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6287
        opn = "cvt.d.s";
6288
        break;
6289
    case FOP(36, 16):
6290
        gen_load_fpr32(fpu32_T[0], fs);
6291
        tcg_gen_helper_0_0(do_float_cvtw_s);
6292
        gen_store_fpr32(fpu32_T[2], fd);
6293
        opn = "cvt.w.s";
6294
        break;
6295
    case FOP(37, 16):
6296
        check_cp1_64bitmode(ctx);
6297
        gen_load_fpr32(fpu32_T[0], fs);
6298
        tcg_gen_helper_0_0(do_float_cvtl_s);
6299
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6300
        opn = "cvt.l.s";
6301
        break;
6302
    case FOP(38, 16):
6303
        check_cp1_64bitmode(ctx);
6304
        gen_load_fpr32(fpu32_T[0], fs);
6305
        gen_load_fpr32(fpu32_T[1], ft);
6306
        tcg_gen_extu_i32_i64(fpu64_T[0], fpu32_T[0]);
6307
        tcg_gen_extu_i32_i64(fpu64_T[1], fpu32_T[1]);
6308
        tcg_gen_shli_i64(fpu64_T[1], fpu64_T[1], 32);
6309
        tcg_gen_or_i64(fpu64_T[2], fpu64_T[0], fpu64_T[1]);
6310
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6311
        opn = "cvt.ps.s";
6312
        break;
6313
    case FOP(48, 16):
6314
    case FOP(49, 16):
6315
    case FOP(50, 16):
6316
    case FOP(51, 16):
6317
    case FOP(52, 16):
6318
    case FOP(53, 16):
6319
    case FOP(54, 16):
6320
    case FOP(55, 16):
6321
    case FOP(56, 16):
6322
    case FOP(57, 16):
6323
    case FOP(58, 16):
6324
    case FOP(59, 16):
6325
    case FOP(60, 16):
6326
    case FOP(61, 16):
6327
    case FOP(62, 16):
6328
    case FOP(63, 16):
6329
        gen_load_fpr32(fpu32_T[0], fs);
6330
        gen_load_fpr32(fpu32_T[1], ft);
6331
        if (ctx->opcode & (1 << 6)) {
6332
            check_cop1x(ctx);
6333
            gen_cmpabs_s(func-48, cc);
6334
            opn = condnames_abs[func-48];
6335
        } else {
6336
            gen_cmp_s(func-48, cc);
6337
            opn = condnames[func-48];
6338
        }
6339
        break;
6340
    case FOP(0, 17):
6341
        check_cp1_registers(ctx, fs | ft | fd);
6342
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6343
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6344
        tcg_gen_helper_0_0(do_float_add_d);
6345
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6346
        opn = "add.d";
6347
        optype = BINOP;
6348
        break;
6349
    case FOP(1, 17):
6350
        check_cp1_registers(ctx, fs | ft | fd);
6351
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6352
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6353
        tcg_gen_helper_0_0(do_float_sub_d);
6354
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6355
        opn = "sub.d";
6356
        optype = BINOP;
6357
        break;
6358
    case FOP(2, 17):
6359
        check_cp1_registers(ctx, fs | ft | fd);
6360
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6361
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6362
        tcg_gen_helper_0_0(do_float_mul_d);
6363
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6364
        opn = "mul.d";
6365
        optype = BINOP;
6366
        break;
6367
    case FOP(3, 17):
6368
        check_cp1_registers(ctx, fs | ft | fd);
6369
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6370
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6371
        tcg_gen_helper_0_0(do_float_div_d);
6372
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6373
        opn = "div.d";
6374
        optype = BINOP;
6375
        break;
6376
    case FOP(4, 17):
6377
        check_cp1_registers(ctx, fs | fd);
6378
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6379
        tcg_gen_helper_0_0(do_float_sqrt_d);
6380
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6381
        opn = "sqrt.d";
6382
        break;
6383
    case FOP(5, 17):
6384
        check_cp1_registers(ctx, fs | fd);
6385
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6386
        tcg_gen_helper_0_0(do_float_abs_d);
6387
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6388
        opn = "abs.d";
6389
        break;
6390
    case FOP(6, 17):
6391
        check_cp1_registers(ctx, fs | fd);
6392
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6393
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6394
        opn = "mov.d";
6395
        break;
6396
    case FOP(7, 17):
6397
        check_cp1_registers(ctx, fs | fd);
6398
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6399
        tcg_gen_helper_0_0(do_float_chs_d);
6400
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6401
        opn = "neg.d";
6402
        break;
6403
    case FOP(8, 17):
6404
        check_cp1_64bitmode(ctx);
6405
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6406
        tcg_gen_helper_0_0(do_float_roundl_d);
6407
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6408
        opn = "round.l.d";
6409
        break;
6410
    case FOP(9, 17):
6411
        check_cp1_64bitmode(ctx);
6412
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6413
        tcg_gen_helper_0_0(do_float_truncl_d);
6414
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6415
        opn = "trunc.l.d";
6416
        break;
6417
    case FOP(10, 17):
6418
        check_cp1_64bitmode(ctx);
6419
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6420
        tcg_gen_helper_0_0(do_float_ceill_d);
6421
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6422
        opn = "ceil.l.d";
6423
        break;
6424
    case FOP(11, 17):
6425
        check_cp1_64bitmode(ctx);
6426
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6427
        tcg_gen_helper_0_0(do_float_floorl_d);
6428
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6429
        opn = "floor.l.d";
6430
        break;
6431
    case FOP(12, 17):
6432
        check_cp1_registers(ctx, fs);
6433
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6434
        tcg_gen_helper_0_0(do_float_roundw_d);
6435
        gen_store_fpr32(fpu32_T[2], fd);
6436
        opn = "round.w.d";
6437
        break;
6438
    case FOP(13, 17):
6439
        check_cp1_registers(ctx, fs);
6440
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6441
        tcg_gen_helper_0_0(do_float_truncw_d);
6442
        gen_store_fpr32(fpu32_T[2], fd);
6443
        opn = "trunc.w.d";
6444
        break;
6445
    case FOP(14, 17):
6446
        check_cp1_registers(ctx, fs);
6447
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6448
        tcg_gen_helper_0_0(do_float_ceilw_d);
6449
        gen_store_fpr32(fpu32_T[2], fd);
6450
        opn = "ceil.w.d";
6451
        break;
6452
    case FOP(15, 17):
6453
        check_cp1_registers(ctx, fs);
6454
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6455
        tcg_gen_helper_0_0(do_float_floorw_d);
6456
        gen_store_fpr32(fpu32_T[2], fd);
6457
        opn = "floor.w.d";
6458
        break;
6459
    case FOP(17, 17):
6460
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6461
        gen_load_fpr64(ctx, fpu64_T[2], fd);
6462
        gen_movcf_d((ft >> 2) & 0x7, ft & 0x1);
6463
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6464
        opn = "movcf.d";
6465
        break;
6466
    case FOP(18, 17):
6467
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6468
        gen_load_fpr64(ctx, fpu64_T[2], fd);
6469
        {
6470
            int l1 = gen_new_label();
6471
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6472

    
6473
            gen_load_gpr(t0, ft);
6474
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6475
            tcg_temp_free(t0);
6476
            tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]);
6477
            gen_set_label(l1);
6478
        }
6479
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6480
        opn = "movz.d";
6481
        break;
6482
    case FOP(19, 17):
6483
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6484
        gen_load_fpr64(ctx, fpu64_T[2], fd);
6485
        {
6486
            int l1 = gen_new_label();
6487
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6488

    
6489
            gen_load_gpr(t0, ft);
6490
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6491
            tcg_temp_free(t0);
6492
            tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]);
6493
            gen_set_label(l1);
6494
        }
6495
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6496
        opn = "movn.d";
6497
        break;
6498
    case FOP(21, 17):
6499
        check_cp1_64bitmode(ctx);
6500
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6501
        tcg_gen_helper_0_0(do_float_recip_d);
6502
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6503
        opn = "recip.d";
6504
        break;
6505
    case FOP(22, 17):
6506
        check_cp1_64bitmode(ctx);
6507
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6508
        tcg_gen_helper_0_0(do_float_rsqrt_d);
6509
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6510
        opn = "rsqrt.d";
6511
        break;
6512
    case FOP(28, 17):
6513
        check_cp1_64bitmode(ctx);
6514
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6515
        gen_load_fpr64(ctx, fpu64_T[2], ft);
6516
        tcg_gen_helper_0_0(do_float_recip2_d);
6517
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6518
        opn = "recip2.d";
6519
        break;
6520
    case FOP(29, 17):
6521
        check_cp1_64bitmode(ctx);
6522
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6523
        tcg_gen_helper_0_0(do_float_recip1_d);
6524
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6525
        opn = "recip1.d";
6526
        break;
6527
    case FOP(30, 17):
6528
        check_cp1_64bitmode(ctx);
6529
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6530
        tcg_gen_helper_0_0(do_float_rsqrt1_d);
6531
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6532
        opn = "rsqrt1.d";
6533
        break;
6534
    case FOP(31, 17):
6535
        check_cp1_64bitmode(ctx);
6536
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6537
        gen_load_fpr64(ctx, fpu64_T[2], ft);
6538
        tcg_gen_helper_0_0(do_float_rsqrt2_d);
6539
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6540
        opn = "rsqrt2.d";
6541
        break;
6542
    case FOP(48, 17):
6543
    case FOP(49, 17):
6544
    case FOP(50, 17):
6545
    case FOP(51, 17):
6546
    case FOP(52, 17):
6547
    case FOP(53, 17):
6548
    case FOP(54, 17):
6549
    case FOP(55, 17):
6550
    case FOP(56, 17):
6551
    case FOP(57, 17):
6552
    case FOP(58, 17):
6553
    case FOP(59, 17):
6554
    case FOP(60, 17):
6555
    case FOP(61, 17):
6556
    case FOP(62, 17):
6557
    case FOP(63, 17):
6558
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6559
        gen_load_fpr64(ctx, fpu64_T[1], ft);
6560
        if (ctx->opcode & (1 << 6)) {
6561
            check_cop1x(ctx);
6562
            check_cp1_registers(ctx, fs | ft);
6563
            gen_cmpabs_d(func-48, cc);
6564
            opn = condnames_abs[func-48];
6565
        } else {
6566
            check_cp1_registers(ctx, fs | ft);
6567
            gen_cmp_d(func-48, cc);
6568
            opn = condnames[func-48];
6569
        }
6570
        break;
6571
    case FOP(32, 17):
6572
        check_cp1_registers(ctx, fs);
6573
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6574
        tcg_gen_helper_0_0(do_float_cvts_d);
6575
        gen_store_fpr32(fpu32_T[2], fd);
6576
        opn = "cvt.s.d";
6577
        break;
6578
    case FOP(36, 17):
6579
        check_cp1_registers(ctx, fs);
6580
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6581
        tcg_gen_helper_0_0(do_float_cvtw_d);
6582
        gen_store_fpr32(fpu32_T[2], fd);
6583
        opn = "cvt.w.d";
6584
        break;
6585
    case FOP(37, 17):
6586
        check_cp1_64bitmode(ctx);
6587
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6588
        tcg_gen_helper_0_0(do_float_cvtl_d);
6589
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6590
        opn = "cvt.l.d";
6591
        break;
6592
    case FOP(32, 20):
6593
        gen_load_fpr32(fpu32_T[0], fs);
6594
        tcg_gen_helper_0_0(do_float_cvts_w);
6595
        gen_store_fpr32(fpu32_T[2], fd);
6596
        opn = "cvt.s.w";
6597
        break;
6598
    case FOP(33, 20):
6599
        check_cp1_registers(ctx, fd);
6600
        gen_load_fpr32(fpu32_T[0], fs);
6601
        tcg_gen_helper_0_0(do_float_cvtd_w);
6602
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6603
        opn = "cvt.d.w";
6604
        break;
6605
    case FOP(32, 21):
6606
        check_cp1_64bitmode(ctx);
6607
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6608
        tcg_gen_helper_0_0(do_float_cvts_l);
6609
        gen_store_fpr32(fpu32_T[2], fd);
6610
        opn = "cvt.s.l";
6611
        break;
6612
    case FOP(33, 21):
6613
        check_cp1_64bitmode(ctx);
6614
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6615
        tcg_gen_helper_0_0(do_float_cvtd_l);
6616
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6617
        opn = "cvt.d.l";
6618
        break;
6619
    case FOP(38, 20):
6620
        check_cp1_64bitmode(ctx);
6621
        gen_load_fpr32(fpu32_T[0], fs);
6622
        gen_load_fpr32h(fpu32h_T[0], fs);
6623
        tcg_gen_helper_0_0(do_float_cvtps_pw);
6624
        gen_store_fpr32(fpu32_T[2], fd);
6625
        gen_store_fpr32h(fpu32h_T[2], fd);
6626
        opn = "cvt.ps.pw";
6627
        break;
6628
    case FOP(0, 22):
6629
        check_cp1_64bitmode(ctx);
6630
        gen_load_fpr32(fpu32_T[0], fs);
6631
        gen_load_fpr32h(fpu32h_T[0], fs);
6632
        gen_load_fpr32(fpu32_T[1], ft);
6633
        gen_load_fpr32h(fpu32h_T[1], ft);
6634
        tcg_gen_helper_0_0(do_float_add_ps);
6635
        gen_store_fpr32(fpu32_T[2], fd);
6636
        gen_store_fpr32h(fpu32h_T[2], fd);
6637
        opn = "add.ps";
6638
        break;
6639
    case FOP(1, 22):
6640
        check_cp1_64bitmode(ctx);
6641
        gen_load_fpr32(fpu32_T[0], fs);
6642
        gen_load_fpr32h(fpu32h_T[0], fs);
6643
        gen_load_fpr32(fpu32_T[1], ft);
6644
        gen_load_fpr32h(fpu32h_T[1], ft);
6645
        tcg_gen_helper_0_0(do_float_sub_ps);
6646
        gen_store_fpr32(fpu32_T[2], fd);
6647
        gen_store_fpr32h(fpu32h_T[2], fd);
6648
        opn = "sub.ps";
6649
        break;
6650
    case FOP(2, 22):
6651
        check_cp1_64bitmode(ctx);
6652
        gen_load_fpr32(fpu32_T[0], fs);
6653
        gen_load_fpr32h(fpu32h_T[0], fs);
6654
        gen_load_fpr32(fpu32_T[1], ft);
6655
        gen_load_fpr32h(fpu32h_T[1], ft);
6656
        tcg_gen_helper_0_0(do_float_mul_ps);
6657
        gen_store_fpr32(fpu32_T[2], fd);
6658
        gen_store_fpr32h(fpu32h_T[2], fd);
6659
        opn = "mul.ps";
6660
        break;
6661
    case FOP(5, 22):
6662
        check_cp1_64bitmode(ctx);
6663
        gen_load_fpr32(fpu32_T[0], fs);
6664
        gen_load_fpr32h(fpu32h_T[0], fs);
6665
        tcg_gen_helper_0_0(do_float_abs_ps);
6666
        gen_store_fpr32(fpu32_T[2], fd);
6667
        gen_store_fpr32h(fpu32h_T[2], fd);
6668
        opn = "abs.ps";
6669
        break;
6670
    case FOP(6, 22):
6671
        check_cp1_64bitmode(ctx);
6672
        gen_load_fpr32(fpu32_T[0], fs);
6673
        gen_load_fpr32h(fpu32h_T[0], fs);
6674
        gen_store_fpr32(fpu32_T[0], fd);
6675
        gen_store_fpr32h(fpu32h_T[0], fd);
6676
        opn = "mov.ps";
6677
        break;
6678
    case FOP(7, 22):
6679
        check_cp1_64bitmode(ctx);
6680
        gen_load_fpr32(fpu32_T[0], fs);
6681
        gen_load_fpr32h(fpu32h_T[0], fs);
6682
        tcg_gen_helper_0_0(do_float_chs_ps);
6683
        gen_store_fpr32(fpu32_T[2], fd);
6684
        gen_store_fpr32h(fpu32h_T[2], fd);
6685
        opn = "neg.ps";
6686
        break;
6687
    case FOP(17, 22):
6688
        check_cp1_64bitmode(ctx);
6689
        gen_load_fpr32(fpu32_T[0], fs);
6690
        gen_load_fpr32h(fpu32h_T[0], fs);
6691
        gen_load_fpr32(fpu32_T[2], fd);
6692
        gen_load_fpr32h(fpu32h_T[2], fd);
6693
        gen_movcf_ps((ft >> 2) & 0x7, ft & 0x1);
6694
        gen_store_fpr32(fpu32_T[2], fd);
6695
        gen_store_fpr32h(fpu32h_T[2], fd);
6696
        opn = "movcf.ps";
6697
        break;
6698
    case FOP(18, 22):
6699
        check_cp1_64bitmode(ctx);
6700
        gen_load_fpr32(fpu32_T[0], fs);
6701
        gen_load_fpr32h(fpu32h_T[0], fs);
6702
        gen_load_fpr32(fpu32_T[2], fd);
6703
        gen_load_fpr32h(fpu32h_T[2], fd);
6704
        {
6705
            int l1 = gen_new_label();
6706
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6707

    
6708
            gen_load_gpr(t0, ft);
6709
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6710
            tcg_temp_free(t0);
6711
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
6712
            tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]);
6713
            gen_set_label(l1);
6714
        }
6715
        gen_store_fpr32(fpu32_T[2], fd);
6716
        gen_store_fpr32h(fpu32h_T[2], fd);
6717
        opn = "movz.ps";
6718
        break;
6719
    case FOP(19, 22):
6720
        check_cp1_64bitmode(ctx);
6721
        gen_load_fpr32(fpu32_T[0], fs);
6722
        gen_load_fpr32h(fpu32h_T[0], fs);
6723
        gen_load_fpr32(fpu32_T[2], fd);
6724
        gen_load_fpr32h(fpu32h_T[2], fd);
6725
        {
6726
            int l1 = gen_new_label();
6727
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6728

    
6729
            gen_load_gpr(t0, ft);
6730
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6731
            tcg_temp_free(t0);
6732
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
6733
            tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]);
6734
            gen_set_label(l1);
6735
        }
6736
        gen_store_fpr32(fpu32_T[2], fd);
6737
        gen_store_fpr32h(fpu32h_T[2], fd);
6738
        opn = "movn.ps";
6739
        break;
6740
    case FOP(24, 22):
6741
        check_cp1_64bitmode(ctx);
6742
        gen_load_fpr32(fpu32_T[0], ft);
6743
        gen_load_fpr32h(fpu32h_T[0], ft);
6744
        gen_load_fpr32(fpu32_T[1], fs);
6745
        gen_load_fpr32h(fpu32h_T[1], fs);
6746
        tcg_gen_helper_0_0(do_float_addr_ps);
6747
        gen_store_fpr32(fpu32_T[2], fd);
6748
        gen_store_fpr32h(fpu32h_T[2], fd);
6749
        opn = "addr.ps";
6750
        break;
6751
    case FOP(26, 22):
6752
        check_cp1_64bitmode(ctx);
6753
        gen_load_fpr32(fpu32_T[0], ft);
6754
        gen_load_fpr32h(fpu32h_T[0], ft);
6755
        gen_load_fpr32(fpu32_T[1], fs);
6756
        gen_load_fpr32h(fpu32h_T[1], fs);
6757
        tcg_gen_helper_0_0(do_float_mulr_ps);
6758
        gen_store_fpr32(fpu32_T[2], fd);
6759
        gen_store_fpr32h(fpu32h_T[2], fd);
6760
        opn = "mulr.ps";
6761
        break;
6762
    case FOP(28, 22):
6763
        check_cp1_64bitmode(ctx);
6764
        gen_load_fpr32(fpu32_T[0], fs);
6765
        gen_load_fpr32h(fpu32h_T[0], fs);
6766
        gen_load_fpr32(fpu32_T[2], fd);
6767
        gen_load_fpr32h(fpu32h_T[2], fd);
6768
        tcg_gen_helper_0_0(do_float_recip2_ps);
6769
        gen_store_fpr32(fpu32_T[2], fd);
6770
        gen_store_fpr32h(fpu32h_T[2], fd);
6771
        opn = "recip2.ps";
6772
        break;
6773
    case FOP(29, 22):
6774
        check_cp1_64bitmode(ctx);
6775
        gen_load_fpr32(fpu32_T[0], fs);
6776
        gen_load_fpr32h(fpu32h_T[0], fs);
6777
        tcg_gen_helper_0_0(do_float_recip1_ps);
6778
        gen_store_fpr32(fpu32_T[2], fd);
6779
        gen_store_fpr32h(fpu32h_T[2], fd);
6780
        opn = "recip1.ps";
6781
        break;
6782
    case FOP(30, 22):
6783
        check_cp1_64bitmode(ctx);
6784
        gen_load_fpr32(fpu32_T[0], fs);
6785
        gen_load_fpr32h(fpu32h_T[0], fs);
6786
        tcg_gen_helper_0_0(do_float_rsqrt1_ps);
6787
        gen_store_fpr32(fpu32_T[2], fd);
6788
        gen_store_fpr32h(fpu32h_T[2], fd);
6789
        opn = "rsqrt1.ps";
6790
        break;
6791
    case FOP(31, 22):
6792
        check_cp1_64bitmode(ctx);
6793
        gen_load_fpr32(fpu32_T[0], fs);
6794
        gen_load_fpr32h(fpu32h_T[0], fs);
6795
        gen_load_fpr32(fpu32_T[2], ft);
6796
        gen_load_fpr32h(fpu32h_T[2], ft);
6797
        tcg_gen_helper_0_0(do_float_rsqrt2_ps);
6798
        gen_store_fpr32(fpu32_T[2], fd);
6799
        gen_store_fpr32h(fpu32h_T[2], fd);
6800
        opn = "rsqrt2.ps";
6801
        break;
6802
    case FOP(32, 22):
6803
        check_cp1_64bitmode(ctx);
6804
        gen_load_fpr32h(fpu32h_T[0], fs);
6805
        tcg_gen_helper_0_0(do_float_cvts_pu);
6806
        gen_store_fpr32(fpu32_T[2], fd);
6807
        opn = "cvt.s.pu";
6808
        break;
6809
    case FOP(36, 22):
6810
        check_cp1_64bitmode(ctx);
6811
        gen_load_fpr32(fpu32_T[0], fs);
6812
        gen_load_fpr32h(fpu32h_T[0], fs);
6813
        tcg_gen_helper_0_0(do_float_cvtpw_ps);
6814
        gen_store_fpr32(fpu32_T[2], fd);
6815
        gen_store_fpr32h(fpu32h_T[2], fd);
6816
        opn = "cvt.pw.ps";
6817
        break;
6818
    case FOP(40, 22):
6819
        check_cp1_64bitmode(ctx);
6820
        gen_load_fpr32(fpu32_T[0], fs);
6821
        tcg_gen_helper_0_0(do_float_cvts_pl);
6822
        gen_store_fpr32(fpu32_T[2], fd);
6823
        opn = "cvt.s.pl";
6824
        break;
6825
    case FOP(44, 22):
6826
        check_cp1_64bitmode(ctx);
6827
        gen_load_fpr32(fpu32_T[0], fs);
6828
        gen_load_fpr32(fpu32_T[1], ft);
6829
        gen_store_fpr32h(fpu32_T[0], fd);
6830
        gen_store_fpr32(fpu32_T[1], fd);
6831
        opn = "pll.ps";
6832
        break;
6833
    case FOP(45, 22):
6834
        check_cp1_64bitmode(ctx);
6835
        gen_load_fpr32(fpu32_T[0], fs);
6836
        gen_load_fpr32h(fpu32h_T[1], ft);
6837
        gen_store_fpr32(fpu32h_T[1], fd);
6838
        gen_store_fpr32h(fpu32_T[0], fd);
6839
        opn = "plu.ps";
6840
        break;
6841
    case FOP(46, 22):
6842
        check_cp1_64bitmode(ctx);
6843
        gen_load_fpr32h(fpu32h_T[0], fs);
6844
        gen_load_fpr32(fpu32_T[1], ft);
6845
        gen_store_fpr32(fpu32_T[1], fd);
6846
        gen_store_fpr32h(fpu32h_T[0], fd);
6847
        opn = "pul.ps";
6848
        break;
6849
    case FOP(47, 22):
6850
        check_cp1_64bitmode(ctx);
6851
        gen_load_fpr32h(fpu32h_T[0], fs);
6852
        gen_load_fpr32h(fpu32h_T[1], ft);
6853
        gen_store_fpr32(fpu32h_T[1], fd);
6854
        gen_store_fpr32h(fpu32h_T[0], fd);
6855
        opn = "puu.ps";
6856
        break;
6857
    case FOP(48, 22):
6858
    case FOP(49, 22):
6859
    case FOP(50, 22):
6860
    case FOP(51, 22):
6861
    case FOP(52, 22):
6862
    case FOP(53, 22):
6863
    case FOP(54, 22):
6864
    case FOP(55, 22):
6865
    case FOP(56, 22):
6866
    case FOP(57, 22):
6867
    case FOP(58, 22):
6868
    case FOP(59, 22):
6869
    case FOP(60, 22):
6870
    case FOP(61, 22):
6871
    case FOP(62, 22):
6872
    case FOP(63, 22):
6873
        check_cp1_64bitmode(ctx);
6874
        gen_load_fpr32(fpu32_T[0], fs);
6875
        gen_load_fpr32h(fpu32h_T[0], fs);
6876
        gen_load_fpr32(fpu32_T[1], ft);
6877
        gen_load_fpr32h(fpu32h_T[1], ft);
6878
        if (ctx->opcode & (1 << 6)) {
6879
            gen_cmpabs_ps(func-48, cc);
6880
            opn = condnames_abs[func-48];
6881
        } else {
6882
            gen_cmp_ps(func-48, cc);
6883
            opn = condnames[func-48];
6884
        }
6885
        break;
6886
    default:
6887
        MIPS_INVAL(opn);
6888
        generate_exception (ctx, EXCP_RI);
6889
        return;
6890
    }
6891
    switch (optype) {
6892
    case BINOP:
6893
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
6894
        break;
6895
    case CMPOP:
6896
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
6897
        break;
6898
    default:
6899
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
6900
        break;
6901
    }
6902
}
6903

    
6904
/* Coprocessor 3 (FPU) */
6905
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6906
                           int fd, int fs, int base, int index)
6907
{
6908
    const char *opn = "extended float load/store";
6909
    int store = 0;
6910
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6911
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
6912

    
6913
    if (base == 0) {
6914
        gen_load_gpr(t0, index);
6915
    } else if (index == 0) {
6916
        gen_load_gpr(t0, base);
6917
    } else {
6918
        gen_load_gpr(t0, base);
6919
        gen_load_gpr(t1, index);
6920
        gen_op_addr_add(t0, t1);
6921
    }
6922
    /* Don't do NOP if destination is zero: we must perform the actual
6923
       memory access. */
6924
    switch (opc) {
6925
    case OPC_LWXC1:
6926
        check_cop1x(ctx);
6927
        tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx);
6928
        gen_store_fpr32(fpu32_T[0], fd);
6929
        opn = "lwxc1";
6930
        break;
6931
    case OPC_LDXC1:
6932
        check_cop1x(ctx);
6933
        check_cp1_registers(ctx, fd);
6934
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
6935
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6936
        opn = "ldxc1";
6937
        break;
6938
    case OPC_LUXC1:
6939
        check_cp1_64bitmode(ctx);
6940
        tcg_gen_andi_tl(t0, t0, ~0x7);
6941
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
6942
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6943
        opn = "luxc1";
6944
        break;
6945
    case OPC_SWXC1:
6946
        check_cop1x(ctx);
6947
        gen_load_fpr32(fpu32_T[0], fs);
6948
        tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx);
6949
        opn = "swxc1";
6950
        store = 1;
6951
        break;
6952
    case OPC_SDXC1:
6953
        check_cop1x(ctx);
6954
        check_cp1_registers(ctx, fs);
6955
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6956
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
6957
        opn = "sdxc1";
6958
        store = 1;
6959
        break;
6960
    case OPC_SUXC1:
6961
        check_cp1_64bitmode(ctx);
6962
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6963
        tcg_gen_andi_tl(t0, t0, ~0x7);
6964
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
6965
        opn = "suxc1";
6966
        store = 1;
6967
        break;
6968
    default:
6969
        MIPS_INVAL(opn);
6970
        generate_exception(ctx, EXCP_RI);
6971
        tcg_temp_free(t0);
6972
        tcg_temp_free(t1);
6973
        return;
6974
    }
6975
    tcg_temp_free(t0);
6976
    tcg_temp_free(t1);
6977
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6978
               regnames[index], regnames[base]);
6979
}
6980

    
6981
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
6982
                            int fd, int fr, int fs, int ft)
6983
{
6984
    const char *opn = "flt3_arith";
6985

    
6986
    switch (opc) {
6987
    case OPC_ALNV_PS:
6988
        check_cp1_64bitmode(ctx);
6989
        {
6990
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6991
            int l1 = gen_new_label();
6992
            int l2 = gen_new_label();
6993

    
6994
            gen_load_gpr(t0, fr);
6995
            tcg_gen_andi_tl(t0, t0, 0x7);
6996
            gen_load_fpr32(fpu32_T[0], fs);
6997
            gen_load_fpr32h(fpu32h_T[0], fs);
6998
            gen_load_fpr32(fpu32_T[1], ft);
6999
            gen_load_fpr32h(fpu32h_T[1], ft);
7000

    
7001
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7002
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
7003
            tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]);
7004
            tcg_gen_br(l2);
7005
            gen_set_label(l1);
7006
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7007
            tcg_temp_free(t0);
7008
#ifdef TARGET_WORDS_BIGENDIAN
7009
            tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[0]);
7010
            tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[1]);
7011
#else
7012
            tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[1]);
7013
            tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[0]);
7014
#endif
7015
            gen_set_label(l2);
7016
        }
7017
        gen_store_fpr32(fpu32_T[2], fd);
7018
        gen_store_fpr32h(fpu32h_T[2], fd);
7019
        opn = "alnv.ps";
7020
        break;
7021
    case OPC_MADD_S:
7022
        check_cop1x(ctx);
7023
        gen_load_fpr32(fpu32_T[0], fs);
7024
        gen_load_fpr32(fpu32_T[1], ft);
7025
        gen_load_fpr32(fpu32_T[2], fr);
7026
        tcg_gen_helper_0_0(do_float_muladd_s);
7027
        gen_store_fpr32(fpu32_T[2], fd);
7028
        opn = "madd.s";
7029
        break;
7030
    case OPC_MADD_D:
7031
        check_cop1x(ctx);
7032
        check_cp1_registers(ctx, fd | fs | ft | fr);
7033
        gen_load_fpr64(ctx, fpu64_T[0], fs);
7034
        gen_load_fpr64(ctx, fpu64_T[1], ft);
7035
        gen_load_fpr64(ctx, fpu64_T[2], fr);
7036
        tcg_gen_helper_0_0(do_float_muladd_d);
7037
        gen_store_fpr64(ctx, fpu64_T[2], fd);
7038
        opn = "madd.d";
7039
        break;
7040
    case OPC_MADD_PS:
7041
        check_cp1_64bitmode(ctx);
7042
        gen_load_fpr32(fpu32_T[0], fs);
7043
        gen_load_fpr32h(fpu32h_T[0], fs);
7044
        gen_load_fpr32(fpu32_T[1], ft);
7045
        gen_load_fpr32h(fpu32h_T[1], ft);
7046
        gen_load_fpr32(fpu32_T[2], fr);
7047
        gen_load_fpr32h(fpu32h_T[2], fr);
7048
        tcg_gen_helper_0_0(do_float_muladd_ps);
7049
        gen_store_fpr32(fpu32_T[2], fd);
7050
        gen_store_fpr32h(fpu32h_T[2], fd);
7051
        opn = "madd.ps";
7052
        break;
7053
    case OPC_MSUB_S:
7054
        check_cop1x(ctx);
7055
        gen_load_fpr32(fpu32_T[0], fs);
7056
        gen_load_fpr32(fpu32_T[1], ft);
7057
        gen_load_fpr32(fpu32_T[2], fr);
7058
        tcg_gen_helper_0_0(do_float_mulsub_s);
7059
        gen_store_fpr32(fpu32_T[2], fd);
7060
        opn = "msub.s";
7061
        break;
7062
    case OPC_MSUB_D:
7063
        check_cop1x(ctx);
7064
        check_cp1_registers(ctx, fd | fs | ft | fr);
7065
        gen_load_fpr64(ctx, fpu64_T[0], fs);
7066
        gen_load_fpr64(ctx, fpu64_T[1], ft);
7067
        gen_load_fpr64(ctx, fpu64_T[2], fr);
7068
        tcg_gen_helper_0_0(do_float_mulsub_d);
7069
        gen_store_fpr64(ctx, fpu64_T[2], fd);
7070
        opn = "msub.d";
7071
        break;
7072
    case OPC_MSUB_PS:
7073
        check_cp1_64bitmode(ctx);
7074
        gen_load_fpr32(fpu32_T[0], fs);
7075
        gen_load_fpr32h(fpu32h_T[0], fs);
7076
        gen_load_fpr32(fpu32_T[1], ft);
7077
        gen_load_fpr32h(fpu32h_T[1], ft);
7078
        gen_load_fpr32(fpu32_T[2], fr);
7079
        gen_load_fpr32h(fpu32h_T[2], fr);
7080
        tcg_gen_helper_0_0(do_float_mulsub_ps);
7081
        gen_store_fpr32(fpu32_T[2], fd);
7082
        gen_store_fpr32h(fpu32h_T[2], fd);
7083
        opn = "msub.ps";
7084
        break;
7085
    case OPC_NMADD_S:
7086
        check_cop1x(ctx);
7087
        gen_load_fpr32(fpu32_T[0], fs);
7088
        gen_load_fpr32(fpu32_T[1], ft);
7089
        gen_load_fpr32(fpu32_T[2], fr);
7090
        tcg_gen_helper_0_0(do_float_nmuladd_s);
7091
        gen_store_fpr32(fpu32_T[2], fd);
7092
        opn = "nmadd.s";
7093
        break;
7094
    case OPC_NMADD_D:
7095
        check_cop1x(ctx);
7096
        check_cp1_registers(ctx, fd | fs | ft | fr);
7097
        gen_load_fpr64(ctx, fpu64_T[0], fs);
7098
        gen_load_fpr64(ctx, fpu64_T[1], ft);
7099
        gen_load_fpr64(ctx, fpu64_T[2], fr);
7100
        tcg_gen_helper_0_0(do_float_nmuladd_d);
7101
        gen_store_fpr64(ctx, fpu64_T[2], fd);
7102
        opn = "nmadd.d";
7103
        break;
7104
    case OPC_NMADD_PS:
7105
        check_cp1_64bitmode(ctx);
7106
        gen_load_fpr32(fpu32_T[0], fs);
7107
        gen_load_fpr32h(fpu32h_T[0], fs);
7108
        gen_load_fpr32(fpu32_T[1], ft);
7109
        gen_load_fpr32h(fpu32h_T[1], ft);
7110
        gen_load_fpr32(fpu32_T[2], fr);
7111
        gen_load_fpr32h(fpu32h_T[2], fr);
7112
        tcg_gen_helper_0_0(do_float_nmuladd_ps);
7113
        gen_store_fpr32(fpu32_T[2], fd);
7114
        gen_store_fpr32h(fpu32h_T[2], fd);
7115
        opn = "nmadd.ps";
7116
        break;
7117
    case OPC_NMSUB_S:
7118
        check_cop1x(ctx);
7119
        gen_load_fpr32(fpu32_T[0], fs);
7120
        gen_load_fpr32(fpu32_T[1], ft);
7121
        gen_load_fpr32(fpu32_T[2], fr);
7122
        tcg_gen_helper_0_0(do_float_nmulsub_s);
7123
        gen_store_fpr32(fpu32_T[2], fd);
7124
        opn = "nmsub.s";
7125
        break;
7126
    case OPC_NMSUB_D:
7127
        check_cop1x(ctx);
7128
        check_cp1_registers(ctx, fd | fs | ft | fr);
7129
        gen_load_fpr64(ctx, fpu64_T[0], fs);
7130
        gen_load_fpr64(ctx, fpu64_T[1], ft);
7131
        gen_load_fpr64(ctx, fpu64_T[2], fr);
7132
        tcg_gen_helper_0_0(do_float_nmulsub_d);
7133
        gen_store_fpr64(ctx, fpu64_T[2], fd);
7134
        opn = "nmsub.d";
7135
        break;
7136
    case OPC_NMSUB_PS:
7137
        check_cp1_64bitmode(ctx);
7138
        gen_load_fpr32(fpu32_T[0], fs);
7139
        gen_load_fpr32h(fpu32h_T[0], fs);
7140
        gen_load_fpr32(fpu32_T[1], ft);
7141
        gen_load_fpr32h(fpu32h_T[1], ft);
7142
        gen_load_fpr32(fpu32_T[2], fr);
7143
        gen_load_fpr32h(fpu32h_T[2], fr);
7144
        tcg_gen_helper_0_0(do_float_nmulsub_ps);
7145
        gen_store_fpr32(fpu32_T[2], fd);
7146
        gen_store_fpr32h(fpu32h_T[2], fd);
7147
        opn = "nmsub.ps";
7148
        break;
7149
    default:
7150
        MIPS_INVAL(opn);
7151
        generate_exception (ctx, EXCP_RI);
7152
        return;
7153
    }
7154
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7155
               fregnames[fs], fregnames[ft]);
7156
}
7157

    
7158
/* ISA extensions (ASEs) */
7159
/* MIPS16 extension to MIPS32 */
7160
/* SmartMIPS extension to MIPS32 */
7161

    
7162
#if defined(TARGET_MIPS64)
7163

    
7164
/* MDMX extension to MIPS64 */
7165

    
7166
#endif
7167

    
7168
static void decode_opc (CPUState *env, DisasContext *ctx)
7169
{
7170
    int32_t offset;
7171
    int rs, rt, rd, sa;
7172
    uint32_t op, op1, op2;
7173
    int16_t imm;
7174

    
7175
    /* make sure instructions are on a word boundary */
7176
    if (ctx->pc & 0x3) {
7177
        env->CP0_BadVAddr = ctx->pc;
7178
        generate_exception(ctx, EXCP_AdEL);
7179
        return;
7180
    }
7181

    
7182
    /* Handle blikely not taken case */
7183
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7184
        int l1 = gen_new_label();
7185

    
7186
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7187
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7188
        {
7189
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
7190

    
7191
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7192
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7193
            tcg_temp_free(r_tmp);
7194
        }
7195
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7196
        gen_set_label(l1);
7197
    }
7198
    op = MASK_OP_MAJOR(ctx->opcode);
7199
    rs = (ctx->opcode >> 21) & 0x1f;
7200
    rt = (ctx->opcode >> 16) & 0x1f;
7201
    rd = (ctx->opcode >> 11) & 0x1f;
7202
    sa = (ctx->opcode >> 6) & 0x1f;
7203
    imm = (int16_t)ctx->opcode;
7204
    switch (op) {
7205
    case OPC_SPECIAL:
7206
        op1 = MASK_SPECIAL(ctx->opcode);
7207
        switch (op1) {
7208
        case OPC_SLL:          /* Arithmetic with immediate */
7209
        case OPC_SRL ... OPC_SRA:
7210
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7211
            break;
7212
        case OPC_MOVZ ... OPC_MOVN:
7213
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7214
        case OPC_SLLV:         /* Arithmetic */
7215
        case OPC_SRLV ... OPC_SRAV:
7216
        case OPC_ADD ... OPC_NOR:
7217
        case OPC_SLT ... OPC_SLTU:
7218
            gen_arith(env, ctx, op1, rd, rs, rt);
7219
            break;
7220
        case OPC_MULT ... OPC_DIVU:
7221
            if (sa) {
7222
                check_insn(env, ctx, INSN_VR54XX);
7223
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7224
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7225
            } else
7226
                gen_muldiv(ctx, op1, rs, rt);
7227
            break;
7228
        case OPC_JR ... OPC_JALR:
7229
            gen_compute_branch(ctx, op1, rs, rd, sa);
7230
            return;
7231
        case OPC_TGE ... OPC_TEQ: /* Traps */
7232
        case OPC_TNE:
7233
            gen_trap(ctx, op1, rs, rt, -1);
7234
            break;
7235
        case OPC_MFHI:          /* Move from HI/LO */
7236
        case OPC_MFLO:
7237
            gen_HILO(ctx, op1, rd);
7238
            break;
7239
        case OPC_MTHI:
7240
        case OPC_MTLO:          /* Move to HI/LO */
7241
            gen_HILO(ctx, op1, rs);
7242
            break;
7243
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7244
#ifdef MIPS_STRICT_STANDARD
7245
            MIPS_INVAL("PMON / selsl");
7246
            generate_exception(ctx, EXCP_RI);
7247
#else
7248
            tcg_gen_helper_0_i(do_pmon, sa);
7249
#endif
7250
            break;
7251
        case OPC_SYSCALL:
7252
            generate_exception(ctx, EXCP_SYSCALL);
7253
            break;
7254
        case OPC_BREAK:
7255
            generate_exception(ctx, EXCP_BREAK);
7256
            break;
7257
        case OPC_SPIM:
7258
#ifdef MIPS_STRICT_STANDARD
7259
            MIPS_INVAL("SPIM");
7260
            generate_exception(ctx, EXCP_RI);
7261
#else
7262
           /* Implemented as RI exception for now. */
7263
            MIPS_INVAL("spim (unofficial)");
7264
            generate_exception(ctx, EXCP_RI);
7265
#endif
7266
            break;
7267
        case OPC_SYNC:
7268
            /* Treat as NOP. */
7269
            break;
7270

    
7271
        case OPC_MOVCI:
7272
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7273
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7274
                save_cpu_state(ctx, 1);
7275
                check_cp1_enabled(ctx);
7276
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7277
                          (ctx->opcode >> 16) & 1);
7278
            } else {
7279
                generate_exception_err(ctx, EXCP_CpU, 1);
7280
            }
7281
            break;
7282

    
7283
#if defined(TARGET_MIPS64)
7284
       /* MIPS64 specific opcodes */
7285
        case OPC_DSLL:
7286
        case OPC_DSRL ... OPC_DSRA:
7287
        case OPC_DSLL32:
7288
        case OPC_DSRL32 ... OPC_DSRA32:
7289
            check_insn(env, ctx, ISA_MIPS3);
7290
            check_mips_64(ctx);
7291
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7292
            break;
7293
        case OPC_DSLLV:
7294
        case OPC_DSRLV ... OPC_DSRAV:
7295
        case OPC_DADD ... OPC_DSUBU:
7296
            check_insn(env, ctx, ISA_MIPS3);
7297
            check_mips_64(ctx);
7298
            gen_arith(env, ctx, op1, rd, rs, rt);
7299
            break;
7300
        case OPC_DMULT ... OPC_DDIVU:
7301
            check_insn(env, ctx, ISA_MIPS3);
7302
            check_mips_64(ctx);
7303
            gen_muldiv(ctx, op1, rs, rt);
7304
            break;
7305
#endif
7306
        default:            /* Invalid */
7307
            MIPS_INVAL("special");
7308
            generate_exception(ctx, EXCP_RI);
7309
            break;
7310
        }
7311
        break;
7312
    case OPC_SPECIAL2:
7313
        op1 = MASK_SPECIAL2(ctx->opcode);
7314
        switch (op1) {
7315
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7316
        case OPC_MSUB ... OPC_MSUBU:
7317
            check_insn(env, ctx, ISA_MIPS32);
7318
            gen_muldiv(ctx, op1, rs, rt);
7319
            break;
7320
        case OPC_MUL:
7321
            gen_arith(env, ctx, op1, rd, rs, rt);
7322
            break;
7323
        case OPC_CLZ ... OPC_CLO:
7324
            check_insn(env, ctx, ISA_MIPS32);
7325
            gen_cl(ctx, op1, rd, rs);
7326
            break;
7327
        case OPC_SDBBP:
7328
            /* XXX: not clear which exception should be raised
7329
             *      when in debug mode...
7330
             */
7331
            check_insn(env, ctx, ISA_MIPS32);
7332
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7333
                generate_exception(ctx, EXCP_DBp);
7334
            } else {
7335
                generate_exception(ctx, EXCP_DBp);
7336
            }
7337
            /* Treat as NOP. */
7338
            break;
7339
#if defined(TARGET_MIPS64)
7340
        case OPC_DCLZ ... OPC_DCLO:
7341
            check_insn(env, ctx, ISA_MIPS64);
7342
            check_mips_64(ctx);
7343
            gen_cl(ctx, op1, rd, rs);
7344
            break;
7345
#endif
7346
        default:            /* Invalid */
7347
            MIPS_INVAL("special2");
7348
            generate_exception(ctx, EXCP_RI);
7349
            break;
7350
        }
7351
        break;
7352
    case OPC_SPECIAL3:
7353
        op1 = MASK_SPECIAL3(ctx->opcode);
7354
        switch (op1) {
7355
        case OPC_EXT:
7356
        case OPC_INS:
7357
            check_insn(env, ctx, ISA_MIPS32R2);
7358
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7359
            break;
7360
        case OPC_BSHFL:
7361
            check_insn(env, ctx, ISA_MIPS32R2);
7362
            op2 = MASK_BSHFL(ctx->opcode);
7363
            {
7364
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7365
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7366

    
7367
                switch (op2) {
7368
                case OPC_WSBH:
7369
                    gen_load_gpr(t1, rt);
7370
                    tcg_gen_helper_1_1(do_wsbh, t0, t1);
7371
                    gen_store_gpr(t0, rd);
7372
                    break;
7373
                case OPC_SEB:
7374
                    gen_load_gpr(t1, rt);
7375
                    tcg_gen_ext8s_tl(t0, t1);
7376
                    gen_store_gpr(t0, rd);
7377
                    break;
7378
                case OPC_SEH:
7379
                    gen_load_gpr(t1, rt);
7380
                    tcg_gen_ext16s_tl(t0, t1);
7381
                    gen_store_gpr(t0, rd);
7382
                    break;
7383
                default:            /* Invalid */
7384
                    MIPS_INVAL("bshfl");
7385
                    generate_exception(ctx, EXCP_RI);
7386
                    break;
7387
                }
7388
                tcg_temp_free(t0);
7389
                tcg_temp_free(t1);
7390
            }
7391
            break;
7392
        case OPC_RDHWR:
7393
            check_insn(env, ctx, ISA_MIPS32R2);
7394
            {
7395
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7396

    
7397
                switch (rd) {
7398
                case 0:
7399
                    save_cpu_state(ctx, 1);
7400
                    tcg_gen_helper_1_0(do_rdhwr_cpunum, t0);
7401
                    break;
7402
                case 1:
7403
                    save_cpu_state(ctx, 1);
7404
                    tcg_gen_helper_1_0(do_rdhwr_synci_step, t0);
7405
                    break;
7406
                case 2:
7407
                    save_cpu_state(ctx, 1);
7408
                    tcg_gen_helper_1_0(do_rdhwr_cc, t0);
7409
                    break;
7410
                case 3:
7411
                    save_cpu_state(ctx, 1);
7412
                    tcg_gen_helper_1_0(do_rdhwr_ccres, t0);
7413
                    break;
7414
                case 29:
7415
#if defined (CONFIG_USER_ONLY)
7416
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7417
                    break;
7418
#else
7419
                    /* XXX: Some CPUs implement this in hardware. Not supported yet. */
7420
#endif
7421
                default:            /* Invalid */
7422
                    MIPS_INVAL("rdhwr");
7423
                    generate_exception(ctx, EXCP_RI);
7424
                    break;
7425
                }
7426
                gen_store_gpr(t0, rt);
7427
                tcg_temp_free(t0);
7428
            }
7429
            break;
7430
        case OPC_FORK:
7431
            check_insn(env, ctx, ASE_MT);
7432
            {
7433
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7434
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7435

    
7436
                gen_load_gpr(t0, rt);
7437
                gen_load_gpr(t1, rs);
7438
                tcg_gen_helper_0_2(do_fork, t0, t1);
7439
                tcg_temp_free(t0);
7440
                tcg_temp_free(t1);
7441
            }
7442
            break;
7443
        case OPC_YIELD:
7444
            check_insn(env, ctx, ASE_MT);
7445
            {
7446
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7447

    
7448
                gen_load_gpr(t0, rs);
7449
                tcg_gen_helper_1_1(do_yield, t0, t0);
7450
                gen_store_gpr(t0, rd);
7451
                tcg_temp_free(t0);
7452
            }
7453
            break;
7454
#if defined(TARGET_MIPS64)
7455
        case OPC_DEXTM ... OPC_DEXT:
7456
        case OPC_DINSM ... OPC_DINS:
7457
            check_insn(env, ctx, ISA_MIPS64R2);
7458
            check_mips_64(ctx);
7459
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7460
            break;
7461
        case OPC_DBSHFL:
7462
            check_insn(env, ctx, ISA_MIPS64R2);
7463
            check_mips_64(ctx);
7464
            op2 = MASK_DBSHFL(ctx->opcode);
7465
            {
7466
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7467
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7468

    
7469
                switch (op2) {
7470
                case OPC_DSBH:
7471
                    gen_load_gpr(t1, rt);
7472
                    tcg_gen_helper_1_1(do_dsbh, t0, t1);
7473
                    break;
7474
                case OPC_DSHD:
7475
                    gen_load_gpr(t1, rt);
7476
                    tcg_gen_helper_1_1(do_dshd, t0, t1);
7477
                    break;
7478
                default:            /* Invalid */
7479
                    MIPS_INVAL("dbshfl");
7480
                    generate_exception(ctx, EXCP_RI);
7481
                    break;
7482
                }
7483
                gen_store_gpr(t0, rd);
7484
                tcg_temp_free(t0);
7485
                tcg_temp_free(t1);
7486
            }
7487
            break;
7488
#endif
7489
        default:            /* Invalid */
7490
            MIPS_INVAL("special3");
7491
            generate_exception(ctx, EXCP_RI);
7492
            break;
7493
        }
7494
        break;
7495
    case OPC_REGIMM:
7496
        op1 = MASK_REGIMM(ctx->opcode);
7497
        switch (op1) {
7498
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7499
        case OPC_BLTZAL ... OPC_BGEZALL:
7500
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7501
            return;
7502
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7503
        case OPC_TNEI:
7504
            gen_trap(ctx, op1, rs, -1, imm);
7505
            break;
7506
        case OPC_SYNCI:
7507
            check_insn(env, ctx, ISA_MIPS32R2);
7508
            /* Treat as NOP. */
7509
            break;
7510
        default:            /* Invalid */
7511
            MIPS_INVAL("regimm");
7512
            generate_exception(ctx, EXCP_RI);
7513
            break;
7514
        }
7515
        break;
7516
    case OPC_CP0:
7517
        check_cp0_enabled(ctx);
7518
        op1 = MASK_CP0(ctx->opcode);
7519
        switch (op1) {
7520
        case OPC_MFC0:
7521
        case OPC_MTC0:
7522
        case OPC_MFTR:
7523
        case OPC_MTTR:
7524
#if defined(TARGET_MIPS64)
7525
        case OPC_DMFC0:
7526
        case OPC_DMTC0:
7527
#endif
7528
#ifndef CONFIG_USER_ONLY
7529
            gen_cp0(env, ctx, op1, rt, rd);
7530
#endif
7531
            break;
7532
        case OPC_C0_FIRST ... OPC_C0_LAST:
7533
#ifndef CONFIG_USER_ONLY
7534
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7535
#endif
7536
            break;
7537
        case OPC_MFMC0:
7538
            op2 = MASK_MFMC0(ctx->opcode);
7539
            {
7540
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7541

    
7542
                switch (op2) {
7543
                case OPC_DMT:
7544
                    check_insn(env, ctx, ASE_MT);
7545
                    tcg_gen_helper_1_1(do_dmt, t0, t0);
7546
                    break;
7547
                case OPC_EMT:
7548
                    check_insn(env, ctx, ASE_MT);
7549
                    tcg_gen_helper_1_1(do_emt, t0, t0);
7550
                     break;
7551
                case OPC_DVPE:
7552
                    check_insn(env, ctx, ASE_MT);
7553
                    tcg_gen_helper_1_1(do_dvpe, t0, t0);
7554
                    break;
7555
                case OPC_EVPE:
7556
                    check_insn(env, ctx, ASE_MT);
7557
                    tcg_gen_helper_1_1(do_evpe, t0, t0);
7558
                    break;
7559
                case OPC_DI:
7560
                    check_insn(env, ctx, ISA_MIPS32R2);
7561
                    save_cpu_state(ctx, 1);
7562
                    tcg_gen_helper_1_0(do_di, t0);
7563
                    /* Stop translation as we may have switched the execution mode */
7564
                    ctx->bstate = BS_STOP;
7565
                    break;
7566
                case OPC_EI:
7567
                    check_insn(env, ctx, ISA_MIPS32R2);
7568
                    save_cpu_state(ctx, 1);
7569
                    tcg_gen_helper_1_0(do_ei, t0);
7570
                    /* Stop translation as we may have switched the execution mode */
7571
                    ctx->bstate = BS_STOP;
7572
                    break;
7573
                default:            /* Invalid */
7574
                    MIPS_INVAL("mfmc0");
7575
                    generate_exception(ctx, EXCP_RI);
7576
                    break;
7577
                }
7578
                gen_store_gpr(t0, rt);
7579
                tcg_temp_free(t0);
7580
            }
7581
            break;
7582
        case OPC_RDPGPR:
7583
            check_insn(env, ctx, ISA_MIPS32R2);
7584
            gen_load_srsgpr(rt, rd);
7585
            break;
7586
        case OPC_WRPGPR:
7587
            check_insn(env, ctx, ISA_MIPS32R2);
7588
            gen_store_srsgpr(rt, rd);
7589
            break;
7590
        default:
7591
            MIPS_INVAL("cp0");
7592
            generate_exception(ctx, EXCP_RI);
7593
            break;
7594
        }
7595
        break;
7596
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7597
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7598
         break;
7599
    case OPC_J ... OPC_JAL: /* Jump */
7600
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7601
         gen_compute_branch(ctx, op, rs, rt, offset);
7602
         return;
7603
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7604
    case OPC_BEQL ... OPC_BGTZL:
7605
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7606
         return;
7607
    case OPC_LB ... OPC_LWR: /* Load and stores */
7608
    case OPC_SB ... OPC_SW:
7609
    case OPC_SWR:
7610
    case OPC_LL:
7611
    case OPC_SC:
7612
         gen_ldst(ctx, op, rt, rs, imm);
7613
         break;
7614
    case OPC_CACHE:
7615
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7616
        /* Treat as NOP. */
7617
        break;
7618
    case OPC_PREF:
7619
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7620
        /* Treat as NOP. */
7621
        break;
7622

    
7623
    /* Floating point (COP1). */
7624
    case OPC_LWC1:
7625
    case OPC_LDC1:
7626
    case OPC_SWC1:
7627
    case OPC_SDC1:
7628
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7629
            save_cpu_state(ctx, 1);
7630
            check_cp1_enabled(ctx);
7631
            gen_flt_ldst(ctx, op, rt, rs, imm);
7632
        } else {
7633
            generate_exception_err(ctx, EXCP_CpU, 1);
7634
        }
7635
        break;
7636

    
7637
    case OPC_CP1:
7638
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7639
            save_cpu_state(ctx, 1);
7640
            check_cp1_enabled(ctx);
7641
            op1 = MASK_CP1(ctx->opcode);
7642
            switch (op1) {
7643
            case OPC_MFHC1:
7644
            case OPC_MTHC1:
7645
                check_insn(env, ctx, ISA_MIPS32R2);
7646
            case OPC_MFC1:
7647
            case OPC_CFC1:
7648
            case OPC_MTC1:
7649
            case OPC_CTC1:
7650
                gen_cp1(ctx, op1, rt, rd);
7651
                break;
7652
#if defined(TARGET_MIPS64)
7653
            case OPC_DMFC1:
7654
            case OPC_DMTC1:
7655
                check_insn(env, ctx, ISA_MIPS3);
7656
                gen_cp1(ctx, op1, rt, rd);
7657
                break;
7658
#endif
7659
            case OPC_BC1ANY2:
7660
            case OPC_BC1ANY4:
7661
                check_cop1x(ctx);
7662
                check_insn(env, ctx, ASE_MIPS3D);
7663
                /* fall through */
7664
            case OPC_BC1:
7665
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7666
                                    (rt >> 2) & 0x7, imm << 2);
7667
                return;
7668
            case OPC_S_FMT:
7669
            case OPC_D_FMT:
7670
            case OPC_W_FMT:
7671
            case OPC_L_FMT:
7672
            case OPC_PS_FMT:
7673
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7674
                           (imm >> 8) & 0x7);
7675
                break;
7676
            default:
7677
                MIPS_INVAL("cp1");
7678
                generate_exception (ctx, EXCP_RI);
7679
                break;
7680
            }
7681
        } else {
7682
            generate_exception_err(ctx, EXCP_CpU, 1);
7683
        }
7684
        break;
7685

    
7686
    /* COP2.  */
7687
    case OPC_LWC2:
7688
    case OPC_LDC2:
7689
    case OPC_SWC2:
7690
    case OPC_SDC2:
7691
    case OPC_CP2:
7692
        /* COP2: Not implemented. */
7693
        generate_exception_err(ctx, EXCP_CpU, 2);
7694
        break;
7695

    
7696
    case OPC_CP3:
7697
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7698
            save_cpu_state(ctx, 1);
7699
            check_cp1_enabled(ctx);
7700
            op1 = MASK_CP3(ctx->opcode);
7701
            switch (op1) {
7702
            case OPC_LWXC1:
7703
            case OPC_LDXC1:
7704
            case OPC_LUXC1:
7705
            case OPC_SWXC1:
7706
            case OPC_SDXC1:
7707
            case OPC_SUXC1:
7708
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7709
                break;
7710
            case OPC_PREFX:
7711
                /* Treat as NOP. */
7712
                break;
7713
            case OPC_ALNV_PS:
7714
            case OPC_MADD_S:
7715
            case OPC_MADD_D:
7716
            case OPC_MADD_PS:
7717
            case OPC_MSUB_S:
7718
            case OPC_MSUB_D:
7719
            case OPC_MSUB_PS:
7720
            case OPC_NMADD_S:
7721
            case OPC_NMADD_D:
7722
            case OPC_NMADD_PS:
7723
            case OPC_NMSUB_S:
7724
            case OPC_NMSUB_D:
7725
            case OPC_NMSUB_PS:
7726
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7727
                break;
7728
            default:
7729
                MIPS_INVAL("cp3");
7730
                generate_exception (ctx, EXCP_RI);
7731
                break;
7732
            }
7733
        } else {
7734
            generate_exception_err(ctx, EXCP_CpU, 1);
7735
        }
7736
        break;
7737

    
7738
#if defined(TARGET_MIPS64)
7739
    /* MIPS64 opcodes */
7740
    case OPC_LWU:
7741
    case OPC_LDL ... OPC_LDR:
7742
    case OPC_SDL ... OPC_SDR:
7743
    case OPC_LLD:
7744
    case OPC_LD:
7745
    case OPC_SCD:
7746
    case OPC_SD:
7747
        check_insn(env, ctx, ISA_MIPS3);
7748
        check_mips_64(ctx);
7749
        gen_ldst(ctx, op, rt, rs, imm);
7750
        break;
7751
    case OPC_DADDI ... OPC_DADDIU:
7752
        check_insn(env, ctx, ISA_MIPS3);
7753
        check_mips_64(ctx);
7754
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7755
        break;
7756
#endif
7757
    case OPC_JALX:
7758
        check_insn(env, ctx, ASE_MIPS16);
7759
        /* MIPS16: Not implemented. */
7760
    case OPC_MDMX:
7761
        check_insn(env, ctx, ASE_MDMX);
7762
        /* MDMX: Not implemented. */
7763
    default:            /* Invalid */
7764
        MIPS_INVAL("major opcode");
7765
        generate_exception(ctx, EXCP_RI);
7766
        break;
7767
    }
7768
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7769
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7770
        /* Branches completion */
7771
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7772
        ctx->bstate = BS_BRANCH;
7773
        save_cpu_state(ctx, 0);
7774
        /* FIXME: Need to clear can_do_io.  */
7775
        switch (hflags) {
7776
        case MIPS_HFLAG_B:
7777
            /* unconditional branch */
7778
            MIPS_DEBUG("unconditional branch");
7779
            gen_goto_tb(ctx, 0, ctx->btarget);
7780
            break;
7781
        case MIPS_HFLAG_BL:
7782
            /* blikely taken case */
7783
            MIPS_DEBUG("blikely branch taken");
7784
            gen_goto_tb(ctx, 0, ctx->btarget);
7785
            break;
7786
        case MIPS_HFLAG_BC:
7787
            /* Conditional branch */
7788
            MIPS_DEBUG("conditional branch");
7789
            {
7790
                int l1 = gen_new_label();
7791

    
7792
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7793
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7794
                gen_set_label(l1);
7795
                gen_goto_tb(ctx, 0, ctx->btarget);
7796
            }
7797
            break;
7798
        case MIPS_HFLAG_BR:
7799
            /* unconditional branch to register */
7800
            MIPS_DEBUG("branch to register");
7801
            tcg_gen_st_tl(btarget, cpu_env, offsetof(CPUState, active_tc.PC));
7802
            tcg_gen_exit_tb(0);
7803
            break;
7804
        default:
7805
            MIPS_DEBUG("unknown branch");
7806
            break;
7807
        }
7808
    }
7809
}
7810

    
7811
static inline int
7812
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7813
                                int search_pc)
7814
{
7815
    DisasContext ctx;
7816
    target_ulong pc_start;
7817
    uint16_t *gen_opc_end;
7818
    int j, lj = -1;
7819
    int num_insns;
7820
    int max_insns;
7821

    
7822
    if (search_pc && loglevel)
7823
        fprintf (logfile, "search pc %d\n", search_pc);
7824

    
7825
    pc_start = tb->pc;
7826
    /* Leave some spare opc slots for branch handling. */
7827
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
7828
    ctx.pc = pc_start;
7829
    ctx.saved_pc = -1;
7830
    ctx.tb = tb;
7831
    ctx.bstate = BS_NONE;
7832
    /* Restore delay slot state from the tb context.  */
7833
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7834
    restore_cpu_state(env, &ctx);
7835
#if defined(CONFIG_USER_ONLY)
7836
    ctx.mem_idx = MIPS_HFLAG_UM;
7837
#else
7838
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7839
#endif
7840
    num_insns = 0;
7841
    max_insns = tb->cflags & CF_COUNT_MASK;
7842
    if (max_insns == 0)
7843
        max_insns = CF_COUNT_MASK;
7844
#ifdef DEBUG_DISAS
7845
    if (loglevel & CPU_LOG_TB_CPU) {
7846
        fprintf(logfile, "------------------------------------------------\n");
7847
        /* FIXME: This may print out stale hflags from env... */
7848
        cpu_dump_state(env, logfile, fprintf, 0);
7849
    }
7850
#endif
7851
#ifdef MIPS_DEBUG_DISAS
7852
    if (loglevel & CPU_LOG_TB_IN_ASM)
7853
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7854
                tb, ctx.mem_idx, ctx.hflags);
7855
#endif
7856
    gen_icount_start();
7857
    while (ctx.bstate == BS_NONE) {
7858
        if (env->nb_breakpoints > 0) {
7859
            for(j = 0; j < env->nb_breakpoints; j++) {
7860
                if (env->breakpoints[j] == ctx.pc) {
7861
                    save_cpu_state(&ctx, 1);
7862
                    ctx.bstate = BS_BRANCH;
7863
                    tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
7864
                    /* Include the breakpoint location or the tb won't
7865
                     * be flushed when it must be.  */
7866
                    ctx.pc += 4;
7867
                    goto done_generating;
7868
                }
7869
            }
7870
        }
7871

    
7872
        if (search_pc) {
7873
            j = gen_opc_ptr - gen_opc_buf;
7874
            if (lj < j) {
7875
                lj++;
7876
                while (lj < j)
7877
                    gen_opc_instr_start[lj++] = 0;
7878
            }
7879
            gen_opc_pc[lj] = ctx.pc;
7880
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7881
            gen_opc_instr_start[lj] = 1;
7882
            gen_opc_icount[lj] = num_insns;
7883
        }
7884
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7885
            gen_io_start();
7886
        ctx.opcode = ldl_code(ctx.pc);
7887
        decode_opc(env, &ctx);
7888
        ctx.pc += 4;
7889
        num_insns++;
7890

    
7891
        if (env->singlestep_enabled)
7892
            break;
7893

    
7894
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7895
            break;
7896

    
7897
        if (gen_opc_ptr >= gen_opc_end)
7898
            break;
7899

    
7900
        if (num_insns >= max_insns)
7901
            break;
7902
#if defined (MIPS_SINGLE_STEP)
7903
        break;
7904
#endif
7905
    }
7906
    if (tb->cflags & CF_LAST_IO)
7907
        gen_io_end();
7908
    if (env->singlestep_enabled) {
7909
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7910
        tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
7911
    } else {
7912
        switch (ctx.bstate) {
7913
        case BS_STOP:
7914
            tcg_gen_helper_0_0(do_interrupt_restart);
7915
            gen_goto_tb(&ctx, 0, ctx.pc);
7916
            break;
7917
        case BS_NONE:
7918
            save_cpu_state(&ctx, 0);
7919
            gen_goto_tb(&ctx, 0, ctx.pc);
7920
            break;
7921
        case BS_EXCP:
7922
            tcg_gen_helper_0_0(do_interrupt_restart);
7923
            tcg_gen_exit_tb(0);
7924
            break;
7925
        case BS_BRANCH:
7926
        default:
7927
            break;
7928
        }
7929
    }
7930
done_generating:
7931
    gen_icount_end(tb, num_insns);
7932
    *gen_opc_ptr = INDEX_op_end;
7933
    if (search_pc) {
7934
        j = gen_opc_ptr - gen_opc_buf;
7935
        lj++;
7936
        while (lj <= j)
7937
            gen_opc_instr_start[lj++] = 0;
7938
    } else {
7939
        tb->size = ctx.pc - pc_start;
7940
        tb->icount = num_insns;
7941
    }
7942
#ifdef DEBUG_DISAS
7943
#if defined MIPS_DEBUG_DISAS
7944
    if (loglevel & CPU_LOG_TB_IN_ASM)
7945
        fprintf(logfile, "\n");
7946
#endif
7947
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7948
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7949
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7950
        fprintf(logfile, "\n");
7951
    }
7952
    if (loglevel & CPU_LOG_TB_CPU) {
7953
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7954
    }
7955
#endif
7956

    
7957
    return 0;
7958
}
7959

    
7960
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7961
{
7962
    return gen_intermediate_code_internal(env, tb, 0);
7963
}
7964

    
7965
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7966
{
7967
    return gen_intermediate_code_internal(env, tb, 1);
7968
}
7969

    
7970
void fpu_dump_state(CPUState *env, FILE *f,
7971
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7972
                    int flags)
7973
{
7974
    int i;
7975
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
7976

    
7977
#define printfpr(fp)                                                        \
7978
    do {                                                                    \
7979
        if (is_fpu64)                                                       \
7980
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
7981
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
7982
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
7983
        else {                                                              \
7984
            fpr_t tmp;                                                      \
7985
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
7986
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
7987
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
7988
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
7989
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
7990
        }                                                                   \
7991
    } while(0)
7992

    
7993

    
7994
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
7995
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
7996
                get_float_exception_flags(&env->fpu->fp_status));
7997
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
7998
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
7999
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
8000
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8001
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8002
        printfpr(&env->fpu->fpr[i]);
8003
    }
8004

    
8005
#undef printfpr
8006
}
8007

    
8008
void dump_fpu (CPUState *env)
8009
{
8010
    if (loglevel) {
8011
        fprintf(logfile,
8012
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
8013
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
8014
                " %04x\n",
8015
                env->active_tc.PC, env->active_tc.HI[0],
8016
                env->active_tc.LO[0], env->hflags, env->btarget,
8017
                env->bcond);
8018
       fpu_dump_state(env, logfile, fprintf, 0);
8019
    }
8020
}
8021

    
8022
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8023
/* Debug help: The architecture requires 32bit code to maintain proper
8024
   sign-extended values on 64bit machines.  */
8025

    
8026
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8027

    
8028
void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8029
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8030
                     int flags)
8031
{
8032
    int i;
8033

    
8034
    if (!SIGN_EXT_P(env->active_tc.PC))
8035
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8036
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8037
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8038
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8039
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8040
    if (!SIGN_EXT_P(env->btarget))
8041
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8042

    
8043
    for (i = 0; i < 32; i++) {
8044
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8045
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8046
    }
8047

    
8048
    if (!SIGN_EXT_P(env->CP0_EPC))
8049
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8050
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8051
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8052
}
8053
#endif
8054

    
8055
void cpu_dump_state (CPUState *env, FILE *f,
8056
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8057
                     int flags)
8058
{
8059
    int i;
8060

    
8061
    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",
8062
                env->active_tc.PC, env->active_tc.HI, env->active_tc.LO, env->hflags, env->btarget, env->bcond);
8063
    for (i = 0; i < 32; i++) {
8064
        if ((i & 3) == 0)
8065
            cpu_fprintf(f, "GPR%02d:", i);
8066
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8067
        if ((i & 3) == 3)
8068
            cpu_fprintf(f, "\n");
8069
    }
8070

    
8071
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8072
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8073
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8074
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8075
    if (env->hflags & MIPS_HFLAG_FPU)
8076
        fpu_dump_state(env, f, cpu_fprintf, flags);
8077
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8078
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8079
#endif
8080
}
8081

    
8082
static void mips_tcg_init(void)
8083
{
8084
    static int inited;
8085

    
8086
    /* Initialize various static tables. */
8087
    if (inited)
8088
        return;
8089

    
8090
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8091
    bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8092
                               offsetof(CPUState, bcond), "bcond");
8093
    btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8094
                                 offsetof(CPUState, btarget), "btarget");
8095
    current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
8096
                                     TCG_AREG0,
8097
                                     offsetof(CPUState, fpu),
8098
                                     "current_fpu");
8099

    
8100
    /* register helpers */
8101
#undef DEF_HELPER
8102
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8103
#include "helper.h"
8104

    
8105
    fpu32_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[FP_ENDIAN_IDX]), "WT0");
8106
    fpu32_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[FP_ENDIAN_IDX]), "WT1");
8107
    fpu32_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[FP_ENDIAN_IDX]), "WT2");
8108
    fpu64_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft0.d), "DT0");
8109
    fpu64_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft1.d), "DT1");
8110
    fpu64_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft2.d), "DT2");
8111
    fpu32h_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[!FP_ENDIAN_IDX]), "WTH0");
8112
    fpu32h_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[!FP_ENDIAN_IDX]), "WTH1");
8113
    fpu32h_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[!FP_ENDIAN_IDX]), "WTH2");
8114

    
8115
    inited = 1;
8116
}
8117

    
8118
#include "translate_init.c"
8119

    
8120
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8121
{
8122
    CPUMIPSState *env;
8123
    const mips_def_t *def;
8124

    
8125
    def = cpu_mips_find_by_name(cpu_model);
8126
    if (!def)
8127
        return NULL;
8128
    env = qemu_mallocz(sizeof(CPUMIPSState));
8129
    if (!env)
8130
        return NULL;
8131
    env->cpu_model = def;
8132

    
8133
    cpu_exec_init(env);
8134
    env->cpu_model_str = cpu_model;
8135
    mips_tcg_init();
8136
    cpu_reset(env);
8137
    return env;
8138
}
8139

    
8140
void cpu_reset (CPUMIPSState *env)
8141
{
8142
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8143

    
8144
    tlb_flush(env, 1);
8145

    
8146
    /* Minimal init */
8147
#if !defined(CONFIG_USER_ONLY)
8148
    if (env->hflags & MIPS_HFLAG_BMASK) {
8149
        /* If the exception was raised from a delay slot,
8150
         * come back to the jump.  */
8151
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8152
    } else {
8153
        env->CP0_ErrorEPC = env->active_tc.PC;
8154
    }
8155
    env->active_tc.PC = (int32_t)0xBFC00000;
8156
    env->CP0_Wired = 0;
8157
    /* SMP not implemented */
8158
    env->CP0_EBase = 0x80000000;
8159
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8160
    /* vectored interrupts not implemented, timer on int 7,
8161
       no performance counters. */
8162
    env->CP0_IntCtl = 0xe0000000;
8163
    {
8164
        int i;
8165

    
8166
        for (i = 0; i < 7; i++) {
8167
            env->CP0_WatchLo[i] = 0;
8168
            env->CP0_WatchHi[i] = 0x80000000;
8169
        }
8170
        env->CP0_WatchLo[7] = 0;
8171
        env->CP0_WatchHi[7] = 0;
8172
    }
8173
    /* Count register increments in debug mode, EJTAG version 1 */
8174
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8175
#endif
8176
    env->exception_index = EXCP_NONE;
8177
#if defined(CONFIG_USER_ONLY)
8178
    env->hflags = MIPS_HFLAG_UM;
8179
    env->user_mode_only = 1;
8180
#else
8181
    env->hflags = MIPS_HFLAG_CP0;
8182
#endif
8183
    cpu_mips_register(env, env->cpu_model);
8184
}
8185

    
8186
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8187
                unsigned long searched_pc, int pc_pos, void *puc)
8188
{
8189
    env->active_tc.PC = gen_opc_pc[pc_pos];
8190
    env->hflags &= ~MIPS_HFLAG_BMASK;
8191
    env->hflags |= gen_opc_hflags[pc_pos];
8192
}