Statistics
| Branch: | Revision:

root / target-mips / translate.c @ dd5d6fe9

History | View | Annotate | Download (244.1 kB)

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

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

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

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

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
425
/* global register indices */
426
static TCGv cpu_env, current_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_2ii(void *func, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4)
468
{
469
    TCGv tmp1 = tcg_const_i32(arg3);
470
    TCGv tmp2 = tcg_const_i32(arg3);
471

    
472
    tcg_gen_helper_0_4(func, arg1, arg2, 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_2i(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3)
494
{
495
    TCGv tmp = tcg_const_i32(arg3);
496

    
497
    tcg_gen_helper_1_3(func, ret, arg1, arg2, tmp);
498
    tcg_temp_free(tmp);
499
}
500

    
501
static inline void tcg_gen_helper_1_2ii(void *func, TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4)
502
{
503
    TCGv tmp1 = tcg_const_i32(arg3);
504
    TCGv tmp2 = tcg_const_i32(arg3);
505

    
506
    tcg_gen_helper_1_4(func, ret, arg1, arg2, tmp1, tmp2);
507
    tcg_temp_free(tmp1);
508
    tcg_temp_free(tmp2);
509
}
510

    
511
typedef struct DisasContext {
512
    struct TranslationBlock *tb;
513
    target_ulong pc, saved_pc;
514
    uint32_t opcode;
515
    uint32_t fp_status;
516
    /* Routine used to access memory */
517
    int mem_idx;
518
    uint32_t hflags, saved_hflags;
519
    int bstate;
520
    target_ulong btarget;
521
} DisasContext;
522

    
523
enum {
524
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
525
                      * exception condition
526
                      */
527
    BS_STOP     = 1, /* We want to stop translation for any reason */
528
    BS_BRANCH   = 2, /* We reached a branch condition     */
529
    BS_EXCP     = 3, /* We reached an exception condition */
530
};
531

    
532
static const char *regnames[] =
533
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
534
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
535
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
536
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
537

    
538
static const char *fregnames[] =
539
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
540
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
541
      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
542
      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
543

    
544
#ifdef MIPS_DEBUG_DISAS
545
#define MIPS_DEBUG(fmt, args...)                                              \
546
do {                                                                          \
547
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
548
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
549
                ctx->pc, ctx->opcode , ##args);                               \
550
    }                                                                         \
551
} while (0)
552
#else
553
#define MIPS_DEBUG(fmt, args...) do { } while(0)
554
#endif
555

    
556
#define MIPS_INVAL(op)                                                        \
557
do {                                                                          \
558
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
559
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
560
} while (0)
561

    
562
/* General purpose registers moves. */
563
static inline void gen_load_gpr (TCGv t, int reg)
564
{
565
    if (reg == 0)
566
        tcg_gen_movi_tl(t, 0);
567
    else
568
        tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
569
                                  sizeof(target_ulong) * reg);
570
}
571

    
572
static inline void gen_store_gpr (TCGv t, int reg)
573
{
574
    if (reg != 0)
575
        tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
576
                                  sizeof(target_ulong) * reg);
577
}
578

    
579
/* Moves to/from HI and LO registers.  */
580
static inline void gen_load_LO (TCGv t, int reg)
581
{
582
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
583
                              sizeof(target_ulong) * reg);
584
}
585

    
586
static inline void gen_store_LO (TCGv t, int reg)
587
{
588
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
589
                              sizeof(target_ulong) * reg);
590
}
591

    
592
static inline void gen_load_HI (TCGv t, int reg)
593
{
594
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
595
                              sizeof(target_ulong) * reg);
596
}
597

    
598
static inline void gen_store_HI (TCGv t, int reg)
599
{
600
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
601
                              sizeof(target_ulong) * reg);
602
}
603

    
604
/* Moves to/from shadow registers. */
605
static inline void gen_load_srsgpr (int from, int to)
606
{
607
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
608

    
609
    if (from == 0)
610
        tcg_gen_movi_tl(r_tmp1, 0);
611
    else {
612
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
613

    
614
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
615
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
616
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
617
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
618
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
619

    
620
        tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from);
621
        tcg_temp_free(r_tmp2);
622
    }
623
    gen_store_gpr(r_tmp1, to);
624
    tcg_temp_free(r_tmp1);
625
}
626

    
627
static inline void gen_store_srsgpr (int from, int to)
628
{
629
    if (to != 0) {
630
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
631
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
632

    
633
        gen_load_gpr(r_tmp1, from);
634
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
635
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
636
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
637
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
638
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
639

    
640
        tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to);
641
        tcg_temp_free(r_tmp1);
642
        tcg_temp_free(r_tmp2);
643
    }
644
}
645

    
646
/* Floating point register moves. */
647
static inline void gen_load_fpr32 (TCGv t, int reg)
648
{
649
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
650
}
651

    
652
static inline void gen_store_fpr32 (TCGv t, int reg)
653
{
654
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * FP_ENDIAN_IDX);
655
}
656

    
657
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
658
{
659
    if (ctx->hflags & MIPS_HFLAG_F64) {
660
        tcg_gen_ld_i64(t, current_fpu, 8 * reg);
661
    } else {
662
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
663
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
664

    
665
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
666
        tcg_gen_extu_i32_i64(t, r_tmp1);
667
        tcg_gen_shli_i64(t, t, 32);
668
        tcg_gen_ld_i32(r_tmp1, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
669
        tcg_gen_extu_i32_i64(r_tmp2, r_tmp1);
670
        tcg_gen_or_i64(t, t, r_tmp2);
671
        tcg_temp_free(r_tmp1);
672
        tcg_temp_free(r_tmp2);
673
    }
674
}
675

    
676
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
677
{
678
    if (ctx->hflags & MIPS_HFLAG_F64) {
679
        tcg_gen_st_i64(t, current_fpu, 8 * reg);
680
    } else {
681
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
682

    
683
        tcg_gen_trunc_i64_i32(r_tmp, t);
684
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg & ~1) + 4 * FP_ENDIAN_IDX);
685
        tcg_gen_shri_i64(t, t, 32);
686
        tcg_gen_trunc_i64_i32(r_tmp, t);
687
        tcg_gen_st_i32(r_tmp, current_fpu, 8 * (reg | 1) + 4 * FP_ENDIAN_IDX);
688
        tcg_temp_free(r_tmp);
689
    }
690
}
691

    
692
static inline void gen_load_fpr32h (TCGv t, int reg)
693
{
694
    tcg_gen_ld_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
695
}
696

    
697
static inline void gen_store_fpr32h (TCGv t, int reg)
698
{
699
    tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX);
700
}
701

    
702
static inline void get_fp_cond (TCGv t)
703
{
704
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
705
    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
706

    
707
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
708
    tcg_gen_shri_i32(r_tmp2, r_tmp1, 24);
709
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
710
    tcg_gen_shri_i32(r_tmp1, r_tmp1, 23);
711
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
712
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
713
    tcg_temp_free(r_tmp1);
714
    tcg_temp_free(r_tmp2);
715
}
716

    
717
#define FOP_CONDS(type, fmt)                                              \
718
static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = {            \
719
    do_cmp ## type ## _ ## fmt ## _f,                                     \
720
    do_cmp ## type ## _ ## fmt ## _un,                                    \
721
    do_cmp ## type ## _ ## fmt ## _eq,                                    \
722
    do_cmp ## type ## _ ## fmt ## _ueq,                                   \
723
    do_cmp ## type ## _ ## fmt ## _olt,                                   \
724
    do_cmp ## type ## _ ## fmt ## _ult,                                   \
725
    do_cmp ## type ## _ ## fmt ## _ole,                                   \
726
    do_cmp ## type ## _ ## fmt ## _ule,                                   \
727
    do_cmp ## type ## _ ## fmt ## _sf,                                    \
728
    do_cmp ## type ## _ ## fmt ## _ngle,                                  \
729
    do_cmp ## type ## _ ## fmt ## _seq,                                   \
730
    do_cmp ## type ## _ ## fmt ## _ngl,                                   \
731
    do_cmp ## type ## _ ## fmt ## _lt,                                    \
732
    do_cmp ## type ## _ ## fmt ## _nge,                                   \
733
    do_cmp ## type ## _ ## fmt ## _le,                                    \
734
    do_cmp ## type ## _ ## fmt ## _ngt,                                   \
735
};                                                                        \
736
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc)            \
737
{                                                                         \
738
    tcg_gen_helper_0_i(fcmp ## type ## _ ## fmt ## _table[n], cc);        \
739
}
740

    
741
FOP_CONDS(, d)
742
FOP_CONDS(abs, d)
743
FOP_CONDS(, s)
744
FOP_CONDS(abs, s)
745
FOP_CONDS(, ps)
746
FOP_CONDS(abs, ps)
747
#undef FOP_CONDS
748

    
749
/* Tests */
750
#define OP_COND(name, cond)                                   \
751
void glue(gen_op_, name) (TCGv t0, TCGv t1)                   \
752
{                                                             \
753
    int l1 = gen_new_label();                                 \
754
    int l2 = gen_new_label();                                 \
755
                                                              \
756
    tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
757
    tcg_gen_movi_tl(t0, 0);                                   \
758
    tcg_gen_br(l2);                                           \
759
    gen_set_label(l1);                                        \
760
    tcg_gen_movi_tl(t0, 1);                                   \
761
    gen_set_label(l2);                                        \
762
}
763
OP_COND(eq, TCG_COND_EQ);
764
OP_COND(ne, TCG_COND_NE);
765
OP_COND(ge, TCG_COND_GE);
766
OP_COND(geu, TCG_COND_GEU);
767
OP_COND(lt, TCG_COND_LT);
768
OP_COND(ltu, TCG_COND_LTU);
769
#undef OP_COND
770

    
771
#define OP_CONDI(name, cond)                                  \
772
void glue(gen_op_, name) (TCGv t, target_ulong val)           \
773
{                                                             \
774
    int l1 = gen_new_label();                                 \
775
    int l2 = gen_new_label();                                 \
776
                                                              \
777
    tcg_gen_brcondi_tl(cond, t, val, l1);                     \
778
    tcg_gen_movi_tl(t, 0);                                    \
779
    tcg_gen_br(l2);                                           \
780
    gen_set_label(l1);                                        \
781
    tcg_gen_movi_tl(t, 1);                                    \
782
    gen_set_label(l2);                                        \
783
}
784
OP_CONDI(lti, TCG_COND_LT);
785
OP_CONDI(ltiu, TCG_COND_LTU);
786
#undef OP_CONDI
787

    
788
#define OP_CONDZ(name, cond)                                  \
789
void glue(gen_op_, name) (TCGv t)                             \
790
{                                                             \
791
    int l1 = gen_new_label();                                 \
792
    int l2 = gen_new_label();                                 \
793
                                                              \
794
    tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
795
    tcg_gen_movi_tl(t, 0);                                    \
796
    tcg_gen_br(l2);                                           \
797
    gen_set_label(l1);                                        \
798
    tcg_gen_movi_tl(t, 1);                                    \
799
    gen_set_label(l2);                                        \
800
}
801
OP_CONDZ(gez, TCG_COND_GE);
802
OP_CONDZ(gtz, TCG_COND_GT);
803
OP_CONDZ(lez, TCG_COND_LE);
804
OP_CONDZ(ltz, TCG_COND_LT);
805
#undef OP_CONDZ
806

    
807
static inline void gen_save_pc(target_ulong pc)
808
{
809
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
810

    
811
    tcg_gen_movi_tl(r_tmp, pc);
812
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC));
813
    tcg_temp_free(r_tmp);
814
}
815

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

    
820
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
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 gen_save_btarget(target_ulong btarget)
826
{
827
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
828

    
829
    tcg_gen_movi_tl(r_tmp, btarget);
830
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
831
    tcg_temp_free(r_tmp);
832
}
833

    
834
static always_inline void gen_save_breg_target(int reg)
835
{
836
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
837

    
838
    gen_load_gpr(r_tmp, reg);
839
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
840
    tcg_temp_free(r_tmp);
841
}
842

    
843
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
844
{
845
#if defined MIPS_DEBUG_DISAS
846
    if (loglevel & CPU_LOG_TB_IN_ASM) {
847
            fprintf(logfile, "hflags %08x saved %08x\n",
848
                    ctx->hflags, ctx->saved_hflags);
849
    }
850
#endif
851
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
852
        gen_save_pc(ctx->pc);
853
        ctx->saved_pc = ctx->pc;
854
    }
855
    if (ctx->hflags != ctx->saved_hflags) {
856
        TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
857

    
858
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
859
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
860
        tcg_temp_free(r_tmp);
861
        ctx->saved_hflags = ctx->hflags;
862
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
863
        case MIPS_HFLAG_BR:
864
            break;
865
        case MIPS_HFLAG_BC:
866
        case MIPS_HFLAG_BL:
867
        case MIPS_HFLAG_B:
868
            gen_save_btarget(ctx->btarget);
869
            break;
870
        }
871
    }
872
}
873

    
874
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
875
{
876
    ctx->saved_hflags = ctx->hflags;
877
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
878
    case MIPS_HFLAG_BR:
879
        break;
880
    case MIPS_HFLAG_BC:
881
    case MIPS_HFLAG_BL:
882
    case MIPS_HFLAG_B:
883
        ctx->btarget = env->btarget;
884
        break;
885
    }
886
}
887

    
888
static always_inline void
889
generate_exception_err (DisasContext *ctx, int excp, int err)
890
{
891
    save_cpu_state(ctx, 1);
892
    tcg_gen_helper_0_ii(do_raise_exception_err, excp, err);
893
    tcg_gen_helper_0_0(do_interrupt_restart);
894
    tcg_gen_exit_tb(0);
895
}
896

    
897
static always_inline void
898
generate_exception (DisasContext *ctx, int excp)
899
{
900
    save_cpu_state(ctx, 1);
901
    tcg_gen_helper_0_i(do_raise_exception, excp);
902
    tcg_gen_helper_0_0(do_interrupt_restart);
903
    tcg_gen_exit_tb(0);
904
}
905

    
906
/* Addresses computation */
907
static inline void gen_op_addr_add (TCGv t0, TCGv t1)
908
{
909
    tcg_gen_add_tl(t0, t0, t1);
910

    
911
#if defined(TARGET_MIPS64)
912
    /* For compatibility with 32-bit code, data reference in user mode
913
       with Status_UX = 0 should be casted to 32-bit and sign extended.
914
       See the MIPS64 PRA manual, section 4.10. */
915
    {
916
        int l1 = gen_new_label();
917
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
918

    
919
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
920
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
921
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
922
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
923
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
924
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
925
        tcg_temp_free(r_tmp);
926
        tcg_gen_ext32s_i64(t0, t0);
927
        gen_set_label(l1);
928
    }
929
#endif
930
}
931

    
932
static always_inline void check_cp0_enabled(DisasContext *ctx)
933
{
934
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
935
        generate_exception_err(ctx, EXCP_CpU, 1);
936
}
937

    
938
static always_inline void check_cp1_enabled(DisasContext *ctx)
939
{
940
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
941
        generate_exception_err(ctx, EXCP_CpU, 1);
942
}
943

    
944
/* Verify that the processor is running with COP1X instructions enabled.
945
   This is associated with the nabla symbol in the MIPS32 and MIPS64
946
   opcode tables.  */
947

    
948
static always_inline void check_cop1x(DisasContext *ctx)
949
{
950
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
951
        generate_exception(ctx, EXCP_RI);
952
}
953

    
954
/* Verify that the processor is running with 64-bit floating-point
955
   operations enabled.  */
956

    
957
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
958
{
959
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
960
        generate_exception(ctx, EXCP_RI);
961
}
962

    
963
/*
964
 * Verify if floating point register is valid; an operation is not defined
965
 * if bit 0 of any register specification is set and the FR bit in the
966
 * Status register equals zero, since the register numbers specify an
967
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
968
 * in the Status register equals one, both even and odd register numbers
969
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
970
 *
971
 * Multiple 64 bit wide registers can be checked by calling
972
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
973
 */
974
void check_cp1_registers(DisasContext *ctx, int regs)
975
{
976
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
977
        generate_exception(ctx, EXCP_RI);
978
}
979

    
980
/* This code generates a "reserved instruction" exception if the
981
   CPU does not support the instruction set corresponding to flags. */
982
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
983
{
984
    if (unlikely(!(env->insn_flags & flags)))
985
        generate_exception(ctx, EXCP_RI);
986
}
987

    
988
/* This code generates a "reserved instruction" exception if 64-bit
989
   instructions are not enabled. */
990
static always_inline void check_mips_64(DisasContext *ctx)
991
{
992
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
993
        generate_exception(ctx, EXCP_RI);
994
}
995

    
996
/* load/store instructions. */
997
#define OP_LD(insn,fname)                                        \
998
void inline op_ldst_##insn(TCGv t0, DisasContext *ctx)           \
999
{                                                                \
1000
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
1001
}
1002
OP_LD(lb,ld8s);
1003
OP_LD(lbu,ld8u);
1004
OP_LD(lh,ld16s);
1005
OP_LD(lhu,ld16u);
1006
OP_LD(lw,ld32s);
1007
#if defined(TARGET_MIPS64)
1008
OP_LD(lwu,ld32u);
1009
OP_LD(ld,ld64);
1010
#endif
1011
#undef OP_LD
1012

    
1013
#define OP_ST(insn,fname)                                        \
1014
void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
1015
{                                                                \
1016
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
1017
}
1018
OP_ST(sb,st8);
1019
OP_ST(sh,st16);
1020
OP_ST(sw,st32);
1021
#if defined(TARGET_MIPS64)
1022
OP_ST(sd,st64);
1023
#endif
1024
#undef OP_ST
1025

    
1026
#define OP_LD_ATOMIC(insn,fname)                                        \
1027
void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)         \
1028
{                                                                       \
1029
    tcg_gen_mov_tl(t1, t0);                                             \
1030
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
1031
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
1032
}
1033
OP_LD_ATOMIC(ll,ld32s);
1034
#if defined(TARGET_MIPS64)
1035
OP_LD_ATOMIC(lld,ld64);
1036
#endif
1037
#undef OP_LD_ATOMIC
1038

    
1039
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1040
void inline op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)         \
1041
{                                                                       \
1042
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);                       \
1043
    int l1 = gen_new_label();                                           \
1044
    int l2 = gen_new_label();                                           \
1045
    int l3 = gen_new_label();                                           \
1046
                                                                        \
1047
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
1048
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1049
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
1050
    generate_exception(ctx, EXCP_AdES);                                 \
1051
    gen_set_label(l1);                                                  \
1052
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1053
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
1054
    tcg_temp_free(r_tmp);                                               \
1055
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
1056
    tcg_gen_movi_tl(t0, 1);                                             \
1057
    tcg_gen_br(l3);                                                     \
1058
    gen_set_label(l2);                                                  \
1059
    tcg_gen_movi_tl(t0, 0);                                             \
1060
    gen_set_label(l3);                                                  \
1061
}
1062
OP_ST_ATOMIC(sc,st32,0x3);
1063
#if defined(TARGET_MIPS64)
1064
OP_ST_ATOMIC(scd,st64,0x7);
1065
#endif
1066
#undef OP_ST_ATOMIC
1067

    
1068
/* Load and store */
1069
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1070
                      int base, int16_t offset)
1071
{
1072
    const char *opn = "ldst";
1073
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1074
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1075

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

    
1232
/* Load and store */
1233
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1234
                      int base, int16_t offset)
1235
{
1236
    const char *opn = "flt_ldst";
1237
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1238

    
1239
    if (base == 0) {
1240
        tcg_gen_movi_tl(t0, offset);
1241
    } else if (offset == 0) {
1242
        gen_load_gpr(t0, base);
1243
    } else {
1244
        TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1245

    
1246
        gen_load_gpr(t0, base);
1247
        tcg_gen_movi_tl(t1, offset);
1248
        gen_op_addr_add(t0, t1);
1249
        tcg_temp_free(t1);
1250
    }
1251
    /* Don't do NOP if destination is zero: we must perform the actual
1252
       memory access. */
1253
    switch (opc) {
1254
    case OPC_LWC1:
1255
        tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx);
1256
        gen_store_fpr32(fpu32_T[0], ft);
1257
        opn = "lwc1";
1258
        break;
1259
    case OPC_SWC1:
1260
        gen_load_fpr32(fpu32_T[0], ft);
1261
        tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx);
1262
        opn = "swc1";
1263
        break;
1264
    case OPC_LDC1:
1265
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
1266
        gen_store_fpr64(ctx, fpu64_T[0], ft);
1267
        opn = "ldc1";
1268
        break;
1269
    case OPC_SDC1:
1270
        gen_load_fpr64(ctx, fpu64_T[0], ft);
1271
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
1272
        opn = "sdc1";
1273
        break;
1274
    default:
1275
        MIPS_INVAL(opn);
1276
        generate_exception(ctx, EXCP_RI);
1277
        goto out;
1278
    }
1279
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1280
 out:
1281
    tcg_temp_free(t0);
1282
}
1283

    
1284
/* Arithmetic with immediate operand */
1285
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1286
                           int rt, int rs, int16_t imm)
1287
{
1288
    target_ulong uimm;
1289
    const char *opn = "imm arith";
1290
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1291

    
1292
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1293
        /* If no destination, treat it as a NOP.
1294
           For addi, we must generate the overflow exception when needed. */
1295
        MIPS_DEBUG("NOP");
1296
        goto out;
1297
    }
1298
    uimm = (uint16_t)imm;
1299
    switch (opc) {
1300
    case OPC_ADDI:
1301
    case OPC_ADDIU:
1302
#if defined(TARGET_MIPS64)
1303
    case OPC_DADDI:
1304
    case OPC_DADDIU:
1305
#endif
1306
    case OPC_SLTI:
1307
    case OPC_SLTIU:
1308
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1309
        /* Fall through. */
1310
    case OPC_ANDI:
1311
    case OPC_ORI:
1312
    case OPC_XORI:
1313
        gen_load_gpr(t0, rs);
1314
        break;
1315
    case OPC_LUI:
1316
        tcg_gen_movi_tl(t0, imm << 16);
1317
        break;
1318
    case OPC_SLL:
1319
    case OPC_SRA:
1320
    case OPC_SRL:
1321
#if defined(TARGET_MIPS64)
1322
    case OPC_DSLL:
1323
    case OPC_DSRA:
1324
    case OPC_DSRL:
1325
    case OPC_DSLL32:
1326
    case OPC_DSRA32:
1327
    case OPC_DSRL32:
1328
#endif
1329
        uimm &= 0x1f;
1330
        gen_load_gpr(t0, rs);
1331
        break;
1332
    }
1333
    switch (opc) {
1334
    case OPC_ADDI:
1335
        {
1336
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1337
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1338
            int l1 = gen_new_label();
1339

    
1340
            save_cpu_state(ctx, 1);
1341
            tcg_gen_ext32s_tl(r_tmp1, t0);
1342
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1343

    
1344
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1345
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1346
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1347
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1348
            tcg_temp_free(r_tmp2);
1349
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1350
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1351
            tcg_temp_free(r_tmp1);
1352
            /* operands of same sign, result different sign */
1353
            generate_exception(ctx, EXCP_OVERFLOW);
1354
            gen_set_label(l1);
1355

    
1356
            tcg_gen_ext32s_tl(t0, t0);
1357
        }
1358
        opn = "addi";
1359
        break;
1360
    case OPC_ADDIU:
1361
        tcg_gen_ext32s_tl(t0, t0);
1362
        tcg_gen_addi_tl(t0, t0, uimm);
1363
        tcg_gen_ext32s_tl(t0, t0);
1364
        opn = "addiu";
1365
        break;
1366
#if defined(TARGET_MIPS64)
1367
    case OPC_DADDI:
1368
        {
1369
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1370
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1371
            int l1 = gen_new_label();
1372

    
1373
            save_cpu_state(ctx, 1);
1374
            tcg_gen_mov_tl(r_tmp1, t0);
1375
            tcg_gen_addi_tl(t0, t0, uimm);
1376

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

    
1446
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1447
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1448
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1449
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1450
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1451
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1452
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1453
                    tcg_temp_free(r_tmp1);
1454
                    tcg_temp_free(r_tmp2);
1455
                }
1456
                opn = "rotr";
1457
            } else {
1458
                tcg_gen_ext32u_tl(t0, t0);
1459
                tcg_gen_shri_tl(t0, t0, uimm);
1460
                tcg_gen_ext32s_tl(t0, t0);
1461
                opn = "srl";
1462
            }
1463
            break;
1464
        default:
1465
            MIPS_INVAL("invalid srl flag");
1466
            generate_exception(ctx, EXCP_RI);
1467
            break;
1468
        }
1469
        break;
1470
#if defined(TARGET_MIPS64)
1471
    case OPC_DSLL:
1472
        tcg_gen_shli_tl(t0, t0, uimm);
1473
        opn = "dsll";
1474
        break;
1475
    case OPC_DSRA:
1476
        tcg_gen_sari_tl(t0, t0, uimm);
1477
        opn = "dsra";
1478
        break;
1479
    case OPC_DSRL:
1480
        switch ((ctx->opcode >> 21) & 0x1f) {
1481
        case 0:
1482
            tcg_gen_shri_tl(t0, t0, uimm);
1483
            opn = "dsrl";
1484
            break;
1485
        case 1:
1486
            /* drotr is decoded as dsrl on non-R2 CPUs */
1487
            if (env->insn_flags & ISA_MIPS32R2) {
1488
                if (uimm != 0) {
1489
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1490

    
1491
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1492
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1493
                    tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1494
                    tcg_gen_shri_tl(t0, t0, uimm);
1495
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1496
                    tcg_temp_free(r_tmp1);
1497
                }
1498
                opn = "drotr";
1499
            } else {
1500
                tcg_gen_shri_tl(t0, t0, uimm);
1501
                opn = "dsrl";
1502
            }
1503
            break;
1504
        default:
1505
            MIPS_INVAL("invalid dsrl flag");
1506
            generate_exception(ctx, EXCP_RI);
1507
            break;
1508
        }
1509
        break;
1510
    case OPC_DSLL32:
1511
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1512
        opn = "dsll32";
1513
        break;
1514
    case OPC_DSRA32:
1515
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1516
        opn = "dsra32";
1517
        break;
1518
    case OPC_DSRL32:
1519
        switch ((ctx->opcode >> 21) & 0x1f) {
1520
        case 0:
1521
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1522
            opn = "dsrl32";
1523
            break;
1524
        case 1:
1525
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1526
            if (env->insn_flags & ISA_MIPS32R2) {
1527
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1528
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1529

    
1530
                tcg_gen_movi_tl(r_tmp1, 0x40);
1531
                tcg_gen_movi_tl(r_tmp2, 32);
1532
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1533
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1534
                tcg_gen_shl_tl(r_tmp1, t0, r_tmp1);
1535
                tcg_gen_shr_tl(t0, t0, r_tmp2);
1536
                tcg_gen_or_tl(t0, t0, r_tmp1);
1537
                tcg_temp_free(r_tmp1);
1538
                tcg_temp_free(r_tmp2);
1539
                opn = "drotr32";
1540
            } else {
1541
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1542
                opn = "dsrl32";
1543
            }
1544
            break;
1545
        default:
1546
            MIPS_INVAL("invalid dsrl32 flag");
1547
            generate_exception(ctx, EXCP_RI);
1548
            break;
1549
        }
1550
        break;
1551
#endif
1552
    default:
1553
        MIPS_INVAL(opn);
1554
        generate_exception(ctx, EXCP_RI);
1555
        goto out;
1556
    }
1557
    gen_store_gpr(t0, rt);
1558
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1559
 out:
1560
    tcg_temp_free(t0);
1561
}
1562

    
1563
/* Arithmetic */
1564
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1565
                       int rd, int rs, int rt)
1566
{
1567
    const char *opn = "arith";
1568
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1569
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1570

    
1571
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1572
       && opc != OPC_DADD && opc != OPC_DSUB) {
1573
        /* If no destination, treat it as a NOP.
1574
           For add & sub, we must generate the overflow exception when needed. */
1575
        MIPS_DEBUG("NOP");
1576
        goto out;
1577
    }
1578
    gen_load_gpr(t0, rs);
1579
    /* Specialcase the conventional move operation. */
1580
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1581
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1582
        gen_store_gpr(t0, rd);
1583
        goto out;
1584
    }
1585
    gen_load_gpr(t1, rt);
1586
    switch (opc) {
1587
    case OPC_ADD:
1588
        {
1589
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1590
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1591
            int l1 = gen_new_label();
1592

    
1593
            save_cpu_state(ctx, 1);
1594
            tcg_gen_ext32s_tl(r_tmp1, t0);
1595
            tcg_gen_ext32s_tl(r_tmp2, t1);
1596
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1597

    
1598
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1599
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1600
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1601
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1602
            tcg_temp_free(r_tmp2);
1603
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1604
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1605
            tcg_temp_free(r_tmp1);
1606
            /* operands of same sign, result different sign */
1607
            generate_exception(ctx, EXCP_OVERFLOW);
1608
            gen_set_label(l1);
1609

    
1610
            tcg_gen_ext32s_tl(t0, t0);
1611
        }
1612
        opn = "add";
1613
        break;
1614
    case OPC_ADDU:
1615
        tcg_gen_ext32s_tl(t0, t0);
1616
        tcg_gen_ext32s_tl(t1, t1);
1617
        tcg_gen_add_tl(t0, t0, t1);
1618
        tcg_gen_ext32s_tl(t0, t0);
1619
        opn = "addu";
1620
        break;
1621
    case OPC_SUB:
1622
        {
1623
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1624
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1625
            int l1 = gen_new_label();
1626

    
1627
            save_cpu_state(ctx, 1);
1628
            tcg_gen_ext32s_tl(r_tmp1, t0);
1629
            tcg_gen_ext32s_tl(r_tmp2, t1);
1630
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1631

    
1632
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1633
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1634
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1635
            tcg_temp_free(r_tmp2);
1636
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1637
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1638
            tcg_temp_free(r_tmp1);
1639
            /* operands of different sign, first operand and result different sign */
1640
            generate_exception(ctx, EXCP_OVERFLOW);
1641
            gen_set_label(l1);
1642

    
1643
            tcg_gen_ext32s_tl(t0, t0);
1644
        }
1645
        opn = "sub";
1646
        break;
1647
    case OPC_SUBU:
1648
        tcg_gen_ext32s_tl(t0, t0);
1649
        tcg_gen_ext32s_tl(t1, t1);
1650
        tcg_gen_sub_tl(t0, t0, t1);
1651
        tcg_gen_ext32s_tl(t0, t0);
1652
        opn = "subu";
1653
        break;
1654
#if defined(TARGET_MIPS64)
1655
    case OPC_DADD:
1656
        {
1657
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1658
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1659
            int l1 = gen_new_label();
1660

    
1661
            save_cpu_state(ctx, 1);
1662
            tcg_gen_mov_tl(r_tmp1, t0);
1663
            tcg_gen_add_tl(t0, t0, t1);
1664

    
1665
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1666
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1667
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1668
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1669
            tcg_temp_free(r_tmp2);
1670
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1671
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1672
            tcg_temp_free(r_tmp1);
1673
            /* operands of same sign, result different sign */
1674
            generate_exception(ctx, EXCP_OVERFLOW);
1675
            gen_set_label(l1);
1676
        }
1677
        opn = "dadd";
1678
        break;
1679
    case OPC_DADDU:
1680
        tcg_gen_add_tl(t0, t0, t1);
1681
        opn = "daddu";
1682
        break;
1683
    case OPC_DSUB:
1684
        {
1685
            TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL);
1686
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1687
            int l1 = gen_new_label();
1688

    
1689
            save_cpu_state(ctx, 1);
1690
            tcg_gen_mov_tl(r_tmp1, t0);
1691
            tcg_gen_sub_tl(t0, t0, t1);
1692

    
1693
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1694
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1695
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1696
            tcg_temp_free(r_tmp2);
1697
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1698
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1699
            tcg_temp_free(r_tmp1);
1700
            /* operands of different sign, first operand and result different sign */
1701
            generate_exception(ctx, EXCP_OVERFLOW);
1702
            gen_set_label(l1);
1703
        }
1704
        opn = "dsub";
1705
        break;
1706
    case OPC_DSUBU:
1707
        tcg_gen_sub_tl(t0, t0, t1);
1708
        opn = "dsubu";
1709
        break;
1710
#endif
1711
    case OPC_SLT:
1712
        gen_op_lt(t0, t1);
1713
        opn = "slt";
1714
        break;
1715
    case OPC_SLTU:
1716
        gen_op_ltu(t0, t1);
1717
        opn = "sltu";
1718
        break;
1719
    case OPC_AND:
1720
        tcg_gen_and_tl(t0, t0, t1);
1721
        opn = "and";
1722
        break;
1723
    case OPC_NOR:
1724
        tcg_gen_or_tl(t0, t0, t1);
1725
        tcg_gen_not_tl(t0, t0);
1726
        opn = "nor";
1727
        break;
1728
    case OPC_OR:
1729
        tcg_gen_or_tl(t0, t0, t1);
1730
        opn = "or";
1731
        break;
1732
    case OPC_XOR:
1733
        tcg_gen_xor_tl(t0, t0, t1);
1734
        opn = "xor";
1735
        break;
1736
    case OPC_MUL:
1737
        tcg_gen_ext32s_tl(t0, t0);
1738
        tcg_gen_ext32s_tl(t1, t1);
1739
        tcg_gen_mul_tl(t0, t0, t1);
1740
        tcg_gen_ext32s_tl(t0, t0);
1741
        opn = "mul";
1742
        break;
1743
    case OPC_MOVN:
1744
        {
1745
            int l1 = gen_new_label();
1746

    
1747
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1748
            gen_store_gpr(t0, rd);
1749
            gen_set_label(l1);
1750
        }
1751
        opn = "movn";
1752
        goto print;
1753
    case OPC_MOVZ:
1754
        {
1755
            int l1 = gen_new_label();
1756

    
1757
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1758
            gen_store_gpr(t0, rd);
1759
            gen_set_label(l1);
1760
        }
1761
        opn = "movz";
1762
        goto print;
1763
    case OPC_SLLV:
1764
        tcg_gen_ext32u_tl(t0, t0);
1765
        tcg_gen_ext32u_tl(t1, t1);
1766
        tcg_gen_andi_tl(t0, t0, 0x1f);
1767
        tcg_gen_shl_tl(t0, t1, t0);
1768
        tcg_gen_ext32s_tl(t0, t0);
1769
        opn = "sllv";
1770
        break;
1771
    case OPC_SRAV:
1772
        tcg_gen_ext32s_tl(t1, t1);
1773
        tcg_gen_andi_tl(t0, t0, 0x1f);
1774
        tcg_gen_sar_tl(t0, t1, t0);
1775
        tcg_gen_ext32s_tl(t0, t0);
1776
        opn = "srav";
1777
        break;
1778
    case OPC_SRLV:
1779
        switch ((ctx->opcode >> 6) & 0x1f) {
1780
        case 0:
1781
            tcg_gen_ext32u_tl(t1, t1);
1782
            tcg_gen_andi_tl(t0, t0, 0x1f);
1783
            tcg_gen_shr_tl(t0, t1, t0);
1784
            tcg_gen_ext32s_tl(t0, t0);
1785
            opn = "srlv";
1786
            break;
1787
        case 1:
1788
            /* rotrv is decoded as srlv on non-R2 CPUs */
1789
            if (env->insn_flags & ISA_MIPS32R2) {
1790
                int l1 = gen_new_label();
1791
                int l2 = gen_new_label();
1792

    
1793
                tcg_gen_andi_tl(t0, t0, 0x1f);
1794
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1795
                {
1796
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1797
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1798
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1799

    
1800
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1801
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1802
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1803
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1804
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1805
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1806
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1807
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1808
                    tcg_temp_free(r_tmp1);
1809
                    tcg_temp_free(r_tmp2);
1810
                    tcg_temp_free(r_tmp3);
1811
                    tcg_gen_br(l2);
1812
                }
1813
                gen_set_label(l1);
1814
                tcg_gen_mov_tl(t0, t1);
1815
                gen_set_label(l2);
1816
                opn = "rotrv";
1817
            } else {
1818
                tcg_gen_ext32u_tl(t1, t1);
1819
                tcg_gen_andi_tl(t0, t0, 0x1f);
1820
                tcg_gen_shr_tl(t0, t1, t0);
1821
                tcg_gen_ext32s_tl(t0, t0);
1822
                opn = "srlv";
1823
            }
1824
            break;
1825
        default:
1826
            MIPS_INVAL("invalid srlv flag");
1827
            generate_exception(ctx, EXCP_RI);
1828
            break;
1829
        }
1830
        break;
1831
#if defined(TARGET_MIPS64)
1832
    case OPC_DSLLV:
1833
        tcg_gen_andi_tl(t0, t0, 0x3f);
1834
        tcg_gen_shl_tl(t0, t1, t0);
1835
        opn = "dsllv";
1836
        break;
1837
    case OPC_DSRAV:
1838
        tcg_gen_andi_tl(t0, t0, 0x3f);
1839
        tcg_gen_sar_tl(t0, t1, t0);
1840
        opn = "dsrav";
1841
        break;
1842
    case OPC_DSRLV:
1843
        switch ((ctx->opcode >> 6) & 0x1f) {
1844
        case 0:
1845
            tcg_gen_andi_tl(t0, t0, 0x3f);
1846
            tcg_gen_shr_tl(t0, t1, t0);
1847
            opn = "dsrlv";
1848
            break;
1849
        case 1:
1850
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1851
            if (env->insn_flags & ISA_MIPS32R2) {
1852
                int l1 = gen_new_label();
1853
                int l2 = gen_new_label();
1854

    
1855
                tcg_gen_andi_tl(t0, t0, 0x3f);
1856
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1857
                {
1858
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1859

    
1860
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1861
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, t0);
1862
                    tcg_gen_shl_tl(r_tmp1, t1, r_tmp1);
1863
                    tcg_gen_shr_tl(t0, t1, t0);
1864
                    tcg_gen_or_tl(t0, t0, r_tmp1);
1865
                    tcg_temp_free(r_tmp1);
1866
                    tcg_gen_br(l2);
1867
                }
1868
                gen_set_label(l1);
1869
                tcg_gen_mov_tl(t0, t1);
1870
                gen_set_label(l2);
1871
                opn = "drotrv";
1872
            } else {
1873
                tcg_gen_andi_tl(t0, t0, 0x3f);
1874
                tcg_gen_shr_tl(t0, t1, t0);
1875
                opn = "dsrlv";
1876
            }
1877
            break;
1878
        default:
1879
            MIPS_INVAL("invalid dsrlv flag");
1880
            generate_exception(ctx, EXCP_RI);
1881
            break;
1882
        }
1883
        break;
1884
#endif
1885
    default:
1886
        MIPS_INVAL(opn);
1887
        generate_exception(ctx, EXCP_RI);
1888
        goto out;
1889
    }
1890
    gen_store_gpr(t0, rd);
1891
 print:
1892
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1893
 out:
1894
    tcg_temp_free(t0);
1895
    tcg_temp_free(t1);
1896
}
1897

    
1898
/* Arithmetic on HI/LO registers */
1899
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1900
{
1901
    const char *opn = "hilo";
1902
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1903

    
1904
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1905
        /* Treat as NOP. */
1906
        MIPS_DEBUG("NOP");
1907
        goto out;
1908
    }
1909
    switch (opc) {
1910
    case OPC_MFHI:
1911
        gen_load_HI(t0, 0);
1912
        gen_store_gpr(t0, reg);
1913
        opn = "mfhi";
1914
        break;
1915
    case OPC_MFLO:
1916
        gen_load_LO(t0, 0);
1917
        gen_store_gpr(t0, reg);
1918
        opn = "mflo";
1919
        break;
1920
    case OPC_MTHI:
1921
        gen_load_gpr(t0, reg);
1922
        gen_store_HI(t0, 0);
1923
        opn = "mthi";
1924
        break;
1925
    case OPC_MTLO:
1926
        gen_load_gpr(t0, reg);
1927
        gen_store_LO(t0, 0);
1928
        opn = "mtlo";
1929
        break;
1930
    default:
1931
        MIPS_INVAL(opn);
1932
        generate_exception(ctx, EXCP_RI);
1933
        goto out;
1934
    }
1935
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1936
 out:
1937
    tcg_temp_free(t0);
1938
}
1939

    
1940
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1941
                        int rs, int rt)
1942
{
1943
    const char *opn = "mul/div";
1944
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1945
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1946

    
1947
    gen_load_gpr(t0, rs);
1948
    gen_load_gpr(t1, rt);
1949
    switch (opc) {
1950
    case OPC_DIV:
1951
        {
1952
            int l1 = gen_new_label();
1953

    
1954
            tcg_gen_ext32s_tl(t0, t0);
1955
            tcg_gen_ext32s_tl(t1, t1);
1956
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1957
            {
1958
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1959
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1960
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1961

    
1962
                tcg_gen_ext_tl_i64(r_tmp1, t0);
1963
                tcg_gen_ext_tl_i64(r_tmp2, t1);
1964
                tcg_gen_div_i64(r_tmp3, r_tmp1, r_tmp2);
1965
                tcg_gen_rem_i64(r_tmp2, r_tmp1, r_tmp2);
1966
                tcg_gen_trunc_i64_tl(t0, r_tmp3);
1967
                tcg_gen_trunc_i64_tl(t1, r_tmp2);
1968
                tcg_temp_free(r_tmp1);
1969
                tcg_temp_free(r_tmp2);
1970
                tcg_temp_free(r_tmp3);
1971
                tcg_gen_ext32s_tl(t0, t0);
1972
                tcg_gen_ext32s_tl(t1, t1);
1973
                gen_store_LO(t0, 0);
1974
                gen_store_HI(t1, 0);
1975
            }
1976
            gen_set_label(l1);
1977
        }
1978
        opn = "div";
1979
        break;
1980
    case OPC_DIVU:
1981
        {
1982
            int l1 = gen_new_label();
1983

    
1984
            tcg_gen_ext32s_tl(t1, t1);
1985
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1986
            {
1987
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1988
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1989
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1990

    
1991
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1992
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1993
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1994
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1995
                tcg_gen_ext_i32_tl(t0, r_tmp3);
1996
                tcg_gen_ext_i32_tl(t1, r_tmp1);
1997
                tcg_temp_free(r_tmp1);
1998
                tcg_temp_free(r_tmp2);
1999
                tcg_temp_free(r_tmp3);
2000
                gen_store_LO(t0, 0);
2001
                gen_store_HI(t1, 0);
2002
            }
2003
            gen_set_label(l1);
2004
        }
2005
        opn = "divu";
2006
        break;
2007
    case OPC_MULT:
2008
        {
2009
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2010
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2011

    
2012
            tcg_gen_ext32s_tl(t0, t0);
2013
            tcg_gen_ext32s_tl(t1, t1);
2014
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2015
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2016
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2017
            tcg_temp_free(r_tmp2);
2018
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2019
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2020
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2021
            tcg_temp_free(r_tmp1);
2022
            tcg_gen_ext32s_tl(t0, t0);
2023
            tcg_gen_ext32s_tl(t1, t1);
2024
            gen_store_LO(t0, 0);
2025
            gen_store_HI(t1, 0);
2026
        }
2027
        opn = "mult";
2028
        break;
2029
    case OPC_MULTU:
2030
        {
2031
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2032
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2033

    
2034
            tcg_gen_ext32u_tl(t0, t0);
2035
            tcg_gen_ext32u_tl(t1, t1);
2036
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2037
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2038
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2039
            tcg_temp_free(r_tmp2);
2040
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2041
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2042
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2043
            tcg_temp_free(r_tmp1);
2044
            tcg_gen_ext32s_tl(t0, t0);
2045
            tcg_gen_ext32s_tl(t1, t1);
2046
            gen_store_LO(t0, 0);
2047
            gen_store_HI(t1, 0);
2048
        }
2049
        opn = "multu";
2050
        break;
2051
#if defined(TARGET_MIPS64)
2052
    case OPC_DDIV:
2053
        {
2054
            int l1 = gen_new_label();
2055

    
2056
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2057
            {
2058
                int l2 = gen_new_label();
2059

    
2060
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2061
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2062
                {
2063
                    tcg_gen_movi_tl(t1, 0);
2064
                    gen_store_LO(t0, 0);
2065
                    gen_store_HI(t1, 0);
2066
                    tcg_gen_br(l1);
2067
                }
2068
                gen_set_label(l2);
2069
                {
2070
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2071
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2072

    
2073
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2074
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2075
                    gen_store_LO(r_tmp1, 0);
2076
                    gen_store_HI(r_tmp2, 0);
2077
                    tcg_temp_free(r_tmp1);
2078
                    tcg_temp_free(r_tmp2);
2079
                }
2080
            }
2081
            gen_set_label(l1);
2082
        }
2083
        opn = "ddiv";
2084
        break;
2085
    case OPC_DDIVU:
2086
        {
2087
            int l1 = gen_new_label();
2088

    
2089
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2090
            {
2091
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2092
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2093

    
2094
                tcg_gen_divu_i64(r_tmp1, t0, t1);
2095
                tcg_gen_remu_i64(r_tmp2, t0, t1);
2096
                tcg_temp_free(r_tmp1);
2097
                tcg_temp_free(r_tmp2);
2098
                gen_store_LO(r_tmp1, 0);
2099
                gen_store_HI(r_tmp2, 0);
2100
            }
2101
            gen_set_label(l1);
2102
        }
2103
        opn = "ddivu";
2104
        break;
2105
    case OPC_DMULT:
2106
        tcg_gen_helper_0_2(do_dmult, t0, t1);
2107
        opn = "dmult";
2108
        break;
2109
    case OPC_DMULTU:
2110
        tcg_gen_helper_0_2(do_dmultu, t0, t1);
2111
        opn = "dmultu";
2112
        break;
2113
#endif
2114
    case OPC_MADD:
2115
        {
2116
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2117
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2118
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2119

    
2120
            tcg_gen_ext32s_tl(t0, t0);
2121
            tcg_gen_ext32s_tl(t1, t1);
2122
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2123
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2124
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2125
            gen_load_LO(t0, 0);
2126
            gen_load_HI(t1, 0);
2127
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2128
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2129
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2130
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2131
            tcg_temp_free(r_tmp3);
2132
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2133
            tcg_temp_free(r_tmp2);
2134
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2135
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2136
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2137
            tcg_temp_free(r_tmp1);
2138
            tcg_gen_ext32s_tl(t0, t0);
2139
            tcg_gen_ext32s_tl(t1, t1);
2140
            gen_store_LO(t0, 0);
2141
            gen_store_HI(t1, 0);
2142
        }
2143
        opn = "madd";
2144
        break;
2145
    case OPC_MADDU:
2146
       {
2147
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2148
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2149
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2150

    
2151
            tcg_gen_ext32u_tl(t0, t0);
2152
            tcg_gen_ext32u_tl(t1, t1);
2153
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2154
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2155
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2156
            gen_load_LO(t0, 0);
2157
            gen_load_HI(t1, 0);
2158
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2159
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2160
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2161
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2162
            tcg_temp_free(r_tmp3);
2163
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2164
            tcg_temp_free(r_tmp2);
2165
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2166
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2167
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2168
            tcg_temp_free(r_tmp1);
2169
            tcg_gen_ext32s_tl(t0, t0);
2170
            tcg_gen_ext32s_tl(t1, t1);
2171
            gen_store_LO(t0, 0);
2172
            gen_store_HI(t1, 0);
2173
        }
2174
        opn = "maddu";
2175
        break;
2176
    case OPC_MSUB:
2177
        {
2178
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2179
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2180
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2181

    
2182
            tcg_gen_ext32s_tl(t0, t0);
2183
            tcg_gen_ext32s_tl(t1, t1);
2184
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2185
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2186
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2187
            gen_load_LO(t0, 0);
2188
            gen_load_HI(t1, 0);
2189
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2190
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2191
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2192
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2193
            tcg_temp_free(r_tmp3);
2194
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2195
            tcg_temp_free(r_tmp2);
2196
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2197
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2198
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2199
            tcg_temp_free(r_tmp1);
2200
            tcg_gen_ext32s_tl(t0, t0);
2201
            tcg_gen_ext32s_tl(t1, t1);
2202
            gen_store_LO(t0, 0);
2203
            gen_store_HI(t1, 0);
2204
        }
2205
        opn = "msub";
2206
        break;
2207
    case OPC_MSUBU:
2208
        {
2209
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2210
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2211
            TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
2212

    
2213
            tcg_gen_ext32u_tl(t0, t0);
2214
            tcg_gen_ext32u_tl(t1, t1);
2215
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2216
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2217
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2218
            gen_load_LO(t0, 0);
2219
            gen_load_HI(t1, 0);
2220
            tcg_gen_extu_tl_i64(r_tmp2, t0);
2221
            tcg_gen_extu_tl_i64(r_tmp3, t1);
2222
            tcg_gen_shli_i64(r_tmp3, r_tmp3, 32);
2223
            tcg_gen_or_i64(r_tmp2, r_tmp2, r_tmp3);
2224
            tcg_temp_free(r_tmp3);
2225
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2226
            tcg_temp_free(r_tmp2);
2227
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2228
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2229
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2230
            tcg_temp_free(r_tmp1);
2231
            tcg_gen_ext32s_tl(t0, t0);
2232
            tcg_gen_ext32s_tl(t1, t1);
2233
            gen_store_LO(t0, 0);
2234
            gen_store_HI(t1, 0);
2235
        }
2236
        opn = "msubu";
2237
        break;
2238
    default:
2239
        MIPS_INVAL(opn);
2240
        generate_exception(ctx, EXCP_RI);
2241
        goto out;
2242
    }
2243
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2244
 out:
2245
    tcg_temp_free(t0);
2246
    tcg_temp_free(t1);
2247
}
2248

    
2249
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2250
                            int rd, int rs, int rt)
2251
{
2252
    const char *opn = "mul vr54xx";
2253
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2254
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2255

    
2256
    gen_load_gpr(t0, rs);
2257
    gen_load_gpr(t1, rt);
2258

    
2259
    switch (opc) {
2260
    case OPC_VR54XX_MULS:
2261
        tcg_gen_helper_1_2(do_muls, t0, t0, t1);
2262
        opn = "muls";
2263
        break;
2264
    case OPC_VR54XX_MULSU:
2265
        tcg_gen_helper_1_2(do_mulsu, t0, t0, t1);
2266
        opn = "mulsu";
2267
        break;
2268
    case OPC_VR54XX_MACC:
2269
        tcg_gen_helper_1_2(do_macc, t0, t0, t1);
2270
        opn = "macc";
2271
        break;
2272
    case OPC_VR54XX_MACCU:
2273
        tcg_gen_helper_1_2(do_maccu, t0, t0, t1);
2274
        opn = "maccu";
2275
        break;
2276
    case OPC_VR54XX_MSAC:
2277
        tcg_gen_helper_1_2(do_msac, t0, t0, t1);
2278
        opn = "msac";
2279
        break;
2280
    case OPC_VR54XX_MSACU:
2281
        tcg_gen_helper_1_2(do_msacu, t0, t0, t1);
2282
        opn = "msacu";
2283
        break;
2284
    case OPC_VR54XX_MULHI:
2285
        tcg_gen_helper_1_2(do_mulhi, t0, t0, t1);
2286
        opn = "mulhi";
2287
        break;
2288
    case OPC_VR54XX_MULHIU:
2289
        tcg_gen_helper_1_2(do_mulhiu, t0, t0, t1);
2290
        opn = "mulhiu";
2291
        break;
2292
    case OPC_VR54XX_MULSHI:
2293
        tcg_gen_helper_1_2(do_mulshi, t0, t0, t1);
2294
        opn = "mulshi";
2295
        break;
2296
    case OPC_VR54XX_MULSHIU:
2297
        tcg_gen_helper_1_2(do_mulshiu, t0, t0, t1);
2298
        opn = "mulshiu";
2299
        break;
2300
    case OPC_VR54XX_MACCHI:
2301
        tcg_gen_helper_1_2(do_macchi, t0, t0, t1);
2302
        opn = "macchi";
2303
        break;
2304
    case OPC_VR54XX_MACCHIU:
2305
        tcg_gen_helper_1_2(do_macchiu, t0, t0, t1);
2306
        opn = "macchiu";
2307
        break;
2308
    case OPC_VR54XX_MSACHI:
2309
        tcg_gen_helper_1_2(do_msachi, t0, t0, t1);
2310
        opn = "msachi";
2311
        break;
2312
    case OPC_VR54XX_MSACHIU:
2313
        tcg_gen_helper_1_2(do_msachiu, t0, t0, t1);
2314
        opn = "msachiu";
2315
        break;
2316
    default:
2317
        MIPS_INVAL("mul vr54xx");
2318
        generate_exception(ctx, EXCP_RI);
2319
        goto out;
2320
    }
2321
    gen_store_gpr(t0, rd);
2322
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2323

    
2324
 out:
2325
    tcg_temp_free(t0);
2326
    tcg_temp_free(t1);
2327
}
2328

    
2329
static void gen_cl (DisasContext *ctx, uint32_t opc,
2330
                    int rd, int rs)
2331
{
2332
    const char *opn = "CLx";
2333
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2334

    
2335
    if (rd == 0) {
2336
        /* Treat as NOP. */
2337
        MIPS_DEBUG("NOP");
2338
        goto out;
2339
    }
2340
    gen_load_gpr(t0, rs);
2341
    switch (opc) {
2342
    case OPC_CLO:
2343
        tcg_gen_helper_1_1(do_clo, t0, t0);
2344
        opn = "clo";
2345
        break;
2346
    case OPC_CLZ:
2347
        tcg_gen_helper_1_1(do_clz, t0, t0);
2348
        opn = "clz";
2349
        break;
2350
#if defined(TARGET_MIPS64)
2351
    case OPC_DCLO:
2352
        tcg_gen_helper_1_1(do_dclo, t0, t0);
2353
        opn = "dclo";
2354
        break;
2355
    case OPC_DCLZ:
2356
        tcg_gen_helper_1_1(do_dclz, t0, t0);
2357
        opn = "dclz";
2358
        break;
2359
#endif
2360
    default:
2361
        MIPS_INVAL(opn);
2362
        generate_exception(ctx, EXCP_RI);
2363
        goto out;
2364
    }
2365
    gen_store_gpr(t0, rd);
2366
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2367

    
2368
 out:
2369
    tcg_temp_free(t0);
2370
}
2371

    
2372
/* Traps */
2373
static void gen_trap (DisasContext *ctx, uint32_t opc,
2374
                      int rs, int rt, int16_t imm)
2375
{
2376
    int cond;
2377
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2378
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2379

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

    
2470
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2471
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2472
        gen_set_label(l1);
2473
    }
2474
    ctx->bstate = BS_STOP;
2475
 out:
2476
    tcg_temp_free(t0);
2477
    tcg_temp_free(t1);
2478
}
2479

    
2480
static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2481
{
2482
    TranslationBlock *tb;
2483
    tb = ctx->tb;
2484
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2485
        tcg_gen_goto_tb(n);
2486
        gen_save_pc(dest);
2487
        tcg_gen_exit_tb((long)tb + n);
2488
    } else {
2489
        gen_save_pc(dest);
2490
        tcg_gen_exit_tb(0);
2491
    }
2492
}
2493

    
2494
/* Branches (before delay slot) */
2495
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2496
                                int rs, int rt, int32_t offset)
2497
{
2498
    target_ulong btarget = -1;
2499
    int blink = 0;
2500
    int bcond = 0;
2501
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2502
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2503

    
2504
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2505
#ifdef MIPS_DEBUG_DISAS
2506
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2507
            fprintf(logfile,
2508
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2509
                    ctx->pc);
2510
        }
2511
#endif
2512
        generate_exception(ctx, EXCP_RI);
2513
        goto out;
2514
    }
2515

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

    
2728
    ctx->btarget = btarget;
2729
    if (blink > 0) {
2730
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2731
        gen_store_gpr(t0, blink);
2732
    }
2733

    
2734
 out:
2735
    tcg_temp_free(t0);
2736
    tcg_temp_free(t1);
2737
}
2738

    
2739
/* special3 bitfield operations */
2740
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2741
                       int rs, int lsb, int msb)
2742
{
2743
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2744
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2745

    
2746
    gen_load_gpr(t1, rs);
2747
    switch (opc) {
2748
    case OPC_EXT:
2749
        if (lsb + msb > 31)
2750
            goto fail;
2751
        tcg_gen_helper_1_2ii(do_ext, t0, t0, t1, lsb, msb + 1);
2752
        break;
2753
#if defined(TARGET_MIPS64)
2754
    case OPC_DEXTM:
2755
        if (lsb + msb > 63)
2756
            goto fail;
2757
        tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb, msb + 1 + 32);
2758
        break;
2759
    case OPC_DEXTU:
2760
        if (lsb + msb > 63)
2761
            goto fail;
2762
        tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb + 32, msb + 1);
2763
        break;
2764
    case OPC_DEXT:
2765
        if (lsb + msb > 63)
2766
            goto fail;
2767
        tcg_gen_helper_1_2ii(do_dext, t0, t0, t1, lsb, msb + 1);
2768
        break;
2769
#endif
2770
    case OPC_INS:
2771
        if (lsb > msb)
2772
            goto fail;
2773
        gen_load_gpr(t0, rt);
2774
        tcg_gen_helper_1_2ii(do_ins, t0, t0, t1, lsb, msb - lsb + 1);
2775
        break;
2776
#if defined(TARGET_MIPS64)
2777
    case OPC_DINSM:
2778
        if (lsb > msb)
2779
            goto fail;
2780
        gen_load_gpr(t0, rt);
2781
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1 + 32);
2782
        break;
2783
    case OPC_DINSU:
2784
        if (lsb > msb)
2785
            goto fail;
2786
        gen_load_gpr(t0, rt);
2787
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb + 32, msb - lsb + 1);
2788
        break;
2789
    case OPC_DINS:
2790
        if (lsb > msb)
2791
            goto fail;
2792
        gen_load_gpr(t0, rt);
2793
        tcg_gen_helper_1_2ii(do_dins, t0, t0, t1, lsb, msb - lsb + 1);
2794
        break;
2795
#endif
2796
    default:
2797
fail:
2798
        MIPS_INVAL("bitops");
2799
        generate_exception(ctx, EXCP_RI);
2800
        tcg_temp_free(t0);
2801
        tcg_temp_free(t1);
2802
        return;
2803
    }
2804
    gen_store_gpr(t0, rt);
2805
    tcg_temp_free(t0);
2806
    tcg_temp_free(t1);
2807
}
2808

    
2809
/* CP0 (MMU and control) */
2810
#ifndef CONFIG_USER_ONLY
2811
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2812
{
2813
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2814

    
2815
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2816
    tcg_gen_ext_i32_tl(t, r_tmp);
2817
    tcg_temp_free(r_tmp);
2818
}
2819

    
2820
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2821
{
2822
    tcg_gen_ld_tl(t, cpu_env, off);
2823
    tcg_gen_ext32s_tl(t, t);
2824
}
2825

    
2826
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2827
{
2828
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2829

    
2830
    tcg_gen_trunc_tl_i32(r_tmp, t);
2831
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2832
    tcg_temp_free(r_tmp);
2833
}
2834

    
2835
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2836
{
2837
    tcg_gen_ext32s_tl(t, t);
2838
    tcg_gen_st_tl(t, cpu_env, off);
2839
}
2840

    
2841
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2842
{
2843
    const char *rn = "invalid";
2844

    
2845
    if (sel != 0)
2846
        check_insn(env, ctx, ISA_MIPS32);
2847

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

    
3417
die:
3418
#if defined MIPS_DEBUG_DISAS
3419
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3420
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3421
                rn, reg, sel);
3422
    }
3423
#endif
3424
    generate_exception(ctx, EXCP_RI);
3425
}
3426

    
3427
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3428
{
3429
    const char *rn = "invalid";
3430

    
3431
    if (sel != 0)
3432
        check_insn(env, ctx, ISA_MIPS32);
3433

    
3434
    if (use_icount)
3435
        gen_io_start();
3436

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

    
4026
die:
4027
#if defined MIPS_DEBUG_DISAS
4028
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4029
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
4030
                rn, reg, sel);
4031
    }
4032
#endif
4033
    generate_exception(ctx, EXCP_RI);
4034
}
4035

    
4036
#if defined(TARGET_MIPS64)
4037
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4038
{
4039
    const char *rn = "invalid";
4040

    
4041
    if (sel != 0)
4042
        check_insn(env, ctx, ISA_MIPS64);
4043

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

    
4601
die:
4602
#if defined MIPS_DEBUG_DISAS
4603
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4604
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4605
                rn, reg, sel);
4606
    }
4607
#endif
4608
    generate_exception(ctx, EXCP_RI);
4609
}
4610

    
4611
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4612
{
4613
    const char *rn = "invalid";
4614

    
4615
    if (sel != 0)
4616
        check_insn(env, ctx, ISA_MIPS64);
4617

    
4618
    if (use_icount)
4619
        gen_io_start();
4620

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

    
5198
die:
5199
    tcg_temp_free(t0);
5200
#if defined MIPS_DEBUG_DISAS
5201
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5202
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5203
                rn, reg, sel);
5204
    }
5205
#endif
5206
    generate_exception(ctx, EXCP_RI);
5207
}
5208
#endif /* TARGET_MIPS64 */
5209

    
5210
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5211
                     int u, int sel, int h)
5212
{
5213
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5214
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5215

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

    
5367
die:
5368
    tcg_temp_free(t0);
5369
#if defined MIPS_DEBUG_DISAS
5370
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5371
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5372
                rt, u, sel, h);
5373
    }
5374
#endif
5375
    generate_exception(ctx, EXCP_RI);
5376
}
5377

    
5378
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5379
                     int u, int sel, int h)
5380
{
5381
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5382
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5383

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

    
5535
die:
5536
    tcg_temp_free(t0);
5537
#if defined MIPS_DEBUG_DISAS
5538
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5539
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5540
                rd, u, sel, h);
5541
    }
5542
#endif
5543
    generate_exception(ctx, EXCP_RI);
5544
}
5545

    
5546
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5547
{
5548
    const char *opn = "ldst";
5549

    
5550
    switch (opc) {
5551
    case OPC_MFC0:
5552
        if (rt == 0) {
5553
            /* Treat as NOP. */
5554
            return;
5555
        }
5556
        {
5557
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5558

    
5559
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5560
            gen_store_gpr(t0, rt);
5561
            tcg_temp_free(t0);
5562
        }
5563
        opn = "mfc0";
5564
        break;
5565
    case OPC_MTC0:
5566
        {
5567
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5568

    
5569
            gen_load_gpr(t0, rt);
5570
            save_cpu_state(ctx, 1);
5571
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5572
            tcg_temp_free(t0);
5573
        }
5574
        opn = "mtc0";
5575
        break;
5576
#if defined(TARGET_MIPS64)
5577
    case OPC_DMFC0:
5578
        check_insn(env, ctx, ISA_MIPS3);
5579
        if (rt == 0) {
5580
            /* Treat as NOP. */
5581
            return;
5582
        }
5583
        {
5584
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5585

    
5586
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5587
            gen_store_gpr(t0, rt);
5588
            tcg_temp_free(t0);
5589
        }
5590
        opn = "dmfc0";
5591
        break;
5592
    case OPC_DMTC0:
5593
        check_insn(env, ctx, ISA_MIPS3);
5594
        {
5595
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5596

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

    
5684
/* CP1 Branches (before delay slot) */
5685
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5686
                                 int32_t cc, int32_t offset)
5687
{
5688
    target_ulong btarget;
5689
    const char *opn = "cp1 cond branch";
5690
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5691
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5692

    
5693
    if (cc != 0)
5694
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5695

    
5696
    btarget = ctx->pc + 4 + offset;
5697

    
5698
    switch (op) {
5699
    case OPC_BC1F:
5700
        {
5701
            int l1 = gen_new_label();
5702
            int l2 = gen_new_label();
5703
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5704

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

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

    
5747
            get_fp_cond(r_tmp1);
5748
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5749
            tcg_temp_free(r_tmp1);
5750
            tcg_gen_movi_tl(t1, 0x1 << cc);
5751
            tcg_gen_and_tl(t0, t0, t1);
5752
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5753
            tcg_gen_movi_tl(t0, 0);
5754
            tcg_gen_br(l2);
5755
            gen_set_label(l1);
5756
            tcg_gen_movi_tl(t0, 1);
5757
            gen_set_label(l2);
5758
        }
5759
        opn = "bc1t";
5760
        goto not_likely;
5761
    case OPC_BC1TL:
5762
        {
5763
            int l1 = gen_new_label();
5764
            int l2 = gen_new_label();
5765
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5766

    
5767
            get_fp_cond(r_tmp1);
5768
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5769
            tcg_temp_free(r_tmp1);
5770
            tcg_gen_movi_tl(t1, 0x1 << cc);
5771
            tcg_gen_and_tl(t0, t0, t1);
5772
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5773
            tcg_gen_movi_tl(t0, 0);
5774
            tcg_gen_br(l2);
5775
            gen_set_label(l1);
5776
            tcg_gen_movi_tl(t0, 1);
5777
            gen_set_label(l2);
5778
        }
5779
        opn = "bc1tl";
5780
    likely:
5781
        ctx->hflags |= MIPS_HFLAG_BL;
5782
        tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond));
5783
        break;
5784
    case OPC_BC1FANY2:
5785
        {
5786
            int l1 = gen_new_label();
5787
            int l2 = gen_new_label();
5788
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5789

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

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

    
5831
            get_fp_cond(r_tmp1);
5832
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5833
            tcg_temp_free(r_tmp1);
5834
            tcg_gen_not_tl(t0, t0);
5835
            tcg_gen_movi_tl(t1, 0xf << cc);
5836
            tcg_gen_and_tl(t0, t0, t1);
5837
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5838
            tcg_gen_movi_tl(t0, 0);
5839
            tcg_gen_br(l2);
5840
            gen_set_label(l1);
5841
            tcg_gen_movi_tl(t0, 1);
5842
            gen_set_label(l2);
5843
        }
5844
        opn = "bc1any4f";
5845
        goto not_likely;
5846
    case OPC_BC1TANY4:
5847
        {
5848
            int l1 = gen_new_label();
5849
            int l2 = gen_new_label();
5850
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5851

    
5852
            get_fp_cond(r_tmp1);
5853
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5854
            tcg_temp_free(r_tmp1);
5855
            tcg_gen_movi_tl(t1, 0xf << cc);
5856
            tcg_gen_and_tl(t0, t0, t1);
5857
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5858
            tcg_gen_movi_tl(t0, 0);
5859
            tcg_gen_br(l2);
5860
            gen_set_label(l1);
5861
            tcg_gen_movi_tl(t0, 1);
5862
            gen_set_label(l2);
5863
        }
5864
        opn = "bc1any4t";
5865
    not_likely:
5866
        ctx->hflags |= MIPS_HFLAG_BC;
5867
        tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, bcond));
5868
        break;
5869
    default:
5870
        MIPS_INVAL(opn);
5871
        generate_exception (ctx, EXCP_RI);
5872
        goto out;
5873
    }
5874
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5875
               ctx->hflags, btarget);
5876
    ctx->btarget = btarget;
5877

    
5878
 out:
5879
    tcg_temp_free(t0);
5880
    tcg_temp_free(t1);
5881
}
5882

    
5883
/* Coprocessor 1 (FPU) */
5884

    
5885
#define FOP(func, fmt) (((fmt) << 21) | (func))
5886

    
5887
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5888
{
5889
    const char *opn = "cp1 move";
5890
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5891

    
5892
    switch (opc) {
5893
    case OPC_MFC1:
5894
        gen_load_fpr32(fpu32_T[0], fs);
5895
        tcg_gen_ext_i32_tl(t0, fpu32_T[0]);
5896
        gen_store_gpr(t0, rt);
5897
        opn = "mfc1";
5898
        break;
5899
    case OPC_MTC1:
5900
        gen_load_gpr(t0, rt);
5901
        tcg_gen_trunc_tl_i32(fpu32_T[0], t0);
5902
        gen_store_fpr32(fpu32_T[0], fs);
5903
        opn = "mtc1";
5904
        break;
5905
    case OPC_CFC1:
5906
        tcg_gen_helper_1_i(do_cfc1, t0, fs);
5907
        gen_store_gpr(t0, rt);
5908
        opn = "cfc1";
5909
        break;
5910
    case OPC_CTC1:
5911
        gen_load_gpr(t0, rt);
5912
        tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5913
        opn = "ctc1";
5914
        break;
5915
    case OPC_DMFC1:
5916
        gen_load_fpr64(ctx, fpu64_T[0], fs);
5917
        tcg_gen_mov_tl(t0, fpu64_T[0]);
5918
        gen_store_gpr(t0, rt);
5919
        opn = "dmfc1";
5920
        break;
5921
    case OPC_DMTC1:
5922
        gen_load_gpr(t0, rt);
5923
        tcg_gen_mov_tl(fpu64_T[0], t0);
5924
        gen_store_fpr64(ctx, fpu64_T[0], fs);
5925
        opn = "dmtc1";
5926
        break;
5927
    case OPC_MFHC1:
5928
        gen_load_fpr32h(fpu32h_T[0], fs);
5929
        tcg_gen_ext_i32_tl(t0, fpu32h_T[0]);
5930
        gen_store_gpr(t0, rt);
5931
        opn = "mfhc1";
5932
        break;
5933
    case OPC_MTHC1:
5934
        gen_load_gpr(t0, rt);
5935
        tcg_gen_trunc_tl_i32(fpu32h_T[0], t0);
5936
        gen_store_fpr32h(fpu32h_T[0], fs);
5937
        opn = "mthc1";
5938
        break;
5939
    default:
5940
        MIPS_INVAL(opn);
5941
        generate_exception (ctx, EXCP_RI);
5942
        goto out;
5943
    }
5944
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5945

    
5946
 out:
5947
    tcg_temp_free(t0);
5948
}
5949

    
5950
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5951
{
5952
    int l1 = gen_new_label();
5953
    uint32_t ccbit;
5954
    TCGCond cond;
5955
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5956
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5957

    
5958
    if (cc)
5959
        ccbit = 1 << (24 + cc);
5960
    else
5961
        ccbit = 1 << 23;
5962
    if (tf)
5963
        cond = TCG_COND_EQ;
5964
    else
5965
        cond = TCG_COND_NE;
5966

    
5967
    gen_load_gpr(t0, rd);
5968
    gen_load_gpr(t1, rs);
5969
    {
5970
        TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
5971
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
5972

    
5973
        tcg_gen_ld_ptr(r_ptr, cpu_env, offsetof(CPUState, fpu));
5974
        tcg_gen_ld_i32(r_tmp, r_ptr, offsetof(CPUMIPSFPUContext, fcr31));
5975
        tcg_temp_free(r_ptr);
5976
        tcg_gen_andi_i32(r_tmp, r_tmp, ccbit);
5977
        tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5978
        tcg_temp_free(r_tmp);
5979
    }
5980
    tcg_gen_mov_tl(t0, t1);
5981
    tcg_temp_free(t1);
5982

    
5983
    gen_set_label(l1);
5984
    gen_store_gpr(t0, rd);
5985
    tcg_temp_free(t0);
5986
}
5987

    
5988
static inline void gen_movcf_s (int cc, int tf)
5989
{
5990
    uint32_t ccbit;
5991
    int cond;
5992
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5993
    int l1 = gen_new_label();
5994

    
5995
    if (cc)
5996
        ccbit = 1 << (24 + cc);
5997
    else
5998
        ccbit = 1 << 23;
5999

    
6000
    if (tf)
6001
        cond = TCG_COND_EQ;
6002
    else
6003
        cond = TCG_COND_NE;
6004

    
6005
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6006
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6007
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6008
    tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]);
6009
    gen_set_label(l1);
6010
    tcg_temp_free(r_tmp1);
6011
}
6012

    
6013
static inline void gen_movcf_d (int cc, int tf)
6014
{
6015
    uint32_t ccbit;
6016
    int cond;
6017
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
6018
    int l1 = gen_new_label();
6019

    
6020
    if (cc)
6021
        ccbit = 1 << (24 + cc);
6022
    else
6023
        ccbit = 1 << 23;
6024

    
6025
    if (tf)
6026
        cond = TCG_COND_EQ;
6027
    else
6028
        cond = TCG_COND_NE;
6029

    
6030
    tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31));
6031
    tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit);
6032
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6033
    tcg_gen_movi_i64(fpu64_T[2], fpu64_T[0]);
6034
    gen_set_label(l1);
6035
    tcg_temp_free(r_tmp1);
6036
}
6037

    
6038
static inline void gen_movcf_ps (int cc, int tf)
6039
{
6040
    int cond;
6041
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6042
    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);
6043
    int l1 = gen_new_label();
6044
    int l2 = gen_new_label();
6045

    
6046
    if (tf)
6047
        cond = TCG_COND_EQ;
6048
    else
6049
        cond = TCG_COND_NE;
6050

    
6051
    get_fp_cond(r_tmp1);
6052
    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);
6053
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);
6054
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);
6055
    tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]);
6056
    gen_set_label(l1);
6057
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);
6058
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);
6059
    tcg_gen_movi_i32(fpu32h_T[2], fpu32h_T[0]);
6060
    gen_set_label(l2);
6061
    tcg_temp_free(r_tmp1);
6062
    tcg_temp_free(r_tmp2);
6063
}
6064

    
6065

    
6066
static void gen_farith (DisasContext *ctx, uint32_t op1,
6067
                        int ft, int fs, int fd, int cc)
6068
{
6069
    const char *opn = "farith";
6070
    const char *condnames[] = {
6071
            "c.f",
6072
            "c.un",
6073
            "c.eq",
6074
            "c.ueq",
6075
            "c.olt",
6076
            "c.ult",
6077
            "c.ole",
6078
            "c.ule",
6079
            "c.sf",
6080
            "c.ngle",
6081
            "c.seq",
6082
            "c.ngl",
6083
            "c.lt",
6084
            "c.nge",
6085
            "c.le",
6086
            "c.ngt",
6087
    };
6088
    const char *condnames_abs[] = {
6089
            "cabs.f",
6090
            "cabs.un",
6091
            "cabs.eq",
6092
            "cabs.ueq",
6093
            "cabs.olt",
6094
            "cabs.ult",
6095
            "cabs.ole",
6096
            "cabs.ule",
6097
            "cabs.sf",
6098
            "cabs.ngle",
6099
            "cabs.seq",
6100
            "cabs.ngl",
6101
            "cabs.lt",
6102
            "cabs.nge",
6103
            "cabs.le",
6104
            "cabs.ngt",
6105
    };
6106
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6107
    uint32_t func = ctx->opcode & 0x3f;
6108

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

    
6231
            gen_load_gpr(t0, ft);
6232
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6233
            tcg_temp_free(t0);
6234
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
6235
            gen_set_label(l1);
6236
        }
6237
        gen_store_fpr32(fpu32_T[2], fd);
6238
        opn = "movz.s";
6239
        break;
6240
    case FOP(19, 16):
6241
        gen_load_fpr32(fpu32_T[0], fs);
6242
        gen_load_fpr32(fpu32_T[2], fd);
6243
        {
6244
            int l1 = gen_new_label();
6245
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6246

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

    
6491
            gen_load_gpr(t0, ft);
6492
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6493
            tcg_temp_free(t0);
6494
            tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]);
6495
            gen_set_label(l1);
6496
        }
6497
        gen_store_fpr64(ctx, fpu64_T[2], fd);
6498
        opn = "movz.d";
6499
        break;
6500
    case FOP(19, 17):
6501
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6502
        gen_load_fpr64(ctx, fpu64_T[2], fd);
6503
        {
6504
            int l1 = gen_new_label();
6505
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6506

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

    
6726
            gen_load_gpr(t0, ft);
6727
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6728
            tcg_temp_free(t0);
6729
            tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]);
6730
            tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]);
6731
            gen_set_label(l1);
6732
        }
6733
        gen_store_fpr32(fpu32_T[2], fd);
6734
        gen_store_fpr32h(fpu32h_T[2], fd);
6735
        opn = "movz.ps";
6736
        break;
6737
    case FOP(19, 22):
6738
        check_cp1_64bitmode(ctx);
6739
        gen_load_fpr32(fpu32_T[0], fs);
6740
        gen_load_fpr32h(fpu32h_T[0], fs);
6741
        gen_load_fpr32(fpu32_T[2], fd);
6742
        gen_load_fpr32h(fpu32h_T[2], fd);
6743
        {
6744
            int l1 = gen_new_label();
6745
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6746

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

    
6922
/* Coprocessor 3 (FPU) */
6923
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
6924
                           int fd, int fs, int base, int index)
6925
{
6926
    const char *opn = "extended float load/store";
6927
    int store = 0;
6928
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6929
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
6930

    
6931
    if (base == 0) {
6932
        gen_load_gpr(t0, index);
6933
    } else if (index == 0) {
6934
        gen_load_gpr(t0, base);
6935
    } else {
6936
        gen_load_gpr(t0, base);
6937
        gen_load_gpr(t1, index);
6938
        gen_op_addr_add(t0, t1);
6939
    }
6940
    /* Don't do NOP if destination is zero: we must perform the actual
6941
       memory access. */
6942
    switch (opc) {
6943
    case OPC_LWXC1:
6944
        check_cop1x(ctx);
6945
        tcg_gen_qemu_ld32s(fpu32_T[0], t0, ctx->mem_idx);
6946
        gen_store_fpr32(fpu32_T[0], fd);
6947
        opn = "lwxc1";
6948
        break;
6949
    case OPC_LDXC1:
6950
        check_cop1x(ctx);
6951
        check_cp1_registers(ctx, fd);
6952
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
6953
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6954
        opn = "ldxc1";
6955
        break;
6956
    case OPC_LUXC1:
6957
        check_cp1_64bitmode(ctx);
6958
        tcg_gen_andi_tl(t0, t0, ~0x7);
6959
        tcg_gen_qemu_ld64(fpu64_T[0], t0, ctx->mem_idx);
6960
        gen_store_fpr64(ctx, fpu64_T[0], fd);
6961
        opn = "luxc1";
6962
        break;
6963
    case OPC_SWXC1:
6964
        check_cop1x(ctx);
6965
        gen_load_fpr32(fpu32_T[0], fs);
6966
        tcg_gen_qemu_st32(fpu32_T[0], t0, ctx->mem_idx);
6967
        opn = "swxc1";
6968
        store = 1;
6969
        break;
6970
    case OPC_SDXC1:
6971
        check_cop1x(ctx);
6972
        check_cp1_registers(ctx, fs);
6973
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6974
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
6975
        opn = "sdxc1";
6976
        store = 1;
6977
        break;
6978
    case OPC_SUXC1:
6979
        check_cp1_64bitmode(ctx);
6980
        gen_load_fpr64(ctx, fpu64_T[0], fs);
6981
        tcg_gen_andi_tl(t0, t0, ~0x7);
6982
        tcg_gen_qemu_st64(fpu64_T[0], t0, ctx->mem_idx);
6983
        opn = "suxc1";
6984
        store = 1;
6985
        break;
6986
    default:
6987
        MIPS_INVAL(opn);
6988
        generate_exception(ctx, EXCP_RI);
6989
        tcg_temp_free(t0);
6990
        tcg_temp_free(t1);
6991
        return;
6992
    }
6993
    tcg_temp_free(t0);
6994
    tcg_temp_free(t1);
6995
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
6996
               regnames[index], regnames[base]);
6997
}
6998

    
6999
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7000
                            int fd, int fr, int fs, int ft)
7001
{
7002
    const char *opn = "flt3_arith";
7003

    
7004
    switch (opc) {
7005
    case OPC_ALNV_PS:
7006
        check_cp1_64bitmode(ctx);
7007
        {
7008
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7009
            int l1 = gen_new_label();
7010
            int l2 = gen_new_label();
7011

    
7012
            gen_load_gpr(t0, fr);
7013
            tcg_gen_andi_tl(t0, t0, 0x7);
7014
            gen_load_fpr32(fpu32_T[0], fs);
7015
            gen_load_fpr32h(fpu32h_T[0], fs);
7016
            gen_load_fpr32(fpu32_T[1], ft);
7017
            gen_load_fpr32h(fpu32h_T[1], ft);
7018

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

    
7176
/* ISA extensions (ASEs) */
7177
/* MIPS16 extension to MIPS32 */
7178
/* SmartMIPS extension to MIPS32 */
7179

    
7180
#if defined(TARGET_MIPS64)
7181

    
7182
/* MDMX extension to MIPS64 */
7183

    
7184
#endif
7185

    
7186
static void decode_opc (CPUState *env, DisasContext *ctx)
7187
{
7188
    int32_t offset;
7189
    int rs, rt, rd, sa;
7190
    uint32_t op, op1, op2;
7191
    int16_t imm;
7192

    
7193
    /* make sure instructions are on a word boundary */
7194
    if (ctx->pc & 0x3) {
7195
        env->CP0_BadVAddr = ctx->pc;
7196
        generate_exception(ctx, EXCP_AdEL);
7197
        return;
7198
    }
7199

    
7200
    /* Handle blikely not taken case */
7201
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7202
        TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
7203
        int l1 = gen_new_label();
7204

    
7205
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7206
        tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7207
        tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7208
        tcg_temp_free(r_tmp);
7209
        {
7210
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
7211

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

    
7292
        case OPC_MOVCI:
7293
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7294
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7295
                save_cpu_state(ctx, 1);
7296
                check_cp1_enabled(ctx);
7297
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7298
                          (ctx->opcode >> 16) & 1);
7299
            } else {
7300
                generate_exception_err(ctx, EXCP_CpU, 1);
7301
            }
7302
            break;
7303

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

    
7388
                switch (op2) {
7389
                case OPC_WSBH:
7390
                    gen_load_gpr(t1, rt);
7391
                    tcg_gen_helper_1_2(do_wsbh, t0, t0, t1);
7392
                    gen_store_gpr(t0, rd);
7393
                    break;
7394
                case OPC_SEB:
7395
                    gen_load_gpr(t1, rt);
7396
                    tcg_gen_ext8s_tl(t0, t1);
7397
                    gen_store_gpr(t0, rd);
7398
                    break;
7399
                case OPC_SEH:
7400
                    gen_load_gpr(t1, rt);
7401
                    tcg_gen_ext16s_tl(t0, t1);
7402
                    gen_store_gpr(t0, rd);
7403
                    break;
7404
                default:            /* Invalid */
7405
                    MIPS_INVAL("bshfl");
7406
                    generate_exception(ctx, EXCP_RI);
7407
                    break;
7408
                }
7409
                tcg_temp_free(t0);
7410
                tcg_temp_free(t1);
7411
            }
7412
            break;
7413
        case OPC_RDHWR:
7414
            check_insn(env, ctx, ISA_MIPS32R2);
7415
            {
7416
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7417

    
7418
                switch (rd) {
7419
                case 0:
7420
                    save_cpu_state(ctx, 1);
7421
                    tcg_gen_helper_1_0(do_rdhwr_cpunum, t0);
7422
                    break;
7423
                case 1:
7424
                    save_cpu_state(ctx, 1);
7425
                    tcg_gen_helper_1_0(do_rdhwr_synci_step, t0);
7426
                    break;
7427
                case 2:
7428
                    save_cpu_state(ctx, 1);
7429
                    tcg_gen_helper_1_0(do_rdhwr_cc, t0);
7430
                    break;
7431
                case 3:
7432
                    save_cpu_state(ctx, 1);
7433
                    tcg_gen_helper_1_0(do_rdhwr_ccres, t0);
7434
                    break;
7435
                case 29:
7436
#if defined (CONFIG_USER_ONLY)
7437
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7438
                    break;
7439
#else
7440
                    /* XXX: Some CPUs implement this in hardware. Not supported yet. */
7441
#endif
7442
                default:            /* Invalid */
7443
                    MIPS_INVAL("rdhwr");
7444
                    generate_exception(ctx, EXCP_RI);
7445
                    break;
7446
                }
7447
                gen_store_gpr(t0, rt);
7448
                tcg_temp_free(t0);
7449
            }
7450
            break;
7451
        case OPC_FORK:
7452
            check_insn(env, ctx, ASE_MT);
7453
            {
7454
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7455
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7456

    
7457
                gen_load_gpr(t0, rt);
7458
                gen_load_gpr(t1, rs);
7459
                tcg_gen_helper_0_2(do_fork, t0, t1);
7460
                tcg_temp_free(t0);
7461
                tcg_temp_free(t1);
7462
            }
7463
            break;
7464
        case OPC_YIELD:
7465
            check_insn(env, ctx, ASE_MT);
7466
            {
7467
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7468

    
7469
                gen_load_gpr(t0, rs);
7470
                tcg_gen_helper_1_1(do_yield, t0, t0);
7471
                gen_store_gpr(t0, rd);
7472
                tcg_temp_free(t0);
7473
            }
7474
            break;
7475
#if defined(TARGET_MIPS64)
7476
        case OPC_DEXTM ... OPC_DEXT:
7477
        case OPC_DINSM ... OPC_DINS:
7478
            check_insn(env, ctx, ISA_MIPS64R2);
7479
            check_mips_64(ctx);
7480
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7481
            break;
7482
        case OPC_DBSHFL:
7483
            check_insn(env, ctx, ISA_MIPS64R2);
7484
            check_mips_64(ctx);
7485
            op2 = MASK_DBSHFL(ctx->opcode);
7486
            {
7487
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7488
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7489

    
7490
                switch (op2) {
7491
                case OPC_DSBH:
7492
                    gen_load_gpr(t1, rt);
7493
                    tcg_gen_helper_1_2(do_dsbh, t0, t0, t1);
7494
                    break;
7495
                case OPC_DSHD:
7496
                    gen_load_gpr(t1, rt);
7497
                    tcg_gen_helper_1_2(do_dshd, t0, t0, t1);
7498
                    break;
7499
                default:            /* Invalid */
7500
                    MIPS_INVAL("dbshfl");
7501
                    generate_exception(ctx, EXCP_RI);
7502
                    break;
7503
                }
7504
                gen_store_gpr(t0, rd);
7505
                tcg_temp_free(t0);
7506
                tcg_temp_free(t1);
7507
            }
7508
            break;
7509
#endif
7510
        default:            /* Invalid */
7511
            MIPS_INVAL("special3");
7512
            generate_exception(ctx, EXCP_RI);
7513
            break;
7514
        }
7515
        break;
7516
    case OPC_REGIMM:
7517
        op1 = MASK_REGIMM(ctx->opcode);
7518
        switch (op1) {
7519
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7520
        case OPC_BLTZAL ... OPC_BGEZALL:
7521
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7522
            return;
7523
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7524
        case OPC_TNEI:
7525
            gen_trap(ctx, op1, rs, -1, imm);
7526
            break;
7527
        case OPC_SYNCI:
7528
            check_insn(env, ctx, ISA_MIPS32R2);
7529
            /* Treat as NOP. */
7530
            break;
7531
        default:            /* Invalid */
7532
            MIPS_INVAL("regimm");
7533
            generate_exception(ctx, EXCP_RI);
7534
            break;
7535
        }
7536
        break;
7537
    case OPC_CP0:
7538
        check_cp0_enabled(ctx);
7539
        op1 = MASK_CP0(ctx->opcode);
7540
        switch (op1) {
7541
        case OPC_MFC0:
7542
        case OPC_MTC0:
7543
        case OPC_MFTR:
7544
        case OPC_MTTR:
7545
#if defined(TARGET_MIPS64)
7546
        case OPC_DMFC0:
7547
        case OPC_DMTC0:
7548
#endif
7549
#ifndef CONFIG_USER_ONLY
7550
            gen_cp0(env, ctx, op1, rt, rd);
7551
#endif
7552
            break;
7553
        case OPC_C0_FIRST ... OPC_C0_LAST:
7554
#ifndef CONFIG_USER_ONLY
7555
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7556
#endif
7557
            break;
7558
        case OPC_MFMC0:
7559
            op2 = MASK_MFMC0(ctx->opcode);
7560
            {
7561
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7562

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

    
7644
    /* Floating point (COP1). */
7645
    case OPC_LWC1:
7646
    case OPC_LDC1:
7647
    case OPC_SWC1:
7648
    case OPC_SDC1:
7649
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7650
            save_cpu_state(ctx, 1);
7651
            check_cp1_enabled(ctx);
7652
            gen_flt_ldst(ctx, op, rt, rs, imm);
7653
        } else {
7654
            generate_exception_err(ctx, EXCP_CpU, 1);
7655
        }
7656
        break;
7657

    
7658
    case OPC_CP1:
7659
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7660
            save_cpu_state(ctx, 1);
7661
            check_cp1_enabled(ctx);
7662
            op1 = MASK_CP1(ctx->opcode);
7663
            switch (op1) {
7664
            case OPC_MFHC1:
7665
            case OPC_MTHC1:
7666
                check_insn(env, ctx, ISA_MIPS32R2);
7667
            case OPC_MFC1:
7668
            case OPC_CFC1:
7669
            case OPC_MTC1:
7670
            case OPC_CTC1:
7671
                gen_cp1(ctx, op1, rt, rd);
7672
                break;
7673
#if defined(TARGET_MIPS64)
7674
            case OPC_DMFC1:
7675
            case OPC_DMTC1:
7676
                check_insn(env, ctx, ISA_MIPS3);
7677
                gen_cp1(ctx, op1, rt, rd);
7678
                break;
7679
#endif
7680
            case OPC_BC1ANY2:
7681
            case OPC_BC1ANY4:
7682
                check_cop1x(ctx);
7683
                check_insn(env, ctx, ASE_MIPS3D);
7684
                /* fall through */
7685
            case OPC_BC1:
7686
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7687
                                    (rt >> 2) & 0x7, imm << 2);
7688
                return;
7689
            case OPC_S_FMT:
7690
            case OPC_D_FMT:
7691
            case OPC_W_FMT:
7692
            case OPC_L_FMT:
7693
            case OPC_PS_FMT:
7694
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7695
                           (imm >> 8) & 0x7);
7696
                break;
7697
            default:
7698
                MIPS_INVAL("cp1");
7699
                generate_exception (ctx, EXCP_RI);
7700
                break;
7701
            }
7702
        } else {
7703
            generate_exception_err(ctx, EXCP_CpU, 1);
7704
        }
7705
        break;
7706

    
7707
    /* COP2.  */
7708
    case OPC_LWC2:
7709
    case OPC_LDC2:
7710
    case OPC_SWC2:
7711
    case OPC_SDC2:
7712
    case OPC_CP2:
7713
        /* COP2: Not implemented. */
7714
        generate_exception_err(ctx, EXCP_CpU, 2);
7715
        break;
7716

    
7717
    case OPC_CP3:
7718
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7719
            save_cpu_state(ctx, 1);
7720
            check_cp1_enabled(ctx);
7721
            op1 = MASK_CP3(ctx->opcode);
7722
            switch (op1) {
7723
            case OPC_LWXC1:
7724
            case OPC_LDXC1:
7725
            case OPC_LUXC1:
7726
            case OPC_SWXC1:
7727
            case OPC_SDXC1:
7728
            case OPC_SUXC1:
7729
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7730
                break;
7731
            case OPC_PREFX:
7732
                /* Treat as NOP. */
7733
                break;
7734
            case OPC_ALNV_PS:
7735
            case OPC_MADD_S:
7736
            case OPC_MADD_D:
7737
            case OPC_MADD_PS:
7738
            case OPC_MSUB_S:
7739
            case OPC_MSUB_D:
7740
            case OPC_MSUB_PS:
7741
            case OPC_NMADD_S:
7742
            case OPC_NMADD_D:
7743
            case OPC_NMADD_PS:
7744
            case OPC_NMSUB_S:
7745
            case OPC_NMSUB_D:
7746
            case OPC_NMSUB_PS:
7747
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
7748
                break;
7749
            default:
7750
                MIPS_INVAL("cp3");
7751
                generate_exception (ctx, EXCP_RI);
7752
                break;
7753
            }
7754
        } else {
7755
            generate_exception_err(ctx, EXCP_CpU, 1);
7756
        }
7757
        break;
7758

    
7759
#if defined(TARGET_MIPS64)
7760
    /* MIPS64 opcodes */
7761
    case OPC_LWU:
7762
    case OPC_LDL ... OPC_LDR:
7763
    case OPC_SDL ... OPC_SDR:
7764
    case OPC_LLD:
7765
    case OPC_LD:
7766
    case OPC_SCD:
7767
    case OPC_SD:
7768
        check_insn(env, ctx, ISA_MIPS3);
7769
        check_mips_64(ctx);
7770
        gen_ldst(ctx, op, rt, rs, imm);
7771
        break;
7772
    case OPC_DADDI ... OPC_DADDIU:
7773
        check_insn(env, ctx, ISA_MIPS3);
7774
        check_mips_64(ctx);
7775
        gen_arith_imm(env, ctx, op, rt, rs, imm);
7776
        break;
7777
#endif
7778
    case OPC_JALX:
7779
        check_insn(env, ctx, ASE_MIPS16);
7780
        /* MIPS16: Not implemented. */
7781
    case OPC_MDMX:
7782
        check_insn(env, ctx, ASE_MDMX);
7783
        /* MDMX: Not implemented. */
7784
    default:            /* Invalid */
7785
        MIPS_INVAL("major opcode");
7786
        generate_exception(ctx, EXCP_RI);
7787
        break;
7788
    }
7789
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
7790
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
7791
        /* Branches completion */
7792
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
7793
        ctx->bstate = BS_BRANCH;
7794
        save_cpu_state(ctx, 0);
7795
        /* FIXME: Need to clear can_do_io.  */
7796
        switch (hflags) {
7797
        case MIPS_HFLAG_B:
7798
            /* unconditional branch */
7799
            MIPS_DEBUG("unconditional branch");
7800
            gen_goto_tb(ctx, 0, ctx->btarget);
7801
            break;
7802
        case MIPS_HFLAG_BL:
7803
            /* blikely taken case */
7804
            MIPS_DEBUG("blikely branch taken");
7805
            gen_goto_tb(ctx, 0, ctx->btarget);
7806
            break;
7807
        case MIPS_HFLAG_BC:
7808
            /* Conditional branch */
7809
            MIPS_DEBUG("conditional branch");
7810
            {
7811
                TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_TL);
7812
                int l1 = gen_new_label();
7813

    
7814
                tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, bcond));
7815
                tcg_gen_brcondi_tl(TCG_COND_NE, r_tmp, 0, l1);
7816
                tcg_temp_free(r_tmp);
7817
                gen_goto_tb(ctx, 1, ctx->pc + 4);
7818
                gen_set_label(l1);
7819
                gen_goto_tb(ctx, 0, ctx->btarget);
7820
            }
7821
            break;
7822
        case MIPS_HFLAG_BR:
7823
            /* unconditional branch to register */
7824
            MIPS_DEBUG("branch to register");
7825
            gen_breg_pc();
7826
            tcg_gen_exit_tb(0);
7827
            break;
7828
        default:
7829
            MIPS_DEBUG("unknown branch");
7830
            break;
7831
        }
7832
    }
7833
}
7834

    
7835
static always_inline int
7836
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
7837
                                int search_pc)
7838
{
7839
    DisasContext ctx;
7840
    target_ulong pc_start;
7841
    uint16_t *gen_opc_end;
7842
    int j, lj = -1;
7843
    int num_insns;
7844
    int max_insns;
7845

    
7846
    if (search_pc && loglevel)
7847
        fprintf (logfile, "search pc %d\n", search_pc);
7848

    
7849
    pc_start = tb->pc;
7850
    /* Leave some spare opc slots for branch handling. */
7851
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
7852
    ctx.pc = pc_start;
7853
    ctx.saved_pc = -1;
7854
    ctx.tb = tb;
7855
    ctx.bstate = BS_NONE;
7856
    /* Restore delay slot state from the tb context.  */
7857
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
7858
    restore_cpu_state(env, &ctx);
7859
#if defined(CONFIG_USER_ONLY)
7860
    ctx.mem_idx = MIPS_HFLAG_UM;
7861
#else
7862
    ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
7863
#endif
7864
    num_insns = 0;
7865
    max_insns = tb->cflags & CF_COUNT_MASK;
7866
    if (max_insns == 0)
7867
        max_insns = CF_COUNT_MASK;
7868
#ifdef DEBUG_DISAS
7869
    if (loglevel & CPU_LOG_TB_CPU) {
7870
        fprintf(logfile, "------------------------------------------------\n");
7871
        /* FIXME: This may print out stale hflags from env... */
7872
        cpu_dump_state(env, logfile, fprintf, 0);
7873
    }
7874
#endif
7875
#ifdef MIPS_DEBUG_DISAS
7876
    if (loglevel & CPU_LOG_TB_IN_ASM)
7877
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
7878
                tb, ctx.mem_idx, ctx.hflags);
7879
#endif
7880
    gen_icount_start();
7881
    while (ctx.bstate == BS_NONE) {
7882
        if (env->nb_breakpoints > 0) {
7883
            for(j = 0; j < env->nb_breakpoints; j++) {
7884
                if (env->breakpoints[j] == ctx.pc) {
7885
                    save_cpu_state(&ctx, 1);
7886
                    ctx.bstate = BS_BRANCH;
7887
                    tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
7888
                    /* Include the breakpoint location or the tb won't
7889
                     * be flushed when it must be.  */
7890
                    ctx.pc += 4;
7891
                    goto done_generating;
7892
                }
7893
            }
7894
        }
7895

    
7896
        if (search_pc) {
7897
            j = gen_opc_ptr - gen_opc_buf;
7898
            if (lj < j) {
7899
                lj++;
7900
                while (lj < j)
7901
                    gen_opc_instr_start[lj++] = 0;
7902
            }
7903
            gen_opc_pc[lj] = ctx.pc;
7904
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
7905
            gen_opc_instr_start[lj] = 1;
7906
            gen_opc_icount[lj] = num_insns;
7907
        }
7908
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
7909
            gen_io_start();
7910
        ctx.opcode = ldl_code(ctx.pc);
7911
        decode_opc(env, &ctx);
7912
        ctx.pc += 4;
7913
        num_insns++;
7914

    
7915
        if (env->singlestep_enabled)
7916
            break;
7917

    
7918
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
7919
            break;
7920

    
7921
        if (gen_opc_ptr >= gen_opc_end)
7922
            break;
7923

    
7924
        if (gen_opc_ptr >= gen_opc_end)
7925
            break;
7926

    
7927
        if (num_insns >= max_insns)
7928
            break;
7929
#if defined (MIPS_SINGLE_STEP)
7930
        break;
7931
#endif
7932
    }
7933
    if (tb->cflags & CF_LAST_IO)
7934
        gen_io_end();
7935
    if (env->singlestep_enabled) {
7936
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
7937
        tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
7938
    } else {
7939
        switch (ctx.bstate) {
7940
        case BS_STOP:
7941
            tcg_gen_helper_0_0(do_interrupt_restart);
7942
            gen_goto_tb(&ctx, 0, ctx.pc);
7943
            break;
7944
        case BS_NONE:
7945
            save_cpu_state(&ctx, 0);
7946
            gen_goto_tb(&ctx, 0, ctx.pc);
7947
            break;
7948
        case BS_EXCP:
7949
            tcg_gen_helper_0_0(do_interrupt_restart);
7950
            tcg_gen_exit_tb(0);
7951
            break;
7952
        case BS_BRANCH:
7953
        default:
7954
            break;
7955
        }
7956
    }
7957
done_generating:
7958
    gen_icount_end(tb, num_insns);
7959
    *gen_opc_ptr = INDEX_op_end;
7960
    if (search_pc) {
7961
        j = gen_opc_ptr - gen_opc_buf;
7962
        lj++;
7963
        while (lj <= j)
7964
            gen_opc_instr_start[lj++] = 0;
7965
    } else {
7966
        tb->size = ctx.pc - pc_start;
7967
        tb->icount = num_insns;
7968
    }
7969
#ifdef DEBUG_DISAS
7970
#if defined MIPS_DEBUG_DISAS
7971
    if (loglevel & CPU_LOG_TB_IN_ASM)
7972
        fprintf(logfile, "\n");
7973
#endif
7974
    if (loglevel & CPU_LOG_TB_IN_ASM) {
7975
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
7976
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
7977
        fprintf(logfile, "\n");
7978
    }
7979
    if (loglevel & CPU_LOG_TB_CPU) {
7980
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
7981
    }
7982
#endif
7983

    
7984
    return 0;
7985
}
7986

    
7987
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
7988
{
7989
    return gen_intermediate_code_internal(env, tb, 0);
7990
}
7991

    
7992
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
7993
{
7994
    return gen_intermediate_code_internal(env, tb, 1);
7995
}
7996

    
7997
void fpu_dump_state(CPUState *env, FILE *f,
7998
                    int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
7999
                    int flags)
8000
{
8001
    int i;
8002
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8003

    
8004
#define printfpr(fp)                                                        \
8005
    do {                                                                    \
8006
        if (is_fpu64)                                                       \
8007
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8008
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8009
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8010
        else {                                                              \
8011
            fpr_t tmp;                                                      \
8012
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8013
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8014
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8015
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8016
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8017
        }                                                                   \
8018
    } while(0)
8019

    
8020

    
8021
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8022
                env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
8023
                get_float_exception_flags(&env->fpu->fp_status));
8024
    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
8025
    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
8026
    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
8027
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8028
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8029
        printfpr(&env->fpu->fpr[i]);
8030
    }
8031

    
8032
#undef printfpr
8033
}
8034

    
8035
void dump_fpu (CPUState *env)
8036
{
8037
    if (loglevel) {
8038
        fprintf(logfile,
8039
                "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
8040
                " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx
8041
                " %04x\n",
8042
                env->active_tc.PC, env->active_tc.HI[0],
8043
                env->active_tc.LO[0], env->hflags, env->btarget,
8044
                env->bcond);
8045
       fpu_dump_state(env, logfile, fprintf, 0);
8046
    }
8047
}
8048

    
8049
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8050
/* Debug help: The architecture requires 32bit code to maintain proper
8051
   sign-extened values on 64bit machines.  */
8052

    
8053
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8054

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

    
8061
    if (!SIGN_EXT_P(env->active_tc.PC))
8062
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8063
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8064
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8065
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8066
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8067
    if (!SIGN_EXT_P(env->btarget))
8068
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8069

    
8070
    for (i = 0; i < 32; i++) {
8071
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8072
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8073
    }
8074

    
8075
    if (!SIGN_EXT_P(env->CP0_EPC))
8076
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8077
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8078
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8079
}
8080
#endif
8081

    
8082
void cpu_dump_state (CPUState *env, FILE *f,
8083
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8084
                     int flags)
8085
{
8086
    int i;
8087

    
8088
    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",
8089
                env->active_tc.PC, env->active_tc.HI, env->active_tc.LO, env->hflags, env->btarget, env->bcond);
8090
    for (i = 0; i < 32; i++) {
8091
        if ((i & 3) == 0)
8092
            cpu_fprintf(f, "GPR%02d:", i);
8093
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8094
        if ((i & 3) == 3)
8095
            cpu_fprintf(f, "\n");
8096
    }
8097

    
8098
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8099
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8100
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8101
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8102
    if (env->hflags & MIPS_HFLAG_FPU)
8103
        fpu_dump_state(env, f, cpu_fprintf, flags);
8104
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8105
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8106
#endif
8107
}
8108

    
8109
static void mips_tcg_init(void)
8110
{
8111
    static int inited;
8112

    
8113
    /* Initialize various static tables. */
8114
    if (inited)
8115
        return;
8116

    
8117
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8118
    current_fpu = tcg_global_mem_new(TCG_TYPE_PTR,
8119
                                     TCG_AREG0,
8120
                                     offsetof(CPUState, fpu),
8121
                                     "current_fpu");
8122

    
8123
    /* register helpers */
8124
#undef DEF_HELPER
8125
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8126
#include "helper.h"
8127

    
8128
    fpu32_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[FP_ENDIAN_IDX]), "WT0");
8129
    fpu32_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[FP_ENDIAN_IDX]), "WT1");
8130
    fpu32_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[FP_ENDIAN_IDX]), "WT2");
8131
    fpu64_T[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft0.d), "DT0");
8132
    fpu64_T[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft1.d), "DT1");
8133
    fpu64_T[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, ft2.d), "DT2");
8134
    fpu32h_T[0] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft0.w[!FP_ENDIAN_IDX]), "WTH0");
8135
    fpu32h_T[1] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft1.w[!FP_ENDIAN_IDX]), "WTH1");
8136
    fpu32h_T[2] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, ft2.w[!FP_ENDIAN_IDX]), "WTH2");
8137

    
8138
    inited = 1;
8139
}
8140

    
8141
#include "translate_init.c"
8142

    
8143
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8144
{
8145
    CPUMIPSState *env;
8146
    const mips_def_t *def;
8147

    
8148
    def = cpu_mips_find_by_name(cpu_model);
8149
    if (!def)
8150
        return NULL;
8151
    env = qemu_mallocz(sizeof(CPUMIPSState));
8152
    if (!env)
8153
        return NULL;
8154
    env->cpu_model = def;
8155

    
8156
    cpu_exec_init(env);
8157
    env->cpu_model_str = cpu_model;
8158
    mips_tcg_init();
8159
    cpu_reset(env);
8160
    return env;
8161
}
8162

    
8163
void cpu_reset (CPUMIPSState *env)
8164
{
8165
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8166

    
8167
    tlb_flush(env, 1);
8168

    
8169
    /* Minimal init */
8170
#if !defined(CONFIG_USER_ONLY)
8171
    if (env->hflags & MIPS_HFLAG_BMASK) {
8172
        /* If the exception was raised from a delay slot,
8173
         * come back to the jump.  */
8174
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8175
    } else {
8176
        env->CP0_ErrorEPC = env->active_tc.PC;
8177
    }
8178
    env->active_tc.PC = (int32_t)0xBFC00000;
8179
    env->CP0_Wired = 0;
8180
    /* SMP not implemented */
8181
    env->CP0_EBase = 0x80000000;
8182
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8183
    /* vectored interrupts not implemented, timer on int 7,
8184
       no performance counters. */
8185
    env->CP0_IntCtl = 0xe0000000;
8186
    {
8187
        int i;
8188

    
8189
        for (i = 0; i < 7; i++) {
8190
            env->CP0_WatchLo[i] = 0;
8191
            env->CP0_WatchHi[i] = 0x80000000;
8192
        }
8193
        env->CP0_WatchLo[7] = 0;
8194
        env->CP0_WatchHi[7] = 0;
8195
    }
8196
    /* Count register increments in debug mode, EJTAG version 1 */
8197
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8198
#endif
8199
    env->exception_index = EXCP_NONE;
8200
#if defined(CONFIG_USER_ONLY)
8201
    env->hflags = MIPS_HFLAG_UM;
8202
    env->user_mode_only = 1;
8203
#else
8204
    env->hflags = MIPS_HFLAG_CP0;
8205
#endif
8206
    cpu_mips_register(env, env->cpu_model);
8207
}
8208

    
8209
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8210
                unsigned long searched_pc, int pc_pos, void *puc)
8211
{
8212
    env->active_tc.PC = gen_opc_pc[pc_pos];
8213
    env->hflags &= ~MIPS_HFLAG_BMASK;
8214
    env->hflags |= gen_opc_hflags[pc_pos];
8215
}