Statistics
| Branch: | Revision:

root / target-mips / translate.c @ f01be154

History | View | Annotate | Download (258.9 kB)

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

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

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

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

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

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

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

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
425
/* global register indices */
426
static TCGv cpu_env, bcond, btarget;
427
static TCGv fpu_fpr32[32], fpu_fpr32h[32], fpu_fpr64[32], fpu_fcr0, fpu_fcr31;
428

    
429
#include "gen-icount.h"
430

    
431
static inline void tcg_gen_helper_0_i(void *func, uint32_t arg)
432

    
433
{
434
    TCGv tmp = tcg_const_i32(arg);
435

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
551
static const char *fregnames_64[] =
552
    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
553
      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
554
      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
555
      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
556

    
557
static const char *fregnames_h[] =
558
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
559
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
560
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
561
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
562

    
563
#ifdef MIPS_DEBUG_DISAS
564
#define MIPS_DEBUG(fmt, args...)                                              \
565
do {                                                                          \
566
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
567
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
568
                ctx->pc, ctx->opcode , ##args);                               \
569
    }                                                                         \
570
} while (0)
571
#else
572
#define MIPS_DEBUG(fmt, args...) do { } while(0)
573
#endif
574

    
575
#define MIPS_INVAL(op)                                                        \
576
do {                                                                          \
577
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
578
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
579
} while (0)
580

    
581
/* General purpose registers moves. */
582
static inline void gen_load_gpr (TCGv t, int reg)
583
{
584
    if (reg == 0)
585
        tcg_gen_movi_tl(t, 0);
586
    else
587
        tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
588
                                  sizeof(target_ulong) * reg);
589
}
590

    
591
static inline void gen_store_gpr (TCGv t, int reg)
592
{
593
    if (reg != 0)
594
        tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.gpr) +
595
                                  sizeof(target_ulong) * reg);
596
}
597

    
598
/* Moves to/from HI and LO registers.  */
599
static inline void gen_load_LO (TCGv t, int reg)
600
{
601
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
602
                              sizeof(target_ulong) * reg);
603
}
604

    
605
static inline void gen_store_LO (TCGv t, int reg)
606
{
607
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.LO) +
608
                              sizeof(target_ulong) * reg);
609
}
610

    
611
static inline void gen_load_HI (TCGv t, int reg)
612
{
613
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
614
                              sizeof(target_ulong) * reg);
615
}
616

    
617
static inline void gen_store_HI (TCGv t, int reg)
618
{
619
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, active_tc.HI) +
620
                              sizeof(target_ulong) * reg);
621
}
622

    
623
/* Moves to/from shadow registers. */
624
static inline void gen_load_srsgpr (int from, int to)
625
{
626
    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
627

    
628
    if (from == 0)
629
        tcg_gen_movi_tl(r_tmp1, 0);
630
    else {
631
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
632

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

    
639
        tcg_gen_ld_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * from);
640
        tcg_temp_free(r_tmp2);
641
    }
642
    gen_store_gpr(r_tmp1, to);
643
    tcg_temp_free(r_tmp1);
644
}
645

    
646
static inline void gen_store_srsgpr (int from, int to)
647
{
648
    if (to != 0) {
649
        TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
650
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
651

    
652
        gen_load_gpr(r_tmp1, from);
653
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
654
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
655
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
656
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
657
        tcg_gen_add_i32(r_tmp2, cpu_env, r_tmp2);
658

    
659
        tcg_gen_st_tl(r_tmp1, r_tmp2, sizeof(target_ulong) * to);
660
        tcg_temp_free(r_tmp1);
661
        tcg_temp_free(r_tmp2);
662
    }
663
}
664

    
665
/* Floating point register moves. */
666
static inline void gen_load_fpr32 (TCGv t, int reg)
667
{
668
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
669
}
670

    
671
static inline void gen_store_fpr32 (TCGv t, int reg)
672
{
673
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
674
}
675

    
676
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv t, int reg)
677
{
678
    if (ctx->hflags & MIPS_HFLAG_F64)
679
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
680
    else {
681
        TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
682

    
683
        tcg_gen_extu_i32_i64(t, fpu_fpr32[reg | 1]);
684
        tcg_gen_shli_i64(t, t, 32);
685
        tcg_gen_extu_i32_i64(r_tmp2, fpu_fpr32[reg & ~1]);
686
        tcg_gen_or_i64(t, t, r_tmp2);
687
        tcg_temp_free(r_tmp2);
688
    }
689
}
690

    
691
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv t, int reg)
692
{
693
    if (ctx->hflags & MIPS_HFLAG_F64)
694
        tcg_gen_mov_i64(fpu_fpr64[reg], t);
695
    else {
696
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
697
        tcg_gen_shri_i64(t, t, 32);
698
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
699
    }
700
}
701

    
702
static inline void gen_load_fpr32h (TCGv t, int reg)
703
{
704
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
705
}
706

    
707
static inline void gen_store_fpr32h (TCGv t, int reg)
708
{
709
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
710
}
711

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

    
717
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
718
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
719
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
720
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
721
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
722
    tcg_temp_free(r_tmp1);
723
    tcg_temp_free(r_tmp2);
724
}
725

    
726
typedef void (fcmp_fun32)(uint32_t, uint32_t, int);
727
typedef void (fcmp_fun64)(uint64_t, uint64_t, int);
728

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

    
753
FOP_CONDS(fcmp_fun64, , d)
754
FOP_CONDS(fcmp_fun64, abs, d)
755
FOP_CONDS(fcmp_fun32, , s)
756
FOP_CONDS(fcmp_fun32, abs, s)
757
FOP_CONDS(fcmp_fun64, , ps)
758
FOP_CONDS(fcmp_fun64, abs, ps)
759
#undef FOP_CONDS
760

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

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

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

    
819
static inline void gen_save_pc(target_ulong pc)
820
{
821
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
822

    
823
    tcg_gen_movi_tl(r_tmp, pc);
824
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, active_tc.PC));
825
    tcg_temp_free(r_tmp);
826
}
827

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

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

    
859
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
860
{
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
        ctx->btarget = env->btarget;
869
        break;
870
    }
871
}
872

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

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

    
891
/* Addresses computation */
892
static inline void gen_op_addr_add (TCGv t0, TCGv t1)
893
{
894
    tcg_gen_add_tl(t0, t0, t1);
895

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

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

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

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

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

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

    
939
/* Verify that the processor is running with 64-bit floating-point
940
   operations enabled.  */
941

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

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

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

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

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

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

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

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

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

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

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

    
1224
    if (base == 0) {
1225
        tcg_gen_movi_tl(t0, offset);
1226
    } else if (offset == 0) {
1227
        gen_load_gpr(t0, base);
1228
    } else {
1229
        TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1230

    
1231
        gen_load_gpr(t0, base);
1232
        tcg_gen_movi_tl(t1, offset);
1233
        gen_op_addr_add(t0, t1);
1234
        tcg_temp_free(t1);
1235
    }
1236
    /* Don't do NOP if destination is zero: we must perform the actual
1237
       memory access. */
1238
    switch (opc) {
1239
    case OPC_LWC1:
1240
        {
1241
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
1242

    
1243
            tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
1244
            gen_store_fpr32(fp0, ft);
1245
            tcg_temp_free(fp0);
1246
        }
1247
        opn = "lwc1";
1248
        break;
1249
    case OPC_SWC1:
1250
        {
1251
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
1252

    
1253
            gen_load_fpr32(fp0, ft);
1254
            tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
1255
            tcg_temp_free(fp0);
1256
        }
1257
        opn = "swc1";
1258
        break;
1259
    case OPC_LDC1:
1260
        {
1261
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
1262

    
1263
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1264
            gen_store_fpr64(ctx, fp0, ft);
1265
            tcg_temp_free(fp0);
1266
        }
1267
        opn = "ldc1";
1268
        break;
1269
    case OPC_SDC1:
1270
        {
1271
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
1272

    
1273
            gen_load_fpr64(ctx, fp0, ft);
1274
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1275
            tcg_temp_free(fp0);
1276
        }
1277
        opn = "sdc1";
1278
        break;
1279
    default:
1280
        MIPS_INVAL(opn);
1281
        generate_exception(ctx, EXCP_RI);
1282
        goto out;
1283
    }
1284
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1285
 out:
1286
    tcg_temp_free(t0);
1287
}
1288

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

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

    
1345
            save_cpu_state(ctx, 1);
1346
            tcg_gen_ext32s_tl(r_tmp1, t0);
1347
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1348

    
1349
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1350
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1351
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1352
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1353
            tcg_temp_free(r_tmp2);
1354
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1355
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1356
            tcg_temp_free(r_tmp1);
1357
            /* operands of same sign, result different sign */
1358
            generate_exception(ctx, EXCP_OVERFLOW);
1359
            gen_set_label(l1);
1360

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

    
1378
            save_cpu_state(ctx, 1);
1379
            tcg_gen_mov_tl(r_tmp1, t0);
1380
            tcg_gen_addi_tl(t0, t0, uimm);
1381

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

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

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

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

    
1568
/* Arithmetic */
1569
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1570
                       int rd, int rs, int rt)
1571
{
1572
    const char *opn = "arith";
1573
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1574
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1575

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

    
1598
            save_cpu_state(ctx, 1);
1599
            tcg_gen_ext32s_tl(r_tmp1, t0);
1600
            tcg_gen_ext32s_tl(r_tmp2, t1);
1601
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1602

    
1603
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1604
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1605
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1606
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1607
            tcg_temp_free(r_tmp2);
1608
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1609
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1610
            tcg_temp_free(r_tmp1);
1611
            /* operands of same sign, result different sign */
1612
            generate_exception(ctx, EXCP_OVERFLOW);
1613
            gen_set_label(l1);
1614

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

    
1632
            save_cpu_state(ctx, 1);
1633
            tcg_gen_ext32s_tl(r_tmp1, t0);
1634
            tcg_gen_ext32s_tl(r_tmp2, t1);
1635
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1636

    
1637
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1638
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1639
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1640
            tcg_temp_free(r_tmp2);
1641
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1642
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1643
            tcg_temp_free(r_tmp1);
1644
            /* operands of different sign, first operand and result different sign */
1645
            generate_exception(ctx, EXCP_OVERFLOW);
1646
            gen_set_label(l1);
1647

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

    
1666
            save_cpu_state(ctx, 1);
1667
            tcg_gen_mov_tl(r_tmp1, t0);
1668
            tcg_gen_add_tl(t0, t0, t1);
1669

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

    
1694
            save_cpu_state(ctx, 1);
1695
            tcg_gen_mov_tl(r_tmp1, t0);
1696
            tcg_gen_sub_tl(t0, t0, t1);
1697

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

    
1752
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1753
            gen_store_gpr(t0, rd);
1754
            gen_set_label(l1);
1755
        }
1756
        opn = "movn";
1757
        goto print;
1758
    case OPC_MOVZ:
1759
        {
1760
            int l1 = gen_new_label();
1761

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

    
1798
                tcg_gen_andi_tl(t0, t0, 0x1f);
1799
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1800
                {
1801
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1802
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1803
                    TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1804

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

    
1860
                tcg_gen_andi_tl(t0, t0, 0x3f);
1861
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1862
                {
1863
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1864

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

    
1903
/* Arithmetic on HI/LO registers */
1904
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1905
{
1906
    const char *opn = "hilo";
1907
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1908

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

    
1945
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1946
                        int rs, int rt)
1947
{
1948
    const char *opn = "mul/div";
1949
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
1950
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
1951

    
1952
    gen_load_gpr(t0, rs);
1953
    gen_load_gpr(t1, rt);
1954
    switch (opc) {
1955
    case OPC_DIV:
1956
        {
1957
            int l1 = gen_new_label();
1958

    
1959
            tcg_gen_ext32s_tl(t0, t0);
1960
            tcg_gen_ext32s_tl(t1, t1);
1961
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1962
            {
1963
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1964
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1965
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I64);
1966

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

    
1989
            tcg_gen_ext32s_tl(t1, t1);
1990
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1991
            {
1992
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
1993
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32);
1994
                TCGv r_tmp3 = tcg_temp_new(TCG_TYPE_I32);
1995

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

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

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

    
2061
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2062
            {
2063
                int l2 = gen_new_label();
2064

    
2065
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2066
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2067
                {
2068
                    tcg_gen_movi_tl(t1, 0);
2069
                    gen_store_LO(t0, 0);
2070
                    gen_store_HI(t1, 0);
2071
                    tcg_gen_br(l1);
2072
                }
2073
                gen_set_label(l2);
2074
                {
2075
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2076
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2077

    
2078
                    tcg_gen_div_i64(r_tmp1, t0, t1);
2079
                    tcg_gen_rem_i64(r_tmp2, t0, t1);
2080
                    gen_store_LO(r_tmp1, 0);
2081
                    gen_store_HI(r_tmp2, 0);
2082
                    tcg_temp_free(r_tmp1);
2083
                    tcg_temp_free(r_tmp2);
2084
                }
2085
            }
2086
            gen_set_label(l1);
2087
        }
2088
        opn = "ddiv";
2089
        break;
2090
    case OPC_DDIVU:
2091
        {
2092
            int l1 = gen_new_label();
2093

    
2094
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2095
            {
2096
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
2097
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
2098

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

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

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

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

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

    
2254
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2255
                            int rd, int rs, int rt)
2256
{
2257
    const char *opn = "mul vr54xx";
2258
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2259
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2260

    
2261
    gen_load_gpr(t0, rs);
2262
    gen_load_gpr(t1, rt);
2263

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

    
2329
 out:
2330
    tcg_temp_free(t0);
2331
    tcg_temp_free(t1);
2332
}
2333

    
2334
static void gen_cl (DisasContext *ctx, uint32_t opc,
2335
                    int rd, int rs)
2336
{
2337
    const char *opn = "CLx";
2338
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2339

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

    
2373
 out:
2374
    tcg_temp_free(t0);
2375
}
2376

    
2377
/* Traps */
2378
static void gen_trap (DisasContext *ctx, uint32_t opc,
2379
                      int rs, int rt, int16_t imm)
2380
{
2381
    int cond;
2382
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2383
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2384

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

    
2475
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2476
        tcg_gen_helper_0_i(do_raise_exception, EXCP_TRAP);
2477
        gen_set_label(l1);
2478
    }
2479
    ctx->bstate = BS_STOP;
2480
 out:
2481
    tcg_temp_free(t0);
2482
    tcg_temp_free(t1);
2483
}
2484

    
2485
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2486
{
2487
    TranslationBlock *tb;
2488
    tb = ctx->tb;
2489
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2490
        tcg_gen_goto_tb(n);
2491
        gen_save_pc(dest);
2492
        tcg_gen_exit_tb((long)tb + n);
2493
    } else {
2494
        gen_save_pc(dest);
2495
        tcg_gen_exit_tb(0);
2496
    }
2497
}
2498

    
2499
/* Branches (before delay slot) */
2500
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2501
                                int rs, int rt, int32_t offset)
2502
{
2503
    target_ulong btgt = -1;
2504
    int blink = 0;
2505
    int bcond_compute = 0;
2506
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2507
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2508

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

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

    
2733
    ctx->btarget = btgt;
2734
    if (blink > 0) {
2735
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2736
        gen_store_gpr(t0, blink);
2737
    }
2738

    
2739
 out:
2740
    tcg_temp_free(t0);
2741
    tcg_temp_free(t1);
2742
}
2743

    
2744
/* special3 bitfield operations */
2745
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2746
                        int rs, int lsb, int msb)
2747
{
2748
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
2749
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
2750

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

    
2814
#ifndef CONFIG_USER_ONLY
2815
/* CP0 (MMU and control) */
2816
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2817
{
2818
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2819

    
2820
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2821
    tcg_gen_ext_i32_tl(t, r_tmp);
2822
    tcg_temp_free(r_tmp);
2823
}
2824

    
2825
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2826
{
2827
    tcg_gen_ld_tl(t, cpu_env, off);
2828
    tcg_gen_ext32s_tl(t, t);
2829
}
2830

    
2831
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2832
{
2833
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2834

    
2835
    tcg_gen_trunc_tl_i32(r_tmp, t);
2836
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2837
    tcg_temp_free(r_tmp);
2838
}
2839

    
2840
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2841
{
2842
    tcg_gen_ext32s_tl(t, t);
2843
    tcg_gen_st_tl(t, cpu_env, off);
2844
}
2845

    
2846
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2847
{
2848
    const char *rn = "invalid";
2849

    
2850
    if (sel != 0)
2851
        check_insn(env, ctx, ISA_MIPS32);
2852

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

    
3422
die:
3423
#if defined MIPS_DEBUG_DISAS
3424
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3425
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3426
                rn, reg, sel);
3427
    }
3428
#endif
3429
    generate_exception(ctx, EXCP_RI);
3430
}
3431

    
3432
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3433
{
3434
    const char *rn = "invalid";
3435

    
3436
    if (sel != 0)
3437
        check_insn(env, ctx, ISA_MIPS32);
3438

    
3439
    if (use_icount)
3440
        gen_io_start();
3441

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

    
4031
die:
4032
#if defined MIPS_DEBUG_DISAS
4033
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4034
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
4035
                rn, reg, sel);
4036
    }
4037
#endif
4038
    generate_exception(ctx, EXCP_RI);
4039
}
4040

    
4041
#if defined(TARGET_MIPS64)
4042
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4043
{
4044
    const char *rn = "invalid";
4045

    
4046
    if (sel != 0)
4047
        check_insn(env, ctx, ISA_MIPS64);
4048

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

    
4606
die:
4607
#if defined MIPS_DEBUG_DISAS
4608
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4609
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4610
                rn, reg, sel);
4611
    }
4612
#endif
4613
    generate_exception(ctx, EXCP_RI);
4614
}
4615

    
4616
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4617
{
4618
    const char *rn = "invalid";
4619

    
4620
    if (sel != 0)
4621
        check_insn(env, ctx, ISA_MIPS64);
4622

    
4623
    if (use_icount)
4624
        gen_io_start();
4625

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

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

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

    
5219
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5220
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5221
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5222
        tcg_gen_movi_tl(t0, -1);
5223
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5224
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5225
        tcg_gen_movi_tl(t0, -1);
5226
    else if (u == 0) {
5227
        switch (rt) {
5228
        case 2:
5229
            switch (sel) {
5230
            case 1:
5231
                tcg_gen_helper_1_1(do_mftc0_tcstatus, t0, t0);
5232
                break;
5233
            case 2:
5234
                tcg_gen_helper_1_1(do_mftc0_tcbind, t0, t0);
5235
                break;
5236
            case 3:
5237
                tcg_gen_helper_1_1(do_mftc0_tcrestart, t0, t0);
5238
                break;
5239
            case 4:
5240
                tcg_gen_helper_1_1(do_mftc0_tchalt, t0, t0);
5241
                break;
5242
            case 5:
5243
                tcg_gen_helper_1_1(do_mftc0_tccontext, t0, t0);
5244
                break;
5245
            case 6:
5246
                tcg_gen_helper_1_1(do_mftc0_tcschedule, t0, t0);
5247
                break;
5248
            case 7:
5249
                tcg_gen_helper_1_1(do_mftc0_tcschefback, t0, t0);
5250
                break;
5251
            default:
5252
                gen_mfc0(env, ctx, t0, rt, sel);
5253
                break;
5254
            }
5255
            break;
5256
        case 10:
5257
            switch (sel) {
5258
            case 0:
5259
                tcg_gen_helper_1_1(do_mftc0_entryhi, t0, t0);
5260
                break;
5261
            default:
5262
                gen_mfc0(env, ctx, t0, rt, sel);
5263
                break;
5264
            }
5265
        case 12:
5266
            switch (sel) {
5267
            case 0:
5268
                tcg_gen_helper_1_1(do_mftc0_status, t0, t0);
5269
                break;
5270
            default:
5271
                gen_mfc0(env, ctx, t0, rt, sel);
5272
                break;
5273
            }
5274
        case 23:
5275
            switch (sel) {
5276
            case 0:
5277
                tcg_gen_helper_1_1(do_mftc0_debug, t0, t0);
5278
                break;
5279
            default:
5280
                gen_mfc0(env, ctx, t0, rt, sel);
5281
                break;
5282
            }
5283
            break;
5284
        default:
5285
            gen_mfc0(env, ctx, t0, rt, sel);
5286
        }
5287
    } else switch (sel) {
5288
    /* GPR registers. */
5289
    case 0:
5290
        tcg_gen_helper_1_1i(do_mftgpr, t0, t0, rt);
5291
        break;
5292
    /* Auxiliary CPU registers */
5293
    case 1:
5294
        switch (rt) {
5295
        case 0:
5296
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 0);
5297
            break;
5298
        case 1:
5299
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 0);
5300
            break;
5301
        case 2:
5302
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 0);
5303
            break;
5304
        case 4:
5305
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 1);
5306
            break;
5307
        case 5:
5308
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 1);
5309
            break;
5310
        case 6:
5311
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 1);
5312
            break;
5313
        case 8:
5314
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 2);
5315
            break;
5316
        case 9:
5317
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 2);
5318
            break;
5319
        case 10:
5320
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 2);
5321
            break;
5322
        case 12:
5323
            tcg_gen_helper_1_1i(do_mftlo, t0, t0, 3);
5324
            break;
5325
        case 13:
5326
            tcg_gen_helper_1_1i(do_mfthi, t0, t0, 3);
5327
            break;
5328
        case 14:
5329
            tcg_gen_helper_1_1i(do_mftacx, t0, t0, 3);
5330
            break;
5331
        case 16:
5332
            tcg_gen_helper_1_1(do_mftdsp, t0, t0);
5333
            break;
5334
        default:
5335
            goto die;
5336
        }
5337
        break;
5338
    /* Floating point (COP1). */
5339
    case 2:
5340
        /* XXX: For now we support only a single FPU context. */
5341
        if (h == 0) {
5342
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5343

    
5344
            gen_load_fpr32(fp0, rt);
5345
            tcg_gen_ext_i32_tl(t0, fp0);
5346
            tcg_temp_free(fp0);
5347
        } else {
5348
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5349

    
5350
            gen_load_fpr32h(fp0, rt);
5351
            tcg_gen_ext_i32_tl(t0, fp0);
5352
            tcg_temp_free(fp0);
5353
        }
5354
        break;
5355
    case 3:
5356
        /* XXX: For now we support only a single FPU context. */
5357
        tcg_gen_helper_1_1i(do_cfc1, t0, t0, rt);
5358
        break;
5359
    /* COP2: Not implemented. */
5360
    case 4:
5361
    case 5:
5362
        /* fall through */
5363
    default:
5364
        goto die;
5365
    }
5366
#if defined MIPS_DEBUG_DISAS
5367
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5368
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5369
                rt, u, sel, h);
5370
    }
5371
#endif
5372
    gen_store_gpr(t0, rd);
5373
    tcg_temp_free(t0);
5374
    return;
5375

    
5376
die:
5377
    tcg_temp_free(t0);
5378
#if defined MIPS_DEBUG_DISAS
5379
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5380
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5381
                rt, u, sel, h);
5382
    }
5383
#endif
5384
    generate_exception(ctx, EXCP_RI);
5385
}
5386

    
5387
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5388
                     int u, int sel, int h)
5389
{
5390
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5391
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5392

    
5393
    gen_load_gpr(t0, rt);
5394
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5395
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5396
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5397
        /* NOP */ ;
5398
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5399
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5400
        /* NOP */ ;
5401
    else if (u == 0) {
5402
        switch (rd) {
5403
        case 2:
5404
            switch (sel) {
5405
            case 1:
5406
                tcg_gen_helper_0_1(do_mttc0_tcstatus, t0);
5407
                break;
5408
            case 2:
5409
                tcg_gen_helper_0_1(do_mttc0_tcbind, t0);
5410
                break;
5411
            case 3:
5412
                tcg_gen_helper_0_1(do_mttc0_tcrestart, t0);
5413
                break;
5414
            case 4:
5415
                tcg_gen_helper_0_1(do_mttc0_tchalt, t0);
5416
                break;
5417
            case 5:
5418
                tcg_gen_helper_0_1(do_mttc0_tccontext, t0);
5419
                break;
5420
            case 6:
5421
                tcg_gen_helper_0_1(do_mttc0_tcschedule, t0);
5422
                break;
5423
            case 7:
5424
                tcg_gen_helper_0_1(do_mttc0_tcschefback, t0);
5425
                break;
5426
            default:
5427
                gen_mtc0(env, ctx, t0, rd, sel);
5428
                break;
5429
            }
5430
            break;
5431
        case 10:
5432
            switch (sel) {
5433
            case 0:
5434
                tcg_gen_helper_0_1(do_mttc0_entryhi, t0);
5435
                break;
5436
            default:
5437
                gen_mtc0(env, ctx, t0, rd, sel);
5438
                break;
5439
            }
5440
        case 12:
5441
            switch (sel) {
5442
            case 0:
5443
                tcg_gen_helper_0_1(do_mttc0_status, t0);
5444
                break;
5445
            default:
5446
                gen_mtc0(env, ctx, t0, rd, sel);
5447
                break;
5448
            }
5449
        case 23:
5450
            switch (sel) {
5451
            case 0:
5452
                tcg_gen_helper_0_1(do_mttc0_debug, t0);
5453
                break;
5454
            default:
5455
                gen_mtc0(env, ctx, t0, rd, sel);
5456
                break;
5457
            }
5458
            break;
5459
        default:
5460
            gen_mtc0(env, ctx, t0, rd, sel);
5461
        }
5462
    } else switch (sel) {
5463
    /* GPR registers. */
5464
    case 0:
5465
        tcg_gen_helper_0_1i(do_mttgpr, t0, rd);
5466
        break;
5467
    /* Auxiliary CPU registers */
5468
    case 1:
5469
        switch (rd) {
5470
        case 0:
5471
            tcg_gen_helper_0_1i(do_mttlo, t0, 0);
5472
            break;
5473
        case 1:
5474
            tcg_gen_helper_0_1i(do_mtthi, t0, 0);
5475
            break;
5476
        case 2:
5477
            tcg_gen_helper_0_1i(do_mttacx, t0, 0);
5478
            break;
5479
        case 4:
5480
            tcg_gen_helper_0_1i(do_mttlo, t0, 1);
5481
            break;
5482
        case 5:
5483
            tcg_gen_helper_0_1i(do_mtthi, t0, 1);
5484
            break;
5485
        case 6:
5486
            tcg_gen_helper_0_1i(do_mttacx, t0, 1);
5487
            break;
5488
        case 8:
5489
            tcg_gen_helper_0_1i(do_mttlo, t0, 2);
5490
            break;
5491
        case 9:
5492
            tcg_gen_helper_0_1i(do_mtthi, t0, 2);
5493
            break;
5494
        case 10:
5495
            tcg_gen_helper_0_1i(do_mttacx, t0, 2);
5496
            break;
5497
        case 12:
5498
            tcg_gen_helper_0_1i(do_mttlo, t0, 3);
5499
            break;
5500
        case 13:
5501
            tcg_gen_helper_0_1i(do_mtthi, t0, 3);
5502
            break;
5503
        case 14:
5504
            tcg_gen_helper_0_1i(do_mttacx, t0, 3);
5505
            break;
5506
        case 16:
5507
            tcg_gen_helper_0_1(do_mttdsp, t0);
5508
            break;
5509
        default:
5510
            goto die;
5511
        }
5512
        break;
5513
    /* Floating point (COP1). */
5514
    case 2:
5515
        /* XXX: For now we support only a single FPU context. */
5516
        if (h == 0) {
5517
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5518

    
5519
            tcg_gen_trunc_tl_i32(fp0, t0);
5520
            gen_store_fpr32(fp0, rd);
5521
            tcg_temp_free(fp0);
5522
        } else {
5523
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5524

    
5525
            tcg_gen_trunc_tl_i32(fp0, t0);
5526
            gen_store_fpr32h(fp0, rd);
5527
            tcg_temp_free(fp0);
5528
        }
5529
        break;
5530
    case 3:
5531
        /* XXX: For now we support only a single FPU context. */
5532
        tcg_gen_helper_0_1i(do_ctc1, t0, rd);
5533
        break;
5534
    /* COP2: Not implemented. */
5535
    case 4:
5536
    case 5:
5537
        /* fall through */
5538
    default:
5539
        goto die;
5540
    }
5541
#if defined MIPS_DEBUG_DISAS
5542
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5543
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5544
                rd, u, sel, h);
5545
    }
5546
#endif
5547
    tcg_temp_free(t0);
5548
    return;
5549

    
5550
die:
5551
    tcg_temp_free(t0);
5552
#if defined MIPS_DEBUG_DISAS
5553
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5554
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5555
                rd, u, sel, h);
5556
    }
5557
#endif
5558
    generate_exception(ctx, EXCP_RI);
5559
}
5560

    
5561
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5562
{
5563
    const char *opn = "ldst";
5564

    
5565
    switch (opc) {
5566
    case OPC_MFC0:
5567
        if (rt == 0) {
5568
            /* Treat as NOP. */
5569
            return;
5570
        }
5571
        {
5572
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5573

    
5574
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5575
            gen_store_gpr(t0, rt);
5576
            tcg_temp_free(t0);
5577
        }
5578
        opn = "mfc0";
5579
        break;
5580
    case OPC_MTC0:
5581
        {
5582
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5583

    
5584
            gen_load_gpr(t0, rt);
5585
            save_cpu_state(ctx, 1);
5586
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5587
            tcg_temp_free(t0);
5588
        }
5589
        opn = "mtc0";
5590
        break;
5591
#if defined(TARGET_MIPS64)
5592
    case OPC_DMFC0:
5593
        check_insn(env, ctx, ISA_MIPS3);
5594
        if (rt == 0) {
5595
            /* Treat as NOP. */
5596
            return;
5597
        }
5598
        {
5599
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5600

    
5601
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5602
            gen_store_gpr(t0, rt);
5603
            tcg_temp_free(t0);
5604
        }
5605
        opn = "dmfc0";
5606
        break;
5607
    case OPC_DMTC0:
5608
        check_insn(env, ctx, ISA_MIPS3);
5609
        {
5610
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5611

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

    
5699
/* CP1 Branches (before delay slot) */
5700
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5701
                                 int32_t cc, int32_t offset)
5702
{
5703
    target_ulong btarget;
5704
    const char *opn = "cp1 cond branch";
5705
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5706
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5707

    
5708
    if (cc != 0)
5709
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5710

    
5711
    btarget = ctx->pc + 4 + offset;
5712

    
5713
    switch (op) {
5714
    case OPC_BC1F:
5715
        {
5716
            int l1 = gen_new_label();
5717
            int l2 = gen_new_label();
5718
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5719

    
5720
            get_fp_cond(r_tmp1);
5721
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5722
            tcg_temp_free(r_tmp1);
5723
            tcg_gen_not_tl(t0, t0);
5724
            tcg_gen_movi_tl(t1, 0x1 << cc);
5725
            tcg_gen_and_tl(t0, t0, t1);
5726
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5727
            tcg_gen_movi_tl(t0, 0);
5728
            tcg_gen_br(l2);
5729
            gen_set_label(l1);
5730
            tcg_gen_movi_tl(t0, 1);
5731
            gen_set_label(l2);
5732
        }
5733
        opn = "bc1f";
5734
        goto not_likely;
5735
    case OPC_BC1FL:
5736
        {
5737
            int l1 = gen_new_label();
5738
            int l2 = gen_new_label();
5739
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5740

    
5741
            get_fp_cond(r_tmp1);
5742
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5743
            tcg_temp_free(r_tmp1);
5744
            tcg_gen_not_tl(t0, t0);
5745
            tcg_gen_movi_tl(t1, 0x1 << cc);
5746
            tcg_gen_and_tl(t0, t0, t1);
5747
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5748
            tcg_gen_movi_tl(t0, 0);
5749
            tcg_gen_br(l2);
5750
            gen_set_label(l1);
5751
            tcg_gen_movi_tl(t0, 1);
5752
            gen_set_label(l2);
5753
        }
5754
        opn = "bc1fl";
5755
        goto likely;
5756
    case OPC_BC1T:
5757
        {
5758
            int l1 = gen_new_label();
5759
            int l2 = gen_new_label();
5760
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5761

    
5762
            get_fp_cond(r_tmp1);
5763
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5764
            tcg_temp_free(r_tmp1);
5765
            tcg_gen_movi_tl(t1, 0x1 << cc);
5766
            tcg_gen_and_tl(t0, t0, t1);
5767
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5768
            tcg_gen_movi_tl(t0, 0);
5769
            tcg_gen_br(l2);
5770
            gen_set_label(l1);
5771
            tcg_gen_movi_tl(t0, 1);
5772
            gen_set_label(l2);
5773
        }
5774
        opn = "bc1t";
5775
        goto not_likely;
5776
    case OPC_BC1TL:
5777
        {
5778
            int l1 = gen_new_label();
5779
            int l2 = gen_new_label();
5780
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5781

    
5782
            get_fp_cond(r_tmp1);
5783
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5784
            tcg_temp_free(r_tmp1);
5785
            tcg_gen_movi_tl(t1, 0x1 << cc);
5786
            tcg_gen_and_tl(t0, t0, t1);
5787
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5788
            tcg_gen_movi_tl(t0, 0);
5789
            tcg_gen_br(l2);
5790
            gen_set_label(l1);
5791
            tcg_gen_movi_tl(t0, 1);
5792
            gen_set_label(l2);
5793
        }
5794
        opn = "bc1tl";
5795
    likely:
5796
        ctx->hflags |= MIPS_HFLAG_BL;
5797
        tcg_gen_trunc_tl_i32(bcond, t0);
5798
        break;
5799
    case OPC_BC1FANY2:
5800
        {
5801
            int l1 = gen_new_label();
5802
            int l2 = gen_new_label();
5803
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5804

    
5805
            get_fp_cond(r_tmp1);
5806
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5807
            tcg_temp_free(r_tmp1);
5808
            tcg_gen_not_tl(t0, t0);
5809
            tcg_gen_movi_tl(t1, 0x3 << cc);
5810
            tcg_gen_and_tl(t0, t0, t1);
5811
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5812
            tcg_gen_movi_tl(t0, 0);
5813
            tcg_gen_br(l2);
5814
            gen_set_label(l1);
5815
            tcg_gen_movi_tl(t0, 1);
5816
            gen_set_label(l2);
5817
        }
5818
        opn = "bc1any2f";
5819
        goto not_likely;
5820
    case OPC_BC1TANY2:
5821
        {
5822
            int l1 = gen_new_label();
5823
            int l2 = gen_new_label();
5824
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5825

    
5826
            get_fp_cond(r_tmp1);
5827
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5828
            tcg_temp_free(r_tmp1);
5829
            tcg_gen_movi_tl(t1, 0x3 << cc);
5830
            tcg_gen_and_tl(t0, t0, t1);
5831
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5832
            tcg_gen_movi_tl(t0, 0);
5833
            tcg_gen_br(l2);
5834
            gen_set_label(l1);
5835
            tcg_gen_movi_tl(t0, 1);
5836
            gen_set_label(l2);
5837
        }
5838
        opn = "bc1any2t";
5839
        goto not_likely;
5840
    case OPC_BC1FANY4:
5841
        {
5842
            int l1 = gen_new_label();
5843
            int l2 = gen_new_label();
5844
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5845

    
5846
            get_fp_cond(r_tmp1);
5847
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5848
            tcg_temp_free(r_tmp1);
5849
            tcg_gen_not_tl(t0, t0);
5850
            tcg_gen_movi_tl(t1, 0xf << cc);
5851
            tcg_gen_and_tl(t0, t0, t1);
5852
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5853
            tcg_gen_movi_tl(t0, 0);
5854
            tcg_gen_br(l2);
5855
            gen_set_label(l1);
5856
            tcg_gen_movi_tl(t0, 1);
5857
            gen_set_label(l2);
5858
        }
5859
        opn = "bc1any4f";
5860
        goto not_likely;
5861
    case OPC_BC1TANY4:
5862
        {
5863
            int l1 = gen_new_label();
5864
            int l2 = gen_new_label();
5865
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5866

    
5867
            get_fp_cond(r_tmp1);
5868
            tcg_gen_ext_i32_tl(t0, r_tmp1);
5869
            tcg_temp_free(r_tmp1);
5870
            tcg_gen_movi_tl(t1, 0xf << cc);
5871
            tcg_gen_and_tl(t0, t0, t1);
5872
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5873
            tcg_gen_movi_tl(t0, 0);
5874
            tcg_gen_br(l2);
5875
            gen_set_label(l1);
5876
            tcg_gen_movi_tl(t0, 1);
5877
            gen_set_label(l2);
5878
        }
5879
        opn = "bc1any4t";
5880
    not_likely:
5881
        ctx->hflags |= MIPS_HFLAG_BC;
5882
        tcg_gen_trunc_tl_i32(bcond, t0);
5883
        break;
5884
    default:
5885
        MIPS_INVAL(opn);
5886
        generate_exception (ctx, EXCP_RI);
5887
        goto out;
5888
    }
5889
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5890
               ctx->hflags, btarget);
5891
    ctx->btarget = btarget;
5892

    
5893
 out:
5894
    tcg_temp_free(t0);
5895
    tcg_temp_free(t1);
5896
}
5897

    
5898
/* Coprocessor 1 (FPU) */
5899

    
5900
#define FOP(func, fmt) (((fmt) << 21) | (func))
5901

    
5902
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5903
{
5904
    const char *opn = "cp1 move";
5905
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5906

    
5907
    switch (opc) {
5908
    case OPC_MFC1:
5909
        {
5910
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5911

    
5912
            gen_load_fpr32(fp0, fs);
5913
            tcg_gen_ext_i32_tl(t0, fp0);
5914
            tcg_temp_free(fp0);
5915
        }
5916
        gen_store_gpr(t0, rt);
5917
        opn = "mfc1";
5918
        break;
5919
    case OPC_MTC1:
5920
        gen_load_gpr(t0, rt);
5921
        {
5922
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5923

    
5924
            tcg_gen_trunc_tl_i32(fp0, t0);
5925
            gen_store_fpr32(fp0, fs);
5926
            tcg_temp_free(fp0);
5927
        }
5928
        opn = "mtc1";
5929
        break;
5930
    case OPC_CFC1:
5931
        tcg_gen_helper_1_i(do_cfc1, t0, fs);
5932
        gen_store_gpr(t0, rt);
5933
        opn = "cfc1";
5934
        break;
5935
    case OPC_CTC1:
5936
        gen_load_gpr(t0, rt);
5937
        tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5938
        opn = "ctc1";
5939
        break;
5940
    case OPC_DMFC1:
5941
        {
5942
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5943

    
5944
            gen_load_fpr64(ctx, fp0, fs);
5945
            tcg_gen_mov_tl(t0, fp0);
5946
            tcg_temp_free(fp0);
5947
        }
5948
        gen_store_gpr(t0, rt);
5949
        opn = "dmfc1";
5950
        break;
5951
    case OPC_DMTC1:
5952
        gen_load_gpr(t0, rt);
5953
        {
5954
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5955

    
5956
            tcg_gen_mov_tl(fp0, t0);
5957
            gen_store_fpr64(ctx, fp0, fs);
5958
            tcg_temp_free(fp0);
5959
        }
5960
        opn = "dmtc1";
5961
        break;
5962
    case OPC_MFHC1:
5963
        {
5964
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5965

    
5966
            gen_load_fpr32h(fp0, fs);
5967
            tcg_gen_ext_i32_tl(t0, fp0);
5968
            tcg_temp_free(fp0);
5969
        }
5970
        gen_store_gpr(t0, rt);
5971
        opn = "mfhc1";
5972
        break;
5973
    case OPC_MTHC1:
5974
        gen_load_gpr(t0, rt);
5975
        {
5976
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5977

    
5978
            tcg_gen_trunc_tl_i32(fp0, t0);
5979
            gen_store_fpr32h(fp0, fs);
5980
            tcg_temp_free(fp0);
5981
        }
5982
        opn = "mthc1";
5983
        break;
5984
    default:
5985
        MIPS_INVAL(opn);
5986
        generate_exception (ctx, EXCP_RI);
5987
        goto out;
5988
    }
5989
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5990

    
5991
 out:
5992
    tcg_temp_free(t0);
5993
}
5994

    
5995
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5996
{
5997
    int l1 = gen_new_label();
5998
    uint32_t ccbit;
5999
    TCGCond cond;
6000
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6001
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
6002
    TCGv r_tmp = tcg_temp_local_new(TCG_TYPE_I32);
6003

    
6004
    if (cc)
6005
        ccbit = 1 << (24 + cc);
6006
    else
6007
        ccbit = 1 << 23;
6008
    if (tf)
6009
        cond = TCG_COND_EQ;
6010
    else
6011
        cond = TCG_COND_NE;
6012

    
6013
    gen_load_gpr(t0, rd);
6014
    gen_load_gpr(t1, rs);
6015
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
6016
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
6017
    tcg_temp_free(r_tmp);
6018

    
6019
    tcg_gen_mov_tl(t0, t1);
6020
    tcg_temp_free(t1);
6021

    
6022
    gen_set_label(l1);
6023
    gen_store_gpr(t0, rd);
6024
    tcg_temp_free(t0);
6025
}
6026

    
6027
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6028
{
6029
    uint32_t ccbit;
6030
    int cond;
6031
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6032
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6033
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6034
    int l1 = gen_new_label();
6035

    
6036
    if (cc)
6037
        ccbit = 1 << (24 + cc);
6038
    else
6039
        ccbit = 1 << 23;
6040

    
6041
    if (tf)
6042
        cond = TCG_COND_EQ;
6043
    else
6044
        cond = TCG_COND_NE;
6045

    
6046
    gen_load_fpr32(fp0, fs);
6047
    gen_load_fpr32(fp1, fd);
6048
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
6049
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6050
    tcg_gen_mov_i32(fp1, fp0);
6051
    tcg_temp_free(fp0);
6052
    gen_set_label(l1);
6053
    tcg_temp_free(r_tmp1);
6054
    gen_store_fpr32(fp1, fd);
6055
    tcg_temp_free(fp1);
6056
}
6057

    
6058
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6059
{
6060
    uint32_t ccbit;
6061
    int cond;
6062
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6063
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6064
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I64);
6065
    int l1 = gen_new_label();
6066

    
6067
    if (cc)
6068
        ccbit = 1 << (24 + cc);
6069
    else
6070
        ccbit = 1 << 23;
6071

    
6072
    if (tf)
6073
        cond = TCG_COND_EQ;
6074
    else
6075
        cond = TCG_COND_NE;
6076

    
6077
    gen_load_fpr64(ctx, fp0, fs);
6078
    gen_load_fpr64(ctx, fp1, fd);
6079
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
6080
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6081
    tcg_gen_mov_i64(fp1, fp0);
6082
    tcg_temp_free(fp0);
6083
    gen_set_label(l1);
6084
    tcg_temp_free(r_tmp1);
6085
    gen_store_fpr64(ctx, fp1, fd);
6086
    tcg_temp_free(fp1);
6087
}
6088

    
6089
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6090
{
6091
    int cond;
6092
    TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6093
    TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32);
6094
    TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6095
    TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
6096
    TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
6097
    TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
6098
    int l1 = gen_new_label();
6099
    int l2 = gen_new_label();
6100

    
6101
    if (tf)
6102
        cond = TCG_COND_EQ;
6103
    else
6104
        cond = TCG_COND_NE;
6105

    
6106
    gen_load_fpr32(fp0, fs);
6107
    gen_load_fpr32h(fph0, fs);
6108
    gen_load_fpr32(fp1, fd);
6109
    gen_load_fpr32h(fph1, fd);
6110
    get_fp_cond(r_tmp1);
6111
    tcg_gen_shri_i32(r_tmp1, r_tmp1, cc);
6112
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1);
6113
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1);
6114
    tcg_gen_mov_i32(fp1, fp0);
6115
    tcg_temp_free(fp0);
6116
    gen_set_label(l1);
6117
    tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2);
6118
    tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2);
6119
    tcg_gen_mov_i32(fph1, fph0);
6120
    tcg_temp_free(fph0);
6121
    gen_set_label(l2);
6122
    tcg_temp_free(r_tmp1);
6123
    tcg_temp_free(r_tmp2);
6124
    gen_store_fpr32(fp1, fd);
6125
    gen_store_fpr32h(fph1, fd);
6126
    tcg_temp_free(fp1);
6127
    tcg_temp_free(fph1);
6128
}
6129

    
6130

    
6131
static void gen_farith (DisasContext *ctx, uint32_t op1,
6132
                        int ft, int fs, int fd, int cc)
6133
{
6134
    const char *opn = "farith";
6135
    const char *condnames[] = {
6136
            "c.f",
6137
            "c.un",
6138
            "c.eq",
6139
            "c.ueq",
6140
            "c.olt",
6141
            "c.ult",
6142
            "c.ole",
6143
            "c.ule",
6144
            "c.sf",
6145
            "c.ngle",
6146
            "c.seq",
6147
            "c.ngl",
6148
            "c.lt",
6149
            "c.nge",
6150
            "c.le",
6151
            "c.ngt",
6152
    };
6153
    const char *condnames_abs[] = {
6154
            "cabs.f",
6155
            "cabs.un",
6156
            "cabs.eq",
6157
            "cabs.ueq",
6158
            "cabs.olt",
6159
            "cabs.ult",
6160
            "cabs.ole",
6161
            "cabs.ule",
6162
            "cabs.sf",
6163
            "cabs.ngle",
6164
            "cabs.seq",
6165
            "cabs.ngl",
6166
            "cabs.lt",
6167
            "cabs.nge",
6168
            "cabs.le",
6169
            "cabs.ngt",
6170
    };
6171
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6172
    uint32_t func = ctx->opcode & 0x3f;
6173

    
6174
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6175
    case FOP(0, 16):
6176
        {
6177
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6178
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6179

    
6180
            gen_load_fpr32(fp0, fs);
6181
            gen_load_fpr32(fp1, ft);
6182
            tcg_gen_helper_1_2(do_float_add_s, fp0, fp0, fp1);
6183
            tcg_temp_free(fp1);
6184
            gen_store_fpr32(fp0, fd);
6185
            tcg_temp_free(fp0);
6186
        }
6187
        opn = "add.s";
6188
        optype = BINOP;
6189
        break;
6190
    case FOP(1, 16):
6191
        {
6192
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6193
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6194

    
6195
            gen_load_fpr32(fp0, fs);
6196
            gen_load_fpr32(fp1, ft);
6197
            tcg_gen_helper_1_2(do_float_sub_s, fp0, fp0, fp1);
6198
            tcg_temp_free(fp1);
6199
            gen_store_fpr32(fp0, fd);
6200
            tcg_temp_free(fp0);
6201
        }
6202
        opn = "sub.s";
6203
        optype = BINOP;
6204
        break;
6205
    case FOP(2, 16):
6206
        {
6207
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6208
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6209

    
6210
            gen_load_fpr32(fp0, fs);
6211
            gen_load_fpr32(fp1, ft);
6212
            tcg_gen_helper_1_2(do_float_mul_s, fp0, fp0, fp1);
6213
            tcg_temp_free(fp1);
6214
            gen_store_fpr32(fp0, fd);
6215
            tcg_temp_free(fp0);
6216
        }
6217
        opn = "mul.s";
6218
        optype = BINOP;
6219
        break;
6220
    case FOP(3, 16):
6221
        {
6222
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6223
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6224

    
6225
            gen_load_fpr32(fp0, fs);
6226
            gen_load_fpr32(fp1, ft);
6227
            tcg_gen_helper_1_2(do_float_div_s, fp0, fp0, fp1);
6228
            tcg_temp_free(fp1);
6229
            gen_store_fpr32(fp0, fd);
6230
            tcg_temp_free(fp0);
6231
        }
6232
        opn = "div.s";
6233
        optype = BINOP;
6234
        break;
6235
    case FOP(4, 16):
6236
        {
6237
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6238

    
6239
            gen_load_fpr32(fp0, fs);
6240
            tcg_gen_helper_1_1(do_float_sqrt_s, fp0, fp0);
6241
            gen_store_fpr32(fp0, fd);
6242
            tcg_temp_free(fp0);
6243
        }
6244
        opn = "sqrt.s";
6245
        break;
6246
    case FOP(5, 16):
6247
        {
6248
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6249

    
6250
            gen_load_fpr32(fp0, fs);
6251
            tcg_gen_helper_1_1(do_float_abs_s, fp0, fp0);
6252
            gen_store_fpr32(fp0, fd);
6253
            tcg_temp_free(fp0);
6254
        }
6255
        opn = "abs.s";
6256
        break;
6257
    case FOP(6, 16):
6258
        {
6259
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6260

    
6261
            gen_load_fpr32(fp0, fs);
6262
            gen_store_fpr32(fp0, fd);
6263
            tcg_temp_free(fp0);
6264
        }
6265
        opn = "mov.s";
6266
        break;
6267
    case FOP(7, 16):
6268
        {
6269
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6270

    
6271
            gen_load_fpr32(fp0, fs);
6272
            tcg_gen_helper_1_1(do_float_chs_s, fp0, fp0);
6273
            gen_store_fpr32(fp0, fd);
6274
            tcg_temp_free(fp0);
6275
        }
6276
        opn = "neg.s";
6277
        break;
6278
    case FOP(8, 16):
6279
        check_cp1_64bitmode(ctx);
6280
        {
6281
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6282
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6283

    
6284
            gen_load_fpr32(fp32, fs);
6285
            tcg_gen_helper_1_1(do_float_roundl_s, fp64, fp32);
6286
            tcg_temp_free(fp32);
6287
            gen_store_fpr64(ctx, fp64, fd);
6288
            tcg_temp_free(fp64);
6289
        }
6290
        opn = "round.l.s";
6291
        break;
6292
    case FOP(9, 16):
6293
        check_cp1_64bitmode(ctx);
6294
        {
6295
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6296
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6297

    
6298
            gen_load_fpr32(fp32, fs);
6299
            tcg_gen_helper_1_1(do_float_truncl_s, fp64, fp32);
6300
            tcg_temp_free(fp32);
6301
            gen_store_fpr64(ctx, fp64, fd);
6302
            tcg_temp_free(fp64);
6303
        }
6304
        opn = "trunc.l.s";
6305
        break;
6306
    case FOP(10, 16):
6307
        check_cp1_64bitmode(ctx);
6308
        {
6309
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6310
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6311

    
6312
            gen_load_fpr32(fp32, fs);
6313
            tcg_gen_helper_1_1(do_float_ceill_s, fp64, fp32);
6314
            tcg_temp_free(fp32);
6315
            gen_store_fpr64(ctx, fp64, fd);
6316
            tcg_temp_free(fp64);
6317
        }
6318
        opn = "ceil.l.s";
6319
        break;
6320
    case FOP(11, 16):
6321
        check_cp1_64bitmode(ctx);
6322
        {
6323
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6324
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6325

    
6326
            gen_load_fpr32(fp32, fs);
6327
            tcg_gen_helper_1_1(do_float_floorl_s, fp64, fp32);
6328
            tcg_temp_free(fp32);
6329
            gen_store_fpr64(ctx, fp64, fd);
6330
            tcg_temp_free(fp64);
6331
        }
6332
        opn = "floor.l.s";
6333
        break;
6334
    case FOP(12, 16):
6335
        {
6336
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6337

    
6338
            gen_load_fpr32(fp0, fs);
6339
            tcg_gen_helper_1_1(do_float_roundw_s, fp0, fp0);
6340
            gen_store_fpr32(fp0, fd);
6341
            tcg_temp_free(fp0);
6342
        }
6343
        opn = "round.w.s";
6344
        break;
6345
    case FOP(13, 16):
6346
        {
6347
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6348

    
6349
            gen_load_fpr32(fp0, fs);
6350
            tcg_gen_helper_1_1(do_float_truncw_s, fp0, fp0);
6351
            gen_store_fpr32(fp0, fd);
6352
            tcg_temp_free(fp0);
6353
        }
6354
        opn = "trunc.w.s";
6355
        break;
6356
    case FOP(14, 16):
6357
        {
6358
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6359

    
6360
            gen_load_fpr32(fp0, fs);
6361
            tcg_gen_helper_1_1(do_float_ceilw_s, fp0, fp0);
6362
            gen_store_fpr32(fp0, fd);
6363
            tcg_temp_free(fp0);
6364
        }
6365
        opn = "ceil.w.s";
6366
        break;
6367
    case FOP(15, 16):
6368
        {
6369
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6370

    
6371
            gen_load_fpr32(fp0, fs);
6372
            tcg_gen_helper_1_1(do_float_floorw_s, fp0, fp0);
6373
            gen_store_fpr32(fp0, fd);
6374
            tcg_temp_free(fp0);
6375
        }
6376
        opn = "floor.w.s";
6377
        break;
6378
    case FOP(17, 16):
6379
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6380
        opn = "movcf.s";
6381
        break;
6382
    case FOP(18, 16):
6383
        {
6384
            int l1 = gen_new_label();
6385
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6386
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6387

    
6388
            gen_load_gpr(t0, ft);
6389
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6390
            tcg_temp_free(t0);
6391
            gen_load_fpr32(fp0, fs);
6392
            gen_store_fpr32(fp0, fd);
6393
            tcg_temp_free(fp0);
6394
            gen_set_label(l1);
6395
        }
6396
        opn = "movz.s";
6397
        break;
6398
    case FOP(19, 16):
6399
        {
6400
            int l1 = gen_new_label();
6401
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6402
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6403

    
6404
            gen_load_gpr(t0, ft);
6405
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6406
            tcg_temp_free(t0);
6407
            gen_load_fpr32(fp0, fs);
6408
            gen_store_fpr32(fp0, fd);
6409
            tcg_temp_free(fp0);
6410
            gen_set_label(l1);
6411
        }
6412
        opn = "movn.s";
6413
        break;
6414
    case FOP(21, 16):
6415
        check_cop1x(ctx);
6416
        {
6417
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6418

    
6419
            gen_load_fpr32(fp0, fs);
6420
            tcg_gen_helper_1_1(do_float_recip_s, fp0, fp0);
6421
            gen_store_fpr32(fp0, fd);
6422
            tcg_temp_free(fp0);
6423
        }
6424
        opn = "recip.s";
6425
        break;
6426
    case FOP(22, 16):
6427
        check_cop1x(ctx);
6428
        {
6429
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6430

    
6431
            gen_load_fpr32(fp0, fs);
6432
            tcg_gen_helper_1_1(do_float_rsqrt_s, fp0, fp0);
6433
            gen_store_fpr32(fp0, fd);
6434
            tcg_temp_free(fp0);
6435
        }
6436
        opn = "rsqrt.s";
6437
        break;
6438
    case FOP(28, 16):
6439
        check_cp1_64bitmode(ctx);
6440
        {
6441
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6442
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6443

    
6444
            gen_load_fpr32(fp0, fs);
6445
            gen_load_fpr32(fp1, fd);
6446
            tcg_gen_helper_1_2(do_float_recip2_s, fp0, fp0, fp1);
6447
            tcg_temp_free(fp1);
6448
            gen_store_fpr32(fp0, fd);
6449
            tcg_temp_free(fp0);
6450
        }
6451
        opn = "recip2.s";
6452
        break;
6453
    case FOP(29, 16):
6454
        check_cp1_64bitmode(ctx);
6455
        {
6456
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6457

    
6458
            gen_load_fpr32(fp0, fs);
6459
            tcg_gen_helper_1_1(do_float_recip1_s, fp0, fp0);
6460
            gen_store_fpr32(fp0, fd);
6461
            tcg_temp_free(fp0);
6462
        }
6463
        opn = "recip1.s";
6464
        break;
6465
    case FOP(30, 16):
6466
        check_cp1_64bitmode(ctx);
6467
        {
6468
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6469

    
6470
            gen_load_fpr32(fp0, fs);
6471
            tcg_gen_helper_1_1(do_float_rsqrt1_s, fp0, fp0);
6472
            gen_store_fpr32(fp0, fd);
6473
            tcg_temp_free(fp0);
6474
        }
6475
        opn = "rsqrt1.s";
6476
        break;
6477
    case FOP(31, 16):
6478
        check_cp1_64bitmode(ctx);
6479
        {
6480
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6481
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6482

    
6483
            gen_load_fpr32(fp0, fs);
6484
            gen_load_fpr32(fp1, ft);
6485
            tcg_gen_helper_1_2(do_float_rsqrt2_s, fp0, fp0, fp1);
6486
            tcg_temp_free(fp1);
6487
            gen_store_fpr32(fp0, fd);
6488
            tcg_temp_free(fp0);
6489
        }
6490
        opn = "rsqrt2.s";
6491
        break;
6492
    case FOP(33, 16):
6493
        check_cp1_registers(ctx, fd);
6494
        {
6495
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6496
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6497

    
6498
            gen_load_fpr32(fp32, fs);
6499
            tcg_gen_helper_1_1(do_float_cvtd_s, fp64, fp32);
6500
            tcg_temp_free(fp32);
6501
            gen_store_fpr64(ctx, fp64, fd);
6502
            tcg_temp_free(fp64);
6503
        }
6504
        opn = "cvt.d.s";
6505
        break;
6506
    case FOP(36, 16):
6507
        {
6508
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6509

    
6510
            gen_load_fpr32(fp0, fs);
6511
            tcg_gen_helper_1_1(do_float_cvtw_s, fp0, fp0);
6512
            gen_store_fpr32(fp0, fd);
6513
            tcg_temp_free(fp0);
6514
        }
6515
        opn = "cvt.w.s";
6516
        break;
6517
    case FOP(37, 16):
6518
        check_cp1_64bitmode(ctx);
6519
        {
6520
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6521
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6522

    
6523
            gen_load_fpr32(fp32, fs);
6524
            tcg_gen_helper_1_1(do_float_cvtl_s, fp64, fp32);
6525
            tcg_temp_free(fp32);
6526
            gen_store_fpr64(ctx, fp64, fd);
6527
            tcg_temp_free(fp64);
6528
        }
6529
        opn = "cvt.l.s";
6530
        break;
6531
    case FOP(38, 16):
6532
        check_cp1_64bitmode(ctx);
6533
        {
6534
            TCGv fp64_0 = tcg_temp_new(TCG_TYPE_I64);
6535
            TCGv fp64_1 = tcg_temp_new(TCG_TYPE_I64);
6536
            TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32);
6537
            TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32);
6538

    
6539
            gen_load_fpr32(fp32_0, fs);
6540
            gen_load_fpr32(fp32_1, ft);
6541
            tcg_gen_extu_i32_i64(fp64_0, fp32_0);
6542
            tcg_gen_extu_i32_i64(fp64_1, fp32_1);
6543
            tcg_temp_free(fp32_0);
6544
            tcg_temp_free(fp32_1);
6545
            tcg_gen_shli_i64(fp64_1, fp64_1, 32);
6546
            tcg_gen_or_i64(fp64_0, fp64_0, fp64_1);
6547
            tcg_temp_free(fp64_1);
6548
            gen_store_fpr64(ctx, fp64_0, fd);
6549
            tcg_temp_free(fp64_0);
6550
        }
6551
        opn = "cvt.ps.s";
6552
        break;
6553
    case FOP(48, 16):
6554
    case FOP(49, 16):
6555
    case FOP(50, 16):
6556
    case FOP(51, 16):
6557
    case FOP(52, 16):
6558
    case FOP(53, 16):
6559
    case FOP(54, 16):
6560
    case FOP(55, 16):
6561
    case FOP(56, 16):
6562
    case FOP(57, 16):
6563
    case FOP(58, 16):
6564
    case FOP(59, 16):
6565
    case FOP(60, 16):
6566
    case FOP(61, 16):
6567
    case FOP(62, 16):
6568
    case FOP(63, 16):
6569
        {
6570
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6571
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6572

    
6573
            gen_load_fpr32(fp0, fs);
6574
            gen_load_fpr32(fp1, ft);
6575
            if (ctx->opcode & (1 << 6)) {
6576
                check_cop1x(ctx);
6577
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6578
                opn = condnames_abs[func-48];
6579
            } else {
6580
                gen_cmp_s(func-48, fp0, fp1, cc);
6581
                opn = condnames[func-48];
6582
            }
6583
            tcg_temp_free(fp0);
6584
            tcg_temp_free(fp1);
6585
        }
6586
        break;
6587
    case FOP(0, 17):
6588
        check_cp1_registers(ctx, fs | ft | fd);
6589
        {
6590
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6591
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6592

    
6593
            gen_load_fpr64(ctx, fp0, fs);
6594
            gen_load_fpr64(ctx, fp1, ft);
6595
            tcg_gen_helper_1_2(do_float_add_d, fp0, fp0, fp1);
6596
            tcg_temp_free(fp1);
6597
            gen_store_fpr64(ctx, fp0, fd);
6598
            tcg_temp_free(fp0);
6599
        }
6600
        opn = "add.d";
6601
        optype = BINOP;
6602
        break;
6603
    case FOP(1, 17):
6604
        check_cp1_registers(ctx, fs | ft | fd);
6605
        {
6606
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6607
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6608

    
6609
            gen_load_fpr64(ctx, fp0, fs);
6610
            gen_load_fpr64(ctx, fp1, ft);
6611
            tcg_gen_helper_1_2(do_float_sub_d, fp0, fp0, fp1);
6612
            tcg_temp_free(fp1);
6613
            gen_store_fpr64(ctx, fp0, fd);
6614
            tcg_temp_free(fp0);
6615
        }
6616
        opn = "sub.d";
6617
        optype = BINOP;
6618
        break;
6619
    case FOP(2, 17):
6620
        check_cp1_registers(ctx, fs | ft | fd);
6621
        {
6622
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6623
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6624

    
6625
            gen_load_fpr64(ctx, fp0, fs);
6626
            gen_load_fpr64(ctx, fp1, ft);
6627
            tcg_gen_helper_1_2(do_float_mul_d, fp0, fp0, fp1);
6628
            tcg_temp_free(fp1);
6629
            gen_store_fpr64(ctx, fp0, fd);
6630
            tcg_temp_free(fp0);
6631
        }
6632
        opn = "mul.d";
6633
        optype = BINOP;
6634
        break;
6635
    case FOP(3, 17):
6636
        check_cp1_registers(ctx, fs | ft | fd);
6637
        {
6638
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6639
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6640

    
6641
            gen_load_fpr64(ctx, fp0, fs);
6642
            gen_load_fpr64(ctx, fp1, ft);
6643
            tcg_gen_helper_1_2(do_float_div_d, fp0, fp0, fp1);
6644
            tcg_temp_free(fp1);
6645
            gen_store_fpr64(ctx, fp0, fd);
6646
            tcg_temp_free(fp0);
6647
        }
6648
        opn = "div.d";
6649
        optype = BINOP;
6650
        break;
6651
    case FOP(4, 17):
6652
        check_cp1_registers(ctx, fs | fd);
6653
        {
6654
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6655

    
6656
            gen_load_fpr64(ctx, fp0, fs);
6657
            tcg_gen_helper_1_1(do_float_sqrt_d, fp0, fp0);
6658
            gen_store_fpr64(ctx, fp0, fd);
6659
            tcg_temp_free(fp0);
6660
        }
6661
        opn = "sqrt.d";
6662
        break;
6663
    case FOP(5, 17):
6664
        check_cp1_registers(ctx, fs | fd);
6665
        {
6666
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6667

    
6668
            gen_load_fpr64(ctx, fp0, fs);
6669
            tcg_gen_helper_1_1(do_float_abs_d, fp0, fp0);
6670
            gen_store_fpr64(ctx, fp0, fd);
6671
            tcg_temp_free(fp0);
6672
        }
6673
        opn = "abs.d";
6674
        break;
6675
    case FOP(6, 17):
6676
        check_cp1_registers(ctx, fs | fd);
6677
        {
6678
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6679

    
6680
            gen_load_fpr64(ctx, fp0, fs);
6681
            gen_store_fpr64(ctx, fp0, fd);
6682
            tcg_temp_free(fp0);
6683
        }
6684
        opn = "mov.d";
6685
        break;
6686
    case FOP(7, 17):
6687
        check_cp1_registers(ctx, fs | fd);
6688
        {
6689
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6690

    
6691
            gen_load_fpr64(ctx, fp0, fs);
6692
            tcg_gen_helper_1_1(do_float_chs_d, fp0, fp0);
6693
            gen_store_fpr64(ctx, fp0, fd);
6694
            tcg_temp_free(fp0);
6695
        }
6696
        opn = "neg.d";
6697
        break;
6698
    case FOP(8, 17):
6699
        check_cp1_64bitmode(ctx);
6700
        {
6701
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6702

    
6703
            gen_load_fpr64(ctx, fp0, fs);
6704
            tcg_gen_helper_1_1(do_float_roundl_d, fp0, fp0);
6705
            gen_store_fpr64(ctx, fp0, fd);
6706
            tcg_temp_free(fp0);
6707
        }
6708
        opn = "round.l.d";
6709
        break;
6710
    case FOP(9, 17):
6711
        check_cp1_64bitmode(ctx);
6712
        {
6713
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6714

    
6715
            gen_load_fpr64(ctx, fp0, fs);
6716
            tcg_gen_helper_1_1(do_float_truncl_d, fp0, fp0);
6717
            gen_store_fpr64(ctx, fp0, fd);
6718
            tcg_temp_free(fp0);
6719
        }
6720
        opn = "trunc.l.d";
6721
        break;
6722
    case FOP(10, 17):
6723
        check_cp1_64bitmode(ctx);
6724
        {
6725
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6726

    
6727
            gen_load_fpr64(ctx, fp0, fs);
6728
            tcg_gen_helper_1_1(do_float_ceill_d, fp0, fp0);
6729
            gen_store_fpr64(ctx, fp0, fd);
6730
            tcg_temp_free(fp0);
6731
        }
6732
        opn = "ceil.l.d";
6733
        break;
6734
    case FOP(11, 17):
6735
        check_cp1_64bitmode(ctx);
6736
        {
6737
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6738

    
6739
            gen_load_fpr64(ctx, fp0, fs);
6740
            tcg_gen_helper_1_1(do_float_floorl_d, fp0, fp0);
6741
            gen_store_fpr64(ctx, fp0, fd);
6742
            tcg_temp_free(fp0);
6743
        }
6744
        opn = "floor.l.d";
6745
        break;
6746
    case FOP(12, 17):
6747
        check_cp1_registers(ctx, fs);
6748
        {
6749
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6750
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6751

    
6752
            gen_load_fpr64(ctx, fp64, fs);
6753
            tcg_gen_helper_1_1(do_float_roundw_d, fp32, fp64);
6754
            tcg_temp_free(fp64);
6755
            gen_store_fpr32(fp32, fd);
6756
            tcg_temp_free(fp32);
6757
        }
6758
        opn = "round.w.d";
6759
        break;
6760
    case FOP(13, 17):
6761
        check_cp1_registers(ctx, fs);
6762
        {
6763
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6764
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6765

    
6766
            gen_load_fpr64(ctx, fp64, fs);
6767
            tcg_gen_helper_1_1(do_float_truncw_d, fp32, fp64);
6768
            tcg_temp_free(fp64);
6769
            gen_store_fpr32(fp32, fd);
6770
            tcg_temp_free(fp32);
6771
        }
6772
        opn = "trunc.w.d";
6773
        break;
6774
    case FOP(14, 17):
6775
        check_cp1_registers(ctx, fs);
6776
        {
6777
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6778
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6779

    
6780
            gen_load_fpr64(ctx, fp64, fs);
6781
            tcg_gen_helper_1_1(do_float_ceilw_d, fp32, fp64);
6782
            tcg_temp_free(fp64);
6783
            gen_store_fpr32(fp32, fd);
6784
            tcg_temp_free(fp32);
6785
        }
6786
        opn = "ceil.w.d";
6787
        break;
6788
    case FOP(15, 17):
6789
        check_cp1_registers(ctx, fs);
6790
        {
6791
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6792
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6793

    
6794
            gen_load_fpr64(ctx, fp64, fs);
6795
            tcg_gen_helper_1_1(do_float_floorw_d, fp32, fp64);
6796
            tcg_temp_free(fp64);
6797
            gen_store_fpr32(fp32, fd);
6798
            tcg_temp_free(fp32);
6799
        }
6800
        opn = "floor.w.d";
6801
        break;
6802
    case FOP(17, 17):
6803
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6804
        opn = "movcf.d";
6805
        break;
6806
    case FOP(18, 17):
6807
        {
6808
            int l1 = gen_new_label();
6809
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6810
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6811

    
6812
            gen_load_gpr(t0, ft);
6813
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6814
            tcg_temp_free(t0);
6815
            gen_load_fpr64(ctx, fp0, fs);
6816
            gen_store_fpr64(ctx, fp0, fd);
6817
            tcg_temp_free(fp0);
6818
            gen_set_label(l1);
6819
        }
6820
        opn = "movz.d";
6821
        break;
6822
    case FOP(19, 17):
6823
        {
6824
            int l1 = gen_new_label();
6825
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
6826
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6827

    
6828
            gen_load_gpr(t0, ft);
6829
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6830
            tcg_temp_free(t0);
6831
            gen_load_fpr64(ctx, fp0, fs);
6832
            gen_store_fpr64(ctx, fp0, fd);
6833
            tcg_temp_free(fp0);
6834
            gen_set_label(l1);
6835
        }
6836
        opn = "movn.d";
6837
        break;
6838
    case FOP(21, 17):
6839
        check_cp1_64bitmode(ctx);
6840
        {
6841
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6842

    
6843
            gen_load_fpr64(ctx, fp0, fs);
6844
            tcg_gen_helper_1_1(do_float_recip_d, fp0, fp0);
6845
            gen_store_fpr64(ctx, fp0, fd);
6846
            tcg_temp_free(fp0);
6847
        }
6848
        opn = "recip.d";
6849
        break;
6850
    case FOP(22, 17):
6851
        check_cp1_64bitmode(ctx);
6852
        {
6853
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6854

    
6855
            gen_load_fpr64(ctx, fp0, fs);
6856
            tcg_gen_helper_1_1(do_float_rsqrt_d, fp0, fp0);
6857
            gen_store_fpr64(ctx, fp0, fd);
6858
            tcg_temp_free(fp0);
6859
        }
6860
        opn = "rsqrt.d";
6861
        break;
6862
    case FOP(28, 17):
6863
        check_cp1_64bitmode(ctx);
6864
        {
6865
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6866
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6867

    
6868
            gen_load_fpr64(ctx, fp0, fs);
6869
            gen_load_fpr64(ctx, fp1, ft);
6870
            tcg_gen_helper_1_2(do_float_recip2_d, fp0, fp0, fp1);
6871
            tcg_temp_free(fp1);
6872
            gen_store_fpr64(ctx, fp0, fd);
6873
            tcg_temp_free(fp0);
6874
        }
6875
        opn = "recip2.d";
6876
        break;
6877
    case FOP(29, 17):
6878
        check_cp1_64bitmode(ctx);
6879
        {
6880
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6881

    
6882
            gen_load_fpr64(ctx, fp0, fs);
6883
            tcg_gen_helper_1_1(do_float_recip1_d, fp0, fp0);
6884
            gen_store_fpr64(ctx, fp0, fd);
6885
            tcg_temp_free(fp0);
6886
        }
6887
        opn = "recip1.d";
6888
        break;
6889
    case FOP(30, 17):
6890
        check_cp1_64bitmode(ctx);
6891
        {
6892
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6893

    
6894
            gen_load_fpr64(ctx, fp0, fs);
6895
            tcg_gen_helper_1_1(do_float_rsqrt1_d, fp0, fp0);
6896
            gen_store_fpr64(ctx, fp0, fd);
6897
            tcg_temp_free(fp0);
6898
        }
6899
        opn = "rsqrt1.d";
6900
        break;
6901
    case FOP(31, 17):
6902
        check_cp1_64bitmode(ctx);
6903
        {
6904
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6905
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6906

    
6907
            gen_load_fpr64(ctx, fp0, fs);
6908
            gen_load_fpr64(ctx, fp1, ft);
6909
            tcg_gen_helper_1_2(do_float_rsqrt2_d, fp0, fp0, fp1);
6910
            tcg_temp_free(fp1);
6911
            gen_store_fpr64(ctx, fp0, fd);
6912
            tcg_temp_free(fp0);
6913
        }
6914
        opn = "rsqrt2.d";
6915
        break;
6916
    case FOP(48, 17):
6917
    case FOP(49, 17):
6918
    case FOP(50, 17):
6919
    case FOP(51, 17):
6920
    case FOP(52, 17):
6921
    case FOP(53, 17):
6922
    case FOP(54, 17):
6923
    case FOP(55, 17):
6924
    case FOP(56, 17):
6925
    case FOP(57, 17):
6926
    case FOP(58, 17):
6927
    case FOP(59, 17):
6928
    case FOP(60, 17):
6929
    case FOP(61, 17):
6930
    case FOP(62, 17):
6931
    case FOP(63, 17):
6932
        {
6933
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6934
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6935

    
6936
            gen_load_fpr64(ctx, fp0, fs);
6937
            gen_load_fpr64(ctx, fp1, ft);
6938
            if (ctx->opcode & (1 << 6)) {
6939
                check_cop1x(ctx);
6940
                check_cp1_registers(ctx, fs | ft);
6941
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6942
                opn = condnames_abs[func-48];
6943
            } else {
6944
                check_cp1_registers(ctx, fs | ft);
6945
                gen_cmp_d(func-48, fp0, fp1, cc);
6946
                opn = condnames[func-48];
6947
            }
6948
            tcg_temp_free(fp0);
6949
            tcg_temp_free(fp1);
6950
        }
6951
        break;
6952
    case FOP(32, 17):
6953
        check_cp1_registers(ctx, fs);
6954
        {
6955
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6956
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6957

    
6958
            gen_load_fpr64(ctx, fp64, fs);
6959
            tcg_gen_helper_1_1(do_float_cvts_d, fp32, fp64);
6960
            tcg_temp_free(fp64);
6961
            gen_store_fpr32(fp32, fd);
6962
            tcg_temp_free(fp32);
6963
        }
6964
        opn = "cvt.s.d";
6965
        break;
6966
    case FOP(36, 17):
6967
        check_cp1_registers(ctx, fs);
6968
        {
6969
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6970
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6971

    
6972
            gen_load_fpr64(ctx, fp64, fs);
6973
            tcg_gen_helper_1_1(do_float_cvtw_d, fp32, fp64);
6974
            tcg_temp_free(fp64);
6975
            gen_store_fpr32(fp32, fd);
6976
            tcg_temp_free(fp32);
6977
        }
6978
        opn = "cvt.w.d";
6979
        break;
6980
    case FOP(37, 17):
6981
        check_cp1_64bitmode(ctx);
6982
        {
6983
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6984

    
6985
            gen_load_fpr64(ctx, fp0, fs);
6986
            tcg_gen_helper_1_1(do_float_cvtl_d, fp0, fp0);
6987
            gen_store_fpr64(ctx, fp0, fd);
6988
            tcg_temp_free(fp0);
6989
        }
6990
        opn = "cvt.l.d";
6991
        break;
6992
    case FOP(32, 20):
6993
        {
6994
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6995

    
6996
            gen_load_fpr32(fp0, fs);
6997
            tcg_gen_helper_1_1(do_float_cvts_w, fp0, fp0);
6998
            gen_store_fpr32(fp0, fd);
6999
            tcg_temp_free(fp0);
7000
        }
7001
        opn = "cvt.s.w";
7002
        break;
7003
    case FOP(33, 20):
7004
        check_cp1_registers(ctx, fd);
7005
        {
7006
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
7007
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
7008

    
7009
            gen_load_fpr32(fp32, fs);
7010
            tcg_gen_helper_1_1(do_float_cvtd_w, fp64, fp32);
7011
            tcg_temp_free(fp32);
7012
            gen_store_fpr64(ctx, fp64, fd);
7013
            tcg_temp_free(fp64);
7014
        }
7015
        opn = "cvt.d.w";
7016
        break;
7017
    case FOP(32, 21):
7018
        check_cp1_64bitmode(ctx);
7019
        {
7020
            TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
7021
            TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
7022

    
7023
            gen_load_fpr64(ctx, fp64, fs);
7024
            tcg_gen_helper_1_1(do_float_cvts_l, fp32, fp64);
7025
            tcg_temp_free(fp64);
7026
            gen_store_fpr32(fp32, fd);
7027
            tcg_temp_free(fp32);
7028
        }
7029
        opn = "cvt.s.l";
7030
        break;
7031
    case FOP(33, 21):
7032
        check_cp1_64bitmode(ctx);
7033
        {
7034
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7035

    
7036
            gen_load_fpr64(ctx, fp0, fs);
7037
            tcg_gen_helper_1_1(do_float_cvtd_l, fp0, fp0);
7038
            gen_store_fpr64(ctx, fp0, fd);
7039
            tcg_temp_free(fp0);
7040
        }
7041
        opn = "cvt.d.l";
7042
        break;
7043
    case FOP(38, 20):
7044
        check_cp1_64bitmode(ctx);
7045
        {
7046
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7047

    
7048
            gen_load_fpr64(ctx, fp0, fs);
7049
            tcg_gen_helper_1_1(do_float_cvtps_pw, fp0, fp0);
7050
            gen_store_fpr64(ctx, fp0, fd);
7051
            tcg_temp_free(fp0);
7052
        }
7053
        opn = "cvt.ps.pw";
7054
        break;
7055
    case FOP(0, 22):
7056
        check_cp1_64bitmode(ctx);
7057
        {
7058
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7059
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7060

    
7061
            gen_load_fpr64(ctx, fp0, fs);
7062
            gen_load_fpr64(ctx, fp1, ft);
7063
            tcg_gen_helper_1_2(do_float_add_ps, fp0, fp0, fp1);
7064
            tcg_temp_free(fp1);
7065
            gen_store_fpr64(ctx, fp0, fd);
7066
            tcg_temp_free(fp0);
7067
        }
7068
        opn = "add.ps";
7069
        break;
7070
    case FOP(1, 22):
7071
        check_cp1_64bitmode(ctx);
7072
        {
7073
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7074
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7075

    
7076
            gen_load_fpr64(ctx, fp0, fs);
7077
            gen_load_fpr64(ctx, fp1, ft);
7078
            tcg_gen_helper_1_2(do_float_sub_ps, fp0, fp0, fp1);
7079
            tcg_temp_free(fp1);
7080
            gen_store_fpr64(ctx, fp0, fd);
7081
            tcg_temp_free(fp0);
7082
        }
7083
        opn = "sub.ps";
7084
        break;
7085
    case FOP(2, 22):
7086
        check_cp1_64bitmode(ctx);
7087
        {
7088
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7089
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7090

    
7091
            gen_load_fpr64(ctx, fp0, fs);
7092
            gen_load_fpr64(ctx, fp1, ft);
7093
            tcg_gen_helper_1_2(do_float_mul_ps, fp0, fp0, fp1);
7094
            tcg_temp_free(fp1);
7095
            gen_store_fpr64(ctx, fp0, fd);
7096
            tcg_temp_free(fp0);
7097
        }
7098
        opn = "mul.ps";
7099
        break;
7100
    case FOP(5, 22):
7101
        check_cp1_64bitmode(ctx);
7102
        {
7103
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7104

    
7105
            gen_load_fpr64(ctx, fp0, fs);
7106
            tcg_gen_helper_1_1(do_float_abs_ps, fp0, fp0);
7107
            gen_store_fpr64(ctx, fp0, fd);
7108
            tcg_temp_free(fp0);
7109
        }
7110
        opn = "abs.ps";
7111
        break;
7112
    case FOP(6, 22):
7113
        check_cp1_64bitmode(ctx);
7114
        {
7115
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7116

    
7117
            gen_load_fpr64(ctx, fp0, fs);
7118
            gen_store_fpr64(ctx, fp0, fd);
7119
            tcg_temp_free(fp0);
7120
        }
7121
        opn = "mov.ps";
7122
        break;
7123
    case FOP(7, 22):
7124
        check_cp1_64bitmode(ctx);
7125
        {
7126
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7127

    
7128
            gen_load_fpr64(ctx, fp0, fs);
7129
            tcg_gen_helper_1_1(do_float_chs_ps, fp0, fp0);
7130
            gen_store_fpr64(ctx, fp0, fd);
7131
            tcg_temp_free(fp0);
7132
        }
7133
        opn = "neg.ps";
7134
        break;
7135
    case FOP(17, 22):
7136
        check_cp1_64bitmode(ctx);
7137
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7138
        opn = "movcf.ps";
7139
        break;
7140
    case FOP(18, 22):
7141
        check_cp1_64bitmode(ctx);
7142
        {
7143
            int l1 = gen_new_label();
7144
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7145
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7146
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7147

    
7148
            gen_load_gpr(t0, ft);
7149
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7150
            tcg_temp_free(t0);
7151
            gen_load_fpr32(fp0, fs);
7152
            gen_load_fpr32h(fph0, fs);
7153
            gen_store_fpr32(fp0, fd);
7154
            gen_store_fpr32h(fph0, fd);
7155
            tcg_temp_free(fp0);
7156
            tcg_temp_free(fph0);
7157
            gen_set_label(l1);
7158
        }
7159
        opn = "movz.ps";
7160
        break;
7161
    case FOP(19, 22):
7162
        check_cp1_64bitmode(ctx);
7163
        {
7164
            int l1 = gen_new_label();
7165
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7166
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7167
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7168

    
7169
            gen_load_gpr(t0, ft);
7170
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
7171
            tcg_temp_free(t0);
7172
            gen_load_fpr32(fp0, fs);
7173
            gen_load_fpr32h(fph0, fs);
7174
            gen_store_fpr32(fp0, fd);
7175
            gen_store_fpr32h(fph0, fd);
7176
            tcg_temp_free(fp0);
7177
            tcg_temp_free(fph0);
7178
            gen_set_label(l1);
7179
        }
7180
        opn = "movn.ps";
7181
        break;
7182
    case FOP(24, 22):
7183
        check_cp1_64bitmode(ctx);
7184
        {
7185
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7186
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7187

    
7188
            gen_load_fpr64(ctx, fp0, ft);
7189
            gen_load_fpr64(ctx, fp1, fs);
7190
            tcg_gen_helper_1_2(do_float_addr_ps, fp0, fp0, fp1);
7191
            tcg_temp_free(fp1);
7192
            gen_store_fpr64(ctx, fp0, fd);
7193
            tcg_temp_free(fp0);
7194
        }
7195
        opn = "addr.ps";
7196
        break;
7197
    case FOP(26, 22):
7198
        check_cp1_64bitmode(ctx);
7199
        {
7200
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7201
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7202

    
7203
            gen_load_fpr64(ctx, fp0, ft);
7204
            gen_load_fpr64(ctx, fp1, fs);
7205
            tcg_gen_helper_1_2(do_float_mulr_ps, fp0, fp0, fp1);
7206
            tcg_temp_free(fp1);
7207
            gen_store_fpr64(ctx, fp0, fd);
7208
            tcg_temp_free(fp0);
7209
        }
7210
        opn = "mulr.ps";
7211
        break;
7212
    case FOP(28, 22):
7213
        check_cp1_64bitmode(ctx);
7214
        {
7215
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7216
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7217

    
7218
            gen_load_fpr64(ctx, fp0, fs);
7219
            gen_load_fpr64(ctx, fp1, fd);
7220
            tcg_gen_helper_1_2(do_float_recip2_ps, fp0, fp0, fp1);
7221
            tcg_temp_free(fp1);
7222
            gen_store_fpr64(ctx, fp0, fd);
7223
            tcg_temp_free(fp0);
7224
        }
7225
        opn = "recip2.ps";
7226
        break;
7227
    case FOP(29, 22):
7228
        check_cp1_64bitmode(ctx);
7229
        {
7230
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7231

    
7232
            gen_load_fpr64(ctx, fp0, fs);
7233
            tcg_gen_helper_1_1(do_float_recip1_ps, fp0, fp0);
7234
            gen_store_fpr64(ctx, fp0, fd);
7235
            tcg_temp_free(fp0);
7236
        }
7237
        opn = "recip1.ps";
7238
        break;
7239
    case FOP(30, 22):
7240
        check_cp1_64bitmode(ctx);
7241
        {
7242
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7243

    
7244
            gen_load_fpr64(ctx, fp0, fs);
7245
            tcg_gen_helper_1_1(do_float_rsqrt1_ps, fp0, fp0);
7246
            gen_store_fpr64(ctx, fp0, fd);
7247
            tcg_temp_free(fp0);
7248
        }
7249
        opn = "rsqrt1.ps";
7250
        break;
7251
    case FOP(31, 22):
7252
        check_cp1_64bitmode(ctx);
7253
        {
7254
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7255
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7256

    
7257
            gen_load_fpr64(ctx, fp0, fs);
7258
            gen_load_fpr64(ctx, fp1, ft);
7259
            tcg_gen_helper_1_2(do_float_rsqrt2_ps, fp0, fp0, fp1);
7260
            tcg_temp_free(fp1);
7261
            gen_store_fpr64(ctx, fp0, fd);
7262
            tcg_temp_free(fp0);
7263
        }
7264
        opn = "rsqrt2.ps";
7265
        break;
7266
    case FOP(32, 22):
7267
        check_cp1_64bitmode(ctx);
7268
        {
7269
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7270

    
7271
            gen_load_fpr32h(fp0, fs);
7272
            tcg_gen_helper_1_1(do_float_cvts_pu, fp0, fp0);
7273
            gen_store_fpr32(fp0, fd);
7274
            tcg_temp_free(fp0);
7275
        }
7276
        opn = "cvt.s.pu";
7277
        break;
7278
    case FOP(36, 22):
7279
        check_cp1_64bitmode(ctx);
7280
        {
7281
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7282

    
7283
            gen_load_fpr64(ctx, fp0, fs);
7284
            tcg_gen_helper_1_1(do_float_cvtpw_ps, fp0, fp0);
7285
            gen_store_fpr64(ctx, fp0, fd);
7286
            tcg_temp_free(fp0);
7287
        }
7288
        opn = "cvt.pw.ps";
7289
        break;
7290
    case FOP(40, 22):
7291
        check_cp1_64bitmode(ctx);
7292
        {
7293
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7294

    
7295
            gen_load_fpr32(fp0, fs);
7296
            tcg_gen_helper_1_1(do_float_cvts_pl, fp0, fp0);
7297
            gen_store_fpr32(fp0, fd);
7298
            tcg_temp_free(fp0);
7299
        }
7300
        opn = "cvt.s.pl";
7301
        break;
7302
    case FOP(44, 22):
7303
        check_cp1_64bitmode(ctx);
7304
        {
7305
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7306
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7307

    
7308
            gen_load_fpr32(fp0, fs);
7309
            gen_load_fpr32(fp1, ft);
7310
            gen_store_fpr32h(fp0, fd);
7311
            gen_store_fpr32(fp1, fd);
7312
            tcg_temp_free(fp0);
7313
            tcg_temp_free(fp1);
7314
        }
7315
        opn = "pll.ps";
7316
        break;
7317
    case FOP(45, 22):
7318
        check_cp1_64bitmode(ctx);
7319
        {
7320
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7321
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7322

    
7323
            gen_load_fpr32(fp0, fs);
7324
            gen_load_fpr32h(fp1, ft);
7325
            gen_store_fpr32(fp1, fd);
7326
            gen_store_fpr32h(fp0, fd);
7327
            tcg_temp_free(fp0);
7328
            tcg_temp_free(fp1);
7329
        }
7330
        opn = "plu.ps";
7331
        break;
7332
    case FOP(46, 22):
7333
        check_cp1_64bitmode(ctx);
7334
        {
7335
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7336
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7337

    
7338
            gen_load_fpr32h(fp0, fs);
7339
            gen_load_fpr32(fp1, ft);
7340
            gen_store_fpr32(fp1, fd);
7341
            gen_store_fpr32h(fp0, fd);
7342
            tcg_temp_free(fp0);
7343
            tcg_temp_free(fp1);
7344
        }
7345
        opn = "pul.ps";
7346
        break;
7347
    case FOP(47, 22):
7348
        check_cp1_64bitmode(ctx);
7349
        {
7350
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7351
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7352

    
7353
            gen_load_fpr32h(fp0, fs);
7354
            gen_load_fpr32h(fp1, ft);
7355
            gen_store_fpr32(fp1, fd);
7356
            gen_store_fpr32h(fp0, fd);
7357
            tcg_temp_free(fp0);
7358
            tcg_temp_free(fp1);
7359
        }
7360
        opn = "puu.ps";
7361
        break;
7362
    case FOP(48, 22):
7363
    case FOP(49, 22):
7364
    case FOP(50, 22):
7365
    case FOP(51, 22):
7366
    case FOP(52, 22):
7367
    case FOP(53, 22):
7368
    case FOP(54, 22):
7369
    case FOP(55, 22):
7370
    case FOP(56, 22):
7371
    case FOP(57, 22):
7372
    case FOP(58, 22):
7373
    case FOP(59, 22):
7374
    case FOP(60, 22):
7375
    case FOP(61, 22):
7376
    case FOP(62, 22):
7377
    case FOP(63, 22):
7378
        check_cp1_64bitmode(ctx);
7379
        {
7380
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7381
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7382

    
7383
            gen_load_fpr64(ctx, fp0, fs);
7384
            gen_load_fpr64(ctx, fp1, ft);
7385
            if (ctx->opcode & (1 << 6)) {
7386
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7387
                opn = condnames_abs[func-48];
7388
            } else {
7389
                gen_cmp_ps(func-48, fp0, fp1, cc);
7390
                opn = condnames[func-48];
7391
            }
7392
            tcg_temp_free(fp0);
7393
            tcg_temp_free(fp1);
7394
        }
7395
        break;
7396
    default:
7397
        MIPS_INVAL(opn);
7398
        generate_exception (ctx, EXCP_RI);
7399
        return;
7400
    }
7401
    switch (optype) {
7402
    case BINOP:
7403
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7404
        break;
7405
    case CMPOP:
7406
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7407
        break;
7408
    default:
7409
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7410
        break;
7411
    }
7412
}
7413

    
7414
/* Coprocessor 3 (FPU) */
7415
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7416
                           int fd, int fs, int base, int index)
7417
{
7418
    const char *opn = "extended float load/store";
7419
    int store = 0;
7420
    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7421
    TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7422

    
7423
    if (base == 0) {
7424
        gen_load_gpr(t0, index);
7425
    } else if (index == 0) {
7426
        gen_load_gpr(t0, base);
7427
    } else {
7428
        gen_load_gpr(t0, base);
7429
        gen_load_gpr(t1, index);
7430
        gen_op_addr_add(t0, t1);
7431
    }
7432
    /* Don't do NOP if destination is zero: we must perform the actual
7433
       memory access. */
7434
    switch (opc) {
7435
    case OPC_LWXC1:
7436
        check_cop1x(ctx);
7437
        {
7438
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7439

    
7440
            tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
7441
            gen_store_fpr32(fp0, fd);
7442
            tcg_temp_free(fp0);
7443
        }
7444
        opn = "lwxc1";
7445
        break;
7446
    case OPC_LDXC1:
7447
        check_cop1x(ctx);
7448
        check_cp1_registers(ctx, fd);
7449
        {
7450
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7451

    
7452
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7453
            gen_store_fpr64(ctx, fp0, fd);
7454
            tcg_temp_free(fp0);
7455
        }
7456
        opn = "ldxc1";
7457
        break;
7458
    case OPC_LUXC1:
7459
        check_cp1_64bitmode(ctx);
7460
        tcg_gen_andi_tl(t0, t0, ~0x7);
7461
        {
7462
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7463

    
7464
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7465
            gen_store_fpr64(ctx, fp0, fd);
7466
            tcg_temp_free(fp0);
7467
        }
7468
        opn = "luxc1";
7469
        break;
7470
    case OPC_SWXC1:
7471
        check_cop1x(ctx);
7472
        {
7473
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7474

    
7475
            gen_load_fpr32(fp0, fs);
7476
            tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
7477
            tcg_temp_free(fp0);
7478
        }
7479
        opn = "swxc1";
7480
        store = 1;
7481
        break;
7482
    case OPC_SDXC1:
7483
        check_cop1x(ctx);
7484
        check_cp1_registers(ctx, fs);
7485
        {
7486
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7487

    
7488
            gen_load_fpr64(ctx, fp0, fs);
7489
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7490
            tcg_temp_free(fp0);
7491
        }
7492
        opn = "sdxc1";
7493
        store = 1;
7494
        break;
7495
    case OPC_SUXC1:
7496
        check_cp1_64bitmode(ctx);
7497
        tcg_gen_andi_tl(t0, t0, ~0x7);
7498
        {
7499
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7500

    
7501
            gen_load_fpr64(ctx, fp0, fs);
7502
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7503
            tcg_temp_free(fp0);
7504
        }
7505
        opn = "suxc1";
7506
        store = 1;
7507
        break;
7508
    default:
7509
        MIPS_INVAL(opn);
7510
        generate_exception(ctx, EXCP_RI);
7511
        tcg_temp_free(t0);
7512
        tcg_temp_free(t1);
7513
        return;
7514
    }
7515
    tcg_temp_free(t0);
7516
    tcg_temp_free(t1);
7517
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7518
               regnames[index], regnames[base]);
7519
}
7520

    
7521
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7522
                            int fd, int fr, int fs, int ft)
7523
{
7524
    const char *opn = "flt3_arith";
7525

    
7526
    switch (opc) {
7527
    case OPC_ALNV_PS:
7528
        check_cp1_64bitmode(ctx);
7529
        {
7530
            TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7531
            TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7532
            TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7533
            TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
7534
            TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
7535
            int l1 = gen_new_label();
7536
            int l2 = gen_new_label();
7537

    
7538
            gen_load_gpr(t0, fr);
7539
            tcg_gen_andi_tl(t0, t0, 0x7);
7540
            gen_load_fpr32(fp0, fs);
7541
            gen_load_fpr32h(fph0, fs);
7542
            gen_load_fpr32(fp1, ft);
7543
            gen_load_fpr32h(fph1, ft);
7544

    
7545
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7546
            gen_store_fpr32(fp0, fd);
7547
            gen_store_fpr32h(fph0, fd);
7548
            tcg_gen_br(l2);
7549
            gen_set_label(l1);
7550
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7551
            tcg_temp_free(t0);
7552
#ifdef TARGET_WORDS_BIGENDIAN
7553
            gen_store_fpr32(fph1, fd);
7554
            gen_store_fpr32h(fp0, fd);
7555
#else
7556
            gen_store_fpr32(fph0, fd);
7557
            gen_store_fpr32h(fp1, fd);
7558
#endif
7559
            gen_set_label(l2);
7560
            tcg_temp_free(fp0);
7561
            tcg_temp_free(fph0);
7562
            tcg_temp_free(fp1);
7563
            tcg_temp_free(fph1);
7564
        }
7565
        opn = "alnv.ps";
7566
        break;
7567
    case OPC_MADD_S:
7568
        check_cop1x(ctx);
7569
        {
7570
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7571
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7572
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7573

    
7574
            gen_load_fpr32(fp0, fs);
7575
            gen_load_fpr32(fp1, ft);
7576
            gen_load_fpr32(fp2, fr);
7577
            tcg_gen_helper_1_3(do_float_muladd_s, fp2, fp0, fp1, fp2);
7578
            tcg_temp_free(fp0);
7579
            tcg_temp_free(fp1);
7580
            gen_store_fpr32(fp2, fd);
7581
            tcg_temp_free(fp2);
7582
        }
7583
        opn = "madd.s";
7584
        break;
7585
    case OPC_MADD_D:
7586
        check_cop1x(ctx);
7587
        check_cp1_registers(ctx, fd | fs | ft | fr);
7588
        {
7589
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7590
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7591
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7592

    
7593
            gen_load_fpr64(ctx, fp0, fs);
7594
            gen_load_fpr64(ctx, fp1, ft);
7595
            gen_load_fpr64(ctx, fp2, fr);
7596
            tcg_gen_helper_1_3(do_float_muladd_d, fp2, fp0, fp1, fp2);
7597
            tcg_temp_free(fp0);
7598
            tcg_temp_free(fp1);
7599
            gen_store_fpr64(ctx, fp2, fd);
7600
            tcg_temp_free(fp2);
7601
        }
7602
        opn = "madd.d";
7603
        break;
7604
    case OPC_MADD_PS:
7605
        check_cp1_64bitmode(ctx);
7606
        {
7607
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7608
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7609
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7610

    
7611
            gen_load_fpr64(ctx, fp0, fs);
7612
            gen_load_fpr64(ctx, fp1, ft);
7613
            gen_load_fpr64(ctx, fp2, fr);
7614
            tcg_gen_helper_1_3(do_float_muladd_ps, fp2, fp0, fp1, fp2);
7615
            tcg_temp_free(fp0);
7616
            tcg_temp_free(fp1);
7617
            gen_store_fpr64(ctx, fp2, fd);
7618
            tcg_temp_free(fp2);
7619
        }
7620
        opn = "madd.ps";
7621
        break;
7622
    case OPC_MSUB_S:
7623
        check_cop1x(ctx);
7624
        {
7625
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7626
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7627
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7628

    
7629
            gen_load_fpr32(fp0, fs);
7630
            gen_load_fpr32(fp1, ft);
7631
            gen_load_fpr32(fp2, fr);
7632
            tcg_gen_helper_1_3(do_float_mulsub_s, fp2, fp0, fp1, fp2);
7633
            tcg_temp_free(fp0);
7634
            tcg_temp_free(fp1);
7635
            gen_store_fpr32(fp2, fd);
7636
            tcg_temp_free(fp2);
7637
        }
7638
        opn = "msub.s";
7639
        break;
7640
    case OPC_MSUB_D:
7641
        check_cop1x(ctx);
7642
        check_cp1_registers(ctx, fd | fs | ft | fr);
7643
        {
7644
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7645
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7646
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7647

    
7648
            gen_load_fpr64(ctx, fp0, fs);
7649
            gen_load_fpr64(ctx, fp1, ft);
7650
            gen_load_fpr64(ctx, fp2, fr);
7651
            tcg_gen_helper_1_3(do_float_mulsub_d, fp2, fp0, fp1, fp2);
7652
            tcg_temp_free(fp0);
7653
            tcg_temp_free(fp1);
7654
            gen_store_fpr64(ctx, fp2, fd);
7655
            tcg_temp_free(fp2);
7656
        }
7657
        opn = "msub.d";
7658
        break;
7659
    case OPC_MSUB_PS:
7660
        check_cp1_64bitmode(ctx);
7661
        {
7662
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7663
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7664
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7665

    
7666
            gen_load_fpr64(ctx, fp0, fs);
7667
            gen_load_fpr64(ctx, fp1, ft);
7668
            gen_load_fpr64(ctx, fp2, fr);
7669
            tcg_gen_helper_1_3(do_float_mulsub_ps, fp2, fp0, fp1, fp2);
7670
            tcg_temp_free(fp0);
7671
            tcg_temp_free(fp1);
7672
            gen_store_fpr64(ctx, fp2, fd);
7673
            tcg_temp_free(fp2);
7674
        }
7675
        opn = "msub.ps";
7676
        break;
7677
    case OPC_NMADD_S:
7678
        check_cop1x(ctx);
7679
        {
7680
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7681
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7682
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7683

    
7684
            gen_load_fpr32(fp0, fs);
7685
            gen_load_fpr32(fp1, ft);
7686
            gen_load_fpr32(fp2, fr);
7687
            tcg_gen_helper_1_3(do_float_nmuladd_s, fp2, fp0, fp1, fp2);
7688
            tcg_temp_free(fp0);
7689
            tcg_temp_free(fp1);
7690
            gen_store_fpr32(fp2, fd);
7691
            tcg_temp_free(fp2);
7692
        }
7693
        opn = "nmadd.s";
7694
        break;
7695
    case OPC_NMADD_D:
7696
        check_cop1x(ctx);
7697
        check_cp1_registers(ctx, fd | fs | ft | fr);
7698
        {
7699
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7700
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7701
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7702

    
7703
            gen_load_fpr64(ctx, fp0, fs);
7704
            gen_load_fpr64(ctx, fp1, ft);
7705
            gen_load_fpr64(ctx, fp2, fr);
7706
            tcg_gen_helper_1_3(do_float_nmuladd_d, fp2, fp0, fp1, fp2);
7707
            tcg_temp_free(fp0);
7708
            tcg_temp_free(fp1);
7709
            gen_store_fpr64(ctx, fp2, fd);
7710
            tcg_temp_free(fp2);
7711
        }
7712
        opn = "nmadd.d";
7713
        break;
7714
    case OPC_NMADD_PS:
7715
        check_cp1_64bitmode(ctx);
7716
        {
7717
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7718
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7719
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7720

    
7721
            gen_load_fpr64(ctx, fp0, fs);
7722
            gen_load_fpr64(ctx, fp1, ft);
7723
            gen_load_fpr64(ctx, fp2, fr);
7724
            tcg_gen_helper_1_3(do_float_nmuladd_ps, fp2, fp0, fp1, fp2);
7725
            tcg_temp_free(fp0);
7726
            tcg_temp_free(fp1);
7727
            gen_store_fpr64(ctx, fp2, fd);
7728
            tcg_temp_free(fp2);
7729
        }
7730
        opn = "nmadd.ps";
7731
        break;
7732
    case OPC_NMSUB_S:
7733
        check_cop1x(ctx);
7734
        {
7735
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7736
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7737
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7738

    
7739
            gen_load_fpr32(fp0, fs);
7740
            gen_load_fpr32(fp1, ft);
7741
            gen_load_fpr32(fp2, fr);
7742
            tcg_gen_helper_1_3(do_float_nmulsub_s, fp2, fp0, fp1, fp2);
7743
            tcg_temp_free(fp0);
7744
            tcg_temp_free(fp1);
7745
            gen_store_fpr32(fp2, fd);
7746
            tcg_temp_free(fp2);
7747
        }
7748
        opn = "nmsub.s";
7749
        break;
7750
    case OPC_NMSUB_D:
7751
        check_cop1x(ctx);
7752
        check_cp1_registers(ctx, fd | fs | ft | fr);
7753
        {
7754
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7755
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7756
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7757

    
7758
            gen_load_fpr64(ctx, fp0, fs);
7759
            gen_load_fpr64(ctx, fp1, ft);
7760
            gen_load_fpr64(ctx, fp2, fr);
7761
            tcg_gen_helper_1_3(do_float_nmulsub_d, fp2, fp0, fp1, fp2);
7762
            tcg_temp_free(fp0);
7763
            tcg_temp_free(fp1);
7764
            gen_store_fpr64(ctx, fp2, fd);
7765
            tcg_temp_free(fp2);
7766
        }
7767
        opn = "nmsub.d";
7768
        break;
7769
    case OPC_NMSUB_PS:
7770
        check_cp1_64bitmode(ctx);
7771
        {
7772
            TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7773
            TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7774
            TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7775

    
7776
            gen_load_fpr64(ctx, fp0, fs);
7777
            gen_load_fpr64(ctx, fp1, ft);
7778
            gen_load_fpr64(ctx, fp2, fr);
7779
            tcg_gen_helper_1_3(do_float_nmulsub_ps, fp2, fp0, fp1, fp2);
7780
            tcg_temp_free(fp0);
7781
            tcg_temp_free(fp1);
7782
            gen_store_fpr64(ctx, fp2, fd);
7783
            tcg_temp_free(fp2);
7784
        }
7785
        opn = "nmsub.ps";
7786
        break;
7787
    default:
7788
        MIPS_INVAL(opn);
7789
        generate_exception (ctx, EXCP_RI);
7790
        return;
7791
    }
7792
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7793
               fregnames[fs], fregnames[ft]);
7794
}
7795

    
7796
/* ISA extensions (ASEs) */
7797
/* MIPS16 extension to MIPS32 */
7798
/* SmartMIPS extension to MIPS32 */
7799

    
7800
#if defined(TARGET_MIPS64)
7801

    
7802
/* MDMX extension to MIPS64 */
7803

    
7804
#endif
7805

    
7806
static void decode_opc (CPUState *env, DisasContext *ctx)
7807
{
7808
    int32_t offset;
7809
    int rs, rt, rd, sa;
7810
    uint32_t op, op1, op2;
7811
    int16_t imm;
7812

    
7813
    /* make sure instructions are on a word boundary */
7814
    if (ctx->pc & 0x3) {
7815
        env->CP0_BadVAddr = ctx->pc;
7816
        generate_exception(ctx, EXCP_AdEL);
7817
        return;
7818
    }
7819

    
7820
    /* Handle blikely not taken case */
7821
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7822
        int l1 = gen_new_label();
7823

    
7824
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7825
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7826
        {
7827
            TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
7828

    
7829
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7830
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7831
            tcg_temp_free(r_tmp);
7832
        }
7833
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7834
        gen_set_label(l1);
7835
    }
7836
    op = MASK_OP_MAJOR(ctx->opcode);
7837
    rs = (ctx->opcode >> 21) & 0x1f;
7838
    rt = (ctx->opcode >> 16) & 0x1f;
7839
    rd = (ctx->opcode >> 11) & 0x1f;
7840
    sa = (ctx->opcode >> 6) & 0x1f;
7841
    imm = (int16_t)ctx->opcode;
7842
    switch (op) {
7843
    case OPC_SPECIAL:
7844
        op1 = MASK_SPECIAL(ctx->opcode);
7845
        switch (op1) {
7846
        case OPC_SLL:          /* Arithmetic with immediate */
7847
        case OPC_SRL ... OPC_SRA:
7848
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7849
            break;
7850
        case OPC_MOVZ ... OPC_MOVN:
7851
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7852
        case OPC_SLLV:         /* Arithmetic */
7853
        case OPC_SRLV ... OPC_SRAV:
7854
        case OPC_ADD ... OPC_NOR:
7855
        case OPC_SLT ... OPC_SLTU:
7856
            gen_arith(env, ctx, op1, rd, rs, rt);
7857
            break;
7858
        case OPC_MULT ... OPC_DIVU:
7859
            if (sa) {
7860
                check_insn(env, ctx, INSN_VR54XX);
7861
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7862
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7863
            } else
7864
                gen_muldiv(ctx, op1, rs, rt);
7865
            break;
7866
        case OPC_JR ... OPC_JALR:
7867
            gen_compute_branch(ctx, op1, rs, rd, sa);
7868
            return;
7869
        case OPC_TGE ... OPC_TEQ: /* Traps */
7870
        case OPC_TNE:
7871
            gen_trap(ctx, op1, rs, rt, -1);
7872
            break;
7873
        case OPC_MFHI:          /* Move from HI/LO */
7874
        case OPC_MFLO:
7875
            gen_HILO(ctx, op1, rd);
7876
            break;
7877
        case OPC_MTHI:
7878
        case OPC_MTLO:          /* Move to HI/LO */
7879
            gen_HILO(ctx, op1, rs);
7880
            break;
7881
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7882
#ifdef MIPS_STRICT_STANDARD
7883
            MIPS_INVAL("PMON / selsl");
7884
            generate_exception(ctx, EXCP_RI);
7885
#else
7886
            tcg_gen_helper_0_i(do_pmon, sa);
7887
#endif
7888
            break;
7889
        case OPC_SYSCALL:
7890
            generate_exception(ctx, EXCP_SYSCALL);
7891
            break;
7892
        case OPC_BREAK:
7893
            generate_exception(ctx, EXCP_BREAK);
7894
            break;
7895
        case OPC_SPIM:
7896
#ifdef MIPS_STRICT_STANDARD
7897
            MIPS_INVAL("SPIM");
7898
            generate_exception(ctx, EXCP_RI);
7899
#else
7900
           /* Implemented as RI exception for now. */
7901
            MIPS_INVAL("spim (unofficial)");
7902
            generate_exception(ctx, EXCP_RI);
7903
#endif
7904
            break;
7905
        case OPC_SYNC:
7906
            /* Treat as NOP. */
7907
            break;
7908

    
7909
        case OPC_MOVCI:
7910
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7911
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7912
                save_cpu_state(ctx, 1);
7913
                check_cp1_enabled(ctx);
7914
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7915
                          (ctx->opcode >> 16) & 1);
7916
            } else {
7917
                generate_exception_err(ctx, EXCP_CpU, 1);
7918
            }
7919
            break;
7920

    
7921
#if defined(TARGET_MIPS64)
7922
       /* MIPS64 specific opcodes */
7923
        case OPC_DSLL:
7924
        case OPC_DSRL ... OPC_DSRA:
7925
        case OPC_DSLL32:
7926
        case OPC_DSRL32 ... OPC_DSRA32:
7927
            check_insn(env, ctx, ISA_MIPS3);
7928
            check_mips_64(ctx);
7929
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7930
            break;
7931
        case OPC_DSLLV:
7932
        case OPC_DSRLV ... OPC_DSRAV:
7933
        case OPC_DADD ... OPC_DSUBU:
7934
            check_insn(env, ctx, ISA_MIPS3);
7935
            check_mips_64(ctx);
7936
            gen_arith(env, ctx, op1, rd, rs, rt);
7937
            break;
7938
        case OPC_DMULT ... OPC_DDIVU:
7939
            check_insn(env, ctx, ISA_MIPS3);
7940
            check_mips_64(ctx);
7941
            gen_muldiv(ctx, op1, rs, rt);
7942
            break;
7943
#endif
7944
        default:            /* Invalid */
7945
            MIPS_INVAL("special");
7946
            generate_exception(ctx, EXCP_RI);
7947
            break;
7948
        }
7949
        break;
7950
    case OPC_SPECIAL2:
7951
        op1 = MASK_SPECIAL2(ctx->opcode);
7952
        switch (op1) {
7953
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7954
        case OPC_MSUB ... OPC_MSUBU:
7955
            check_insn(env, ctx, ISA_MIPS32);
7956
            gen_muldiv(ctx, op1, rs, rt);
7957
            break;
7958
        case OPC_MUL:
7959
            gen_arith(env, ctx, op1, rd, rs, rt);
7960
            break;
7961
        case OPC_CLZ ... OPC_CLO:
7962
            check_insn(env, ctx, ISA_MIPS32);
7963
            gen_cl(ctx, op1, rd, rs);
7964
            break;
7965
        case OPC_SDBBP:
7966
            /* XXX: not clear which exception should be raised
7967
             *      when in debug mode...
7968
             */
7969
            check_insn(env, ctx, ISA_MIPS32);
7970
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7971
                generate_exception(ctx, EXCP_DBp);
7972
            } else {
7973
                generate_exception(ctx, EXCP_DBp);
7974
            }
7975
            /* Treat as NOP. */
7976
            break;
7977
#if defined(TARGET_MIPS64)
7978
        case OPC_DCLZ ... OPC_DCLO:
7979
            check_insn(env, ctx, ISA_MIPS64);
7980
            check_mips_64(ctx);
7981
            gen_cl(ctx, op1, rd, rs);
7982
            break;
7983
#endif
7984
        default:            /* Invalid */
7985
            MIPS_INVAL("special2");
7986
            generate_exception(ctx, EXCP_RI);
7987
            break;
7988
        }
7989
        break;
7990
    case OPC_SPECIAL3:
7991
        op1 = MASK_SPECIAL3(ctx->opcode);
7992
        switch (op1) {
7993
        case OPC_EXT:
7994
        case OPC_INS:
7995
            check_insn(env, ctx, ISA_MIPS32R2);
7996
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7997
            break;
7998
        case OPC_BSHFL:
7999
            check_insn(env, ctx, ISA_MIPS32R2);
8000
            op2 = MASK_BSHFL(ctx->opcode);
8001
            {
8002
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8003
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8004

    
8005
                switch (op2) {
8006
                case OPC_WSBH:
8007
                    gen_load_gpr(t1, rt);
8008
                    tcg_gen_helper_1_1(do_wsbh, t0, t1);
8009
                    gen_store_gpr(t0, rd);
8010
                    break;
8011
                case OPC_SEB:
8012
                    gen_load_gpr(t1, rt);
8013
                    tcg_gen_ext8s_tl(t0, t1);
8014
                    gen_store_gpr(t0, rd);
8015
                    break;
8016
                case OPC_SEH:
8017
                    gen_load_gpr(t1, rt);
8018
                    tcg_gen_ext16s_tl(t0, t1);
8019
                    gen_store_gpr(t0, rd);
8020
                    break;
8021
                default:            /* Invalid */
8022
                    MIPS_INVAL("bshfl");
8023
                    generate_exception(ctx, EXCP_RI);
8024
                    break;
8025
                }
8026
                tcg_temp_free(t0);
8027
                tcg_temp_free(t1);
8028
            }
8029
            break;
8030
        case OPC_RDHWR:
8031
            check_insn(env, ctx, ISA_MIPS32R2);
8032
            {
8033
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8034

    
8035
                switch (rd) {
8036
                case 0:
8037
                    save_cpu_state(ctx, 1);
8038
                    tcg_gen_helper_1_0(do_rdhwr_cpunum, t0);
8039
                    break;
8040
                case 1:
8041
                    save_cpu_state(ctx, 1);
8042
                    tcg_gen_helper_1_0(do_rdhwr_synci_step, t0);
8043
                    break;
8044
                case 2:
8045
                    save_cpu_state(ctx, 1);
8046
                    tcg_gen_helper_1_0(do_rdhwr_cc, t0);
8047
                    break;
8048
                case 3:
8049
                    save_cpu_state(ctx, 1);
8050
                    tcg_gen_helper_1_0(do_rdhwr_ccres, t0);
8051
                    break;
8052
                case 29:
8053
                    if (env->user_mode_only) {
8054
                        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8055
                        break;
8056
                    } else {
8057
                        /* XXX: Some CPUs implement this in hardware.
8058
                           Not supported yet. */
8059
                    }
8060
                default:            /* Invalid */
8061
                    MIPS_INVAL("rdhwr");
8062
                    generate_exception(ctx, EXCP_RI);
8063
                    break;
8064
                }
8065
                gen_store_gpr(t0, rt);
8066
                tcg_temp_free(t0);
8067
            }
8068
            break;
8069
        case OPC_FORK:
8070
            check_insn(env, ctx, ASE_MT);
8071
            {
8072
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8073
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8074

    
8075
                gen_load_gpr(t0, rt);
8076
                gen_load_gpr(t1, rs);
8077
                tcg_gen_helper_0_2(do_fork, t0, t1);
8078
                tcg_temp_free(t0);
8079
                tcg_temp_free(t1);
8080
            }
8081
            break;
8082
        case OPC_YIELD:
8083
            check_insn(env, ctx, ASE_MT);
8084
            {
8085
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8086

    
8087
                gen_load_gpr(t0, rs);
8088
                tcg_gen_helper_1_1(do_yield, t0, t0);
8089
                gen_store_gpr(t0, rd);
8090
                tcg_temp_free(t0);
8091
            }
8092
            break;
8093
#if defined(TARGET_MIPS64)
8094
        case OPC_DEXTM ... OPC_DEXT:
8095
        case OPC_DINSM ... OPC_DINS:
8096
            check_insn(env, ctx, ISA_MIPS64R2);
8097
            check_mips_64(ctx);
8098
            gen_bitops(ctx, op1, rt, rs, sa, rd);
8099
            break;
8100
        case OPC_DBSHFL:
8101
            check_insn(env, ctx, ISA_MIPS64R2);
8102
            check_mips_64(ctx);
8103
            op2 = MASK_DBSHFL(ctx->opcode);
8104
            {
8105
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8106
                TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
8107

    
8108
                switch (op2) {
8109
                case OPC_DSBH:
8110
                    gen_load_gpr(t1, rt);
8111
                    tcg_gen_helper_1_1(do_dsbh, t0, t1);
8112
                    break;
8113
                case OPC_DSHD:
8114
                    gen_load_gpr(t1, rt);
8115
                    tcg_gen_helper_1_1(do_dshd, t0, t1);
8116
                    break;
8117
                default:            /* Invalid */
8118
                    MIPS_INVAL("dbshfl");
8119
                    generate_exception(ctx, EXCP_RI);
8120
                    break;
8121
                }
8122
                gen_store_gpr(t0, rd);
8123
                tcg_temp_free(t0);
8124
                tcg_temp_free(t1);
8125
            }
8126
            break;
8127
#endif
8128
        default:            /* Invalid */
8129
            MIPS_INVAL("special3");
8130
            generate_exception(ctx, EXCP_RI);
8131
            break;
8132
        }
8133
        break;
8134
    case OPC_REGIMM:
8135
        op1 = MASK_REGIMM(ctx->opcode);
8136
        switch (op1) {
8137
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
8138
        case OPC_BLTZAL ... OPC_BGEZALL:
8139
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
8140
            return;
8141
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
8142
        case OPC_TNEI:
8143
            gen_trap(ctx, op1, rs, -1, imm);
8144
            break;
8145
        case OPC_SYNCI:
8146
            check_insn(env, ctx, ISA_MIPS32R2);
8147
            /* Treat as NOP. */
8148
            break;
8149
        default:            /* Invalid */
8150
            MIPS_INVAL("regimm");
8151
            generate_exception(ctx, EXCP_RI);
8152
            break;
8153
        }
8154
        break;
8155
    case OPC_CP0:
8156
        check_cp0_enabled(ctx);
8157
        op1 = MASK_CP0(ctx->opcode);
8158
        switch (op1) {
8159
        case OPC_MFC0:
8160
        case OPC_MTC0:
8161
        case OPC_MFTR:
8162
        case OPC_MTTR:
8163
#if defined(TARGET_MIPS64)
8164
        case OPC_DMFC0:
8165
        case OPC_DMTC0:
8166
#endif
8167
#ifndef CONFIG_USER_ONLY
8168
            if (!env->user_mode_only)
8169
                gen_cp0(env, ctx, op1, rt, rd);
8170
#endif /* !CONFIG_USER_ONLY */
8171
            break;
8172
        case OPC_C0_FIRST ... OPC_C0_LAST:
8173
#ifndef CONFIG_USER_ONLY
8174
            if (!env->user_mode_only)
8175
                gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
8176
#endif /* !CONFIG_USER_ONLY */
8177
            break;
8178
        case OPC_MFMC0:
8179
#ifndef CONFIG_USER_ONLY
8180
            if (!env->user_mode_only) {
8181
                TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8182

    
8183
                op2 = MASK_MFMC0(ctx->opcode);
8184
                switch (op2) {
8185
                case OPC_DMT:
8186
                    check_insn(env, ctx, ASE_MT);
8187
                    tcg_gen_helper_1_1(do_dmt, t0, t0);
8188
                    break;
8189
                case OPC_EMT:
8190
                    check_insn(env, ctx, ASE_MT);
8191
                    tcg_gen_helper_1_1(do_emt, t0, t0);
8192
                     break;
8193
                case OPC_DVPE:
8194
                    check_insn(env, ctx, ASE_MT);
8195
                    tcg_gen_helper_1_1(do_dvpe, t0, t0);
8196
                    break;
8197
                case OPC_EVPE:
8198
                    check_insn(env, ctx, ASE_MT);
8199
                    tcg_gen_helper_1_1(do_evpe, t0, t0);
8200
                    break;
8201
                case OPC_DI:
8202
                    check_insn(env, ctx, ISA_MIPS32R2);
8203
                    save_cpu_state(ctx, 1);
8204
                    tcg_gen_helper_1_0(do_di, t0);
8205
                    /* Stop translation as we may have switched the execution mode */
8206
                    ctx->bstate = BS_STOP;
8207
                    break;
8208
                case OPC_EI:
8209
                    check_insn(env, ctx, ISA_MIPS32R2);
8210
                    save_cpu_state(ctx, 1);
8211
                    tcg_gen_helper_1_0(do_ei, t0);
8212
                    /* Stop translation as we may have switched the execution mode */
8213
                    ctx->bstate = BS_STOP;
8214
                    break;
8215
                default:            /* Invalid */
8216
                    MIPS_INVAL("mfmc0");
8217
                    generate_exception(ctx, EXCP_RI);
8218
                    break;
8219
                }
8220
                gen_store_gpr(t0, rt);
8221
                tcg_temp_free(t0);
8222
            }
8223
#endif /* !CONFIG_USER_ONLY */
8224
            break;
8225
        case OPC_RDPGPR:
8226
            check_insn(env, ctx, ISA_MIPS32R2);
8227
            gen_load_srsgpr(rt, rd);
8228
            break;
8229
        case OPC_WRPGPR:
8230
            check_insn(env, ctx, ISA_MIPS32R2);
8231
            gen_store_srsgpr(rt, rd);
8232
            break;
8233
        default:
8234
            MIPS_INVAL("cp0");
8235
            generate_exception(ctx, EXCP_RI);
8236
            break;
8237
        }
8238
        break;
8239
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
8240
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8241
         break;
8242
    case OPC_J ... OPC_JAL: /* Jump */
8243
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8244
         gen_compute_branch(ctx, op, rs, rt, offset);
8245
         return;
8246
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8247
    case OPC_BEQL ... OPC_BGTZL:
8248
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8249
         return;
8250
    case OPC_LB ... OPC_LWR: /* Load and stores */
8251
    case OPC_SB ... OPC_SW:
8252
    case OPC_SWR:
8253
    case OPC_LL:
8254
    case OPC_SC:
8255
         gen_ldst(ctx, op, rt, rs, imm);
8256
         break;
8257
    case OPC_CACHE:
8258
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8259
        /* Treat as NOP. */
8260
        break;
8261
    case OPC_PREF:
8262
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8263
        /* Treat as NOP. */
8264
        break;
8265

    
8266
    /* Floating point (COP1). */
8267
    case OPC_LWC1:
8268
    case OPC_LDC1:
8269
    case OPC_SWC1:
8270
    case OPC_SDC1:
8271
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8272
            save_cpu_state(ctx, 1);
8273
            check_cp1_enabled(ctx);
8274
            gen_flt_ldst(ctx, op, rt, rs, imm);
8275
        } else {
8276
            generate_exception_err(ctx, EXCP_CpU, 1);
8277
        }
8278
        break;
8279

    
8280
    case OPC_CP1:
8281
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8282
            save_cpu_state(ctx, 1);
8283
            check_cp1_enabled(ctx);
8284
            op1 = MASK_CP1(ctx->opcode);
8285
            switch (op1) {
8286
            case OPC_MFHC1:
8287
            case OPC_MTHC1:
8288
                check_insn(env, ctx, ISA_MIPS32R2);
8289
            case OPC_MFC1:
8290
            case OPC_CFC1:
8291
            case OPC_MTC1:
8292
            case OPC_CTC1:
8293
                gen_cp1(ctx, op1, rt, rd);
8294
                break;
8295
#if defined(TARGET_MIPS64)
8296
            case OPC_DMFC1:
8297
            case OPC_DMTC1:
8298
                check_insn(env, ctx, ISA_MIPS3);
8299
                gen_cp1(ctx, op1, rt, rd);
8300
                break;
8301
#endif
8302
            case OPC_BC1ANY2:
8303
            case OPC_BC1ANY4:
8304
                check_cop1x(ctx);
8305
                check_insn(env, ctx, ASE_MIPS3D);
8306
                /* fall through */
8307
            case OPC_BC1:
8308
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8309
                                    (rt >> 2) & 0x7, imm << 2);
8310
                return;
8311
            case OPC_S_FMT:
8312
            case OPC_D_FMT:
8313
            case OPC_W_FMT:
8314
            case OPC_L_FMT:
8315
            case OPC_PS_FMT:
8316
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8317
                           (imm >> 8) & 0x7);
8318
                break;
8319
            default:
8320
                MIPS_INVAL("cp1");
8321
                generate_exception (ctx, EXCP_RI);
8322
                break;
8323
            }
8324
        } else {
8325
            generate_exception_err(ctx, EXCP_CpU, 1);
8326
        }
8327
        break;
8328

    
8329
    /* COP2.  */
8330
    case OPC_LWC2:
8331
    case OPC_LDC2:
8332
    case OPC_SWC2:
8333
    case OPC_SDC2:
8334
    case OPC_CP2:
8335
        /* COP2: Not implemented. */
8336
        generate_exception_err(ctx, EXCP_CpU, 2);
8337
        break;
8338

    
8339
    case OPC_CP3:
8340
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8341
            save_cpu_state(ctx, 1);
8342
            check_cp1_enabled(ctx);
8343
            op1 = MASK_CP3(ctx->opcode);
8344
            switch (op1) {
8345
            case OPC_LWXC1:
8346
            case OPC_LDXC1:
8347
            case OPC_LUXC1:
8348
            case OPC_SWXC1:
8349
            case OPC_SDXC1:
8350
            case OPC_SUXC1:
8351
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8352
                break;
8353
            case OPC_PREFX:
8354
                /* Treat as NOP. */
8355
                break;
8356
            case OPC_ALNV_PS:
8357
            case OPC_MADD_S:
8358
            case OPC_MADD_D:
8359
            case OPC_MADD_PS:
8360
            case OPC_MSUB_S:
8361
            case OPC_MSUB_D:
8362
            case OPC_MSUB_PS:
8363
            case OPC_NMADD_S:
8364
            case OPC_NMADD_D:
8365
            case OPC_NMADD_PS:
8366
            case OPC_NMSUB_S:
8367
            case OPC_NMSUB_D:
8368
            case OPC_NMSUB_PS:
8369
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8370
                break;
8371
            default:
8372
                MIPS_INVAL("cp3");
8373
                generate_exception (ctx, EXCP_RI);
8374
                break;
8375
            }
8376
        } else {
8377
            generate_exception_err(ctx, EXCP_CpU, 1);
8378
        }
8379
        break;
8380

    
8381
#if defined(TARGET_MIPS64)
8382
    /* MIPS64 opcodes */
8383
    case OPC_LWU:
8384
    case OPC_LDL ... OPC_LDR:
8385
    case OPC_SDL ... OPC_SDR:
8386
    case OPC_LLD:
8387
    case OPC_LD:
8388
    case OPC_SCD:
8389
    case OPC_SD:
8390
        check_insn(env, ctx, ISA_MIPS3);
8391
        check_mips_64(ctx);
8392
        gen_ldst(ctx, op, rt, rs, imm);
8393
        break;
8394
    case OPC_DADDI ... OPC_DADDIU:
8395
        check_insn(env, ctx, ISA_MIPS3);
8396
        check_mips_64(ctx);
8397
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8398
        break;
8399
#endif
8400
    case OPC_JALX:
8401
        check_insn(env, ctx, ASE_MIPS16);
8402
        /* MIPS16: Not implemented. */
8403
    case OPC_MDMX:
8404
        check_insn(env, ctx, ASE_MDMX);
8405
        /* MDMX: Not implemented. */
8406
    default:            /* Invalid */
8407
        MIPS_INVAL("major opcode");
8408
        generate_exception(ctx, EXCP_RI);
8409
        break;
8410
    }
8411
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8412
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8413
        /* Branches completion */
8414
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8415
        ctx->bstate = BS_BRANCH;
8416
        save_cpu_state(ctx, 0);
8417
        /* FIXME: Need to clear can_do_io.  */
8418
        switch (hflags) {
8419
        case MIPS_HFLAG_B:
8420
            /* unconditional branch */
8421
            MIPS_DEBUG("unconditional branch");
8422
            gen_goto_tb(ctx, 0, ctx->btarget);
8423
            break;
8424
        case MIPS_HFLAG_BL:
8425
            /* blikely taken case */
8426
            MIPS_DEBUG("blikely branch taken");
8427
            gen_goto_tb(ctx, 0, ctx->btarget);
8428
            break;
8429
        case MIPS_HFLAG_BC:
8430
            /* Conditional branch */
8431
            MIPS_DEBUG("conditional branch");
8432
            {
8433
                int l1 = gen_new_label();
8434

    
8435
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8436
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8437
                gen_set_label(l1);
8438
                gen_goto_tb(ctx, 0, ctx->btarget);
8439
            }
8440
            break;
8441
        case MIPS_HFLAG_BR:
8442
            /* unconditional branch to register */
8443
            MIPS_DEBUG("branch to register");
8444
            tcg_gen_st_tl(btarget, cpu_env, offsetof(CPUState, active_tc.PC));
8445
            tcg_gen_exit_tb(0);
8446
            break;
8447
        default:
8448
            MIPS_DEBUG("unknown branch");
8449
            break;
8450
        }
8451
    }
8452
}
8453

    
8454
static inline void
8455
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8456
                                int search_pc)
8457
{
8458
    DisasContext ctx;
8459
    target_ulong pc_start;
8460
    uint16_t *gen_opc_end;
8461
    int j, lj = -1;
8462
    int num_insns;
8463
    int max_insns;
8464

    
8465
    if (search_pc && loglevel)
8466
        fprintf (logfile, "search pc %d\n", search_pc);
8467

    
8468
    pc_start = tb->pc;
8469
    /* Leave some spare opc slots for branch handling. */
8470
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8471
    ctx.pc = pc_start;
8472
    ctx.saved_pc = -1;
8473
    ctx.tb = tb;
8474
    ctx.bstate = BS_NONE;
8475
    /* Restore delay slot state from the tb context.  */
8476
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8477
    restore_cpu_state(env, &ctx);
8478
    if (env->user_mode_only)
8479
        ctx.mem_idx = MIPS_HFLAG_UM;
8480
    else
8481
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8482
    num_insns = 0;
8483
    max_insns = tb->cflags & CF_COUNT_MASK;
8484
    if (max_insns == 0)
8485
        max_insns = CF_COUNT_MASK;
8486
#ifdef DEBUG_DISAS
8487
    if (loglevel & CPU_LOG_TB_CPU) {
8488
        fprintf(logfile, "------------------------------------------------\n");
8489
        /* FIXME: This may print out stale hflags from env... */
8490
        cpu_dump_state(env, logfile, fprintf, 0);
8491
    }
8492
#endif
8493
#ifdef MIPS_DEBUG_DISAS
8494
    if (loglevel & CPU_LOG_TB_IN_ASM)
8495
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
8496
                tb, ctx.mem_idx, ctx.hflags);
8497
#endif
8498
    gen_icount_start();
8499
    while (ctx.bstate == BS_NONE) {
8500
        if (env->nb_breakpoints > 0) {
8501
            for(j = 0; j < env->nb_breakpoints; j++) {
8502
                if (env->breakpoints[j] == ctx.pc) {
8503
                    save_cpu_state(&ctx, 1);
8504
                    ctx.bstate = BS_BRANCH;
8505
                    tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8506
                    /* Include the breakpoint location or the tb won't
8507
                     * be flushed when it must be.  */
8508
                    ctx.pc += 4;
8509
                    goto done_generating;
8510
                }
8511
            }
8512
        }
8513

    
8514
        if (search_pc) {
8515
            j = gen_opc_ptr - gen_opc_buf;
8516
            if (lj < j) {
8517
                lj++;
8518
                while (lj < j)
8519
                    gen_opc_instr_start[lj++] = 0;
8520
            }
8521
            gen_opc_pc[lj] = ctx.pc;
8522
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8523
            gen_opc_instr_start[lj] = 1;
8524
            gen_opc_icount[lj] = num_insns;
8525
        }
8526
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8527
            gen_io_start();
8528
        ctx.opcode = ldl_code(ctx.pc);
8529
        decode_opc(env, &ctx);
8530
        ctx.pc += 4;
8531
        num_insns++;
8532

    
8533
        if (env->singlestep_enabled)
8534
            break;
8535

    
8536
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8537
            break;
8538

    
8539
        if (gen_opc_ptr >= gen_opc_end)
8540
            break;
8541

    
8542
        if (num_insns >= max_insns)
8543
            break;
8544
#if defined (MIPS_SINGLE_STEP)
8545
        break;
8546
#endif
8547
    }
8548
    if (tb->cflags & CF_LAST_IO)
8549
        gen_io_end();
8550
    if (env->singlestep_enabled) {
8551
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8552
        tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8553
    } else {
8554
        switch (ctx.bstate) {
8555
        case BS_STOP:
8556
            tcg_gen_helper_0_0(do_interrupt_restart);
8557
            gen_goto_tb(&ctx, 0, ctx.pc);
8558
            break;
8559
        case BS_NONE:
8560
            save_cpu_state(&ctx, 0);
8561
            gen_goto_tb(&ctx, 0, ctx.pc);
8562
            break;
8563
        case BS_EXCP:
8564
            tcg_gen_helper_0_0(do_interrupt_restart);
8565
            tcg_gen_exit_tb(0);
8566
            break;
8567
        case BS_BRANCH:
8568
        default:
8569
            break;
8570
        }
8571
    }
8572
done_generating:
8573
    gen_icount_end(tb, num_insns);
8574
    *gen_opc_ptr = INDEX_op_end;
8575
    if (search_pc) {
8576
        j = gen_opc_ptr - gen_opc_buf;
8577
        lj++;
8578
        while (lj <= j)
8579
            gen_opc_instr_start[lj++] = 0;
8580
    } else {
8581
        tb->size = ctx.pc - pc_start;
8582
        tb->icount = num_insns;
8583
    }
8584
#ifdef DEBUG_DISAS
8585
#if defined MIPS_DEBUG_DISAS
8586
    if (loglevel & CPU_LOG_TB_IN_ASM)
8587
        fprintf(logfile, "\n");
8588
#endif
8589
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8590
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8591
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
8592
        fprintf(logfile, "\n");
8593
    }
8594
    if (loglevel & CPU_LOG_TB_CPU) {
8595
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8596
    }
8597
#endif
8598
}
8599

    
8600
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8601
{
8602
    gen_intermediate_code_internal(env, tb, 0);
8603
}
8604

    
8605
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8606
{
8607
    gen_intermediate_code_internal(env, tb, 1);
8608
}
8609

    
8610
static void fpu_dump_state(CPUState *env, FILE *f,
8611
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8612
                           int flags)
8613
{
8614
    int i;
8615
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8616

    
8617
#define printfpr(fp)                                                        \
8618
    do {                                                                    \
8619
        if (is_fpu64)                                                       \
8620
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8621
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8622
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8623
        else {                                                              \
8624
            fpr_t tmp;                                                      \
8625
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8626
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8627
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8628
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8629
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8630
        }                                                                   \
8631
    } while(0)
8632

    
8633

    
8634
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8635
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8636
                get_float_exception_flags(&env->active_fpu.fp_status));
8637
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8638
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8639
        printfpr(&env->active_fpu.fpr[i]);
8640
    }
8641

    
8642
#undef printfpr
8643
}
8644

    
8645
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8646
/* Debug help: The architecture requires 32bit code to maintain proper
8647
   sign-extended values on 64bit machines.  */
8648

    
8649
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8650

    
8651
static void
8652
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8653
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8654
                                int flags)
8655
{
8656
    int i;
8657

    
8658
    if (!SIGN_EXT_P(env->active_tc.PC))
8659
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8660
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8661
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8662
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8663
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8664
    if (!SIGN_EXT_P(env->btarget))
8665
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8666

    
8667
    for (i = 0; i < 32; i++) {
8668
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8669
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8670
    }
8671

    
8672
    if (!SIGN_EXT_P(env->CP0_EPC))
8673
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8674
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8675
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8676
}
8677
#endif
8678

    
8679
void cpu_dump_state (CPUState *env, FILE *f,
8680
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8681
                     int flags)
8682
{
8683
    int i;
8684

    
8685
    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",
8686
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8687
                env->hflags, env->btarget, env->bcond);
8688
    for (i = 0; i < 32; i++) {
8689
        if ((i & 3) == 0)
8690
            cpu_fprintf(f, "GPR%02d:", i);
8691
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8692
        if ((i & 3) == 3)
8693
            cpu_fprintf(f, "\n");
8694
    }
8695

    
8696
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8697
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8698
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8699
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8700
    if (env->hflags & MIPS_HFLAG_FPU)
8701
        fpu_dump_state(env, f, cpu_fprintf, flags);
8702
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8703
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8704
#endif
8705
}
8706

    
8707
static void mips_tcg_init(void)
8708
{
8709
    int i;
8710
    static int inited;
8711

    
8712
    /* Initialize various static tables. */
8713
    if (inited)
8714
        return;
8715

    
8716
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8717
    bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8718
                               offsetof(CPUState, bcond), "bcond");
8719
    btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8720
                                 offsetof(CPUState, btarget), "btarget");
8721
    for (i = 0; i < 32; i++)
8722
        fpu_fpr32[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8723
                                          offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8724
                                          fregnames[i]);
8725
    for (i = 0; i < 32; i++)
8726
        fpu_fpr64[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
8727
                                          offsetof(CPUState, active_fpu.fpr[i]),
8728
                                          fregnames_64[i]);
8729
    for (i = 0; i < 32; i++)
8730
        fpu_fpr32h[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8731
                                           offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8732
                                           fregnames_h[i]);
8733
    fpu_fcr0 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8734
                                   offsetof(CPUState, active_fpu.fcr0),
8735
                                   "fcr0");
8736
    fpu_fcr31 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8737
                                   offsetof(CPUState, active_fpu.fcr31),
8738
                                   "fcr31");
8739

    
8740
    /* register helpers */
8741
#undef DEF_HELPER
8742
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8743
#include "helper.h"
8744

    
8745
    inited = 1;
8746
}
8747

    
8748
#include "translate_init.c"
8749

    
8750
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8751
{
8752
    CPUMIPSState *env;
8753
    const mips_def_t *def;
8754

    
8755
    def = cpu_mips_find_by_name(cpu_model);
8756
    if (!def)
8757
        return NULL;
8758
    env = qemu_mallocz(sizeof(CPUMIPSState));
8759
    if (!env)
8760
        return NULL;
8761
    env->cpu_model = def;
8762

    
8763
    cpu_exec_init(env);
8764
    env->cpu_model_str = cpu_model;
8765
    mips_tcg_init();
8766
    cpu_reset(env);
8767
    return env;
8768
}
8769

    
8770
void cpu_reset (CPUMIPSState *env)
8771
{
8772
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8773

    
8774
    tlb_flush(env, 1);
8775

    
8776
    /* Minimal init */
8777
#if defined(CONFIG_USER_ONLY)
8778
    env->user_mode_only = 1;
8779
#endif
8780
    if (env->user_mode_only) {
8781
        env->hflags = MIPS_HFLAG_UM;
8782
    } else {
8783
        if (env->hflags & MIPS_HFLAG_BMASK) {
8784
            /* If the exception was raised from a delay slot,
8785
               come back to the jump.  */
8786
            env->CP0_ErrorEPC = env->active_tc.PC - 4;
8787
        } else {
8788
            env->CP0_ErrorEPC = env->active_tc.PC;
8789
        }
8790
        env->active_tc.PC = (int32_t)0xBFC00000;
8791
        env->CP0_Wired = 0;
8792
        /* SMP not implemented */
8793
        env->CP0_EBase = 0x80000000;
8794
        env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8795
        /* vectored interrupts not implemented, timer on int 7,
8796
           no performance counters. */
8797
        env->CP0_IntCtl = 0xe0000000;
8798
        {
8799
            int i;
8800

    
8801
            for (i = 0; i < 7; i++) {
8802
                env->CP0_WatchLo[i] = 0;
8803
                env->CP0_WatchHi[i] = 0x80000000;
8804
            }
8805
            env->CP0_WatchLo[7] = 0;
8806
            env->CP0_WatchHi[7] = 0;
8807
        }
8808
        /* Count register increments in debug mode, EJTAG version 1 */
8809
        env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8810
        env->hflags = MIPS_HFLAG_CP0;
8811
    }
8812
    env->exception_index = EXCP_NONE;
8813
    cpu_mips_register(env, env->cpu_model);
8814
}
8815

    
8816
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8817
                unsigned long searched_pc, int pc_pos, void *puc)
8818
{
8819
    env->active_tc.PC = gen_opc_pc[pc_pos];
8820
    env->hflags &= ~MIPS_HFLAG_BMASK;
8821
    env->hflags |= gen_opc_hflags[pc_pos];
8822
}