Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 6d066274

History | View | Annotate | Download (243.5 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., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 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 "tcg-op.h"
33
#include "qemu-common.h"
34

    
35
#include "helper.h"
36
#define GEN_HELPER 1
37
#include "helper.h"
38

    
39
//#define MIPS_DEBUG_DISAS
40
//#define MIPS_DEBUG_SIGN_EXTENSIONS
41
//#define MIPS_SINGLE_STEP
42

    
43
/* MIPS major opcodes */
44
#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
45

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

    
121
/* MIPS special opcodes */
122
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
123

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

    
187
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
188

    
189
    /* Special */
190
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
191
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
192
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
193
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
194
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
195

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

    
205
/* Multiplication variants of the vr54xx. */
206
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
207

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

    
225
/* REGIMM (rt field) opcodes */
226
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
227

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

    
246
/* Special2 opcodes */
247
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
248

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

    
265
/* Special3 opcodes */
266
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
267

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

    
284
/* BSHFL opcodes */
285
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
286

    
287
enum {
288
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
289
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
290
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
291
};
292

    
293
/* DBSHFL opcodes */
294
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
295

    
296
enum {
297
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
298
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
299
};
300

    
301
/* Coprocessor 0 (rs field) */
302
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
303

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

    
319
/* MFMC0 opcodes */
320
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
321

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

    
331
/* Coprocessor 0 (with rs == C0) */
332
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
333

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

    
345
/* Coprocessor 1 (rs field) */
346
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
347

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

    
369
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
370
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
371

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

    
379
enum {
380
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
381
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
382
};
383

    
384
enum {
385
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
386
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
387
};
388

    
389
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
390

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

    
403
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
404

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

    
428
/* global register indices */
429
static TCGv_ptr cpu_env;
430
static TCGv cpu_gpr[32], cpu_PC;
431
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
432
static TCGv cpu_dspctrl, btarget, bcond;
433
static TCGv_i32 hflags;
434
static TCGv_i32 fpu_fcr0, fpu_fcr31;
435

    
436
#include "gen-icount.h"
437

    
438
#define gen_helper_0i(name, arg) do {                             \
439
    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
440
    gen_helper_##name(helper_tmp);                                \
441
    tcg_temp_free_i32(helper_tmp);                                \
442
    } while(0)
443

    
444
#define gen_helper_1i(name, arg1, arg2) do {                      \
445
    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
446
    gen_helper_##name(arg1, helper_tmp);                          \
447
    tcg_temp_free_i32(helper_tmp);                                \
448
    } while(0)
449

    
450
#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
451
    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
452
    gen_helper_##name(arg1, arg2, helper_tmp);                    \
453
    tcg_temp_free_i32(helper_tmp);                                \
454
    } while(0)
455

    
456
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
457
    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
458
    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
459
    tcg_temp_free_i32(helper_tmp);                                \
460
    } while(0)
461

    
462
typedef struct DisasContext {
463
    struct TranslationBlock *tb;
464
    target_ulong pc, saved_pc;
465
    uint32_t opcode;
466
    /* Routine used to access memory */
467
    int mem_idx;
468
    uint32_t hflags, saved_hflags;
469
    int bstate;
470
    target_ulong btarget;
471
} DisasContext;
472

    
473
enum {
474
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
475
                      * exception condition */
476
    BS_STOP     = 1, /* We want to stop translation for any reason */
477
    BS_BRANCH   = 2, /* We reached a branch condition     */
478
    BS_EXCP     = 3, /* We reached an exception condition */
479
};
480

    
481
static const char *regnames[] =
482
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
483
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
484
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
485
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
486

    
487
static const char *regnames_HI[] =
488
    { "HI0", "HI1", "HI2", "HI3", };
489

    
490
static const char *regnames_LO[] =
491
    { "LO0", "LO1", "LO2", "LO3", };
492

    
493
static const char *regnames_ACX[] =
494
    { "ACX0", "ACX1", "ACX2", "ACX3", };
495

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

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

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

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

    
528
static inline void gen_store_gpr (TCGv t, int reg)
529
{
530
    if (reg != 0)
531
        tcg_gen_mov_tl(cpu_gpr[reg], t);
532
}
533

    
534
/* Moves to/from ACX register.  */
535
static inline void gen_load_ACX (TCGv t, int reg)
536
{
537
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
538
}
539

    
540
static inline void gen_store_ACX (TCGv t, int reg)
541
{
542
    tcg_gen_mov_tl(cpu_ACX[reg], t);
543
}
544

    
545
/* Moves to/from shadow registers. */
546
static inline void gen_load_srsgpr (int from, int to)
547
{
548
    TCGv r_tmp1 = tcg_temp_new();
549

    
550
    if (from == 0)
551
        tcg_gen_movi_tl(r_tmp1, 0);
552
    else {
553
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
554
        TCGv_ptr addr = tcg_temp_new_ptr();
555

    
556
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
557
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
558
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
559
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
560
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
561
        tcg_gen_add_ptr(addr, cpu_env, addr);
562

    
563
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
564
        tcg_temp_free_ptr(addr);
565
        tcg_temp_free_i32(r_tmp2);
566
    }
567
    gen_store_gpr(r_tmp1, to);
568
    tcg_temp_free(r_tmp1);
569
}
570

    
571
static inline void gen_store_srsgpr (int from, int to)
572
{
573
    if (to != 0) {
574
        TCGv r_tmp1 = tcg_temp_new();
575
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
576
        TCGv_ptr addr = tcg_temp_new_ptr();
577

    
578
        gen_load_gpr(r_tmp1, from);
579
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
580
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
581
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
582
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
583
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
584
        tcg_gen_add_ptr(addr, cpu_env, addr);
585

    
586
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
587
        tcg_temp_free_ptr(addr);
588
        tcg_temp_free_i32(r_tmp2);
589
        tcg_temp_free(r_tmp1);
590
    }
591
}
592

    
593
/* Floating point register moves. */
594
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
595
{
596
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
597
}
598

    
599
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
600
{
601
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
602
}
603

    
604
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
605
{
606
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
607
}
608

    
609
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
610
{
611
    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
612
}
613

    
614
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
615
{
616
    if (ctx->hflags & MIPS_HFLAG_F64) {
617
        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
618
    } else {
619
        TCGv_i32 t0 = tcg_temp_new_i32();
620
        TCGv_i32 t1 = tcg_temp_new_i32();
621
        gen_load_fpr32(t0, reg & ~1);
622
        gen_load_fpr32(t1, reg | 1);
623
        tcg_gen_concat_i32_i64(t, t0, t1);
624
        tcg_temp_free_i32(t0);
625
        tcg_temp_free_i32(t1);
626
    }
627
}
628

    
629
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
630
{
631
    if (ctx->hflags & MIPS_HFLAG_F64) {
632
        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
633
    } else {
634
        TCGv_i64 t0 = tcg_temp_new_i64();
635
        TCGv_i32 t1 = tcg_temp_new_i32();
636
        tcg_gen_trunc_i64_i32(t1, t);
637
        gen_store_fpr32(t1, reg & ~1);
638
        tcg_gen_shri_i64(t0, t, 32);
639
        tcg_gen_trunc_i64_i32(t1, t0);
640
        gen_store_fpr32(t1, reg | 1);
641
        tcg_temp_free_i32(t1);
642
        tcg_temp_free_i64(t0);
643
    }
644
}
645

    
646
static inline void get_fp_cond (TCGv_i32 t)
647
{
648
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
649
    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
650

    
651
    tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
652
    tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
653
    tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
654
    tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
655
    tcg_gen_or_i32(t, r_tmp1, r_tmp2);
656
    tcg_temp_free_i32(r_tmp1);
657
    tcg_temp_free_i32(r_tmp2);
658
}
659

    
660
#define FOP_CONDS(type, fmt, bits)                                            \
661
static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
662
                                               TCGv_i##bits b, int cc)        \
663
{                                                                             \
664
    switch (n) {                                                              \
665
    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
666
    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
667
    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
668
    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
669
    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
670
    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
671
    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
672
    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
673
    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
674
    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
675
    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
676
    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
677
    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
678
    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
679
    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
680
    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
681
    default: abort();                                                         \
682
    }                                                                         \
683
}
684

    
685
FOP_CONDS(, d, 64)
686
FOP_CONDS(abs, d, 64)
687
FOP_CONDS(, s, 32)
688
FOP_CONDS(abs, s, 32)
689
FOP_CONDS(, ps, 64)
690
FOP_CONDS(abs, ps, 64)
691
#undef FOP_CONDS
692

    
693
/* Tests */
694
#define OP_COND(name, cond)                                         \
695
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
696
{                                                                   \
697
    int l1 = gen_new_label();                                       \
698
    int l2 = gen_new_label();                                       \
699
                                                                    \
700
    tcg_gen_brcond_tl(cond, t0, t1, l1);                            \
701
    tcg_gen_movi_tl(ret, 0);                                        \
702
    tcg_gen_br(l2);                                                 \
703
    gen_set_label(l1);                                              \
704
    tcg_gen_movi_tl(ret, 1);                                        \
705
    gen_set_label(l2);                                              \
706
}
707
OP_COND(eq, TCG_COND_EQ);
708
OP_COND(ne, TCG_COND_NE);
709
OP_COND(ge, TCG_COND_GE);
710
OP_COND(geu, TCG_COND_GEU);
711
OP_COND(lt, TCG_COND_LT);
712
OP_COND(ltu, TCG_COND_LTU);
713
#undef OP_COND
714

    
715
#define OP_CONDI(name, cond)                                                 \
716
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
717
{                                                                            \
718
    int l1 = gen_new_label();                                                \
719
    int l2 = gen_new_label();                                                \
720
                                                                             \
721
    tcg_gen_brcondi_tl(cond, t0, val, l1);                                   \
722
    tcg_gen_movi_tl(ret, 0);                                                 \
723
    tcg_gen_br(l2);                                                          \
724
    gen_set_label(l1);                                                       \
725
    tcg_gen_movi_tl(ret, 1);                                                 \
726
    gen_set_label(l2);                                                       \
727
}
728
OP_CONDI(lti, TCG_COND_LT);
729
OP_CONDI(ltiu, TCG_COND_LTU);
730
#undef OP_CONDI
731

    
732
#define OP_CONDZ(name, cond)                                  \
733
static inline void glue(gen_op_, name) (TCGv ret, TCGv t0)    \
734
{                                                             \
735
    int l1 = gen_new_label();                                 \
736
    int l2 = gen_new_label();                                 \
737
                                                              \
738
    tcg_gen_brcondi_tl(cond, t0, 0, l1);                      \
739
    tcg_gen_movi_tl(ret, 0);                                  \
740
    tcg_gen_br(l2);                                           \
741
    gen_set_label(l1);                                        \
742
    tcg_gen_movi_tl(ret, 1);                                  \
743
    gen_set_label(l2);                                        \
744
}
745
OP_CONDZ(gez, TCG_COND_GE);
746
OP_CONDZ(gtz, TCG_COND_GT);
747
OP_CONDZ(lez, TCG_COND_LE);
748
OP_CONDZ(ltz, TCG_COND_LT);
749
#undef OP_CONDZ
750

    
751
static inline void gen_save_pc(target_ulong pc)
752
{
753
    tcg_gen_movi_tl(cpu_PC, pc);
754
}
755

    
756
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
757
{
758
    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
759
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
760
        gen_save_pc(ctx->pc);
761
        ctx->saved_pc = ctx->pc;
762
    }
763
    if (ctx->hflags != ctx->saved_hflags) {
764
        tcg_gen_movi_i32(hflags, ctx->hflags);
765
        ctx->saved_hflags = ctx->hflags;
766
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
767
        case MIPS_HFLAG_BR:
768
            break;
769
        case MIPS_HFLAG_BC:
770
        case MIPS_HFLAG_BL:
771
        case MIPS_HFLAG_B:
772
            tcg_gen_movi_tl(btarget, ctx->btarget);
773
            break;
774
        }
775
    }
776
}
777

    
778
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
779
{
780
    ctx->saved_hflags = ctx->hflags;
781
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
782
    case MIPS_HFLAG_BR:
783
        break;
784
    case MIPS_HFLAG_BC:
785
    case MIPS_HFLAG_BL:
786
    case MIPS_HFLAG_B:
787
        ctx->btarget = env->btarget;
788
        break;
789
    }
790
}
791

    
792
static inline void
793
generate_exception_err (DisasContext *ctx, int excp, int err)
794
{
795
    TCGv_i32 texcp = tcg_const_i32(excp);
796
    TCGv_i32 terr = tcg_const_i32(err);
797
    save_cpu_state(ctx, 1);
798
    gen_helper_raise_exception_err(texcp, terr);
799
    tcg_temp_free_i32(terr);
800
    tcg_temp_free_i32(texcp);
801
    gen_helper_interrupt_restart();
802
    tcg_gen_exit_tb(0);
803
}
804

    
805
static inline void
806
generate_exception (DisasContext *ctx, int excp)
807
{
808
    save_cpu_state(ctx, 1);
809
    gen_helper_0i(raise_exception, excp);
810
    gen_helper_interrupt_restart();
811
    tcg_gen_exit_tb(0);
812
}
813

    
814
/* Addresses computation */
815
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
816
{
817
    tcg_gen_add_tl(t0, t0, t1);
818

    
819
#if defined(TARGET_MIPS64)
820
    /* For compatibility with 32-bit code, data reference in user mode
821
       with Status_UX = 0 should be casted to 32-bit and sign extended.
822
       See the MIPS64 PRA manual, section 4.10. */
823
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
824
        !(ctx->hflags & MIPS_HFLAG_UX)) {
825
        tcg_gen_ext32s_i64(t0, t0);
826
    }
827
#endif
828
}
829

    
830
static inline void check_cp0_enabled(DisasContext *ctx)
831
{
832
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
833
        generate_exception_err(ctx, EXCP_CpU, 1);
834
}
835

    
836
static inline void check_cp1_enabled(DisasContext *ctx)
837
{
838
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
839
        generate_exception_err(ctx, EXCP_CpU, 1);
840
}
841

    
842
/* Verify that the processor is running with COP1X instructions enabled.
843
   This is associated with the nabla symbol in the MIPS32 and MIPS64
844
   opcode tables.  */
845

    
846
static inline void check_cop1x(DisasContext *ctx)
847
{
848
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
849
        generate_exception(ctx, EXCP_RI);
850
}
851

    
852
/* Verify that the processor is running with 64-bit floating-point
853
   operations enabled.  */
854

    
855
static inline void check_cp1_64bitmode(DisasContext *ctx)
856
{
857
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
858
        generate_exception(ctx, EXCP_RI);
859
}
860

    
861
/*
862
 * Verify if floating point register is valid; an operation is not defined
863
 * if bit 0 of any register specification is set and the FR bit in the
864
 * Status register equals zero, since the register numbers specify an
865
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
866
 * in the Status register equals one, both even and odd register numbers
867
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
868
 *
869
 * Multiple 64 bit wide registers can be checked by calling
870
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
871
 */
872
static inline void check_cp1_registers(DisasContext *ctx, int regs)
873
{
874
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
875
        generate_exception(ctx, EXCP_RI);
876
}
877

    
878
/* This code generates a "reserved instruction" exception if the
879
   CPU does not support the instruction set corresponding to flags. */
880
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
881
{
882
    if (unlikely(!(env->insn_flags & flags)))
883
        generate_exception(ctx, EXCP_RI);
884
}
885

    
886
/* This code generates a "reserved instruction" exception if 64-bit
887
   instructions are not enabled. */
888
static inline void check_mips_64(DisasContext *ctx)
889
{
890
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
891
        generate_exception(ctx, EXCP_RI);
892
}
893

    
894
/* load/store instructions. */
895
#define OP_LD(insn,fname)                                        \
896
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
897
{                                                                \
898
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
899
}
900
OP_LD(lb,ld8s);
901
OP_LD(lbu,ld8u);
902
OP_LD(lh,ld16s);
903
OP_LD(lhu,ld16u);
904
OP_LD(lw,ld32s);
905
#if defined(TARGET_MIPS64)
906
OP_LD(lwu,ld32u);
907
OP_LD(ld,ld64);
908
#endif
909
#undef OP_LD
910

    
911
#define OP_ST(insn,fname)                                        \
912
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
913
{                                                                \
914
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
915
}
916
OP_ST(sb,st8);
917
OP_ST(sh,st16);
918
OP_ST(sw,st32);
919
#if defined(TARGET_MIPS64)
920
OP_ST(sd,st64);
921
#endif
922
#undef OP_ST
923

    
924
#define OP_LD_ATOMIC(insn,fname)                                        \
925
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
926
{                                                                       \
927
    tcg_gen_mov_tl(t1, t0);                                             \
928
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
929
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
930
}
931
OP_LD_ATOMIC(ll,ld32s);
932
#if defined(TARGET_MIPS64)
933
OP_LD_ATOMIC(lld,ld64);
934
#endif
935
#undef OP_LD_ATOMIC
936

    
937
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
938
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
939
{                                                                       \
940
    TCGv r_tmp = tcg_temp_local_new();                       \
941
    int l1 = gen_new_label();                                           \
942
    int l2 = gen_new_label();                                           \
943
    int l3 = gen_new_label();                                           \
944
                                                                        \
945
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
946
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
947
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
948
    generate_exception(ctx, EXCP_AdES);                                 \
949
    gen_set_label(l1);                                                  \
950
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
951
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
952
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
953
    tcg_gen_movi_tl(t0, 1);                                             \
954
    tcg_gen_br(l3);                                                     \
955
    gen_set_label(l2);                                                  \
956
    tcg_gen_movi_tl(t0, 0);                                             \
957
    gen_set_label(l3);                                                  \
958
    tcg_temp_free(r_tmp);                                               \
959
}
960
OP_ST_ATOMIC(sc,st32,0x3);
961
#if defined(TARGET_MIPS64)
962
OP_ST_ATOMIC(scd,st64,0x7);
963
#endif
964
#undef OP_ST_ATOMIC
965

    
966
/* Load and store */
967
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
968
                      int base, int16_t offset)
969
{
970
    const char *opn = "ldst";
971
    TCGv t0 = tcg_temp_local_new();
972
    TCGv t1 = tcg_temp_local_new();
973

    
974
    if (base == 0) {
975
        tcg_gen_movi_tl(t0, offset);
976
    } else if (offset == 0) {
977
        gen_load_gpr(t0, base);
978
    } else {
979
        tcg_gen_movi_tl(t0, offset);
980
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
981
    }
982
    /* Don't do NOP if destination is zero: we must perform the actual
983
       memory access. */
984
    switch (opc) {
985
#if defined(TARGET_MIPS64)
986
    case OPC_LWU:
987
        op_ldst_lwu(t0, ctx);
988
        gen_store_gpr(t0, rt);
989
        opn = "lwu";
990
        break;
991
    case OPC_LD:
992
        op_ldst_ld(t0, ctx);
993
        gen_store_gpr(t0, rt);
994
        opn = "ld";
995
        break;
996
    case OPC_LLD:
997
        op_ldst_lld(t0, t1, ctx);
998
        gen_store_gpr(t0, rt);
999
        opn = "lld";
1000
        break;
1001
    case OPC_SD:
1002
        gen_load_gpr(t1, rt);
1003
        op_ldst_sd(t0, t1, ctx);
1004
        opn = "sd";
1005
        break;
1006
    case OPC_SCD:
1007
        save_cpu_state(ctx, 1);
1008
        gen_load_gpr(t1, rt);
1009
        op_ldst_scd(t0, t1, ctx);
1010
        gen_store_gpr(t0, rt);
1011
        opn = "scd";
1012
        break;
1013
    case OPC_LDL:
1014
        save_cpu_state(ctx, 1);
1015
        gen_load_gpr(t1, rt);
1016
        gen_helper_3i(ldl, t1, t0, t1, ctx->mem_idx);
1017
        gen_store_gpr(t1, rt);
1018
        opn = "ldl";
1019
        break;
1020
    case OPC_SDL:
1021
        save_cpu_state(ctx, 1);
1022
        gen_load_gpr(t1, rt);
1023
        gen_helper_2i(sdl, t0, t1, ctx->mem_idx);
1024
        opn = "sdl";
1025
        break;
1026
    case OPC_LDR:
1027
        save_cpu_state(ctx, 1);
1028
        gen_load_gpr(t1, rt);
1029
        gen_helper_3i(ldr, t1, t0, t1, ctx->mem_idx);
1030
        gen_store_gpr(t1, rt);
1031
        opn = "ldr";
1032
        break;
1033
    case OPC_SDR:
1034
        save_cpu_state(ctx, 1);
1035
        gen_load_gpr(t1, rt);
1036
        gen_helper_2i(sdr, t0, t1, ctx->mem_idx);
1037
        opn = "sdr";
1038
        break;
1039
#endif
1040
    case OPC_LW:
1041
        op_ldst_lw(t0, ctx);
1042
        gen_store_gpr(t0, rt);
1043
        opn = "lw";
1044
        break;
1045
    case OPC_SW:
1046
        gen_load_gpr(t1, rt);
1047
        op_ldst_sw(t0, t1, ctx);
1048
        opn = "sw";
1049
        break;
1050
    case OPC_LH:
1051
        op_ldst_lh(t0, ctx);
1052
        gen_store_gpr(t0, rt);
1053
        opn = "lh";
1054
        break;
1055
    case OPC_SH:
1056
        gen_load_gpr(t1, rt);
1057
        op_ldst_sh(t0, t1, ctx);
1058
        opn = "sh";
1059
        break;
1060
    case OPC_LHU:
1061
        op_ldst_lhu(t0, ctx);
1062
        gen_store_gpr(t0, rt);
1063
        opn = "lhu";
1064
        break;
1065
    case OPC_LB:
1066
        op_ldst_lb(t0, ctx);
1067
        gen_store_gpr(t0, rt);
1068
        opn = "lb";
1069
        break;
1070
    case OPC_SB:
1071
        gen_load_gpr(t1, rt);
1072
        op_ldst_sb(t0, t1, ctx);
1073
        opn = "sb";
1074
        break;
1075
    case OPC_LBU:
1076
        op_ldst_lbu(t0, ctx);
1077
        gen_store_gpr(t0, rt);
1078
        opn = "lbu";
1079
        break;
1080
    case OPC_LWL:
1081
        save_cpu_state(ctx, 1);
1082
        gen_load_gpr(t1, rt);
1083
        gen_helper_3i(lwl, t1, t0, t1, ctx->mem_idx);
1084
        gen_store_gpr(t1, rt);
1085
        opn = "lwl";
1086
        break;
1087
    case OPC_SWL:
1088
        save_cpu_state(ctx, 1);
1089
        gen_load_gpr(t1, rt);
1090
        gen_helper_2i(swl, t0, t1, ctx->mem_idx);
1091
        opn = "swr";
1092
        break;
1093
    case OPC_LWR:
1094
        save_cpu_state(ctx, 1);
1095
        gen_load_gpr(t1, rt);
1096
        gen_helper_3i(lwr, t1, t0, t1, ctx->mem_idx);
1097
        gen_store_gpr(t1, rt);
1098
        opn = "lwr";
1099
        break;
1100
    case OPC_SWR:
1101
        save_cpu_state(ctx, 1);
1102
        gen_load_gpr(t1, rt);
1103
        gen_helper_2i(swr, t0, t1, ctx->mem_idx);
1104
        opn = "swr";
1105
        break;
1106
    case OPC_LL:
1107
        op_ldst_ll(t0, t1, ctx);
1108
        gen_store_gpr(t0, rt);
1109
        opn = "ll";
1110
        break;
1111
    case OPC_SC:
1112
        save_cpu_state(ctx, 1);
1113
        gen_load_gpr(t1, rt);
1114
        op_ldst_sc(t0, t1, ctx);
1115
        gen_store_gpr(t0, rt);
1116
        opn = "sc";
1117
        break;
1118
    default:
1119
        MIPS_INVAL(opn);
1120
        generate_exception(ctx, EXCP_RI);
1121
        goto out;
1122
    }
1123
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1124
 out:
1125
    tcg_temp_free(t0);
1126
    tcg_temp_free(t1);
1127
}
1128

    
1129
/* Load and store */
1130
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1131
                          int base, int16_t offset)
1132
{
1133
    const char *opn = "flt_ldst";
1134
    TCGv t0 = tcg_temp_local_new();
1135

    
1136
    if (base == 0) {
1137
        tcg_gen_movi_tl(t0, offset);
1138
    } else if (offset == 0) {
1139
        gen_load_gpr(t0, base);
1140
    } else {
1141
        tcg_gen_movi_tl(t0, offset);
1142
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1143
    }
1144
    /* Don't do NOP if destination is zero: we must perform the actual
1145
       memory access. */
1146
    switch (opc) {
1147
    case OPC_LWC1:
1148
        {
1149
            TCGv_i32 fp0 = tcg_temp_new_i32();
1150
            TCGv t1 = tcg_temp_new();
1151

    
1152
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1153
            tcg_gen_trunc_tl_i32(fp0, t1);
1154
            gen_store_fpr32(fp0, ft);
1155
            tcg_temp_free(t1);
1156
            tcg_temp_free_i32(fp0);
1157
        }
1158
        opn = "lwc1";
1159
        break;
1160
    case OPC_SWC1:
1161
        {
1162
            TCGv_i32 fp0 = tcg_temp_new_i32();
1163
            TCGv t1 = tcg_temp_new();
1164

    
1165
            gen_load_fpr32(fp0, ft);
1166
            tcg_gen_extu_i32_tl(t1, fp0);
1167
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1168
            tcg_temp_free(t1);
1169
            tcg_temp_free_i32(fp0);
1170
        }
1171
        opn = "swc1";
1172
        break;
1173
    case OPC_LDC1:
1174
        {
1175
            TCGv_i64 fp0 = tcg_temp_new_i64();
1176

    
1177
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1178
            gen_store_fpr64(ctx, fp0, ft);
1179
            tcg_temp_free_i64(fp0);
1180
        }
1181
        opn = "ldc1";
1182
        break;
1183
    case OPC_SDC1:
1184
        {
1185
            TCGv_i64 fp0 = tcg_temp_new_i64();
1186

    
1187
            gen_load_fpr64(ctx, fp0, ft);
1188
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1189
            tcg_temp_free_i64(fp0);
1190
        }
1191
        opn = "sdc1";
1192
        break;
1193
    default:
1194
        MIPS_INVAL(opn);
1195
        generate_exception(ctx, EXCP_RI);
1196
        goto out;
1197
    }
1198
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1199
 out:
1200
    tcg_temp_free(t0);
1201
}
1202

    
1203
/* Arithmetic with immediate operand */
1204
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1205
                           int rt, int rs, int16_t imm)
1206
{
1207
    target_ulong uimm;
1208
    const char *opn = "imm arith";
1209
    TCGv t0 = tcg_temp_local_new();
1210

    
1211
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1212
        /* If no destination, treat it as a NOP.
1213
           For addi, we must generate the overflow exception when needed. */
1214
        MIPS_DEBUG("NOP");
1215
        goto out;
1216
    }
1217
    uimm = (uint16_t)imm;
1218
    switch (opc) {
1219
    case OPC_ADDI:
1220
    case OPC_ADDIU:
1221
#if defined(TARGET_MIPS64)
1222
    case OPC_DADDI:
1223
    case OPC_DADDIU:
1224
#endif
1225
    case OPC_SLTI:
1226
    case OPC_SLTIU:
1227
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1228
        /* Fall through. */
1229
    case OPC_ANDI:
1230
    case OPC_ORI:
1231
    case OPC_XORI:
1232
        gen_load_gpr(t0, rs);
1233
        break;
1234
    case OPC_LUI:
1235
        tcg_gen_movi_tl(t0, imm << 16);
1236
        break;
1237
    case OPC_SLL:
1238
    case OPC_SRA:
1239
    case OPC_SRL:
1240
#if defined(TARGET_MIPS64)
1241
    case OPC_DSLL:
1242
    case OPC_DSRA:
1243
    case OPC_DSRL:
1244
    case OPC_DSLL32:
1245
    case OPC_DSRA32:
1246
    case OPC_DSRL32:
1247
#endif
1248
        uimm &= 0x1f;
1249
        gen_load_gpr(t0, rs);
1250
        break;
1251
    }
1252
    switch (opc) {
1253
    case OPC_ADDI:
1254
        {
1255
            TCGv r_tmp1 = tcg_temp_new();
1256
            TCGv r_tmp2 = tcg_temp_new();
1257
            int l1 = gen_new_label();
1258

    
1259
            save_cpu_state(ctx, 1);
1260
            tcg_gen_ext32s_tl(r_tmp1, t0);
1261
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1262

    
1263
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1264
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1265
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1266
            tcg_temp_free(r_tmp2);
1267
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1268
            /* operands of same sign, result different sign */
1269
            generate_exception(ctx, EXCP_OVERFLOW);
1270
            gen_set_label(l1);
1271
            tcg_temp_free(r_tmp1);
1272

    
1273
            tcg_gen_ext32s_tl(t0, t0);
1274
        }
1275
        opn = "addi";
1276
        break;
1277
    case OPC_ADDIU:
1278
        tcg_gen_addi_tl(t0, t0, uimm);
1279
        tcg_gen_ext32s_tl(t0, t0);
1280
        opn = "addiu";
1281
        break;
1282
#if defined(TARGET_MIPS64)
1283
    case OPC_DADDI:
1284
        {
1285
            TCGv r_tmp1 = tcg_temp_new();
1286
            TCGv r_tmp2 = tcg_temp_new();
1287
            int l1 = gen_new_label();
1288

    
1289
            save_cpu_state(ctx, 1);
1290
            tcg_gen_mov_tl(r_tmp1, t0);
1291
            tcg_gen_addi_tl(t0, t0, uimm);
1292

    
1293
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1294
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1295
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1296
            tcg_temp_free(r_tmp2);
1297
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1298
            /* operands of same sign, result different sign */
1299
            generate_exception(ctx, EXCP_OVERFLOW);
1300
            gen_set_label(l1);
1301
            tcg_temp_free(r_tmp1);
1302
        }
1303
        opn = "daddi";
1304
        break;
1305
    case OPC_DADDIU:
1306
        tcg_gen_addi_tl(t0, t0, uimm);
1307
        opn = "daddiu";
1308
        break;
1309
#endif
1310
    case OPC_SLTI:
1311
        gen_op_lti(t0, t0, uimm);
1312
        opn = "slti";
1313
        break;
1314
    case OPC_SLTIU:
1315
        gen_op_ltiu(t0, t0, uimm);
1316
        opn = "sltiu";
1317
        break;
1318
    case OPC_ANDI:
1319
        tcg_gen_andi_tl(t0, t0, uimm);
1320
        opn = "andi";
1321
        break;
1322
    case OPC_ORI:
1323
        tcg_gen_ori_tl(t0, t0, uimm);
1324
        opn = "ori";
1325
        break;
1326
    case OPC_XORI:
1327
        tcg_gen_xori_tl(t0, t0, uimm);
1328
        opn = "xori";
1329
        break;
1330
    case OPC_LUI:
1331
        opn = "lui";
1332
        break;
1333
    case OPC_SLL:
1334
        tcg_gen_shli_tl(t0, t0, uimm);
1335
        tcg_gen_ext32s_tl(t0, t0);
1336
        opn = "sll";
1337
        break;
1338
    case OPC_SRA:
1339
        tcg_gen_ext32s_tl(t0, t0);
1340
        tcg_gen_sari_tl(t0, t0, uimm);
1341
        opn = "sra";
1342
        break;
1343
    case OPC_SRL:
1344
        switch ((ctx->opcode >> 21) & 0x1f) {
1345
        case 0:
1346
            if (uimm != 0) {
1347
                tcg_gen_ext32u_tl(t0, t0);
1348
                tcg_gen_shri_tl(t0, t0, uimm);
1349
            } else {
1350
                tcg_gen_ext32s_tl(t0, t0);
1351
            }
1352
            opn = "srl";
1353
            break;
1354
        case 1:
1355
            /* rotr is decoded as srl on non-R2 CPUs */
1356
            if (env->insn_flags & ISA_MIPS32R2) {
1357
                if (uimm != 0) {
1358
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1359

    
1360
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1361
                    tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
1362
                    tcg_gen_ext_i32_tl(t0, r_tmp1);
1363
                    tcg_temp_free_i32(r_tmp1);
1364
                }
1365
                opn = "rotr";
1366
            } else {
1367
                if (uimm != 0) {
1368
                    tcg_gen_ext32u_tl(t0, t0);
1369
                    tcg_gen_shri_tl(t0, t0, uimm);
1370
                } else {
1371
                    tcg_gen_ext32s_tl(t0, t0);
1372
                }
1373
                opn = "srl";
1374
            }
1375
            break;
1376
        default:
1377
            MIPS_INVAL("invalid srl flag");
1378
            generate_exception(ctx, EXCP_RI);
1379
            break;
1380
        }
1381
        break;
1382
#if defined(TARGET_MIPS64)
1383
    case OPC_DSLL:
1384
        tcg_gen_shli_tl(t0, t0, uimm);
1385
        opn = "dsll";
1386
        break;
1387
    case OPC_DSRA:
1388
        tcg_gen_sari_tl(t0, t0, uimm);
1389
        opn = "dsra";
1390
        break;
1391
    case OPC_DSRL:
1392
        switch ((ctx->opcode >> 21) & 0x1f) {
1393
        case 0:
1394
            tcg_gen_shri_tl(t0, t0, uimm);
1395
            opn = "dsrl";
1396
            break;
1397
        case 1:
1398
            /* drotr is decoded as dsrl on non-R2 CPUs */
1399
            if (env->insn_flags & ISA_MIPS32R2) {
1400
                if (uimm != 0) {
1401
                    tcg_gen_rotri_tl(t0, t0, uimm);
1402
                }
1403
                opn = "drotr";
1404
            } else {
1405
                tcg_gen_shri_tl(t0, t0, uimm);
1406
                opn = "dsrl";
1407
            }
1408
            break;
1409
        default:
1410
            MIPS_INVAL("invalid dsrl flag");
1411
            generate_exception(ctx, EXCP_RI);
1412
            break;
1413
        }
1414
        break;
1415
    case OPC_DSLL32:
1416
        tcg_gen_shli_tl(t0, t0, uimm + 32);
1417
        opn = "dsll32";
1418
        break;
1419
    case OPC_DSRA32:
1420
        tcg_gen_sari_tl(t0, t0, uimm + 32);
1421
        opn = "dsra32";
1422
        break;
1423
    case OPC_DSRL32:
1424
        switch ((ctx->opcode >> 21) & 0x1f) {
1425
        case 0:
1426
            tcg_gen_shri_tl(t0, t0, uimm + 32);
1427
            opn = "dsrl32";
1428
            break;
1429
        case 1:
1430
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1431
            if (env->insn_flags & ISA_MIPS32R2) {
1432
                tcg_gen_rotri_tl(t0, t0, uimm + 32);
1433
                opn = "drotr32";
1434
            } else {
1435
                tcg_gen_shri_tl(t0, t0, uimm + 32);
1436
                opn = "dsrl32";
1437
            }
1438
            break;
1439
        default:
1440
            MIPS_INVAL("invalid dsrl32 flag");
1441
            generate_exception(ctx, EXCP_RI);
1442
            break;
1443
        }
1444
        break;
1445
#endif
1446
    default:
1447
        MIPS_INVAL(opn);
1448
        generate_exception(ctx, EXCP_RI);
1449
        goto out;
1450
    }
1451
    gen_store_gpr(t0, rt);
1452
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1453
 out:
1454
    tcg_temp_free(t0);
1455
}
1456

    
1457
/* Arithmetic */
1458
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1459
                       int rd, int rs, int rt)
1460
{
1461
    const char *opn = "arith";
1462
    TCGv t0 = tcg_temp_local_new();
1463
    TCGv t1 = tcg_temp_local_new();
1464

    
1465
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1466
       && opc != OPC_DADD && opc != OPC_DSUB) {
1467
        /* If no destination, treat it as a NOP.
1468
           For add & sub, we must generate the overflow exception when needed. */
1469
        MIPS_DEBUG("NOP");
1470
        goto out;
1471
    }
1472
    gen_load_gpr(t0, rs);
1473
    /* Specialcase the conventional move operation. */
1474
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1475
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1476
        gen_store_gpr(t0, rd);
1477
        goto out;
1478
    }
1479
    gen_load_gpr(t1, rt);
1480
    switch (opc) {
1481
    case OPC_ADD:
1482
        {
1483
            TCGv r_tmp1 = tcg_temp_new();
1484
            TCGv r_tmp2 = tcg_temp_new();
1485
            int l1 = gen_new_label();
1486

    
1487
            save_cpu_state(ctx, 1);
1488
            tcg_gen_ext32s_tl(r_tmp1, t0);
1489
            tcg_gen_ext32s_tl(r_tmp2, t1);
1490
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1491

    
1492
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1493
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1494
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1495
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1496
            tcg_temp_free(r_tmp2);
1497
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1498
            /* operands of same sign, result different sign */
1499
            generate_exception(ctx, EXCP_OVERFLOW);
1500
            gen_set_label(l1);
1501
            tcg_temp_free(r_tmp1);
1502

    
1503
            tcg_gen_ext32s_tl(t0, t0);
1504
        }
1505
        opn = "add";
1506
        break;
1507
    case OPC_ADDU:
1508
        tcg_gen_add_tl(t0, t0, t1);
1509
        tcg_gen_ext32s_tl(t0, t0);
1510
        opn = "addu";
1511
        break;
1512
    case OPC_SUB:
1513
        {
1514
            TCGv r_tmp1 = tcg_temp_new();
1515
            TCGv r_tmp2 = tcg_temp_new();
1516
            int l1 = gen_new_label();
1517

    
1518
            save_cpu_state(ctx, 1);
1519
            tcg_gen_ext32s_tl(r_tmp1, t0);
1520
            tcg_gen_ext32s_tl(r_tmp2, t1);
1521
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1522

    
1523
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1524
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1525
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1526
            tcg_temp_free(r_tmp2);
1527
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1528
            /* operands of different sign, first operand and result different sign */
1529
            generate_exception(ctx, EXCP_OVERFLOW);
1530
            gen_set_label(l1);
1531
            tcg_temp_free(r_tmp1);
1532

    
1533
            tcg_gen_ext32s_tl(t0, t0);
1534
        }
1535
        opn = "sub";
1536
        break;
1537
    case OPC_SUBU:
1538
        tcg_gen_sub_tl(t0, t0, t1);
1539
        tcg_gen_ext32s_tl(t0, t0);
1540
        opn = "subu";
1541
        break;
1542
#if defined(TARGET_MIPS64)
1543
    case OPC_DADD:
1544
        {
1545
            TCGv r_tmp1 = tcg_temp_new();
1546
            TCGv r_tmp2 = tcg_temp_new();
1547
            int l1 = gen_new_label();
1548

    
1549
            save_cpu_state(ctx, 1);
1550
            tcg_gen_mov_tl(r_tmp1, t0);
1551
            tcg_gen_add_tl(t0, t0, t1);
1552

    
1553
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1554
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1555
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1556
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1557
            tcg_temp_free(r_tmp2);
1558
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1559
            /* operands of same sign, result different sign */
1560
            generate_exception(ctx, EXCP_OVERFLOW);
1561
            gen_set_label(l1);
1562
            tcg_temp_free(r_tmp1);
1563
        }
1564
        opn = "dadd";
1565
        break;
1566
    case OPC_DADDU:
1567
        tcg_gen_add_tl(t0, t0, t1);
1568
        opn = "daddu";
1569
        break;
1570
    case OPC_DSUB:
1571
        {
1572
            TCGv r_tmp1 = tcg_temp_new();
1573
            TCGv r_tmp2 = tcg_temp_new();
1574
            int l1 = gen_new_label();
1575

    
1576
            save_cpu_state(ctx, 1);
1577
            tcg_gen_mov_tl(r_tmp1, t0);
1578
            tcg_gen_sub_tl(t0, t0, t1);
1579

    
1580
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1581
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1582
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1583
            tcg_temp_free(r_tmp2);
1584
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1585
            /* operands of different sign, first operand and result different sign */
1586
            generate_exception(ctx, EXCP_OVERFLOW);
1587
            gen_set_label(l1);
1588
            tcg_temp_free(r_tmp1);
1589
        }
1590
        opn = "dsub";
1591
        break;
1592
    case OPC_DSUBU:
1593
        tcg_gen_sub_tl(t0, t0, t1);
1594
        opn = "dsubu";
1595
        break;
1596
#endif
1597
    case OPC_SLT:
1598
        gen_op_lt(t0, t0, t1);
1599
        opn = "slt";
1600
        break;
1601
    case OPC_SLTU:
1602
        gen_op_ltu(t0, t0, t1);
1603
        opn = "sltu";
1604
        break;
1605
    case OPC_AND:
1606
        tcg_gen_and_tl(t0, t0, t1);
1607
        opn = "and";
1608
        break;
1609
    case OPC_NOR:
1610
        tcg_gen_nor_tl(t0, t0, t1);
1611
        opn = "nor";
1612
        break;
1613
    case OPC_OR:
1614
        tcg_gen_or_tl(t0, t0, t1);
1615
        opn = "or";
1616
        break;
1617
    case OPC_XOR:
1618
        tcg_gen_xor_tl(t0, t0, t1);
1619
        opn = "xor";
1620
        break;
1621
    case OPC_MUL:
1622
        tcg_gen_mul_tl(t0, t0, t1);
1623
        tcg_gen_ext32s_tl(t0, t0);
1624
        opn = "mul";
1625
        break;
1626
    case OPC_MOVN:
1627
        {
1628
            int l1 = gen_new_label();
1629

    
1630
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1631
            gen_store_gpr(t0, rd);
1632
            gen_set_label(l1);
1633
        }
1634
        opn = "movn";
1635
        goto print;
1636
    case OPC_MOVZ:
1637
        {
1638
            int l1 = gen_new_label();
1639

    
1640
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1641
            gen_store_gpr(t0, rd);
1642
            gen_set_label(l1);
1643
        }
1644
        opn = "movz";
1645
        goto print;
1646
    case OPC_SLLV:
1647
        tcg_gen_andi_tl(t0, t0, 0x1f);
1648
        tcg_gen_shl_tl(t0, t1, t0);
1649
        tcg_gen_ext32s_tl(t0, t0);
1650
        opn = "sllv";
1651
        break;
1652
    case OPC_SRAV:
1653
        tcg_gen_ext32s_tl(t1, t1);
1654
        tcg_gen_andi_tl(t0, t0, 0x1f);
1655
        tcg_gen_sar_tl(t0, t1, t0);
1656
        opn = "srav";
1657
        break;
1658
    case OPC_SRLV:
1659
        switch ((ctx->opcode >> 6) & 0x1f) {
1660
        case 0:
1661
            tcg_gen_ext32u_tl(t1, t1);
1662
            tcg_gen_andi_tl(t0, t0, 0x1f);
1663
            tcg_gen_shr_tl(t0, t1, t0);
1664
            tcg_gen_ext32s_tl(t0, t0);
1665
            opn = "srlv";
1666
            break;
1667
        case 1:
1668
            /* rotrv is decoded as srlv on non-R2 CPUs */
1669
            if (env->insn_flags & ISA_MIPS32R2) {
1670
                int l1 = gen_new_label();
1671
                int l2 = gen_new_label();
1672

    
1673
                tcg_gen_andi_tl(t0, t0, 0x1f);
1674
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1675
                {
1676
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1677
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1678

    
1679
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1680
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1681
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1682
                    tcg_temp_free_i32(r_tmp1);
1683
                    tcg_temp_free_i32(r_tmp2);
1684
                    tcg_gen_br(l2);
1685
                }
1686
                gen_set_label(l1);
1687
                tcg_gen_mov_tl(t0, t1);
1688
                gen_set_label(l2);
1689
                opn = "rotrv";
1690
            } else {
1691
                tcg_gen_ext32u_tl(t1, t1);
1692
                tcg_gen_andi_tl(t0, t0, 0x1f);
1693
                tcg_gen_shr_tl(t0, t1, t0);
1694
                tcg_gen_ext32s_tl(t0, t0);
1695
                opn = "srlv";
1696
            }
1697
            break;
1698
        default:
1699
            MIPS_INVAL("invalid srlv flag");
1700
            generate_exception(ctx, EXCP_RI);
1701
            break;
1702
        }
1703
        break;
1704
#if defined(TARGET_MIPS64)
1705
    case OPC_DSLLV:
1706
        tcg_gen_andi_tl(t0, t0, 0x3f);
1707
        tcg_gen_shl_tl(t0, t1, t0);
1708
        opn = "dsllv";
1709
        break;
1710
    case OPC_DSRAV:
1711
        tcg_gen_andi_tl(t0, t0, 0x3f);
1712
        tcg_gen_sar_tl(t0, t1, t0);
1713
        opn = "dsrav";
1714
        break;
1715
    case OPC_DSRLV:
1716
        switch ((ctx->opcode >> 6) & 0x1f) {
1717
        case 0:
1718
            tcg_gen_andi_tl(t0, t0, 0x3f);
1719
            tcg_gen_shr_tl(t0, t1, t0);
1720
            opn = "dsrlv";
1721
            break;
1722
        case 1:
1723
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1724
            if (env->insn_flags & ISA_MIPS32R2) {
1725
                int l1 = gen_new_label();
1726
                int l2 = gen_new_label();
1727

    
1728
                tcg_gen_andi_tl(t0, t0, 0x3f);
1729
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1730
                {
1731
                    tcg_gen_rotr_tl(t0, t1, t0);
1732
                    tcg_gen_br(l2);
1733
                }
1734
                gen_set_label(l1);
1735
                tcg_gen_mov_tl(t0, t1);
1736
                gen_set_label(l2);
1737
                opn = "drotrv";
1738
            } else {
1739
                tcg_gen_andi_tl(t0, t0, 0x3f);
1740
                tcg_gen_shr_tl(t0, t1, t0);
1741
                opn = "dsrlv";
1742
            }
1743
            break;
1744
        default:
1745
            MIPS_INVAL("invalid dsrlv flag");
1746
            generate_exception(ctx, EXCP_RI);
1747
            break;
1748
        }
1749
        break;
1750
#endif
1751
    default:
1752
        MIPS_INVAL(opn);
1753
        generate_exception(ctx, EXCP_RI);
1754
        goto out;
1755
    }
1756
    gen_store_gpr(t0, rd);
1757
 print:
1758
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1759
 out:
1760
    tcg_temp_free(t0);
1761
    tcg_temp_free(t1);
1762
}
1763

    
1764
/* Arithmetic on HI/LO registers */
1765
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1766
{
1767
    const char *opn = "hilo";
1768

    
1769
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1770
        /* Treat as NOP. */
1771
        MIPS_DEBUG("NOP");
1772
        return;
1773
    }
1774
    switch (opc) {
1775
    case OPC_MFHI:
1776
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1777
        opn = "mfhi";
1778
        break;
1779
    case OPC_MFLO:
1780
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1781
        opn = "mflo";
1782
        break;
1783
    case OPC_MTHI:
1784
        if (reg != 0)
1785
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1786
        else
1787
            tcg_gen_movi_tl(cpu_HI[0], 0);
1788
        opn = "mthi";
1789
        break;
1790
    case OPC_MTLO:
1791
        if (reg != 0)
1792
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1793
        else
1794
            tcg_gen_movi_tl(cpu_LO[0], 0);
1795
        opn = "mtlo";
1796
        break;
1797
    }
1798
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1799
}
1800

    
1801
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1802
                        int rs, int rt)
1803
{
1804
    const char *opn = "mul/div";
1805
    TCGv t0, t1;
1806

    
1807
    switch (opc) {
1808
    case OPC_DIV:
1809
    case OPC_DIVU:
1810
#if defined(TARGET_MIPS64)
1811
    case OPC_DDIV:
1812
    case OPC_DDIVU:
1813
#endif
1814
        t0 = tcg_temp_local_new();
1815
        t1 = tcg_temp_local_new();
1816
        break;
1817
    default:
1818
        t0 = tcg_temp_new();
1819
        t1 = tcg_temp_new();
1820
        break;
1821
    }
1822

    
1823
    gen_load_gpr(t0, rs);
1824
    gen_load_gpr(t1, rt);
1825
    switch (opc) {
1826
    case OPC_DIV:
1827
        {
1828
            int l1 = gen_new_label();
1829
            int l2 = gen_new_label();
1830

    
1831
            tcg_gen_ext32s_tl(t0, t0);
1832
            tcg_gen_ext32s_tl(t1, t1);
1833
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1834
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
1835
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
1836

    
1837
            tcg_gen_mov_tl(cpu_LO[0], t0);
1838
            tcg_gen_movi_tl(cpu_HI[0], 0);
1839
            tcg_gen_br(l1);
1840
            gen_set_label(l2);
1841
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
1842
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
1843
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1844
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1845
            gen_set_label(l1);
1846
        }
1847
        opn = "div";
1848
        break;
1849
    case OPC_DIVU:
1850
        {
1851
            int l1 = gen_new_label();
1852

    
1853
            tcg_gen_ext32u_tl(t0, t0);
1854
            tcg_gen_ext32u_tl(t1, t1);
1855
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1856
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
1857
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
1858
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
1859
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1860
            gen_set_label(l1);
1861
        }
1862
        opn = "divu";
1863
        break;
1864
    case OPC_MULT:
1865
        {
1866
            TCGv_i64 t2 = tcg_temp_new_i64();
1867
            TCGv_i64 t3 = tcg_temp_new_i64();
1868

    
1869
            tcg_gen_ext_tl_i64(t2, t0);
1870
            tcg_gen_ext_tl_i64(t3, t1);
1871
            tcg_gen_mul_i64(t2, t2, t3);
1872
            tcg_temp_free_i64(t3);
1873
            tcg_gen_trunc_i64_tl(t0, t2);
1874
            tcg_gen_shri_i64(t2, t2, 32);
1875
            tcg_gen_trunc_i64_tl(t1, t2);
1876
            tcg_temp_free_i64(t2);
1877
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1878
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1879
        }
1880
        opn = "mult";
1881
        break;
1882
    case OPC_MULTU:
1883
        {
1884
            TCGv_i64 t2 = tcg_temp_new_i64();
1885
            TCGv_i64 t3 = tcg_temp_new_i64();
1886

    
1887
            tcg_gen_ext32u_tl(t0, t0);
1888
            tcg_gen_ext32u_tl(t1, t1);
1889
            tcg_gen_extu_tl_i64(t2, t0);
1890
            tcg_gen_extu_tl_i64(t3, t1);
1891
            tcg_gen_mul_i64(t2, t2, t3);
1892
            tcg_temp_free_i64(t3);
1893
            tcg_gen_trunc_i64_tl(t0, t2);
1894
            tcg_gen_shri_i64(t2, t2, 32);
1895
            tcg_gen_trunc_i64_tl(t1, t2);
1896
            tcg_temp_free_i64(t2);
1897
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1898
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1899
        }
1900
        opn = "multu";
1901
        break;
1902
#if defined(TARGET_MIPS64)
1903
    case OPC_DDIV:
1904
        {
1905
            int l1 = gen_new_label();
1906
            int l2 = gen_new_label();
1907

    
1908
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1909
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1910
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1911
            tcg_gen_mov_tl(cpu_LO[0], t0);
1912
            tcg_gen_movi_tl(cpu_HI[0], 0);
1913
            tcg_gen_br(l1);
1914
            gen_set_label(l2);
1915
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
1916
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1917
            gen_set_label(l1);
1918
        }
1919
        opn = "ddiv";
1920
        break;
1921
    case OPC_DDIVU:
1922
        {
1923
            int l1 = gen_new_label();
1924

    
1925
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1926
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1927
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1928
            gen_set_label(l1);
1929
        }
1930
        opn = "ddivu";
1931
        break;
1932
    case OPC_DMULT:
1933
        gen_helper_dmult(t0, t1);
1934
        opn = "dmult";
1935
        break;
1936
    case OPC_DMULTU:
1937
        gen_helper_dmultu(t0, t1);
1938
        opn = "dmultu";
1939
        break;
1940
#endif
1941
    case OPC_MADD:
1942
        {
1943
            TCGv_i64 t2 = tcg_temp_new_i64();
1944
            TCGv_i64 t3 = tcg_temp_new_i64();
1945

    
1946
            tcg_gen_ext_tl_i64(t2, t0);
1947
            tcg_gen_ext_tl_i64(t3, t1);
1948
            tcg_gen_mul_i64(t2, t2, t3);
1949
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1950
            tcg_gen_add_i64(t2, t2, t3);
1951
            tcg_temp_free_i64(t3);
1952
            tcg_gen_trunc_i64_tl(t0, t2);
1953
            tcg_gen_shri_i64(t2, t2, 32);
1954
            tcg_gen_trunc_i64_tl(t1, t2);
1955
            tcg_temp_free_i64(t2);
1956
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1957
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1958
        }
1959
        opn = "madd";
1960
        break;
1961
    case OPC_MADDU:
1962
       {
1963
            TCGv_i64 t2 = tcg_temp_new_i64();
1964
            TCGv_i64 t3 = tcg_temp_new_i64();
1965

    
1966
            tcg_gen_ext32u_tl(t0, t0);
1967
            tcg_gen_ext32u_tl(t1, t1);
1968
            tcg_gen_extu_tl_i64(t2, t0);
1969
            tcg_gen_extu_tl_i64(t3, t1);
1970
            tcg_gen_mul_i64(t2, t2, t3);
1971
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1972
            tcg_gen_add_i64(t2, t2, t3);
1973
            tcg_temp_free_i64(t3);
1974
            tcg_gen_trunc_i64_tl(t0, t2);
1975
            tcg_gen_shri_i64(t2, t2, 32);
1976
            tcg_gen_trunc_i64_tl(t1, t2);
1977
            tcg_temp_free_i64(t2);
1978
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1979
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1980
        }
1981
        opn = "maddu";
1982
        break;
1983
    case OPC_MSUB:
1984
        {
1985
            TCGv_i64 t2 = tcg_temp_new_i64();
1986
            TCGv_i64 t3 = tcg_temp_new_i64();
1987

    
1988
            tcg_gen_ext_tl_i64(t2, t0);
1989
            tcg_gen_ext_tl_i64(t3, t1);
1990
            tcg_gen_mul_i64(t2, t2, t3);
1991
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
1992
            tcg_gen_sub_i64(t2, t2, t3);
1993
            tcg_temp_free_i64(t3);
1994
            tcg_gen_trunc_i64_tl(t0, t2);
1995
            tcg_gen_shri_i64(t2, t2, 32);
1996
            tcg_gen_trunc_i64_tl(t1, t2);
1997
            tcg_temp_free_i64(t2);
1998
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1999
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2000
        }
2001
        opn = "msub";
2002
        break;
2003
    case OPC_MSUBU:
2004
        {
2005
            TCGv_i64 t2 = tcg_temp_new_i64();
2006
            TCGv_i64 t3 = tcg_temp_new_i64();
2007

    
2008
            tcg_gen_ext32u_tl(t0, t0);
2009
            tcg_gen_ext32u_tl(t1, t1);
2010
            tcg_gen_extu_tl_i64(t2, t0);
2011
            tcg_gen_extu_tl_i64(t3, t1);
2012
            tcg_gen_mul_i64(t2, t2, t3);
2013
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2014
            tcg_gen_sub_i64(t2, t2, t3);
2015
            tcg_temp_free_i64(t3);
2016
            tcg_gen_trunc_i64_tl(t0, t2);
2017
            tcg_gen_shri_i64(t2, t2, 32);
2018
            tcg_gen_trunc_i64_tl(t1, t2);
2019
            tcg_temp_free_i64(t2);
2020
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2021
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2022
        }
2023
        opn = "msubu";
2024
        break;
2025
    default:
2026
        MIPS_INVAL(opn);
2027
        generate_exception(ctx, EXCP_RI);
2028
        goto out;
2029
    }
2030
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2031
 out:
2032
    tcg_temp_free(t0);
2033
    tcg_temp_free(t1);
2034
}
2035

    
2036
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2037
                            int rd, int rs, int rt)
2038
{
2039
    const char *opn = "mul vr54xx";
2040
    TCGv t0 = tcg_temp_new();
2041
    TCGv t1 = tcg_temp_new();
2042

    
2043
    gen_load_gpr(t0, rs);
2044
    gen_load_gpr(t1, rt);
2045

    
2046
    switch (opc) {
2047
    case OPC_VR54XX_MULS:
2048
        gen_helper_muls(t0, t0, t1);
2049
        opn = "muls";
2050
        break;
2051
    case OPC_VR54XX_MULSU:
2052
        gen_helper_mulsu(t0, t0, t1);
2053
        opn = "mulsu";
2054
        break;
2055
    case OPC_VR54XX_MACC:
2056
        gen_helper_macc(t0, t0, t1);
2057
        opn = "macc";
2058
        break;
2059
    case OPC_VR54XX_MACCU:
2060
        gen_helper_maccu(t0, t0, t1);
2061
        opn = "maccu";
2062
        break;
2063
    case OPC_VR54XX_MSAC:
2064
        gen_helper_msac(t0, t0, t1);
2065
        opn = "msac";
2066
        break;
2067
    case OPC_VR54XX_MSACU:
2068
        gen_helper_msacu(t0, t0, t1);
2069
        opn = "msacu";
2070
        break;
2071
    case OPC_VR54XX_MULHI:
2072
        gen_helper_mulhi(t0, t0, t1);
2073
        opn = "mulhi";
2074
        break;
2075
    case OPC_VR54XX_MULHIU:
2076
        gen_helper_mulhiu(t0, t0, t1);
2077
        opn = "mulhiu";
2078
        break;
2079
    case OPC_VR54XX_MULSHI:
2080
        gen_helper_mulshi(t0, t0, t1);
2081
        opn = "mulshi";
2082
        break;
2083
    case OPC_VR54XX_MULSHIU:
2084
        gen_helper_mulshiu(t0, t0, t1);
2085
        opn = "mulshiu";
2086
        break;
2087
    case OPC_VR54XX_MACCHI:
2088
        gen_helper_macchi(t0, t0, t1);
2089
        opn = "macchi";
2090
        break;
2091
    case OPC_VR54XX_MACCHIU:
2092
        gen_helper_macchiu(t0, t0, t1);
2093
        opn = "macchiu";
2094
        break;
2095
    case OPC_VR54XX_MSACHI:
2096
        gen_helper_msachi(t0, t0, t1);
2097
        opn = "msachi";
2098
        break;
2099
    case OPC_VR54XX_MSACHIU:
2100
        gen_helper_msachiu(t0, t0, t1);
2101
        opn = "msachiu";
2102
        break;
2103
    default:
2104
        MIPS_INVAL("mul vr54xx");
2105
        generate_exception(ctx, EXCP_RI);
2106
        goto out;
2107
    }
2108
    gen_store_gpr(t0, rd);
2109
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2110

    
2111
 out:
2112
    tcg_temp_free(t0);
2113
    tcg_temp_free(t1);
2114
}
2115

    
2116
static void gen_cl (DisasContext *ctx, uint32_t opc,
2117
                    int rd, int rs)
2118
{
2119
    const char *opn = "CLx";
2120
    TCGv t0;
2121

    
2122
    if (rd == 0) {
2123
        /* Treat as NOP. */
2124
        MIPS_DEBUG("NOP");
2125
        return;
2126
    }
2127
    t0 = tcg_temp_new();
2128
    gen_load_gpr(t0, rs);
2129
    switch (opc) {
2130
    case OPC_CLO:
2131
        gen_helper_clo(cpu_gpr[rd], t0);
2132
        opn = "clo";
2133
        break;
2134
    case OPC_CLZ:
2135
        gen_helper_clz(cpu_gpr[rd], t0);
2136
        opn = "clz";
2137
        break;
2138
#if defined(TARGET_MIPS64)
2139
    case OPC_DCLO:
2140
        gen_helper_dclo(cpu_gpr[rd], t0);
2141
        opn = "dclo";
2142
        break;
2143
    case OPC_DCLZ:
2144
        gen_helper_dclz(cpu_gpr[rd], t0);
2145
        opn = "dclz";
2146
        break;
2147
#endif
2148
    }
2149
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2150
    tcg_temp_free(t0);
2151
}
2152

    
2153
/* Traps */
2154
static void gen_trap (DisasContext *ctx, uint32_t opc,
2155
                      int rs, int rt, int16_t imm)
2156
{
2157
    int cond;
2158
    TCGv t0 = tcg_temp_new();
2159
    TCGv t1 = tcg_temp_new();
2160

    
2161
    cond = 0;
2162
    /* Load needed operands */
2163
    switch (opc) {
2164
    case OPC_TEQ:
2165
    case OPC_TGE:
2166
    case OPC_TGEU:
2167
    case OPC_TLT:
2168
    case OPC_TLTU:
2169
    case OPC_TNE:
2170
        /* Compare two registers */
2171
        if (rs != rt) {
2172
            gen_load_gpr(t0, rs);
2173
            gen_load_gpr(t1, rt);
2174
            cond = 1;
2175
        }
2176
        break;
2177
    case OPC_TEQI:
2178
    case OPC_TGEI:
2179
    case OPC_TGEIU:
2180
    case OPC_TLTI:
2181
    case OPC_TLTIU:
2182
    case OPC_TNEI:
2183
        /* Compare register to immediate */
2184
        if (rs != 0 || imm != 0) {
2185
            gen_load_gpr(t0, rs);
2186
            tcg_gen_movi_tl(t1, (int32_t)imm);
2187
            cond = 1;
2188
        }
2189
        break;
2190
    }
2191
    if (cond == 0) {
2192
        switch (opc) {
2193
        case OPC_TEQ:   /* rs == rs */
2194
        case OPC_TEQI:  /* r0 == 0  */
2195
        case OPC_TGE:   /* rs >= rs */
2196
        case OPC_TGEI:  /* r0 >= 0  */
2197
        case OPC_TGEU:  /* rs >= rs unsigned */
2198
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2199
            /* Always trap */
2200
            generate_exception(ctx, EXCP_TRAP);
2201
            break;
2202
        case OPC_TLT:   /* rs < rs           */
2203
        case OPC_TLTI:  /* r0 < 0            */
2204
        case OPC_TLTU:  /* rs < rs unsigned  */
2205
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2206
        case OPC_TNE:   /* rs != rs          */
2207
        case OPC_TNEI:  /* r0 != 0           */
2208
            /* Never trap: treat as NOP. */
2209
            break;
2210
        }
2211
    } else {
2212
        int l1 = gen_new_label();
2213

    
2214
        switch (opc) {
2215
        case OPC_TEQ:
2216
        case OPC_TEQI:
2217
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2218
            break;
2219
        case OPC_TGE:
2220
        case OPC_TGEI:
2221
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2222
            break;
2223
        case OPC_TGEU:
2224
        case OPC_TGEIU:
2225
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2226
            break;
2227
        case OPC_TLT:
2228
        case OPC_TLTI:
2229
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2230
            break;
2231
        case OPC_TLTU:
2232
        case OPC_TLTIU:
2233
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2234
            break;
2235
        case OPC_TNE:
2236
        case OPC_TNEI:
2237
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2238
            break;
2239
        }
2240
        generate_exception(ctx, EXCP_TRAP);
2241
        gen_set_label(l1);
2242
    }
2243
    tcg_temp_free(t0);
2244
    tcg_temp_free(t1);
2245
}
2246

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

    
2261
/* Branches (before delay slot) */
2262
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2263
                                int rs, int rt, int32_t offset)
2264
{
2265
    target_ulong btgt = -1;
2266
    int blink = 0;
2267
    int bcond_compute = 0;
2268
    TCGv t0 = tcg_temp_new();
2269
    TCGv t1 = tcg_temp_new();
2270

    
2271
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2272
#ifdef MIPS_DEBUG_DISAS
2273
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2274
#endif
2275
        generate_exception(ctx, EXCP_RI);
2276
        goto out;
2277
    }
2278

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

    
2487
    ctx->btarget = btgt;
2488
    if (blink > 0) {
2489
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2490
    }
2491

    
2492
 out:
2493
    tcg_temp_free(t0);
2494
    tcg_temp_free(t1);
2495
}
2496

    
2497
/* special3 bitfield operations */
2498
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2499
                        int rs, int lsb, int msb)
2500
{
2501
    TCGv t0 = tcg_temp_new();
2502
    TCGv t1 = tcg_temp_new();
2503
    target_ulong mask;
2504

    
2505
    gen_load_gpr(t1, rs);
2506
    switch (opc) {
2507
    case OPC_EXT:
2508
        if (lsb + msb > 31)
2509
            goto fail;
2510
        tcg_gen_shri_tl(t0, t1, lsb);
2511
        if (msb != 31) {
2512
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2513
        } else {
2514
            tcg_gen_ext32s_tl(t0, t0);
2515
        }
2516
        break;
2517
#if defined(TARGET_MIPS64)
2518
    case OPC_DEXTM:
2519
        tcg_gen_shri_tl(t0, t1, lsb);
2520
        if (msb != 31) {
2521
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2522
        }
2523
        break;
2524
    case OPC_DEXTU:
2525
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2526
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2527
        break;
2528
    case OPC_DEXT:
2529
        tcg_gen_shri_tl(t0, t1, lsb);
2530
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2531
        break;
2532
#endif
2533
    case OPC_INS:
2534
        if (lsb > msb)
2535
            goto fail;
2536
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2537
        gen_load_gpr(t0, rt);
2538
        tcg_gen_andi_tl(t0, t0, ~mask);
2539
        tcg_gen_shli_tl(t1, t1, lsb);
2540
        tcg_gen_andi_tl(t1, t1, mask);
2541
        tcg_gen_or_tl(t0, t0, t1);
2542
        tcg_gen_ext32s_tl(t0, t0);
2543
        break;
2544
#if defined(TARGET_MIPS64)
2545
    case OPC_DINSM:
2546
        if (lsb > msb)
2547
            goto fail;
2548
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2549
        gen_load_gpr(t0, rt);
2550
        tcg_gen_andi_tl(t0, t0, ~mask);
2551
        tcg_gen_shli_tl(t1, t1, lsb);
2552
        tcg_gen_andi_tl(t1, t1, mask);
2553
        tcg_gen_or_tl(t0, t0, t1);
2554
        break;
2555
    case OPC_DINSU:
2556
        if (lsb > msb)
2557
            goto fail;
2558
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2559
        gen_load_gpr(t0, rt);
2560
        tcg_gen_andi_tl(t0, t0, ~mask);
2561
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2562
        tcg_gen_andi_tl(t1, t1, mask);
2563
        tcg_gen_or_tl(t0, t0, t1);
2564
        break;
2565
    case OPC_DINS:
2566
        if (lsb > msb)
2567
            goto fail;
2568
        gen_load_gpr(t0, rt);
2569
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2570
        gen_load_gpr(t0, rt);
2571
        tcg_gen_andi_tl(t0, t0, ~mask);
2572
        tcg_gen_shli_tl(t1, t1, lsb);
2573
        tcg_gen_andi_tl(t1, t1, mask);
2574
        tcg_gen_or_tl(t0, t0, t1);
2575
        break;
2576
#endif
2577
    default:
2578
fail:
2579
        MIPS_INVAL("bitops");
2580
        generate_exception(ctx, EXCP_RI);
2581
        tcg_temp_free(t0);
2582
        tcg_temp_free(t1);
2583
        return;
2584
    }
2585
    gen_store_gpr(t0, rt);
2586
    tcg_temp_free(t0);
2587
    tcg_temp_free(t1);
2588
}
2589

    
2590
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2591
{
2592
    TCGv t0;
2593

    
2594
    if (rd == 0) {
2595
        /* If no destination, treat it as a NOP. */
2596
        MIPS_DEBUG("NOP");
2597
        return;
2598
    }
2599

    
2600
    t0 = tcg_temp_new();
2601
    gen_load_gpr(t0, rt);
2602
    switch (op2) {
2603
    case OPC_WSBH:
2604
        {
2605
            TCGv t1 = tcg_temp_new();
2606

    
2607
            tcg_gen_shri_tl(t1, t0, 8);
2608
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2609
            tcg_gen_shli_tl(t0, t0, 8);
2610
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2611
            tcg_gen_or_tl(t0, t0, t1);
2612
            tcg_temp_free(t1);
2613
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2614
        }
2615
        break;
2616
    case OPC_SEB:
2617
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2618
        break;
2619
    case OPC_SEH:
2620
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2621
        break;
2622
#if defined(TARGET_MIPS64)
2623
    case OPC_DSBH:
2624
        {
2625
            TCGv t1 = tcg_temp_new();
2626

    
2627
            tcg_gen_shri_tl(t1, t0, 8);
2628
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2629
            tcg_gen_shli_tl(t0, t0, 8);
2630
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2631
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2632
            tcg_temp_free(t1);
2633
        }
2634
        break;
2635
    case OPC_DSHD:
2636
        {
2637
            TCGv t1 = tcg_temp_new();
2638

    
2639
            tcg_gen_shri_tl(t1, t0, 16);
2640
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2641
            tcg_gen_shli_tl(t0, t0, 16);
2642
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2643
            tcg_gen_or_tl(t0, t0, t1);
2644
            tcg_gen_shri_tl(t1, t0, 32);
2645
            tcg_gen_shli_tl(t0, t0, 32);
2646
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2647
            tcg_temp_free(t1);
2648
        }
2649
        break;
2650
#endif
2651
    default:
2652
        MIPS_INVAL("bsfhl");
2653
        generate_exception(ctx, EXCP_RI);
2654
        tcg_temp_free(t0);
2655
        return;
2656
    }
2657
    tcg_temp_free(t0);
2658
}
2659

    
2660
#ifndef CONFIG_USER_ONLY
2661
/* CP0 (MMU and control) */
2662
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2663
{
2664
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2665

    
2666
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2667
    tcg_gen_ext_i32_tl(t, r_tmp);
2668
    tcg_temp_free_i32(r_tmp);
2669
}
2670

    
2671
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2672
{
2673
    tcg_gen_ld_tl(t, cpu_env, off);
2674
    tcg_gen_ext32s_tl(t, t);
2675
}
2676

    
2677
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2678
{
2679
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2680

    
2681
    tcg_gen_trunc_tl_i32(r_tmp, t);
2682
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2683
    tcg_temp_free_i32(r_tmp);
2684
}
2685

    
2686
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2687
{
2688
    tcg_gen_ext32s_tl(t, t);
2689
    tcg_gen_st_tl(t, cpu_env, off);
2690
}
2691

    
2692
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2693
{
2694
    const char *rn = "invalid";
2695

    
2696
    if (sel != 0)
2697
        check_insn(env, ctx, ISA_MIPS32);
2698

    
2699
    switch (reg) {
2700
    case 0:
2701
        switch (sel) {
2702
        case 0:
2703
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
2704
            rn = "Index";
2705
            break;
2706
        case 1:
2707
            check_insn(env, ctx, ASE_MT);
2708
            gen_helper_mfc0_mvpcontrol(t0);
2709
            rn = "MVPControl";
2710
            break;
2711
        case 2:
2712
            check_insn(env, ctx, ASE_MT);
2713
            gen_helper_mfc0_mvpconf0(t0);
2714
            rn = "MVPConf0";
2715
            break;
2716
        case 3:
2717
            check_insn(env, ctx, ASE_MT);
2718
            gen_helper_mfc0_mvpconf1(t0);
2719
            rn = "MVPConf1";
2720
            break;
2721
        default:
2722
            goto die;
2723
        }
2724
        break;
2725
    case 1:
2726
        switch (sel) {
2727
        case 0:
2728
            gen_helper_mfc0_random(t0);
2729
            rn = "Random";
2730
            break;
2731
        case 1:
2732
            check_insn(env, ctx, ASE_MT);
2733
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
2734
            rn = "VPEControl";
2735
            break;
2736
        case 2:
2737
            check_insn(env, ctx, ASE_MT);
2738
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
2739
            rn = "VPEConf0";
2740
            break;
2741
        case 3:
2742
            check_insn(env, ctx, ASE_MT);
2743
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
2744
            rn = "VPEConf1";
2745
            break;
2746
        case 4:
2747
            check_insn(env, ctx, ASE_MT);
2748
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask));
2749
            rn = "YQMask";
2750
            break;
2751
        case 5:
2752
            check_insn(env, ctx, ASE_MT);
2753
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule));
2754
            rn = "VPESchedule";
2755
            break;
2756
        case 6:
2757
            check_insn(env, ctx, ASE_MT);
2758
            gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack));
2759
            rn = "VPEScheFBack";
2760
            break;
2761
        case 7:
2762
            check_insn(env, ctx, ASE_MT);
2763
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
2764
            rn = "VPEOpt";
2765
            break;
2766
        default:
2767
            goto die;
2768
        }
2769
        break;
2770
    case 2:
2771
        switch (sel) {
2772
        case 0:
2773
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2774
            tcg_gen_ext32s_tl(t0, t0);
2775
            rn = "EntryLo0";
2776
            break;
2777
        case 1:
2778
            check_insn(env, ctx, ASE_MT);
2779
            gen_helper_mfc0_tcstatus(t0);
2780
            rn = "TCStatus";
2781
            break;
2782
        case 2:
2783
            check_insn(env, ctx, ASE_MT);
2784
            gen_helper_mfc0_tcbind(t0);
2785
            rn = "TCBind";
2786
            break;
2787
        case 3:
2788
            check_insn(env, ctx, ASE_MT);
2789
            gen_helper_mfc0_tcrestart(t0);
2790
            rn = "TCRestart";
2791
            break;
2792
        case 4:
2793
            check_insn(env, ctx, ASE_MT);
2794
            gen_helper_mfc0_tchalt(t0);
2795
            rn = "TCHalt";
2796
            break;
2797
        case 5:
2798
            check_insn(env, ctx, ASE_MT);
2799
            gen_helper_mfc0_tccontext(t0);
2800
            rn = "TCContext";
2801
            break;
2802
        case 6:
2803
            check_insn(env, ctx, ASE_MT);
2804
            gen_helper_mfc0_tcschedule(t0);
2805
            rn = "TCSchedule";
2806
            break;
2807
        case 7:
2808
            check_insn(env, ctx, ASE_MT);
2809
            gen_helper_mfc0_tcschefback(t0);
2810
            rn = "TCScheFBack";
2811
            break;
2812
        default:
2813
            goto die;
2814
        }
2815
        break;
2816
    case 3:
2817
        switch (sel) {
2818
        case 0:
2819
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
2820
            tcg_gen_ext32s_tl(t0, t0);
2821
            rn = "EntryLo1";
2822
            break;
2823
        default:
2824
            goto die;
2825
        }
2826
        break;
2827
    case 4:
2828
        switch (sel) {
2829
        case 0:
2830
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
2831
            tcg_gen_ext32s_tl(t0, t0);
2832
            rn = "Context";
2833
            break;
2834
        case 1:
2835
//            gen_helper_mfc0_contextconfig(t0); /* SmartMIPS ASE */
2836
            rn = "ContextConfig";
2837
//            break;
2838
        default:
2839
            goto die;
2840
        }
2841
        break;
2842
    case 5:
2843
        switch (sel) {
2844
        case 0:
2845
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
2846
            rn = "PageMask";
2847
            break;
2848
        case 1:
2849
            check_insn(env, ctx, ISA_MIPS32R2);
2850
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
2851
            rn = "PageGrain";
2852
            break;
2853
        default:
2854
            goto die;
2855
        }
2856
        break;
2857
    case 6:
2858
        switch (sel) {
2859
        case 0:
2860
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
2861
            rn = "Wired";
2862
            break;
2863
        case 1:
2864
            check_insn(env, ctx, ISA_MIPS32R2);
2865
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
2866
            rn = "SRSConf0";
2867
            break;
2868
        case 2:
2869
            check_insn(env, ctx, ISA_MIPS32R2);
2870
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
2871
            rn = "SRSConf1";
2872
            break;
2873
        case 3:
2874
            check_insn(env, ctx, ISA_MIPS32R2);
2875
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
2876
            rn = "SRSConf2";
2877
            break;
2878
        case 4:
2879
            check_insn(env, ctx, ISA_MIPS32R2);
2880
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
2881
            rn = "SRSConf3";
2882
            break;
2883
        case 5:
2884
            check_insn(env, ctx, ISA_MIPS32R2);
2885
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
2886
            rn = "SRSConf4";
2887
            break;
2888
        default:
2889
            goto die;
2890
        }
2891
        break;
2892
    case 7:
2893
        switch (sel) {
2894
        case 0:
2895
            check_insn(env, ctx, ISA_MIPS32R2);
2896
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
2897
            rn = "HWREna";
2898
            break;
2899
        default:
2900
            goto die;
2901
        }
2902
        break;
2903
    case 8:
2904
        switch (sel) {
2905
        case 0:
2906
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
2907
            tcg_gen_ext32s_tl(t0, t0);
2908
            rn = "BadVAddr";
2909
            break;
2910
        default:
2911
            goto die;
2912
       }
2913
        break;
2914
    case 9:
2915
        switch (sel) {
2916
        case 0:
2917
            /* Mark as an IO operation because we read the time.  */
2918
            if (use_icount)
2919
                gen_io_start();
2920
            gen_helper_mfc0_count(t0);
2921
            if (use_icount) {
2922
                gen_io_end();
2923
                ctx->bstate = BS_STOP;
2924
            }
2925
            rn = "Count";
2926
            break;
2927
        /* 6,7 are implementation dependent */
2928
        default:
2929
            goto die;
2930
        }
2931
        break;
2932
    case 10:
2933
        switch (sel) {
2934
        case 0:
2935
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
2936
            tcg_gen_ext32s_tl(t0, t0);
2937
            rn = "EntryHi";
2938
            break;
2939
        default:
2940
            goto die;
2941
        }
2942
        break;
2943
    case 11:
2944
        switch (sel) {
2945
        case 0:
2946
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
2947
            rn = "Compare";
2948
            break;
2949
        /* 6,7 are implementation dependent */
2950
        default:
2951
            goto die;
2952
        }
2953
        break;
2954
    case 12:
2955
        switch (sel) {
2956
        case 0:
2957
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
2958
            rn = "Status";
2959
            break;
2960
        case 1:
2961
            check_insn(env, ctx, ISA_MIPS32R2);
2962
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
2963
            rn = "IntCtl";
2964
            break;
2965
        case 2:
2966
            check_insn(env, ctx, ISA_MIPS32R2);
2967
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
2968
            rn = "SRSCtl";
2969
            break;
2970
        case 3:
2971
            check_insn(env, ctx, ISA_MIPS32R2);
2972
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
2973
            rn = "SRSMap";
2974
            break;
2975
        default:
2976
            goto die;
2977
       }
2978
        break;
2979
    case 13:
2980
        switch (sel) {
2981
        case 0:
2982
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
2983
            rn = "Cause";
2984
            break;
2985
        default:
2986
            goto die;
2987
       }
2988
        break;
2989
    case 14:
2990
        switch (sel) {
2991
        case 0:
2992
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
2993
            tcg_gen_ext32s_tl(t0, t0);
2994
            rn = "EPC";
2995
            break;
2996
        default:
2997
            goto die;
2998
        }
2999
        break;
3000
    case 15:
3001
        switch (sel) {
3002
        case 0:
3003
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
3004
            rn = "PRid";
3005
            break;
3006
        case 1:
3007
            check_insn(env, ctx, ISA_MIPS32R2);
3008
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
3009
            rn = "EBase";
3010
            break;
3011
        default:
3012
            goto die;
3013
       }
3014
        break;
3015
    case 16:
3016
        switch (sel) {
3017
        case 0:
3018
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
3019
            rn = "Config";
3020
            break;
3021
        case 1:
3022
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
3023
            rn = "Config1";
3024
            break;
3025
        case 2:
3026
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
3027
            rn = "Config2";
3028
            break;
3029
        case 3:
3030
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
3031
            rn = "Config3";
3032
            break;
3033
        /* 4,5 are reserved */
3034
        /* 6,7 are implementation dependent */
3035
        case 6:
3036
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
3037
            rn = "Config6";
3038
            break;
3039
        case 7:
3040
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
3041
            rn = "Config7";
3042
            break;
3043
        default:
3044
            goto die;
3045
        }
3046
        break;
3047
    case 17:
3048
        switch (sel) {
3049
        case 0:
3050
            gen_helper_mfc0_lladdr(t0);
3051
            rn = "LLAddr";
3052
            break;
3053
        default:
3054
            goto die;
3055
        }
3056
        break;
3057
    case 18:
3058
        switch (sel) {
3059
        case 0 ... 7:
3060
            gen_helper_1i(mfc0_watchlo, t0, sel);
3061
            rn = "WatchLo";
3062
            break;
3063
        default:
3064
            goto die;
3065
        }
3066
        break;
3067
    case 19:
3068
        switch (sel) {
3069
        case 0 ...7:
3070
            gen_helper_1i(mfc0_watchhi, t0, sel);
3071
            rn = "WatchHi";
3072
            break;
3073
        default:
3074
            goto die;
3075
        }
3076
        break;
3077
    case 20:
3078
        switch (sel) {
3079
        case 0:
3080
#if defined(TARGET_MIPS64)
3081
            check_insn(env, ctx, ISA_MIPS3);
3082
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
3083
            tcg_gen_ext32s_tl(t0, t0);
3084
            rn = "XContext";
3085
            break;
3086
#endif
3087
        default:
3088
            goto die;
3089
        }
3090
        break;
3091
    case 21:
3092
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3093
        switch (sel) {
3094
        case 0:
3095
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
3096
            rn = "Framemask";
3097
            break;
3098
        default:
3099
            goto die;
3100
        }
3101
        break;
3102
    case 22:
3103
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
3104
        rn = "'Diagnostic"; /* implementation dependent */
3105
        break;
3106
    case 23:
3107
        switch (sel) {
3108
        case 0:
3109
            gen_helper_mfc0_debug(t0); /* EJTAG support */
3110
            rn = "Debug";
3111
            break;
3112
        case 1:
3113
//            gen_helper_mfc0_tracecontrol(t0); /* PDtrace support */
3114
            rn = "TraceControl";
3115
//            break;
3116
        case 2:
3117
//            gen_helper_mfc0_tracecontrol2(t0); /* PDtrace support */
3118
            rn = "TraceControl2";
3119
//            break;
3120
        case 3:
3121
//            gen_helper_mfc0_usertracedata(t0); /* PDtrace support */
3122
            rn = "UserTraceData";
3123
//            break;
3124
        case 4:
3125
//            gen_helper_mfc0_tracebpc(t0); /* PDtrace support */
3126
            rn = "TraceBPC";
3127
//            break;
3128
        default:
3129
            goto die;
3130
        }
3131
        break;
3132
    case 24:
3133
        switch (sel) {
3134
        case 0:
3135
            /* EJTAG support */
3136
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
3137
            tcg_gen_ext32s_tl(t0, t0);
3138
            rn = "DEPC";
3139
            break;
3140
        default:
3141
            goto die;
3142
        }
3143
        break;
3144
    case 25:
3145
        switch (sel) {
3146
        case 0:
3147
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
3148
            rn = "Performance0";
3149
            break;
3150
        case 1:
3151
//            gen_helper_mfc0_performance1(t0);
3152
            rn = "Performance1";
3153
//            break;
3154
        case 2:
3155
//            gen_helper_mfc0_performance2(t0);
3156
            rn = "Performance2";
3157
//            break;
3158
        case 3:
3159
//            gen_helper_mfc0_performance3(t0);
3160
            rn = "Performance3";
3161
//            break;
3162
        case 4:
3163
//            gen_helper_mfc0_performance4(t0);
3164
            rn = "Performance4";
3165
//            break;
3166
        case 5:
3167
//            gen_helper_mfc0_performance5(t0);
3168
            rn = "Performance5";
3169
//            break;
3170
        case 6:
3171
//            gen_helper_mfc0_performance6(t0);
3172
            rn = "Performance6";
3173
//            break;
3174
        case 7:
3175
//            gen_helper_mfc0_performance7(t0);
3176
            rn = "Performance7";
3177
//            break;
3178
        default:
3179
            goto die;
3180
        }
3181
        break;
3182
    case 26:
3183
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
3184
        rn = "ECC";
3185
        break;
3186
    case 27:
3187
        switch (sel) {
3188
        case 0 ... 3:
3189
            tcg_gen_movi_tl(t0, 0); /* unimplemented */
3190
            rn = "CacheErr";
3191
            break;
3192
        default:
3193
            goto die;
3194
        }
3195
        break;
3196
    case 28:
3197
        switch (sel) {
3198
        case 0:
3199
        case 2:
3200
        case 4:
3201
        case 6:
3202
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
3203
            rn = "TagLo";
3204
            break;
3205
        case 1:
3206
        case 3:
3207
        case 5:
3208
        case 7:
3209
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
3210
            rn = "DataLo";
3211
            break;
3212
        default:
3213
            goto die;
3214
        }
3215
        break;
3216
    case 29:
3217
        switch (sel) {
3218
        case 0:
3219
        case 2:
3220
        case 4:
3221
        case 6:
3222
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
3223
            rn = "TagHi";
3224
            break;
3225
        case 1:
3226
        case 3:
3227
        case 5:
3228
        case 7:
3229
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
3230
            rn = "DataHi";
3231
            break;
3232
        default:
3233
            goto die;
3234
        }
3235
        break;
3236
    case 30:
3237
        switch (sel) {
3238
        case 0:
3239
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3240
            tcg_gen_ext32s_tl(t0, t0);
3241
            rn = "ErrorEPC";
3242
            break;
3243
        default:
3244
            goto die;
3245
        }
3246
        break;
3247
    case 31:
3248
        switch (sel) {
3249
        case 0:
3250
            /* EJTAG support */
3251
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
3252
            rn = "DESAVE";
3253
            break;
3254
        default:
3255
            goto die;
3256
        }
3257
        break;
3258
    default:
3259
       goto die;
3260
    }
3261
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3262
    return;
3263

    
3264
die:
3265
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3266
    generate_exception(ctx, EXCP_RI);
3267
}
3268

    
3269
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3270
{
3271
    const char *rn = "invalid";
3272

    
3273
    if (sel != 0)
3274
        check_insn(env, ctx, ISA_MIPS32);
3275

    
3276
    if (use_icount)
3277
        gen_io_start();
3278

    
3279
    switch (reg) {
3280
    case 0:
3281
        switch (sel) {
3282
        case 0:
3283
            gen_helper_mtc0_index(t0);
3284
            rn = "Index";
3285
            break;
3286
        case 1:
3287
            check_insn(env, ctx, ASE_MT);
3288
            gen_helper_mtc0_mvpcontrol(t0);
3289
            rn = "MVPControl";
3290
            break;
3291
        case 2:
3292
            check_insn(env, ctx, ASE_MT);
3293
            /* ignored */
3294
            rn = "MVPConf0";
3295
            break;
3296
        case 3:
3297
            check_insn(env, ctx, ASE_MT);
3298
            /* ignored */
3299
            rn = "MVPConf1";
3300
            break;
3301
        default:
3302
            goto die;
3303
        }
3304
        break;
3305
    case 1:
3306
        switch (sel) {
3307
        case 0:
3308
            /* ignored */
3309
            rn = "Random";
3310
            break;
3311
        case 1:
3312
            check_insn(env, ctx, ASE_MT);
3313
            gen_helper_mtc0_vpecontrol(t0);
3314
            rn = "VPEControl";
3315
            break;
3316
        case 2:
3317
            check_insn(env, ctx, ASE_MT);
3318
            gen_helper_mtc0_vpeconf0(t0);
3319
            rn = "VPEConf0";
3320
            break;
3321
        case 3:
3322
            check_insn(env, ctx, ASE_MT);
3323
            gen_helper_mtc0_vpeconf1(t0);
3324
            rn = "VPEConf1";
3325
            break;
3326
        case 4:
3327
            check_insn(env, ctx, ASE_MT);
3328
            gen_helper_mtc0_yqmask(t0);
3329
            rn = "YQMask";
3330
            break;
3331
        case 5:
3332
            check_insn(env, ctx, ASE_MT);
3333
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
3334
            rn = "VPESchedule";
3335
            break;
3336
        case 6:
3337
            check_insn(env, ctx, ASE_MT);
3338
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
3339
            rn = "VPEScheFBack";
3340
            break;
3341
        case 7:
3342
            check_insn(env, ctx, ASE_MT);
3343
            gen_helper_mtc0_vpeopt(t0);
3344
            rn = "VPEOpt";
3345
            break;
3346
        default:
3347
            goto die;
3348
        }
3349
        break;
3350
    case 2:
3351
        switch (sel) {
3352
        case 0:
3353
            gen_helper_mtc0_entrylo0(t0);
3354
            rn = "EntryLo0";
3355
            break;
3356
        case 1:
3357
            check_insn(env, ctx, ASE_MT);
3358
            gen_helper_mtc0_tcstatus(t0);
3359
            rn = "TCStatus";
3360
            break;
3361
        case 2:
3362
            check_insn(env, ctx, ASE_MT);
3363
            gen_helper_mtc0_tcbind(t0);
3364
            rn = "TCBind";
3365
            break;
3366
        case 3:
3367
            check_insn(env, ctx, ASE_MT);
3368
            gen_helper_mtc0_tcrestart(t0);
3369
            rn = "TCRestart";
3370
            break;
3371
        case 4:
3372
            check_insn(env, ctx, ASE_MT);
3373
            gen_helper_mtc0_tchalt(t0);
3374
            rn = "TCHalt";
3375
            break;
3376
        case 5:
3377
            check_insn(env, ctx, ASE_MT);
3378
            gen_helper_mtc0_tccontext(t0);
3379
            rn = "TCContext";
3380
            break;
3381
        case 6:
3382
            check_insn(env, ctx, ASE_MT);
3383
            gen_helper_mtc0_tcschedule(t0);
3384
            rn = "TCSchedule";
3385
            break;
3386
        case 7:
3387
            check_insn(env, ctx, ASE_MT);
3388
            gen_helper_mtc0_tcschefback(t0);
3389
            rn = "TCScheFBack";
3390
            break;
3391
        default:
3392
            goto die;
3393
        }
3394
        break;
3395
    case 3:
3396
        switch (sel) {
3397
        case 0:
3398
            gen_helper_mtc0_entrylo1(t0);
3399
            rn = "EntryLo1";
3400
            break;
3401
        default:
3402
            goto die;
3403
        }
3404
        break;
3405
    case 4:
3406
        switch (sel) {
3407
        case 0:
3408
            gen_helper_mtc0_context(t0);
3409
            rn = "Context";
3410
            break;
3411
        case 1:
3412
//            gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
3413
            rn = "ContextConfig";
3414
//            break;
3415
        default:
3416
            goto die;
3417
        }
3418
        break;
3419
    case 5:
3420
        switch (sel) {
3421
        case 0:
3422
            gen_helper_mtc0_pagemask(t0);
3423
            rn = "PageMask";
3424
            break;
3425
        case 1:
3426
            check_insn(env, ctx, ISA_MIPS32R2);
3427
            gen_helper_mtc0_pagegrain(t0);
3428
            rn = "PageGrain";
3429
            break;
3430
        default:
3431
            goto die;
3432
        }
3433
        break;
3434
    case 6:
3435
        switch (sel) {
3436
        case 0:
3437
            gen_helper_mtc0_wired(t0);
3438
            rn = "Wired";
3439
            break;
3440
        case 1:
3441
            check_insn(env, ctx, ISA_MIPS32R2);
3442
            gen_helper_mtc0_srsconf0(t0);
3443
            rn = "SRSConf0";
3444
            break;
3445
        case 2:
3446
            check_insn(env, ctx, ISA_MIPS32R2);
3447
            gen_helper_mtc0_srsconf1(t0);
3448
            rn = "SRSConf1";
3449
            break;
3450
        case 3:
3451
            check_insn(env, ctx, ISA_MIPS32R2);
3452
            gen_helper_mtc0_srsconf2(t0);
3453
            rn = "SRSConf2";
3454
            break;
3455
        case 4:
3456
            check_insn(env, ctx, ISA_MIPS32R2);
3457
            gen_helper_mtc0_srsconf3(t0);
3458
            rn = "SRSConf3";
3459
            break;
3460
        case 5:
3461
            check_insn(env, ctx, ISA_MIPS32R2);
3462
            gen_helper_mtc0_srsconf4(t0);
3463
            rn = "SRSConf4";
3464
            break;
3465
        default:
3466
            goto die;
3467
        }
3468
        break;
3469
    case 7:
3470
        switch (sel) {
3471
        case 0:
3472
            check_insn(env, ctx, ISA_MIPS32R2);
3473
            gen_helper_mtc0_hwrena(t0);
3474
            rn = "HWREna";
3475
            break;
3476
        default:
3477
            goto die;
3478
        }
3479
        break;
3480
    case 8:
3481
        /* ignored */
3482
        rn = "BadVAddr";
3483
        break;
3484
    case 9:
3485
        switch (sel) {
3486
        case 0:
3487
            gen_helper_mtc0_count(t0);
3488
            rn = "Count";
3489
            break;
3490
        /* 6,7 are implementation dependent */
3491
        default:
3492
            goto die;
3493
        }
3494
        /* Stop translation as we may have switched the execution mode */
3495
        ctx->bstate = BS_STOP;
3496
        break;
3497
    case 10:
3498
        switch (sel) {
3499
        case 0:
3500
            gen_helper_mtc0_entryhi(t0);
3501
            rn = "EntryHi";
3502
            break;
3503
        default:
3504
            goto die;
3505
        }
3506
        break;
3507
    case 11:
3508
        switch (sel) {
3509
        case 0:
3510
            gen_helper_mtc0_compare(t0);
3511
            rn = "Compare";
3512
            break;
3513
        /* 6,7 are implementation dependent */
3514
        default:
3515
            goto die;
3516
        }
3517
        /* Stop translation as we may have switched the execution mode */
3518
        ctx->bstate = BS_STOP;
3519
        break;
3520
    case 12:
3521
        switch (sel) {
3522
        case 0:
3523
            gen_helper_mtc0_status(t0);
3524
            /* BS_STOP isn't good enough here, hflags may have changed. */
3525
            gen_save_pc(ctx->pc + 4);
3526
            ctx->bstate = BS_EXCP;
3527
            rn = "Status";
3528
            break;
3529
        case 1:
3530
            check_insn(env, ctx, ISA_MIPS32R2);
3531
            gen_helper_mtc0_intctl(t0);
3532
            /* Stop translation as we may have switched the execution mode */
3533
            ctx->bstate = BS_STOP;
3534
            rn = "IntCtl";
3535
            break;
3536
        case 2:
3537
            check_insn(env, ctx, ISA_MIPS32R2);
3538
            gen_helper_mtc0_srsctl(t0);
3539
            /* Stop translation as we may have switched the execution mode */
3540
            ctx->bstate = BS_STOP;
3541
            rn = "SRSCtl";
3542
            break;
3543
        case 3:
3544
            check_insn(env, ctx, ISA_MIPS32R2);
3545
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
3546
            /* Stop translation as we may have switched the execution mode */
3547
            ctx->bstate = BS_STOP;
3548
            rn = "SRSMap";
3549
            break;
3550
        default:
3551
            goto die;
3552
        }
3553
        break;
3554
    case 13:
3555
        switch (sel) {
3556
        case 0:
3557
            gen_helper_mtc0_cause(t0);
3558
            rn = "Cause";
3559
            break;
3560
        default:
3561
            goto die;
3562
        }
3563
        /* Stop translation as we may have switched the execution mode */
3564
        ctx->bstate = BS_STOP;
3565
        break;
3566
    case 14:
3567
        switch (sel) {
3568
        case 0:
3569
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
3570
            rn = "EPC";
3571
            break;
3572
        default:
3573
            goto die;
3574
        }
3575
        break;
3576
    case 15:
3577
        switch (sel) {
3578
        case 0:
3579
            /* ignored */
3580
            rn = "PRid";
3581
            break;
3582
        case 1:
3583
            check_insn(env, ctx, ISA_MIPS32R2);
3584
            gen_helper_mtc0_ebase(t0);
3585
            rn = "EBase";
3586
            break;
3587
        default:
3588
            goto die;
3589
        }
3590
        break;
3591
    case 16:
3592
        switch (sel) {
3593
        case 0:
3594
            gen_helper_mtc0_config0(t0);
3595
            rn = "Config";
3596
            /* Stop translation as we may have switched the execution mode */
3597
            ctx->bstate = BS_STOP;
3598
            break;
3599
        case 1:
3600
            /* ignored, read only */
3601
            rn = "Config1";
3602
            break;
3603
        case 2:
3604
            gen_helper_mtc0_config2(t0);
3605
            rn = "Config2";
3606
            /* Stop translation as we may have switched the execution mode */
3607
            ctx->bstate = BS_STOP;
3608
            break;
3609
        case 3:
3610
            /* ignored, read only */
3611
            rn = "Config3";
3612
            break;
3613
        /* 4,5 are reserved */
3614
        /* 6,7 are implementation dependent */
3615
        case 6:
3616
            /* ignored */
3617
            rn = "Config6";
3618
            break;
3619
        case 7:
3620
            /* ignored */
3621
            rn = "Config7";
3622
            break;
3623
        default:
3624
            rn = "Invalid config selector";
3625
            goto die;
3626
        }
3627
        break;
3628
    case 17:
3629
        switch (sel) {
3630
        case 0:
3631
            /* ignored */
3632
            rn = "LLAddr";
3633
            break;
3634
        default:
3635
            goto die;
3636
        }
3637
        break;
3638
    case 18:
3639
        switch (sel) {
3640
        case 0 ... 7:
3641
            gen_helper_1i(mtc0_watchlo, t0, sel);
3642
            rn = "WatchLo";
3643
            break;
3644
        default:
3645
            goto die;
3646
        }
3647
        break;
3648
    case 19:
3649
        switch (sel) {
3650
        case 0 ... 7:
3651
            gen_helper_1i(mtc0_watchhi, t0, sel);
3652
            rn = "WatchHi";
3653
            break;
3654
        default:
3655
            goto die;
3656
        }
3657
        break;
3658
    case 20:
3659
        switch (sel) {
3660
        case 0:
3661
#if defined(TARGET_MIPS64)
3662
            check_insn(env, ctx, ISA_MIPS3);
3663
            gen_helper_mtc0_xcontext(t0);
3664
            rn = "XContext";
3665
            break;
3666
#endif
3667
        default:
3668
            goto die;
3669
        }
3670
        break;
3671
    case 21:
3672
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3673
        switch (sel) {
3674
        case 0:
3675
            gen_helper_mtc0_framemask(t0);
3676
            rn = "Framemask";
3677
            break;
3678
        default:
3679
            goto die;
3680
        }
3681
        break;
3682
    case 22:
3683
        /* ignored */
3684
        rn = "Diagnostic"; /* implementation dependent */
3685
        break;
3686
    case 23:
3687
        switch (sel) {
3688
        case 0:
3689
            gen_helper_mtc0_debug(t0); /* EJTAG support */
3690
            /* BS_STOP isn't good enough here, hflags may have changed. */
3691
            gen_save_pc(ctx->pc + 4);
3692
            ctx->bstate = BS_EXCP;
3693
            rn = "Debug";
3694
            break;
3695
        case 1:
3696
//            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
3697
            rn = "TraceControl";
3698
            /* Stop translation as we may have switched the execution mode */
3699
            ctx->bstate = BS_STOP;
3700
//            break;
3701
        case 2:
3702
//            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
3703
            rn = "TraceControl2";
3704
            /* Stop translation as we may have switched the execution mode */
3705
            ctx->bstate = BS_STOP;
3706
//            break;
3707
        case 3:
3708
            /* Stop translation as we may have switched the execution mode */
3709
            ctx->bstate = BS_STOP;
3710
//            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
3711
            rn = "UserTraceData";
3712
            /* Stop translation as we may have switched the execution mode */
3713
            ctx->bstate = BS_STOP;
3714
//            break;
3715
        case 4:
3716
//            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
3717
            /* Stop translation as we may have switched the execution mode */
3718
            ctx->bstate = BS_STOP;
3719
            rn = "TraceBPC";
3720
//            break;
3721
        default:
3722
            goto die;
3723
        }
3724
        break;
3725
    case 24:
3726
        switch (sel) {
3727
        case 0:
3728
            /* EJTAG support */
3729
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
3730
            rn = "DEPC";
3731
            break;
3732
        default:
3733
            goto die;
3734
        }
3735
        break;
3736
    case 25:
3737
        switch (sel) {
3738
        case 0:
3739
            gen_helper_mtc0_performance0(t0);
3740
            rn = "Performance0";
3741
            break;
3742
        case 1:
3743
//            gen_helper_mtc0_performance1(t0);
3744
            rn = "Performance1";
3745
//            break;
3746
        case 2:
3747
//            gen_helper_mtc0_performance2(t0);
3748
            rn = "Performance2";
3749
//            break;
3750
        case 3:
3751
//            gen_helper_mtc0_performance3(t0);
3752
            rn = "Performance3";
3753
//            break;
3754
        case 4:
3755
//            gen_helper_mtc0_performance4(t0);
3756
            rn = "Performance4";
3757
//            break;
3758
        case 5:
3759
//            gen_helper_mtc0_performance5(t0);
3760
            rn = "Performance5";
3761
//            break;
3762
        case 6:
3763
//            gen_helper_mtc0_performance6(t0);
3764
            rn = "Performance6";
3765
//            break;
3766
        case 7:
3767
//            gen_helper_mtc0_performance7(t0);
3768
            rn = "Performance7";
3769
//            break;
3770
        default:
3771
            goto die;
3772
        }
3773
       break;
3774
    case 26:
3775
        /* ignored */
3776
        rn = "ECC";
3777
        break;
3778
    case 27:
3779
        switch (sel) {
3780
        case 0 ... 3:
3781
            /* ignored */
3782
            rn = "CacheErr";
3783
            break;
3784
        default:
3785
            goto die;
3786
        }
3787
       break;
3788
    case 28:
3789
        switch (sel) {
3790
        case 0:
3791
        case 2:
3792
        case 4:
3793
        case 6:
3794
            gen_helper_mtc0_taglo(t0);
3795
            rn = "TagLo";
3796
            break;
3797
        case 1:
3798
        case 3:
3799
        case 5:
3800
        case 7:
3801
            gen_helper_mtc0_datalo(t0);
3802
            rn = "DataLo";
3803
            break;
3804
        default:
3805
            goto die;
3806
        }
3807
        break;
3808
    case 29:
3809
        switch (sel) {
3810
        case 0:
3811
        case 2:
3812
        case 4:
3813
        case 6:
3814
            gen_helper_mtc0_taghi(t0);
3815
            rn = "TagHi";
3816
            break;
3817
        case 1:
3818
        case 3:
3819
        case 5:
3820
        case 7:
3821
            gen_helper_mtc0_datahi(t0);
3822
            rn = "DataHi";
3823
            break;
3824
        default:
3825
            rn = "invalid sel";
3826
            goto die;
3827
        }
3828
       break;
3829
    case 30:
3830
        switch (sel) {
3831
        case 0:
3832
            gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
3833
            rn = "ErrorEPC";
3834
            break;
3835
        default:
3836
            goto die;
3837
        }
3838
        break;
3839
    case 31:
3840
        switch (sel) {
3841
        case 0:
3842
            /* EJTAG support */
3843
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
3844
            rn = "DESAVE";
3845
            break;
3846
        default:
3847
            goto die;
3848
        }
3849
        /* Stop translation as we may have switched the execution mode */
3850
        ctx->bstate = BS_STOP;
3851
        break;
3852
    default:
3853
       goto die;
3854
    }
3855
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3856
    /* For simplicity assume that all writes can cause interrupts.  */
3857
    if (use_icount) {
3858
        gen_io_end();
3859
        ctx->bstate = BS_STOP;
3860
    }
3861
    return;
3862

    
3863
die:
3864
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3865
    generate_exception(ctx, EXCP_RI);
3866
}
3867

    
3868
#if defined(TARGET_MIPS64)
3869
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3870
{
3871
    const char *rn = "invalid";
3872

    
3873
    if (sel != 0)
3874
        check_insn(env, ctx, ISA_MIPS64);
3875

    
3876
    switch (reg) {
3877
    case 0:
3878
        switch (sel) {
3879
        case 0:
3880
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
3881
            rn = "Index";
3882
            break;
3883
        case 1:
3884
            check_insn(env, ctx, ASE_MT);
3885
            gen_helper_mfc0_mvpcontrol(t0);
3886
            rn = "MVPControl";
3887
            break;
3888
        case 2:
3889
            check_insn(env, ctx, ASE_MT);
3890
            gen_helper_mfc0_mvpconf0(t0);
3891
            rn = "MVPConf0";
3892
            break;
3893
        case 3:
3894
            check_insn(env, ctx, ASE_MT);
3895
            gen_helper_mfc0_mvpconf1(t0);
3896
            rn = "MVPConf1";
3897
            break;
3898
        default:
3899
            goto die;
3900
        }
3901
        break;
3902
    case 1:
3903
        switch (sel) {
3904
        case 0:
3905
            gen_helper_mfc0_random(t0);
3906
            rn = "Random";
3907
            break;
3908
        case 1:
3909
            check_insn(env, ctx, ASE_MT);
3910
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
3911
            rn = "VPEControl";
3912
            break;
3913
        case 2:
3914
            check_insn(env, ctx, ASE_MT);
3915
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
3916
            rn = "VPEConf0";
3917
            break;
3918
        case 3:
3919
            check_insn(env, ctx, ASE_MT);
3920
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
3921
            rn = "VPEConf1";
3922
            break;
3923
        case 4:
3924
            check_insn(env, ctx, ASE_MT);
3925
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask));
3926
            rn = "YQMask";
3927
            break;
3928
        case 5:
3929
            check_insn(env, ctx, ASE_MT);
3930
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
3931
            rn = "VPESchedule";
3932
            break;
3933
        case 6:
3934
            check_insn(env, ctx, ASE_MT);
3935
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3936
            rn = "VPEScheFBack";
3937
            break;
3938
        case 7:
3939
            check_insn(env, ctx, ASE_MT);
3940
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
3941
            rn = "VPEOpt";
3942
            break;
3943
        default:
3944
            goto die;
3945
        }
3946
        break;
3947
    case 2:
3948
        switch (sel) {
3949
        case 0:
3950
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3951
            rn = "EntryLo0";
3952
            break;
3953
        case 1:
3954
            check_insn(env, ctx, ASE_MT);
3955
            gen_helper_mfc0_tcstatus(t0);
3956
            rn = "TCStatus";
3957
            break;
3958
        case 2:
3959
            check_insn(env, ctx, ASE_MT);
3960
            gen_helper_mfc0_tcbind(t0);
3961
            rn = "TCBind";
3962
            break;
3963
        case 3:
3964
            check_insn(env, ctx, ASE_MT);
3965
            gen_helper_dmfc0_tcrestart(t0);
3966
            rn = "TCRestart";
3967
            break;
3968
        case 4:
3969
            check_insn(env, ctx, ASE_MT);
3970
            gen_helper_dmfc0_tchalt(t0);
3971
            rn = "TCHalt";
3972
            break;
3973
        case 5:
3974
            check_insn(env, ctx, ASE_MT);
3975
            gen_helper_dmfc0_tccontext(t0);
3976
            rn = "TCContext";
3977
            break;
3978
        case 6:
3979
            check_insn(env, ctx, ASE_MT);
3980
            gen_helper_dmfc0_tcschedule(t0);
3981
            rn = "TCSchedule";
3982
            break;
3983
        case 7:
3984
            check_insn(env, ctx, ASE_MT);
3985
            gen_helper_dmfc0_tcschefback(t0);
3986
            rn = "TCScheFBack";
3987
            break;
3988
        default:
3989
            goto die;
3990
        }
3991
        break;
3992
    case 3:
3993
        switch (sel) {
3994
        case 0:
3995
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3996
            rn = "EntryLo1";
3997
            break;
3998
        default:
3999
            goto die;
4000
        }
4001
        break;
4002
    case 4:
4003
        switch (sel) {
4004
        case 0:
4005
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
4006
            rn = "Context";
4007
            break;
4008
        case 1:
4009
//            gen_helper_dmfc0_contextconfig(t0); /* SmartMIPS ASE */
4010
            rn = "ContextConfig";
4011
//            break;
4012
        default:
4013
            goto die;
4014
        }
4015
        break;
4016
    case 5:
4017
        switch (sel) {
4018
        case 0:
4019
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
4020
            rn = "PageMask";
4021
            break;
4022
        case 1:
4023
            check_insn(env, ctx, ISA_MIPS32R2);
4024
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
4025
            rn = "PageGrain";
4026
            break;
4027
        default:
4028
            goto die;
4029
        }
4030
        break;
4031
    case 6:
4032
        switch (sel) {
4033
        case 0:
4034
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
4035
            rn = "Wired";
4036
            break;
4037
        case 1:
4038
            check_insn(env, ctx, ISA_MIPS32R2);
4039
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
4040
            rn = "SRSConf0";
4041
            break;
4042
        case 2:
4043
            check_insn(env, ctx, ISA_MIPS32R2);
4044
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
4045
            rn = "SRSConf1";
4046
            break;
4047
        case 3:
4048
            check_insn(env, ctx, ISA_MIPS32R2);
4049
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
4050
            rn = "SRSConf2";
4051
            break;
4052
        case 4:
4053
            check_insn(env, ctx, ISA_MIPS32R2);
4054
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
4055
            rn = "SRSConf3";
4056
            break;
4057
        case 5:
4058
            check_insn(env, ctx, ISA_MIPS32R2);
4059
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
4060
            rn = "SRSConf4";
4061
            break;
4062
        default:
4063
            goto die;
4064
        }
4065
        break;
4066
    case 7:
4067
        switch (sel) {
4068
        case 0:
4069
            check_insn(env, ctx, ISA_MIPS32R2);
4070
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
4071
            rn = "HWREna";
4072
            break;
4073
        default:
4074
            goto die;
4075
        }
4076
        break;
4077
    case 8:
4078
        switch (sel) {
4079
        case 0:
4080
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4081
            rn = "BadVAddr";
4082
            break;
4083
        default:
4084
            goto die;
4085
        }
4086
        break;
4087
    case 9:
4088
        switch (sel) {
4089
        case 0:
4090
            /* Mark as an IO operation because we read the time.  */
4091
            if (use_icount)
4092
                gen_io_start();
4093
            gen_helper_mfc0_count(t0);
4094
            if (use_icount) {
4095
                gen_io_end();
4096
                ctx->bstate = BS_STOP;
4097
            }
4098
            rn = "Count";
4099
            break;
4100
        /* 6,7 are implementation dependent */
4101
        default:
4102
            goto die;
4103
        }
4104
        break;
4105
    case 10:
4106
        switch (sel) {
4107
        case 0:
4108
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
4109
            rn = "EntryHi";
4110
            break;
4111
        default:
4112
            goto die;
4113
        }
4114
        break;
4115
    case 11:
4116
        switch (sel) {
4117
        case 0:
4118
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
4119
            rn = "Compare";
4120
            break;
4121
        /* 6,7 are implementation dependent */
4122
        default:
4123
            goto die;
4124
        }
4125
        break;
4126
    case 12:
4127
        switch (sel) {
4128
        case 0:
4129
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
4130
            rn = "Status";
4131
            break;
4132
        case 1:
4133
            check_insn(env, ctx, ISA_MIPS32R2);
4134
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
4135
            rn = "IntCtl";
4136
            break;
4137
        case 2:
4138
            check_insn(env, ctx, ISA_MIPS32R2);
4139
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
4140
            rn = "SRSCtl";
4141
            break;
4142
        case 3:
4143
            check_insn(env, ctx, ISA_MIPS32R2);
4144
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
4145
            rn = "SRSMap";
4146
            break;
4147
        default:
4148
            goto die;
4149
        }
4150
        break;
4151
    case 13:
4152
        switch (sel) {
4153
        case 0:
4154
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
4155
            rn = "Cause";
4156
            break;
4157
        default:
4158
            goto die;
4159
        }
4160
        break;
4161
    case 14:
4162
        switch (sel) {
4163
        case 0:
4164
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4165
            rn = "EPC";
4166
            break;
4167
        default:
4168
            goto die;
4169
        }
4170
        break;
4171
    case 15:
4172
        switch (sel) {
4173
        case 0:
4174
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
4175
            rn = "PRid";
4176
            break;
4177
        case 1:
4178
            check_insn(env, ctx, ISA_MIPS32R2);
4179
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
4180
            rn = "EBase";
4181
            break;
4182
        default:
4183
            goto die;
4184
        }
4185
        break;
4186
    case 16:
4187
        switch (sel) {
4188
        case 0:
4189
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
4190
            rn = "Config";
4191
            break;
4192
        case 1:
4193
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
4194
            rn = "Config1";
4195
            break;
4196
        case 2:
4197
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
4198
            rn = "Config2";
4199
            break;
4200
        case 3:
4201
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
4202
            rn = "Config3";
4203
            break;
4204
       /* 6,7 are implementation dependent */
4205
        case 6:
4206
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
4207
            rn = "Config6";
4208
            break;
4209
        case 7:
4210
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
4211
            rn = "Config7";
4212
            break;
4213
        default:
4214
            goto die;
4215
        }
4216
        break;
4217
    case 17:
4218
        switch (sel) {
4219
        case 0:
4220
            gen_helper_dmfc0_lladdr(t0);
4221
            rn = "LLAddr";
4222
            break;
4223
        default:
4224
            goto die;
4225
        }
4226
        break;
4227
    case 18:
4228
        switch (sel) {
4229
        case 0 ... 7:
4230
            gen_helper_1i(dmfc0_watchlo, t0, sel);
4231
            rn = "WatchLo";
4232
            break;
4233
        default:
4234
            goto die;
4235
        }
4236
        break;
4237
    case 19:
4238
        switch (sel) {
4239
        case 0 ... 7:
4240
            gen_helper_1i(mfc0_watchhi, t0, sel);
4241
            rn = "WatchHi";
4242
            break;
4243
        default:
4244
            goto die;
4245
        }
4246
        break;
4247
    case 20:
4248
        switch (sel) {
4249
        case 0:
4250
            check_insn(env, ctx, ISA_MIPS3);
4251
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
4252
            rn = "XContext";
4253
            break;
4254
        default:
4255
            goto die;
4256
        }
4257
        break;
4258
    case 21:
4259
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4260
        switch (sel) {
4261
        case 0:
4262
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
4263
            rn = "Framemask";
4264
            break;
4265
        default:
4266
            goto die;
4267
        }
4268
        break;
4269
    case 22:
4270
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
4271
        rn = "'Diagnostic"; /* implementation dependent */
4272
        break;
4273
    case 23:
4274
        switch (sel) {
4275
        case 0:
4276
            gen_helper_mfc0_debug(t0); /* EJTAG support */
4277
            rn = "Debug";
4278
            break;
4279
        case 1:
4280
//            gen_helper_dmfc0_tracecontrol(t0); /* PDtrace support */
4281
            rn = "TraceControl";
4282
//            break;
4283
        case 2:
4284
//            gen_helper_dmfc0_tracecontrol2(t0); /* PDtrace support */
4285
            rn = "TraceControl2";
4286
//            break;
4287
        case 3:
4288
//            gen_helper_dmfc0_usertracedata(t0); /* PDtrace support */
4289
            rn = "UserTraceData";
4290
//            break;
4291
        case 4:
4292
//            gen_helper_dmfc0_tracebpc(t0); /* PDtrace support */
4293
            rn = "TraceBPC";
4294
//            break;
4295
        default:
4296
            goto die;
4297
        }
4298
        break;
4299
    case 24:
4300
        switch (sel) {
4301
        case 0:
4302
            /* EJTAG support */
4303
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4304
            rn = "DEPC";
4305
            break;
4306
        default:
4307
            goto die;
4308
        }
4309
        break;
4310
    case 25:
4311
        switch (sel) {
4312
        case 0:
4313
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
4314
            rn = "Performance0";
4315
            break;
4316
        case 1:
4317
//            gen_helper_dmfc0_performance1(t0);
4318
            rn = "Performance1";
4319
//            break;
4320
        case 2:
4321
//            gen_helper_dmfc0_performance2(t0);
4322
            rn = "Performance2";
4323
//            break;
4324
        case 3:
4325
//            gen_helper_dmfc0_performance3(t0);
4326
            rn = "Performance3";
4327
//            break;
4328
        case 4:
4329
//            gen_helper_dmfc0_performance4(t0);
4330
            rn = "Performance4";
4331
//            break;
4332
        case 5:
4333
//            gen_helper_dmfc0_performance5(t0);
4334
            rn = "Performance5";
4335
//            break;
4336
        case 6:
4337
//            gen_helper_dmfc0_performance6(t0);
4338
            rn = "Performance6";
4339
//            break;
4340
        case 7:
4341
//            gen_helper_dmfc0_performance7(t0);
4342
            rn = "Performance7";
4343
//            break;
4344
        default:
4345
            goto die;
4346
        }
4347
        break;
4348
    case 26:
4349
        tcg_gen_movi_tl(t0, 0); /* unimplemented */
4350
        rn = "ECC";
4351
        break;
4352
    case 27:
4353
        switch (sel) {
4354
        /* ignored */
4355
        case 0 ... 3:
4356
            tcg_gen_movi_tl(t0, 0); /* unimplemented */
4357
            rn = "CacheErr";
4358
            break;
4359
        default:
4360
            goto die;
4361
        }
4362
        break;
4363
    case 28:
4364
        switch (sel) {
4365
        case 0:
4366
        case 2:
4367
        case 4:
4368
        case 6:
4369
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
4370
            rn = "TagLo";
4371
            break;
4372
        case 1:
4373
        case 3:
4374
        case 5:
4375
        case 7:
4376
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
4377
            rn = "DataLo";
4378
            break;
4379
        default:
4380
            goto die;
4381
        }
4382
        break;
4383
    case 29:
4384
        switch (sel) {
4385
        case 0:
4386
        case 2:
4387
        case 4:
4388
        case 6:
4389
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
4390
            rn = "TagHi";
4391
            break;
4392
        case 1:
4393
        case 3:
4394
        case 5:
4395
        case 7:
4396
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
4397
            rn = "DataHi";
4398
            break;
4399
        default:
4400
            goto die;
4401
        }
4402
        break;
4403
    case 30:
4404
        switch (sel) {
4405
        case 0:
4406
            tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4407
            rn = "ErrorEPC";
4408
            break;
4409
        default:
4410
            goto die;
4411
        }
4412
        break;
4413
    case 31:
4414
        switch (sel) {
4415
        case 0:
4416
            /* EJTAG support */
4417
            gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
4418
            rn = "DESAVE";
4419
            break;
4420
        default:
4421
            goto die;
4422
        }
4423
        break;
4424
    default:
4425
        goto die;
4426
    }
4427
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4428
    return;
4429

    
4430
die:
4431
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4432
    generate_exception(ctx, EXCP_RI);
4433
}
4434

    
4435
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4436
{
4437
    const char *rn = "invalid";
4438

    
4439
    if (sel != 0)
4440
        check_insn(env, ctx, ISA_MIPS64);
4441

    
4442
    if (use_icount)
4443
        gen_io_start();
4444

    
4445
    switch (reg) {
4446
    case 0:
4447
        switch (sel) {
4448
        case 0:
4449
            gen_helper_mtc0_index(t0);
4450
            rn = "Index";
4451
            break;
4452
        case 1:
4453
            check_insn(env, ctx, ASE_MT);
4454
            gen_helper_mtc0_mvpcontrol(t0);
4455
            rn = "MVPControl";
4456
            break;
4457
        case 2:
4458
            check_insn(env, ctx, ASE_MT);
4459
            /* ignored */
4460
            rn = "MVPConf0";
4461
            break;
4462
        case 3:
4463
            check_insn(env, ctx, ASE_MT);
4464
            /* ignored */
4465
            rn = "MVPConf1";
4466
            break;
4467
        default:
4468
            goto die;
4469
        }
4470
        break;
4471
    case 1:
4472
        switch (sel) {
4473
        case 0:
4474
            /* ignored */
4475
            rn = "Random";
4476
            break;
4477
        case 1:
4478
            check_insn(env, ctx, ASE_MT);
4479
            gen_helper_mtc0_vpecontrol(t0);
4480
            rn = "VPEControl";
4481
            break;
4482
        case 2:
4483
            check_insn(env, ctx, ASE_MT);
4484
            gen_helper_mtc0_vpeconf0(t0);
4485
            rn = "VPEConf0";
4486
            break;
4487
        case 3:
4488
            check_insn(env, ctx, ASE_MT);
4489
            gen_helper_mtc0_vpeconf1(t0);
4490
            rn = "VPEConf1";
4491
            break;
4492
        case 4:
4493
            check_insn(env, ctx, ASE_MT);
4494
            gen_helper_mtc0_yqmask(t0);
4495
            rn = "YQMask";
4496
            break;
4497
        case 5:
4498
            check_insn(env, ctx, ASE_MT);
4499
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4500
            rn = "VPESchedule";
4501
            break;
4502
        case 6:
4503
            check_insn(env, ctx, ASE_MT);
4504
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4505
            rn = "VPEScheFBack";
4506
            break;
4507
        case 7:
4508
            check_insn(env, ctx, ASE_MT);
4509
            gen_helper_mtc0_vpeopt(t0);
4510
            rn = "VPEOpt";
4511
            break;
4512
        default:
4513
            goto die;
4514
        }
4515
        break;
4516
    case 2:
4517
        switch (sel) {
4518
        case 0:
4519
            gen_helper_mtc0_entrylo0(t0);
4520
            rn = "EntryLo0";
4521
            break;
4522
        case 1:
4523
            check_insn(env, ctx, ASE_MT);
4524
            gen_helper_mtc0_tcstatus(t0);
4525
            rn = "TCStatus";
4526
            break;
4527
        case 2:
4528
            check_insn(env, ctx, ASE_MT);
4529
            gen_helper_mtc0_tcbind(t0);
4530
            rn = "TCBind";
4531
            break;
4532
        case 3:
4533
            check_insn(env, ctx, ASE_MT);
4534
            gen_helper_mtc0_tcrestart(t0);
4535
            rn = "TCRestart";
4536
            break;
4537
        case 4:
4538
            check_insn(env, ctx, ASE_MT);
4539
            gen_helper_mtc0_tchalt(t0);
4540
            rn = "TCHalt";
4541
            break;
4542
        case 5:
4543
            check_insn(env, ctx, ASE_MT);
4544
            gen_helper_mtc0_tccontext(t0);
4545
            rn = "TCContext";
4546
            break;
4547
        case 6:
4548
            check_insn(env, ctx, ASE_MT);
4549
            gen_helper_mtc0_tcschedule(t0);
4550
            rn = "TCSchedule";
4551
            break;
4552
        case 7:
4553
            check_insn(env, ctx, ASE_MT);
4554
            gen_helper_mtc0_tcschefback(t0);
4555
            rn = "TCScheFBack";
4556
            break;
4557
        default:
4558
            goto die;
4559
        }
4560
        break;
4561
    case 3:
4562
        switch (sel) {
4563
        case 0:
4564
            gen_helper_mtc0_entrylo1(t0);
4565
            rn = "EntryLo1";
4566
            break;
4567
        default:
4568
            goto die;
4569
        }
4570
        break;
4571
    case 4:
4572
        switch (sel) {
4573
        case 0:
4574
            gen_helper_mtc0_context(t0);
4575
            rn = "Context";
4576
            break;
4577
        case 1:
4578
//           gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4579
            rn = "ContextConfig";
4580
//           break;
4581
        default:
4582
            goto die;
4583
        }
4584
        break;
4585
    case 5:
4586
        switch (sel) {
4587
        case 0:
4588
            gen_helper_mtc0_pagemask(t0);
4589
            rn = "PageMask";
4590
            break;
4591
        case 1:
4592
            check_insn(env, ctx, ISA_MIPS32R2);
4593
            gen_helper_mtc0_pagegrain(t0);
4594
            rn = "PageGrain";
4595
            break;
4596
        default:
4597
            goto die;
4598
        }
4599
        break;
4600
    case 6:
4601
        switch (sel) {
4602
        case 0:
4603
            gen_helper_mtc0_wired(t0);
4604
            rn = "Wired";
4605
            break;
4606
        case 1:
4607
            check_insn(env, ctx, ISA_MIPS32R2);
4608
            gen_helper_mtc0_srsconf0(t0);
4609
            rn = "SRSConf0";
4610
            break;
4611
        case 2:
4612
            check_insn(env, ctx, ISA_MIPS32R2);
4613
            gen_helper_mtc0_srsconf1(t0);
4614
            rn = "SRSConf1";
4615
            break;
4616
        case 3:
4617
            check_insn(env, ctx, ISA_MIPS32R2);
4618
            gen_helper_mtc0_srsconf2(t0);
4619
            rn = "SRSConf2";
4620
            break;
4621
        case 4:
4622
            check_insn(env, ctx, ISA_MIPS32R2);
4623
            gen_helper_mtc0_srsconf3(t0);
4624
            rn = "SRSConf3";
4625
            break;
4626
        case 5:
4627
            check_insn(env, ctx, ISA_MIPS32R2);
4628
            gen_helper_mtc0_srsconf4(t0);
4629
            rn = "SRSConf4";
4630
            break;
4631
        default:
4632
            goto die;
4633
        }
4634
        break;
4635
    case 7:
4636
        switch (sel) {
4637
        case 0:
4638
            check_insn(env, ctx, ISA_MIPS32R2);
4639
            gen_helper_mtc0_hwrena(t0);
4640
            rn = "HWREna";
4641
            break;
4642
        default:
4643
            goto die;
4644
        }
4645
        break;
4646
    case 8:
4647
        /* ignored */
4648
        rn = "BadVAddr";
4649
        break;
4650
    case 9:
4651
        switch (sel) {
4652
        case 0:
4653
            gen_helper_mtc0_count(t0);
4654
            rn = "Count";
4655
            break;
4656
        /* 6,7 are implementation dependent */
4657
        default:
4658
            goto die;
4659
        }
4660
        /* Stop translation as we may have switched the execution mode */
4661
        ctx->bstate = BS_STOP;
4662
        break;
4663
    case 10:
4664
        switch (sel) {
4665
        case 0:
4666
            gen_helper_mtc0_entryhi(t0);
4667
            rn = "EntryHi";
4668
            break;
4669
        default:
4670
            goto die;
4671
        }
4672
        break;
4673
    case 11:
4674
        switch (sel) {
4675
        case 0:
4676
            gen_helper_mtc0_compare(t0);
4677
            rn = "Compare";
4678
            break;
4679
        /* 6,7 are implementation dependent */
4680
        default:
4681
            goto die;
4682
        }
4683
        /* Stop translation as we may have switched the execution mode */
4684
        ctx->bstate = BS_STOP;
4685
        break;
4686
    case 12:
4687
        switch (sel) {
4688
        case 0:
4689
            gen_helper_mtc0_status(t0);
4690
            /* BS_STOP isn't good enough here, hflags may have changed. */
4691
            gen_save_pc(ctx->pc + 4);
4692
            ctx->bstate = BS_EXCP;
4693
            rn = "Status";
4694
            break;
4695
        case 1:
4696
            check_insn(env, ctx, ISA_MIPS32R2);
4697
            gen_helper_mtc0_intctl(t0);
4698
            /* Stop translation as we may have switched the execution mode */
4699
            ctx->bstate = BS_STOP;
4700
            rn = "IntCtl";
4701
            break;
4702
        case 2:
4703
            check_insn(env, ctx, ISA_MIPS32R2);
4704
            gen_helper_mtc0_srsctl(t0);
4705
            /* Stop translation as we may have switched the execution mode */
4706
            ctx->bstate = BS_STOP;
4707
            rn = "SRSCtl";
4708
            break;
4709
        case 3:
4710
            check_insn(env, ctx, ISA_MIPS32R2);
4711
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
4712
            /* Stop translation as we may have switched the execution mode */
4713
            ctx->bstate = BS_STOP;
4714
            rn = "SRSMap";
4715
            break;
4716
        default:
4717
            goto die;
4718
        }
4719
        break;
4720
    case 13:
4721
        switch (sel) {
4722
        case 0:
4723
            gen_helper_mtc0_cause(t0);
4724
            rn = "Cause";
4725
            break;
4726
        default:
4727
            goto die;
4728
        }
4729
        /* Stop translation as we may have switched the execution mode */
4730
        ctx->bstate = BS_STOP;
4731
        break;
4732
    case 14:
4733
        switch (sel) {
4734
        case 0:
4735
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4736
            rn = "EPC";
4737
            break;
4738
        default:
4739
            goto die;
4740
        }
4741
        break;
4742
    case 15:
4743
        switch (sel) {
4744
        case 0:
4745
            /* ignored */
4746
            rn = "PRid";
4747
            break;
4748
        case 1:
4749
            check_insn(env, ctx, ISA_MIPS32R2);
4750
            gen_helper_mtc0_ebase(t0);
4751
            rn = "EBase";
4752
            break;
4753
        default:
4754
            goto die;
4755
        }
4756
        break;
4757
    case 16:
4758
        switch (sel) {
4759
        case 0:
4760
            gen_helper_mtc0_config0(t0);
4761
            rn = "Config";
4762
            /* Stop translation as we may have switched the execution mode */
4763
            ctx->bstate = BS_STOP;
4764
            break;
4765
        case 1:
4766
            /* ignored */
4767
            rn = "Config1";
4768
            break;
4769
        case 2:
4770
            gen_helper_mtc0_config2(t0);
4771
            rn = "Config2";
4772
            /* Stop translation as we may have switched the execution mode */
4773
            ctx->bstate = BS_STOP;
4774
            break;
4775
        case 3:
4776
            /* ignored */
4777
            rn = "Config3";
4778
            break;
4779
        /* 6,7 are implementation dependent */
4780
        default:
4781
            rn = "Invalid config selector";
4782
            goto die;
4783
        }
4784
        break;
4785
    case 17:
4786
        switch (sel) {
4787
        case 0:
4788
            /* ignored */
4789
            rn = "LLAddr";
4790
            break;
4791
        default:
4792
            goto die;
4793
        }
4794
        break;
4795
    case 18:
4796
        switch (sel) {
4797
        case 0 ... 7:
4798
            gen_helper_1i(mtc0_watchlo, t0, sel);
4799
            rn = "WatchLo";
4800
            break;
4801
        default:
4802
            goto die;
4803
        }
4804
        break;
4805
    case 19:
4806
        switch (sel) {
4807
        case 0 ... 7:
4808
            gen_helper_1i(mtc0_watchhi, t0, sel);
4809
            rn = "WatchHi";
4810
            break;
4811
        default:
4812
            goto die;
4813
        }
4814
        break;
4815
    case 20:
4816
        switch (sel) {
4817
        case 0:
4818
            check_insn(env, ctx, ISA_MIPS3);
4819
            gen_helper_mtc0_xcontext(t0);
4820
            rn = "XContext";
4821
            break;
4822
        default:
4823
            goto die;
4824
        }
4825
        break;
4826
    case 21:
4827
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4828
        switch (sel) {
4829
        case 0:
4830
            gen_helper_mtc0_framemask(t0);
4831
            rn = "Framemask";
4832
            break;
4833
        default:
4834
            goto die;
4835
        }
4836
        break;
4837
    case 22:
4838
        /* ignored */
4839
        rn = "Diagnostic"; /* implementation dependent */
4840
        break;
4841
    case 23:
4842
        switch (sel) {
4843
        case 0:
4844
            gen_helper_mtc0_debug(t0); /* EJTAG support */
4845
            /* BS_STOP isn't good enough here, hflags may have changed. */
4846
            gen_save_pc(ctx->pc + 4);
4847
            ctx->bstate = BS_EXCP;
4848
            rn = "Debug";
4849
            break;
4850
        case 1:
4851
//            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
4852
            /* Stop translation as we may have switched the execution mode */
4853
            ctx->bstate = BS_STOP;
4854
            rn = "TraceControl";
4855
//            break;
4856
        case 2:
4857
//            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
4858
            /* Stop translation as we may have switched the execution mode */
4859
            ctx->bstate = BS_STOP;
4860
            rn = "TraceControl2";
4861
//            break;
4862
        case 3:
4863
//            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
4864
            /* Stop translation as we may have switched the execution mode */
4865
            ctx->bstate = BS_STOP;
4866
            rn = "UserTraceData";
4867
//            break;
4868
        case 4:
4869
//            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
4870
            /* Stop translation as we may have switched the execution mode */
4871
            ctx->bstate = BS_STOP;
4872
            rn = "TraceBPC";
4873
//            break;
4874
        default:
4875
            goto die;
4876
        }
4877
        break;
4878
    case 24:
4879
        switch (sel) {
4880
        case 0:
4881
            /* EJTAG support */
4882
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4883
            rn = "DEPC";
4884
            break;
4885
        default:
4886
            goto die;
4887
        }
4888
        break;
4889
    case 25:
4890
        switch (sel) {
4891
        case 0:
4892
            gen_helper_mtc0_performance0(t0);
4893
            rn = "Performance0";
4894
            break;
4895
        case 1:
4896
//            gen_helper_mtc0_performance1(t0);
4897
            rn = "Performance1";
4898
//            break;
4899
        case 2:
4900
//            gen_helper_mtc0_performance2(t0);
4901
            rn = "Performance2";
4902
//            break;
4903
        case 3:
4904
//            gen_helper_mtc0_performance3(t0);
4905
            rn = "Performance3";
4906
//            break;
4907
        case 4:
4908
//            gen_helper_mtc0_performance4(t0);
4909
            rn = "Performance4";
4910
//            break;
4911
        case 5:
4912
//            gen_helper_mtc0_performance5(t0);
4913
            rn = "Performance5";
4914
//            break;
4915
        case 6:
4916
//            gen_helper_mtc0_performance6(t0);
4917
            rn = "Performance6";
4918
//            break;
4919
        case 7:
4920
//            gen_helper_mtc0_performance7(t0);
4921
            rn = "Performance7";
4922
//            break;
4923
        default:
4924
            goto die;
4925
        }
4926
        break;
4927
    case 26:
4928
        /* ignored */
4929
        rn = "ECC";
4930
        break;
4931
    case 27:
4932
        switch (sel) {
4933
        case 0 ... 3:
4934
            /* ignored */
4935
            rn = "CacheErr";
4936
            break;
4937
        default:
4938
            goto die;
4939
        }
4940
        break;
4941
    case 28:
4942
        switch (sel) {
4943
        case 0:
4944
        case 2:
4945
        case 4:
4946
        case 6:
4947
            gen_helper_mtc0_taglo(t0);
4948
            rn = "TagLo";
4949
            break;
4950
        case 1:
4951
        case 3:
4952
        case 5:
4953
        case 7:
4954
            gen_helper_mtc0_datalo(t0);
4955
            rn = "DataLo";
4956
            break;
4957
        default:
4958
            goto die;
4959
        }
4960
        break;
4961
    case 29:
4962
        switch (sel) {
4963
        case 0:
4964
        case 2:
4965
        case 4:
4966
        case 6:
4967
            gen_helper_mtc0_taghi(t0);
4968
            rn = "TagHi";
4969
            break;
4970
        case 1:
4971
        case 3:
4972
        case 5:
4973
        case 7:
4974
            gen_helper_mtc0_datahi(t0);
4975
            rn = "DataHi";
4976
            break;
4977
        default:
4978
            rn = "invalid sel";
4979
            goto die;
4980
        }
4981
        break;
4982
    case 30:
4983
        switch (sel) {
4984
        case 0:
4985
            tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4986
            rn = "ErrorEPC";
4987
            break;
4988
        default:
4989
            goto die;
4990
        }
4991
        break;
4992
    case 31:
4993
        switch (sel) {
4994
        case 0:
4995
            /* EJTAG support */
4996
            gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
4997
            rn = "DESAVE";
4998
            break;
4999
        default:
5000
            goto die;
5001
        }
5002
        /* Stop translation as we may have switched the execution mode */
5003
        ctx->bstate = BS_STOP;
5004
        break;
5005
    default:
5006
        goto die;
5007
    }
5008
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5009
    /* For simplicity assume that all writes can cause interrupts.  */
5010
    if (use_icount) {
5011
        gen_io_end();
5012
        ctx->bstate = BS_STOP;
5013
    }
5014
    return;
5015

    
5016
die:
5017
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5018
    generate_exception(ctx, EXCP_RI);
5019
}
5020
#endif /* TARGET_MIPS64 */
5021

    
5022
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5023
                     int u, int sel, int h)
5024
{
5025
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5026
    TCGv t0 = tcg_temp_local_new();
5027

    
5028
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5029
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5030
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5031
        tcg_gen_movi_tl(t0, -1);
5032
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5033
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5034
        tcg_gen_movi_tl(t0, -1);
5035
    else if (u == 0) {
5036
        switch (rt) {
5037
        case 2:
5038
            switch (sel) {
5039
            case 1:
5040
                gen_helper_mftc0_tcstatus(t0);
5041
                break;
5042
            case 2:
5043
                gen_helper_mftc0_tcbind(t0);
5044
                break;
5045
            case 3:
5046
                gen_helper_mftc0_tcrestart(t0);
5047
                break;
5048
            case 4:
5049
                gen_helper_mftc0_tchalt(t0);
5050
                break;
5051
            case 5:
5052
                gen_helper_mftc0_tccontext(t0);
5053
                break;
5054
            case 6:
5055
                gen_helper_mftc0_tcschedule(t0);
5056
                break;
5057
            case 7:
5058
                gen_helper_mftc0_tcschefback(t0);
5059
                break;
5060
            default:
5061
                gen_mfc0(env, ctx, t0, rt, sel);
5062
                break;
5063
            }
5064
            break;
5065
        case 10:
5066
            switch (sel) {
5067
            case 0:
5068
                gen_helper_mftc0_entryhi(t0);
5069
                break;
5070
            default:
5071
                gen_mfc0(env, ctx, t0, rt, sel);
5072
                break;
5073
            }
5074
        case 12:
5075
            switch (sel) {
5076
            case 0:
5077
                gen_helper_mftc0_status(t0);
5078
                break;
5079
            default:
5080
                gen_mfc0(env, ctx, t0, rt, sel);
5081
                break;
5082
            }
5083
        case 23:
5084
            switch (sel) {
5085
            case 0:
5086
                gen_helper_mftc0_debug(t0);
5087
                break;
5088
            default:
5089
                gen_mfc0(env, ctx, t0, rt, sel);
5090
                break;
5091
            }
5092
            break;
5093
        default:
5094
            gen_mfc0(env, ctx, t0, rt, sel);
5095
        }
5096
    } else switch (sel) {
5097
    /* GPR registers. */
5098
    case 0:
5099
        gen_helper_1i(mftgpr, t0, rt);
5100
        break;
5101
    /* Auxiliary CPU registers */
5102
    case 1:
5103
        switch (rt) {
5104
        case 0:
5105
            gen_helper_1i(mftlo, t0, 0);
5106
            break;
5107
        case 1:
5108
            gen_helper_1i(mfthi, t0, 0);
5109
            break;
5110
        case 2:
5111
            gen_helper_1i(mftacx, t0, 0);
5112
            break;
5113
        case 4:
5114
            gen_helper_1i(mftlo, t0, 1);
5115
            break;
5116
        case 5:
5117
            gen_helper_1i(mfthi, t0, 1);
5118
            break;
5119
        case 6:
5120
            gen_helper_1i(mftacx, t0, 1);
5121
            break;
5122
        case 8:
5123
            gen_helper_1i(mftlo, t0, 2);
5124
            break;
5125
        case 9:
5126
            gen_helper_1i(mfthi, t0, 2);
5127
            break;
5128
        case 10:
5129
            gen_helper_1i(mftacx, t0, 2);
5130
            break;
5131
        case 12:
5132
            gen_helper_1i(mftlo, t0, 3);
5133
            break;
5134
        case 13:
5135
            gen_helper_1i(mfthi, t0, 3);
5136
            break;
5137
        case 14:
5138
            gen_helper_1i(mftacx, t0, 3);
5139
            break;
5140
        case 16:
5141
            gen_helper_mftdsp(t0);
5142
            break;
5143
        default:
5144
            goto die;
5145
        }
5146
        break;
5147
    /* Floating point (COP1). */
5148
    case 2:
5149
        /* XXX: For now we support only a single FPU context. */
5150
        if (h == 0) {
5151
            TCGv_i32 fp0 = tcg_temp_new_i32();
5152

    
5153
            gen_load_fpr32(fp0, rt);
5154
            tcg_gen_ext_i32_tl(t0, fp0);
5155
            tcg_temp_free_i32(fp0);
5156
        } else {
5157
            TCGv_i32 fp0 = tcg_temp_new_i32();
5158

    
5159
            gen_load_fpr32h(fp0, rt);
5160
            tcg_gen_ext_i32_tl(t0, fp0);
5161
            tcg_temp_free_i32(fp0);
5162
        }
5163
        break;
5164
    case 3:
5165
        /* XXX: For now we support only a single FPU context. */
5166
        gen_helper_1i(cfc1, t0, rt);
5167
        break;
5168
    /* COP2: Not implemented. */
5169
    case 4:
5170
    case 5:
5171
        /* fall through */
5172
    default:
5173
        goto die;
5174
    }
5175
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5176
    gen_store_gpr(t0, rd);
5177
    tcg_temp_free(t0);
5178
    return;
5179

    
5180
die:
5181
    tcg_temp_free(t0);
5182
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5183
    generate_exception(ctx, EXCP_RI);
5184
}
5185

    
5186
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5187
                     int u, int sel, int h)
5188
{
5189
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5190
    TCGv t0 = tcg_temp_local_new();
5191

    
5192
    gen_load_gpr(t0, rt);
5193
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5194
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5195
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5196
        /* NOP */ ;
5197
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5198
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5199
        /* NOP */ ;
5200
    else if (u == 0) {
5201
        switch (rd) {
5202
        case 2:
5203
            switch (sel) {
5204
            case 1:
5205
                gen_helper_mttc0_tcstatus(t0);
5206
                break;
5207
            case 2:
5208
                gen_helper_mttc0_tcbind(t0);
5209
                break;
5210
            case 3:
5211
                gen_helper_mttc0_tcrestart(t0);
5212
                break;
5213
            case 4:
5214
                gen_helper_mttc0_tchalt(t0);
5215
                break;
5216
            case 5:
5217
                gen_helper_mttc0_tccontext(t0);
5218
                break;
5219
            case 6:
5220
                gen_helper_mttc0_tcschedule(t0);
5221
                break;
5222
            case 7:
5223
                gen_helper_mttc0_tcschefback(t0);
5224
                break;
5225
            default:
5226
                gen_mtc0(env, ctx, t0, rd, sel);
5227
                break;
5228
            }
5229
            break;
5230
        case 10:
5231
            switch (sel) {
5232
            case 0:
5233
                gen_helper_mttc0_entryhi(t0);
5234
                break;
5235
            default:
5236
                gen_mtc0(env, ctx, t0, rd, sel);
5237
                break;
5238
            }
5239
        case 12:
5240
            switch (sel) {
5241
            case 0:
5242
                gen_helper_mttc0_status(t0);
5243
                break;
5244
            default:
5245
                gen_mtc0(env, ctx, t0, rd, sel);
5246
                break;
5247
            }
5248
        case 23:
5249
            switch (sel) {
5250
            case 0:
5251
                gen_helper_mttc0_debug(t0);
5252
                break;
5253
            default:
5254
                gen_mtc0(env, ctx, t0, rd, sel);
5255
                break;
5256
            }
5257
            break;
5258
        default:
5259
            gen_mtc0(env, ctx, t0, rd, sel);
5260
        }
5261
    } else switch (sel) {
5262
    /* GPR registers. */
5263
    case 0:
5264
        gen_helper_1i(mttgpr, t0, rd);
5265
        break;
5266
    /* Auxiliary CPU registers */
5267
    case 1:
5268
        switch (rd) {
5269
        case 0:
5270
            gen_helper_1i(mttlo, t0, 0);
5271
            break;
5272
        case 1:
5273
            gen_helper_1i(mtthi, t0, 0);
5274
            break;
5275
        case 2:
5276
            gen_helper_1i(mttacx, t0, 0);
5277
            break;
5278
        case 4:
5279
            gen_helper_1i(mttlo, t0, 1);
5280
            break;
5281
        case 5:
5282
            gen_helper_1i(mtthi, t0, 1);
5283
            break;
5284
        case 6:
5285
            gen_helper_1i(mttacx, t0, 1);
5286
            break;
5287
        case 8:
5288
            gen_helper_1i(mttlo, t0, 2);
5289
            break;
5290
        case 9:
5291
            gen_helper_1i(mtthi, t0, 2);
5292
            break;
5293
        case 10:
5294
            gen_helper_1i(mttacx, t0, 2);
5295
            break;
5296
        case 12:
5297
            gen_helper_1i(mttlo, t0, 3);
5298
            break;
5299
        case 13:
5300
            gen_helper_1i(mtthi, t0, 3);
5301
            break;
5302
        case 14:
5303
            gen_helper_1i(mttacx, t0, 3);
5304
            break;
5305
        case 16:
5306
            gen_helper_mttdsp(t0);
5307
            break;
5308
        default:
5309
            goto die;
5310
        }
5311
        break;
5312
    /* Floating point (COP1). */
5313
    case 2:
5314
        /* XXX: For now we support only a single FPU context. */
5315
        if (h == 0) {
5316
            TCGv_i32 fp0 = tcg_temp_new_i32();
5317

    
5318
            tcg_gen_trunc_tl_i32(fp0, t0);
5319
            gen_store_fpr32(fp0, rd);
5320
            tcg_temp_free_i32(fp0);
5321
        } else {
5322
            TCGv_i32 fp0 = tcg_temp_new_i32();
5323

    
5324
            tcg_gen_trunc_tl_i32(fp0, t0);
5325
            gen_store_fpr32h(fp0, rd);
5326
            tcg_temp_free_i32(fp0);
5327
        }
5328
        break;
5329
    case 3:
5330
        /* XXX: For now we support only a single FPU context. */
5331
        gen_helper_1i(ctc1, t0, rd);
5332
        break;
5333
    /* COP2: Not implemented. */
5334
    case 4:
5335
    case 5:
5336
        /* fall through */
5337
    default:
5338
        goto die;
5339
    }
5340
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5341
    tcg_temp_free(t0);
5342
    return;
5343

    
5344
die:
5345
    tcg_temp_free(t0);
5346
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5347
    generate_exception(ctx, EXCP_RI);
5348
}
5349

    
5350
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5351
{
5352
    const char *opn = "ldst";
5353

    
5354
    switch (opc) {
5355
    case OPC_MFC0:
5356
        if (rt == 0) {
5357
            /* Treat as NOP. */
5358
            return;
5359
        }
5360
        {
5361
            TCGv t0 = tcg_temp_local_new();
5362

    
5363
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5364
            gen_store_gpr(t0, rt);
5365
            tcg_temp_free(t0);
5366
        }
5367
        opn = "mfc0";
5368
        break;
5369
    case OPC_MTC0:
5370
        {
5371
            TCGv t0 = tcg_temp_local_new();
5372

    
5373
            gen_load_gpr(t0, rt);
5374
            save_cpu_state(ctx, 1);
5375
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5376
            tcg_temp_free(t0);
5377
        }
5378
        opn = "mtc0";
5379
        break;
5380
#if defined(TARGET_MIPS64)
5381
    case OPC_DMFC0:
5382
        check_insn(env, ctx, ISA_MIPS3);
5383
        if (rt == 0) {
5384
            /* Treat as NOP. */
5385
            return;
5386
        }
5387
        {
5388
            TCGv t0 = tcg_temp_local_new();
5389

    
5390
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5391
            gen_store_gpr(t0, rt);
5392
            tcg_temp_free(t0);
5393
        }
5394
        opn = "dmfc0";
5395
        break;
5396
    case OPC_DMTC0:
5397
        check_insn(env, ctx, ISA_MIPS3);
5398
        {
5399
            TCGv t0 = tcg_temp_local_new();
5400

    
5401
            gen_load_gpr(t0, rt);
5402
            save_cpu_state(ctx, 1);
5403
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5404
            tcg_temp_free(t0);
5405
        }
5406
        opn = "dmtc0";
5407
        break;
5408
#endif
5409
    case OPC_MFTR:
5410
        check_insn(env, ctx, ASE_MT);
5411
        if (rd == 0) {
5412
            /* Treat as NOP. */
5413
            return;
5414
        }
5415
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5416
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5417
        opn = "mftr";
5418
        break;
5419
    case OPC_MTTR:
5420
        check_insn(env, ctx, ASE_MT);
5421
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5422
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5423
        opn = "mttr";
5424
        break;
5425
    case OPC_TLBWI:
5426
        opn = "tlbwi";
5427
        if (!env->tlb->helper_tlbwi)
5428
            goto die;
5429
        gen_helper_tlbwi();
5430
        break;
5431
    case OPC_TLBWR:
5432
        opn = "tlbwr";
5433
        if (!env->tlb->helper_tlbwr)
5434
            goto die;
5435
        gen_helper_tlbwr();
5436
        break;
5437
    case OPC_TLBP:
5438
        opn = "tlbp";
5439
        if (!env->tlb->helper_tlbp)
5440
            goto die;
5441
        gen_helper_tlbp();
5442
        break;
5443
    case OPC_TLBR:
5444
        opn = "tlbr";
5445
        if (!env->tlb->helper_tlbr)
5446
            goto die;
5447
        gen_helper_tlbr();
5448
        break;
5449
    case OPC_ERET:
5450
        opn = "eret";
5451
        check_insn(env, ctx, ISA_MIPS2);
5452
        save_cpu_state(ctx, 1);
5453
        gen_helper_eret();
5454
        ctx->bstate = BS_EXCP;
5455
        break;
5456
    case OPC_DERET:
5457
        opn = "deret";
5458
        check_insn(env, ctx, ISA_MIPS32);
5459
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5460
            MIPS_INVAL(opn);
5461
            generate_exception(ctx, EXCP_RI);
5462
        } else {
5463
            save_cpu_state(ctx, 1);
5464
            gen_helper_deret();
5465
            ctx->bstate = BS_EXCP;
5466
        }
5467
        break;
5468
    case OPC_WAIT:
5469
        opn = "wait";
5470
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5471
        /* If we get an exception, we want to restart at next instruction */
5472
        ctx->pc += 4;
5473
        save_cpu_state(ctx, 1);
5474
        ctx->pc -= 4;
5475
        gen_helper_wait();
5476
        ctx->bstate = BS_EXCP;
5477
        break;
5478
    default:
5479
 die:
5480
        MIPS_INVAL(opn);
5481
        generate_exception(ctx, EXCP_RI);
5482
        return;
5483
    }
5484
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5485
}
5486
#endif /* !CONFIG_USER_ONLY */
5487

    
5488
/* CP1 Branches (before delay slot) */
5489
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5490
                                 int32_t cc, int32_t offset)
5491
{
5492
    target_ulong btarget;
5493
    const char *opn = "cp1 cond branch";
5494
    TCGv_i32 t0 = tcg_temp_new_i32();
5495

    
5496
    if (cc != 0)
5497
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5498

    
5499
    btarget = ctx->pc + 4 + offset;
5500

    
5501
    switch (op) {
5502
    case OPC_BC1F:
5503
        {
5504
            int l1 = gen_new_label();
5505
            int l2 = gen_new_label();
5506

    
5507
            get_fp_cond(t0);
5508
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5509
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5510
            tcg_gen_movi_tl(bcond, 0);
5511
            tcg_gen_br(l2);
5512
            gen_set_label(l1);
5513
            tcg_gen_movi_tl(bcond, 1);
5514
            gen_set_label(l2);
5515
        }
5516
        opn = "bc1f";
5517
        goto not_likely;
5518
    case OPC_BC1FL:
5519
        {
5520
            int l1 = gen_new_label();
5521
            int l2 = gen_new_label();
5522

    
5523
            get_fp_cond(t0);
5524
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5525
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5526
            tcg_gen_movi_tl(bcond, 0);
5527
            tcg_gen_br(l2);
5528
            gen_set_label(l1);
5529
            tcg_gen_movi_tl(bcond, 1);
5530
            gen_set_label(l2);
5531
        }
5532
        opn = "bc1fl";
5533
        goto likely;
5534
    case OPC_BC1T:
5535
        {
5536
            int l1 = gen_new_label();
5537
            int l2 = gen_new_label();
5538

    
5539
            get_fp_cond(t0);
5540
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5541
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5542
            tcg_gen_movi_tl(bcond, 0);
5543
            tcg_gen_br(l2);
5544
            gen_set_label(l1);
5545
            tcg_gen_movi_tl(bcond, 1);
5546
            gen_set_label(l2);
5547
        }
5548
        opn = "bc1t";
5549
        goto not_likely;
5550
    case OPC_BC1TL:
5551
        {
5552
            int l1 = gen_new_label();
5553
            int l2 = gen_new_label();
5554

    
5555
            get_fp_cond(t0);
5556
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5557
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5558
            tcg_gen_movi_tl(bcond, 0);
5559
            tcg_gen_br(l2);
5560
            gen_set_label(l1);
5561
            tcg_gen_movi_tl(bcond, 1);
5562
            gen_set_label(l2);
5563
        }
5564
        opn = "bc1tl";
5565
    likely:
5566
        ctx->hflags |= MIPS_HFLAG_BL;
5567
        break;
5568
    case OPC_BC1FANY2:
5569
        {
5570
            int l1 = gen_new_label();
5571
            int l2 = gen_new_label();
5572

    
5573
            get_fp_cond(t0);
5574
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5575
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5576
            tcg_gen_movi_tl(bcond, 0);
5577
            tcg_gen_br(l2);
5578
            gen_set_label(l1);
5579
            tcg_gen_movi_tl(bcond, 1);
5580
            gen_set_label(l2);
5581
        }
5582
        opn = "bc1any2f";
5583
        goto not_likely;
5584
    case OPC_BC1TANY2:
5585
        {
5586
            int l1 = gen_new_label();
5587
            int l2 = gen_new_label();
5588

    
5589
            get_fp_cond(t0);
5590
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5591
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5592
            tcg_gen_movi_tl(bcond, 0);
5593
            tcg_gen_br(l2);
5594
            gen_set_label(l1);
5595
            tcg_gen_movi_tl(bcond, 1);
5596
            gen_set_label(l2);
5597
        }
5598
        opn = "bc1any2t";
5599
        goto not_likely;
5600
    case OPC_BC1FANY4:
5601
        {
5602
            int l1 = gen_new_label();
5603
            int l2 = gen_new_label();
5604

    
5605
            get_fp_cond(t0);
5606
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5607
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5608
            tcg_gen_movi_tl(bcond, 0);
5609
            tcg_gen_br(l2);
5610
            gen_set_label(l1);
5611
            tcg_gen_movi_tl(bcond, 1);
5612
            gen_set_label(l2);
5613
        }
5614
        opn = "bc1any4f";
5615
        goto not_likely;
5616
    case OPC_BC1TANY4:
5617
        {
5618
            int l1 = gen_new_label();
5619
            int l2 = gen_new_label();
5620

    
5621
            get_fp_cond(t0);
5622
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5623
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5624
            tcg_gen_movi_tl(bcond, 0);
5625
            tcg_gen_br(l2);
5626
            gen_set_label(l1);
5627
            tcg_gen_movi_tl(bcond, 1);
5628
            gen_set_label(l2);
5629
        }
5630
        opn = "bc1any4t";
5631
    not_likely:
5632
        ctx->hflags |= MIPS_HFLAG_BC;
5633
        break;
5634
    default:
5635
        MIPS_INVAL(opn);
5636
        generate_exception (ctx, EXCP_RI);
5637
        goto out;
5638
    }
5639
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5640
               ctx->hflags, btarget);
5641
    ctx->btarget = btarget;
5642

    
5643
 out:
5644
    tcg_temp_free_i32(t0);
5645
}
5646

    
5647
/* Coprocessor 1 (FPU) */
5648

    
5649
#define FOP(func, fmt) (((fmt) << 21) | (func))
5650

    
5651
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5652
{
5653
    const char *opn = "cp1 move";
5654
    TCGv t0 = tcg_temp_local_new();
5655

    
5656
    switch (opc) {
5657
    case OPC_MFC1:
5658
        {
5659
            TCGv_i32 fp0 = tcg_temp_new_i32();
5660

    
5661
            gen_load_fpr32(fp0, fs);
5662
            tcg_gen_ext_i32_tl(t0, fp0);
5663
            tcg_temp_free_i32(fp0);
5664
        }
5665
        gen_store_gpr(t0, rt);
5666
        opn = "mfc1";
5667
        break;
5668
    case OPC_MTC1:
5669
        gen_load_gpr(t0, rt);
5670
        {
5671
            TCGv_i32 fp0 = tcg_temp_new_i32();
5672

    
5673
            tcg_gen_trunc_tl_i32(fp0, t0);
5674
            gen_store_fpr32(fp0, fs);
5675
            tcg_temp_free_i32(fp0);
5676
        }
5677
        opn = "mtc1";
5678
        break;
5679
    case OPC_CFC1:
5680
        gen_helper_1i(cfc1, t0, fs);
5681
        gen_store_gpr(t0, rt);
5682
        opn = "cfc1";
5683
        break;
5684
    case OPC_CTC1:
5685
        gen_load_gpr(t0, rt);
5686
        gen_helper_1i(ctc1, t0, fs);
5687
        opn = "ctc1";
5688
        break;
5689
    case OPC_DMFC1:
5690
        {
5691
            TCGv_i64 fp0 = tcg_temp_new_i64();
5692

    
5693
            gen_load_fpr64(ctx, fp0, fs);
5694
            tcg_gen_trunc_i64_tl(t0, fp0);
5695
            tcg_temp_free_i64(fp0);
5696
        }
5697
        gen_store_gpr(t0, rt);
5698
        opn = "dmfc1";
5699
        break;
5700
    case OPC_DMTC1:
5701
        gen_load_gpr(t0, rt);
5702
        {
5703
            TCGv_i64 fp0 = tcg_temp_new_i64();
5704

    
5705
            tcg_gen_extu_tl_i64(fp0, t0);
5706
            gen_store_fpr64(ctx, fp0, fs);
5707
            tcg_temp_free_i64(fp0);
5708
        }
5709
        opn = "dmtc1";
5710
        break;
5711
    case OPC_MFHC1:
5712
        {
5713
            TCGv_i32 fp0 = tcg_temp_new_i32();
5714

    
5715
            gen_load_fpr32h(fp0, fs);
5716
            tcg_gen_ext_i32_tl(t0, fp0);
5717
            tcg_temp_free_i32(fp0);
5718
        }
5719
        gen_store_gpr(t0, rt);
5720
        opn = "mfhc1";
5721
        break;
5722
    case OPC_MTHC1:
5723
        gen_load_gpr(t0, rt);
5724
        {
5725
            TCGv_i32 fp0 = tcg_temp_new_i32();
5726

    
5727
            tcg_gen_trunc_tl_i32(fp0, t0);
5728
            gen_store_fpr32h(fp0, fs);
5729
            tcg_temp_free_i32(fp0);
5730
        }
5731
        opn = "mthc1";
5732
        break;
5733
    default:
5734
        MIPS_INVAL(opn);
5735
        generate_exception (ctx, EXCP_RI);
5736
        goto out;
5737
    }
5738
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5739

    
5740
 out:
5741
    tcg_temp_free(t0);
5742
}
5743

    
5744
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5745
{
5746
    int l1 = gen_new_label();
5747
    uint32_t ccbit;
5748
    TCGCond cond;
5749
    TCGv t0 = tcg_temp_local_new();
5750
    TCGv_i32 r_tmp = tcg_temp_new_i32();
5751

    
5752
    if (cc)
5753
        ccbit = 1 << (24 + cc);
5754
    else
5755
        ccbit = 1 << 23;
5756
    if (tf)
5757
        cond = TCG_COND_EQ;
5758
    else
5759
        cond = TCG_COND_NE;
5760

    
5761
    gen_load_gpr(t0, rd);
5762
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5763
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5764
    tcg_temp_free_i32(r_tmp);
5765
    gen_load_gpr(t0, rs);
5766
    gen_set_label(l1);
5767
    gen_store_gpr(t0, rd);
5768
    tcg_temp_free(t0);
5769
}
5770

    
5771
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5772
{
5773
    uint32_t ccbit;
5774
    int cond;
5775
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5776
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5777
    int l1 = gen_new_label();
5778

    
5779
    if (cc)
5780
        ccbit = 1 << (24 + cc);
5781
    else
5782
        ccbit = 1 << 23;
5783

    
5784
    if (tf)
5785
        cond = TCG_COND_EQ;
5786
    else
5787
        cond = TCG_COND_NE;
5788

    
5789
    gen_load_fpr32(fp0, fd);
5790
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5791
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5792
    tcg_temp_free_i32(r_tmp1);
5793
    gen_load_fpr32(fp0, fs);
5794
    gen_set_label(l1);
5795
    gen_store_fpr32(fp0, fd);
5796
    tcg_temp_free_i32(fp0);
5797
}
5798

    
5799
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5800
{
5801
    uint32_t ccbit;
5802
    int cond;
5803
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5804
    TCGv_i64 fp0 = tcg_temp_local_new_i64();
5805
    int l1 = gen_new_label();
5806

    
5807
    if (cc)
5808
        ccbit = 1 << (24 + cc);
5809
    else
5810
        ccbit = 1 << 23;
5811

    
5812
    if (tf)
5813
        cond = TCG_COND_EQ;
5814
    else
5815
        cond = TCG_COND_NE;
5816

    
5817
    gen_load_fpr64(ctx, fp0, fd);
5818
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5819
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5820
    tcg_temp_free_i32(r_tmp1);
5821
    gen_load_fpr64(ctx, fp0, fs);
5822
    gen_set_label(l1);
5823
    gen_store_fpr64(ctx, fp0, fd);
5824
    tcg_temp_free_i64(fp0);
5825
}
5826

    
5827
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5828
{
5829
    uint32_t ccbit1, ccbit2;
5830
    int cond;
5831
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5832
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5833
    int l1 = gen_new_label();
5834
    int l2 = gen_new_label();
5835

    
5836
    if (cc) {
5837
        ccbit1 = 1 << (24 + cc);
5838
        ccbit2 = 1 << (25 + cc);
5839
    } else {
5840
        ccbit1 = 1 << 23;
5841
        ccbit2 = 1 << 25;
5842
    }
5843

    
5844
    if (tf)
5845
        cond = TCG_COND_EQ;
5846
    else
5847
        cond = TCG_COND_NE;
5848

    
5849
    gen_load_fpr32(fp0, fd);
5850
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5851
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5852
    gen_load_fpr32(fp0, fs);
5853
    gen_set_label(l1);
5854
    gen_store_fpr32(fp0, fd);
5855

    
5856
    gen_load_fpr32h(fp0, fd);
5857
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5858
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5859
    gen_load_fpr32h(fp0, fs);
5860
    gen_set_label(l2);
5861
    gen_store_fpr32h(fp0, fd);
5862

    
5863
    tcg_temp_free_i32(r_tmp1);
5864
    tcg_temp_free_i32(fp0);
5865
}
5866

    
5867

    
5868
static void gen_farith (DisasContext *ctx, uint32_t op1,
5869
                        int ft, int fs, int fd, int cc)
5870
{
5871
    const char *opn = "farith";
5872
    const char *condnames[] = {
5873
            "c.f",
5874
            "c.un",
5875
            "c.eq",
5876
            "c.ueq",
5877
            "c.olt",
5878
            "c.ult",
5879
            "c.ole",
5880
            "c.ule",
5881
            "c.sf",
5882
            "c.ngle",
5883
            "c.seq",
5884
            "c.ngl",
5885
            "c.lt",
5886
            "c.nge",
5887
            "c.le",
5888
            "c.ngt",
5889
    };
5890
    const char *condnames_abs[] = {
5891
            "cabs.f",
5892
            "cabs.un",
5893
            "cabs.eq",
5894
            "cabs.ueq",
5895
            "cabs.olt",
5896
            "cabs.ult",
5897
            "cabs.ole",
5898
            "cabs.ule",
5899
            "cabs.sf",
5900
            "cabs.ngle",
5901
            "cabs.seq",
5902
            "cabs.ngl",
5903
            "cabs.lt",
5904
            "cabs.nge",
5905
            "cabs.le",
5906
            "cabs.ngt",
5907
    };
5908
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5909
    uint32_t func = ctx->opcode & 0x3f;
5910

    
5911
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5912
    case FOP(0, 16):
5913
        {
5914
            TCGv_i32 fp0 = tcg_temp_new_i32();
5915
            TCGv_i32 fp1 = tcg_temp_new_i32();
5916

    
5917
            gen_load_fpr32(fp0, fs);
5918
            gen_load_fpr32(fp1, ft);
5919
            gen_helper_float_add_s(fp0, fp0, fp1);
5920
            tcg_temp_free_i32(fp1);
5921
            gen_store_fpr32(fp0, fd);
5922
            tcg_temp_free_i32(fp0);
5923
        }
5924
        opn = "add.s";
5925
        optype = BINOP;
5926
        break;
5927
    case FOP(1, 16):
5928
        {
5929
            TCGv_i32 fp0 = tcg_temp_new_i32();
5930
            TCGv_i32 fp1 = tcg_temp_new_i32();
5931

    
5932
            gen_load_fpr32(fp0, fs);
5933
            gen_load_fpr32(fp1, ft);
5934
            gen_helper_float_sub_s(fp0, fp0, fp1);
5935
            tcg_temp_free_i32(fp1);
5936
            gen_store_fpr32(fp0, fd);
5937
            tcg_temp_free_i32(fp0);
5938
        }
5939
        opn = "sub.s";
5940
        optype = BINOP;
5941
        break;
5942
    case FOP(2, 16):
5943
        {
5944
            TCGv_i32 fp0 = tcg_temp_new_i32();
5945
            TCGv_i32 fp1 = tcg_temp_new_i32();
5946

    
5947
            gen_load_fpr32(fp0, fs);
5948
            gen_load_fpr32(fp1, ft);
5949
            gen_helper_float_mul_s(fp0, fp0, fp1);
5950
            tcg_temp_free_i32(fp1);
5951
            gen_store_fpr32(fp0, fd);
5952
            tcg_temp_free_i32(fp0);
5953
        }
5954
        opn = "mul.s";
5955
        optype = BINOP;
5956
        break;
5957
    case FOP(3, 16):
5958
        {
5959
            TCGv_i32 fp0 = tcg_temp_new_i32();
5960
            TCGv_i32 fp1 = tcg_temp_new_i32();
5961

    
5962
            gen_load_fpr32(fp0, fs);
5963
            gen_load_fpr32(fp1, ft);
5964
            gen_helper_float_div_s(fp0, fp0, fp1);
5965
            tcg_temp_free_i32(fp1);
5966
            gen_store_fpr32(fp0, fd);
5967
            tcg_temp_free_i32(fp0);
5968
        }
5969
        opn = "div.s";
5970
        optype = BINOP;
5971
        break;
5972
    case FOP(4, 16):
5973
        {
5974
            TCGv_i32 fp0 = tcg_temp_new_i32();
5975

    
5976
            gen_load_fpr32(fp0, fs);
5977
            gen_helper_float_sqrt_s(fp0, fp0);
5978
            gen_store_fpr32(fp0, fd);
5979
            tcg_temp_free_i32(fp0);
5980
        }
5981
        opn = "sqrt.s";
5982
        break;
5983
    case FOP(5, 16):
5984
        {
5985
            TCGv_i32 fp0 = tcg_temp_new_i32();
5986

    
5987
            gen_load_fpr32(fp0, fs);
5988
            gen_helper_float_abs_s(fp0, fp0);
5989
            gen_store_fpr32(fp0, fd);
5990
            tcg_temp_free_i32(fp0);
5991
        }
5992
        opn = "abs.s";
5993
        break;
5994
    case FOP(6, 16):
5995
        {
5996
            TCGv_i32 fp0 = tcg_temp_new_i32();
5997

    
5998
            gen_load_fpr32(fp0, fs);
5999
            gen_store_fpr32(fp0, fd);
6000
            tcg_temp_free_i32(fp0);
6001
        }
6002
        opn = "mov.s";
6003
        break;
6004
    case FOP(7, 16):
6005
        {
6006
            TCGv_i32 fp0 = tcg_temp_new_i32();
6007

    
6008
            gen_load_fpr32(fp0, fs);
6009
            gen_helper_float_chs_s(fp0, fp0);
6010
            gen_store_fpr32(fp0, fd);
6011
            tcg_temp_free_i32(fp0);
6012
        }
6013
        opn = "neg.s";
6014
        break;
6015
    case FOP(8, 16):
6016
        check_cp1_64bitmode(ctx);
6017
        {
6018
            TCGv_i32 fp32 = tcg_temp_new_i32();
6019
            TCGv_i64 fp64 = tcg_temp_new_i64();
6020

    
6021
            gen_load_fpr32(fp32, fs);
6022
            gen_helper_float_roundl_s(fp64, fp32);
6023
            tcg_temp_free_i32(fp32);
6024
            gen_store_fpr64(ctx, fp64, fd);
6025
            tcg_temp_free_i64(fp64);
6026
        }
6027
        opn = "round.l.s";
6028
        break;
6029
    case FOP(9, 16):
6030
        check_cp1_64bitmode(ctx);
6031
        {
6032
            TCGv_i32 fp32 = tcg_temp_new_i32();
6033
            TCGv_i64 fp64 = tcg_temp_new_i64();
6034

    
6035
            gen_load_fpr32(fp32, fs);
6036
            gen_helper_float_truncl_s(fp64, fp32);
6037
            tcg_temp_free_i32(fp32);
6038
            gen_store_fpr64(ctx, fp64, fd);
6039
            tcg_temp_free_i64(fp64);
6040
        }
6041
        opn = "trunc.l.s";
6042
        break;
6043
    case FOP(10, 16):
6044
        check_cp1_64bitmode(ctx);
6045
        {
6046
            TCGv_i32 fp32 = tcg_temp_new_i32();
6047
            TCGv_i64 fp64 = tcg_temp_new_i64();
6048

    
6049
            gen_load_fpr32(fp32, fs);
6050
            gen_helper_float_ceill_s(fp64, fp32);
6051
            tcg_temp_free_i32(fp32);
6052
            gen_store_fpr64(ctx, fp64, fd);
6053
            tcg_temp_free_i64(fp64);
6054
        }
6055
        opn = "ceil.l.s";
6056
        break;
6057
    case FOP(11, 16):
6058
        check_cp1_64bitmode(ctx);
6059
        {
6060
            TCGv_i32 fp32 = tcg_temp_new_i32();
6061
            TCGv_i64 fp64 = tcg_temp_new_i64();
6062

    
6063
            gen_load_fpr32(fp32, fs);
6064
            gen_helper_float_floorl_s(fp64, fp32);
6065
            tcg_temp_free_i32(fp32);
6066
            gen_store_fpr64(ctx, fp64, fd);
6067
            tcg_temp_free_i64(fp64);
6068
        }
6069
        opn = "floor.l.s";
6070
        break;
6071
    case FOP(12, 16):
6072
        {
6073
            TCGv_i32 fp0 = tcg_temp_new_i32();
6074

    
6075
            gen_load_fpr32(fp0, fs);
6076
            gen_helper_float_roundw_s(fp0, fp0);
6077
            gen_store_fpr32(fp0, fd);
6078
            tcg_temp_free_i32(fp0);
6079
        }
6080
        opn = "round.w.s";
6081
        break;
6082
    case FOP(13, 16):
6083
        {
6084
            TCGv_i32 fp0 = tcg_temp_new_i32();
6085

    
6086
            gen_load_fpr32(fp0, fs);
6087
            gen_helper_float_truncw_s(fp0, fp0);
6088
            gen_store_fpr32(fp0, fd);
6089
            tcg_temp_free_i32(fp0);
6090
        }
6091
        opn = "trunc.w.s";
6092
        break;
6093
    case FOP(14, 16):
6094
        {
6095
            TCGv_i32 fp0 = tcg_temp_new_i32();
6096

    
6097
            gen_load_fpr32(fp0, fs);
6098
            gen_helper_float_ceilw_s(fp0, fp0);
6099
            gen_store_fpr32(fp0, fd);
6100
            tcg_temp_free_i32(fp0);
6101
        }
6102
        opn = "ceil.w.s";
6103
        break;
6104
    case FOP(15, 16):
6105
        {
6106
            TCGv_i32 fp0 = tcg_temp_new_i32();
6107

    
6108
            gen_load_fpr32(fp0, fs);
6109
            gen_helper_float_floorw_s(fp0, fp0);
6110
            gen_store_fpr32(fp0, fd);
6111
            tcg_temp_free_i32(fp0);
6112
        }
6113
        opn = "floor.w.s";
6114
        break;
6115
    case FOP(17, 16):
6116
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6117
        opn = "movcf.s";
6118
        break;
6119
    case FOP(18, 16):
6120
        {
6121
            int l1 = gen_new_label();
6122
            TCGv t0 = tcg_temp_new();
6123
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6124

    
6125
            gen_load_gpr(t0, ft);
6126
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6127
            gen_load_fpr32(fp0, fs);
6128
            gen_store_fpr32(fp0, fd);
6129
            tcg_temp_free_i32(fp0);
6130
            gen_set_label(l1);
6131
            tcg_temp_free(t0);
6132
        }
6133
        opn = "movz.s";
6134
        break;
6135
    case FOP(19, 16):
6136
        {
6137
            int l1 = gen_new_label();
6138
            TCGv t0 = tcg_temp_new();
6139
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6140

    
6141
            gen_load_gpr(t0, ft);
6142
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6143
            gen_load_fpr32(fp0, fs);
6144
            gen_store_fpr32(fp0, fd);
6145
            tcg_temp_free_i32(fp0);
6146
            gen_set_label(l1);
6147
            tcg_temp_free(t0);
6148
        }
6149
        opn = "movn.s";
6150
        break;
6151
    case FOP(21, 16):
6152
        check_cop1x(ctx);
6153
        {
6154
            TCGv_i32 fp0 = tcg_temp_new_i32();
6155

    
6156
            gen_load_fpr32(fp0, fs);
6157
            gen_helper_float_recip_s(fp0, fp0);
6158
            gen_store_fpr32(fp0, fd);
6159
            tcg_temp_free_i32(fp0);
6160
        }
6161
        opn = "recip.s";
6162
        break;
6163
    case FOP(22, 16):
6164
        check_cop1x(ctx);
6165
        {
6166
            TCGv_i32 fp0 = tcg_temp_new_i32();
6167

    
6168
            gen_load_fpr32(fp0, fs);
6169
            gen_helper_float_rsqrt_s(fp0, fp0);
6170
            gen_store_fpr32(fp0, fd);
6171
            tcg_temp_free_i32(fp0);
6172
        }
6173
        opn = "rsqrt.s";
6174
        break;
6175
    case FOP(28, 16):
6176
        check_cp1_64bitmode(ctx);
6177
        {
6178
            TCGv_i32 fp0 = tcg_temp_new_i32();
6179
            TCGv_i32 fp1 = tcg_temp_new_i32();
6180

    
6181
            gen_load_fpr32(fp0, fs);
6182
            gen_load_fpr32(fp1, fd);
6183
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6184
            tcg_temp_free_i32(fp1);
6185
            gen_store_fpr32(fp0, fd);
6186
            tcg_temp_free_i32(fp0);
6187
        }
6188
        opn = "recip2.s";
6189
        break;
6190
    case FOP(29, 16):
6191
        check_cp1_64bitmode(ctx);
6192
        {
6193
            TCGv_i32 fp0 = tcg_temp_new_i32();
6194

    
6195
            gen_load_fpr32(fp0, fs);
6196
            gen_helper_float_recip1_s(fp0, fp0);
6197
            gen_store_fpr32(fp0, fd);
6198
            tcg_temp_free_i32(fp0);
6199
        }
6200
        opn = "recip1.s";
6201
        break;
6202
    case FOP(30, 16):
6203
        check_cp1_64bitmode(ctx);
6204
        {
6205
            TCGv_i32 fp0 = tcg_temp_new_i32();
6206

    
6207
            gen_load_fpr32(fp0, fs);
6208
            gen_helper_float_rsqrt1_s(fp0, fp0);
6209
            gen_store_fpr32(fp0, fd);
6210
            tcg_temp_free_i32(fp0);
6211
        }
6212
        opn = "rsqrt1.s";
6213
        break;
6214
    case FOP(31, 16):
6215
        check_cp1_64bitmode(ctx);
6216
        {
6217
            TCGv_i32 fp0 = tcg_temp_new_i32();
6218
            TCGv_i32 fp1 = tcg_temp_new_i32();
6219

    
6220
            gen_load_fpr32(fp0, fs);
6221
            gen_load_fpr32(fp1, ft);
6222
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6223
            tcg_temp_free_i32(fp1);
6224
            gen_store_fpr32(fp0, fd);
6225
            tcg_temp_free_i32(fp0);
6226
        }
6227
        opn = "rsqrt2.s";
6228
        break;
6229
    case FOP(33, 16):
6230
        check_cp1_registers(ctx, fd);
6231
        {
6232
            TCGv_i32 fp32 = tcg_temp_new_i32();
6233
            TCGv_i64 fp64 = tcg_temp_new_i64();
6234

    
6235
            gen_load_fpr32(fp32, fs);
6236
            gen_helper_float_cvtd_s(fp64, fp32);
6237
            tcg_temp_free_i32(fp32);
6238
            gen_store_fpr64(ctx, fp64, fd);
6239
            tcg_temp_free_i64(fp64);
6240
        }
6241
        opn = "cvt.d.s";
6242
        break;
6243
    case FOP(36, 16):
6244
        {
6245
            TCGv_i32 fp0 = tcg_temp_new_i32();
6246

    
6247
            gen_load_fpr32(fp0, fs);
6248
            gen_helper_float_cvtw_s(fp0, fp0);
6249
            gen_store_fpr32(fp0, fd);
6250
            tcg_temp_free_i32(fp0);
6251
        }
6252
        opn = "cvt.w.s";
6253
        break;
6254
    case FOP(37, 16):
6255
        check_cp1_64bitmode(ctx);
6256
        {
6257
            TCGv_i32 fp32 = tcg_temp_new_i32();
6258
            TCGv_i64 fp64 = tcg_temp_new_i64();
6259

    
6260
            gen_load_fpr32(fp32, fs);
6261
            gen_helper_float_cvtl_s(fp64, fp32);
6262
            tcg_temp_free_i32(fp32);
6263
            gen_store_fpr64(ctx, fp64, fd);
6264
            tcg_temp_free_i64(fp64);
6265
        }
6266
        opn = "cvt.l.s";
6267
        break;
6268
    case FOP(38, 16):
6269
        check_cp1_64bitmode(ctx);
6270
        {
6271
            TCGv_i64 fp64 = tcg_temp_new_i64();
6272
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6273
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6274

    
6275
            gen_load_fpr32(fp32_0, fs);
6276
            gen_load_fpr32(fp32_1, ft);
6277
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6278
            tcg_temp_free_i32(fp32_1);
6279
            tcg_temp_free_i32(fp32_0);
6280
            gen_store_fpr64(ctx, fp64, fd);
6281
            tcg_temp_free_i64(fp64);
6282
        }
6283
        opn = "cvt.ps.s";
6284
        break;
6285
    case FOP(48, 16):
6286
    case FOP(49, 16):
6287
    case FOP(50, 16):
6288
    case FOP(51, 16):
6289
    case FOP(52, 16):
6290
    case FOP(53, 16):
6291
    case FOP(54, 16):
6292
    case FOP(55, 16):
6293
    case FOP(56, 16):
6294
    case FOP(57, 16):
6295
    case FOP(58, 16):
6296
    case FOP(59, 16):
6297
    case FOP(60, 16):
6298
    case FOP(61, 16):
6299
    case FOP(62, 16):
6300
    case FOP(63, 16):
6301
        {
6302
            TCGv_i32 fp0 = tcg_temp_new_i32();
6303
            TCGv_i32 fp1 = tcg_temp_new_i32();
6304

    
6305
            gen_load_fpr32(fp0, fs);
6306
            gen_load_fpr32(fp1, ft);
6307
            if (ctx->opcode & (1 << 6)) {
6308
                check_cop1x(ctx);
6309
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6310
                opn = condnames_abs[func-48];
6311
            } else {
6312
                gen_cmp_s(func-48, fp0, fp1, cc);
6313
                opn = condnames[func-48];
6314
            }
6315
            tcg_temp_free_i32(fp0);
6316
            tcg_temp_free_i32(fp1);
6317
        }
6318
        break;
6319
    case FOP(0, 17):
6320
        check_cp1_registers(ctx, fs | ft | fd);
6321
        {
6322
            TCGv_i64 fp0 = tcg_temp_new_i64();
6323
            TCGv_i64 fp1 = tcg_temp_new_i64();
6324

    
6325
            gen_load_fpr64(ctx, fp0, fs);
6326
            gen_load_fpr64(ctx, fp1, ft);
6327
            gen_helper_float_add_d(fp0, fp0, fp1);
6328
            tcg_temp_free_i64(fp1);
6329
            gen_store_fpr64(ctx, fp0, fd);
6330
            tcg_temp_free_i64(fp0);
6331
        }
6332
        opn = "add.d";
6333
        optype = BINOP;
6334
        break;
6335
    case FOP(1, 17):
6336
        check_cp1_registers(ctx, fs | ft | fd);
6337
        {
6338
            TCGv_i64 fp0 = tcg_temp_new_i64();
6339
            TCGv_i64 fp1 = tcg_temp_new_i64();
6340

    
6341
            gen_load_fpr64(ctx, fp0, fs);
6342
            gen_load_fpr64(ctx, fp1, ft);
6343
            gen_helper_float_sub_d(fp0, fp0, fp1);
6344
            tcg_temp_free_i64(fp1);
6345
            gen_store_fpr64(ctx, fp0, fd);
6346
            tcg_temp_free_i64(fp0);
6347
        }
6348
        opn = "sub.d";
6349
        optype = BINOP;
6350
        break;
6351
    case FOP(2, 17):
6352
        check_cp1_registers(ctx, fs | ft | fd);
6353
        {
6354
            TCGv_i64 fp0 = tcg_temp_new_i64();
6355
            TCGv_i64 fp1 = tcg_temp_new_i64();
6356

    
6357
            gen_load_fpr64(ctx, fp0, fs);
6358
            gen_load_fpr64(ctx, fp1, ft);
6359
            gen_helper_float_mul_d(fp0, fp0, fp1);
6360
            tcg_temp_free_i64(fp1);
6361
            gen_store_fpr64(ctx, fp0, fd);
6362
            tcg_temp_free_i64(fp0);
6363
        }
6364
        opn = "mul.d";
6365
        optype = BINOP;
6366
        break;
6367
    case FOP(3, 17):
6368
        check_cp1_registers(ctx, fs | ft | fd);
6369
        {
6370
            TCGv_i64 fp0 = tcg_temp_new_i64();
6371
            TCGv_i64 fp1 = tcg_temp_new_i64();
6372

    
6373
            gen_load_fpr64(ctx, fp0, fs);
6374
            gen_load_fpr64(ctx, fp1, ft);
6375
            gen_helper_float_div_d(fp0, fp0, fp1);
6376
            tcg_temp_free_i64(fp1);
6377
            gen_store_fpr64(ctx, fp0, fd);
6378
            tcg_temp_free_i64(fp0);
6379
        }
6380
        opn = "div.d";
6381
        optype = BINOP;
6382
        break;
6383
    case FOP(4, 17):
6384
        check_cp1_registers(ctx, fs | fd);
6385
        {
6386
            TCGv_i64 fp0 = tcg_temp_new_i64();
6387

    
6388
            gen_load_fpr64(ctx, fp0, fs);
6389
            gen_helper_float_sqrt_d(fp0, fp0);
6390
            gen_store_fpr64(ctx, fp0, fd);
6391
            tcg_temp_free_i64(fp0);
6392
        }
6393
        opn = "sqrt.d";
6394
        break;
6395
    case FOP(5, 17):
6396
        check_cp1_registers(ctx, fs | fd);
6397
        {
6398
            TCGv_i64 fp0 = tcg_temp_new_i64();
6399

    
6400
            gen_load_fpr64(ctx, fp0, fs);
6401
            gen_helper_float_abs_d(fp0, fp0);
6402
            gen_store_fpr64(ctx, fp0, fd);
6403
            tcg_temp_free_i64(fp0);
6404
        }
6405
        opn = "abs.d";
6406
        break;
6407
    case FOP(6, 17):
6408
        check_cp1_registers(ctx, fs | fd);
6409
        {
6410
            TCGv_i64 fp0 = tcg_temp_new_i64();
6411

    
6412
            gen_load_fpr64(ctx, fp0, fs);
6413
            gen_store_fpr64(ctx, fp0, fd);
6414
            tcg_temp_free_i64(fp0);
6415
        }
6416
        opn = "mov.d";
6417
        break;
6418
    case FOP(7, 17):
6419
        check_cp1_registers(ctx, fs | fd);
6420
        {
6421
            TCGv_i64 fp0 = tcg_temp_new_i64();
6422

    
6423
            gen_load_fpr64(ctx, fp0, fs);
6424
            gen_helper_float_chs_d(fp0, fp0);
6425
            gen_store_fpr64(ctx, fp0, fd);
6426
            tcg_temp_free_i64(fp0);
6427
        }
6428
        opn = "neg.d";
6429
        break;
6430
    case FOP(8, 17):
6431
        check_cp1_64bitmode(ctx);
6432
        {
6433
            TCGv_i64 fp0 = tcg_temp_new_i64();
6434

    
6435
            gen_load_fpr64(ctx, fp0, fs);
6436
            gen_helper_float_roundl_d(fp0, fp0);
6437
            gen_store_fpr64(ctx, fp0, fd);
6438
            tcg_temp_free_i64(fp0);
6439
        }
6440
        opn = "round.l.d";
6441
        break;
6442
    case FOP(9, 17):
6443
        check_cp1_64bitmode(ctx);
6444
        {
6445
            TCGv_i64 fp0 = tcg_temp_new_i64();
6446

    
6447
            gen_load_fpr64(ctx, fp0, fs);
6448
            gen_helper_float_truncl_d(fp0, fp0);
6449
            gen_store_fpr64(ctx, fp0, fd);
6450
            tcg_temp_free_i64(fp0);
6451
        }
6452
        opn = "trunc.l.d";
6453
        break;
6454
    case FOP(10, 17):
6455
        check_cp1_64bitmode(ctx);
6456
        {
6457
            TCGv_i64 fp0 = tcg_temp_new_i64();
6458

    
6459
            gen_load_fpr64(ctx, fp0, fs);
6460
            gen_helper_float_ceill_d(fp0, fp0);
6461
            gen_store_fpr64(ctx, fp0, fd);
6462
            tcg_temp_free_i64(fp0);
6463
        }
6464
        opn = "ceil.l.d";
6465
        break;
6466
    case FOP(11, 17):
6467
        check_cp1_64bitmode(ctx);
6468
        {
6469
            TCGv_i64 fp0 = tcg_temp_new_i64();
6470

    
6471
            gen_load_fpr64(ctx, fp0, fs);
6472
            gen_helper_float_floorl_d(fp0, fp0);
6473
            gen_store_fpr64(ctx, fp0, fd);
6474
            tcg_temp_free_i64(fp0);
6475
        }
6476
        opn = "floor.l.d";
6477
        break;
6478
    case FOP(12, 17):
6479
        check_cp1_registers(ctx, fs);
6480
        {
6481
            TCGv_i32 fp32 = tcg_temp_new_i32();
6482
            TCGv_i64 fp64 = tcg_temp_new_i64();
6483

    
6484
            gen_load_fpr64(ctx, fp64, fs);
6485
            gen_helper_float_roundw_d(fp32, fp64);
6486
            tcg_temp_free_i64(fp64);
6487
            gen_store_fpr32(fp32, fd);
6488
            tcg_temp_free_i32(fp32);
6489
        }
6490
        opn = "round.w.d";
6491
        break;
6492
    case FOP(13, 17):
6493
        check_cp1_registers(ctx, fs);
6494
        {
6495
            TCGv_i32 fp32 = tcg_temp_new_i32();
6496
            TCGv_i64 fp64 = tcg_temp_new_i64();
6497

    
6498
            gen_load_fpr64(ctx, fp64, fs);
6499
            gen_helper_float_truncw_d(fp32, fp64);
6500
            tcg_temp_free_i64(fp64);
6501
            gen_store_fpr32(fp32, fd);
6502
            tcg_temp_free_i32(fp32);
6503
        }
6504
        opn = "trunc.w.d";
6505
        break;
6506
    case FOP(14, 17):
6507
        check_cp1_registers(ctx, fs);
6508
        {
6509
            TCGv_i32 fp32 = tcg_temp_new_i32();
6510
            TCGv_i64 fp64 = tcg_temp_new_i64();
6511

    
6512
            gen_load_fpr64(ctx, fp64, fs);
6513
            gen_helper_float_ceilw_d(fp32, fp64);
6514
            tcg_temp_free_i64(fp64);
6515
            gen_store_fpr32(fp32, fd);
6516
            tcg_temp_free_i32(fp32);
6517
        }
6518
        opn = "ceil.w.d";
6519
        break;
6520
    case FOP(15, 17):
6521
        check_cp1_registers(ctx, fs);
6522
        {
6523
            TCGv_i32 fp32 = tcg_temp_new_i32();
6524
            TCGv_i64 fp64 = tcg_temp_new_i64();
6525

    
6526
            gen_load_fpr64(ctx, fp64, fs);
6527
            gen_helper_float_floorw_d(fp32, fp64);
6528
            tcg_temp_free_i64(fp64);
6529
            gen_store_fpr32(fp32, fd);
6530
            tcg_temp_free_i32(fp32);
6531
        }
6532
        opn = "floor.w.d";
6533
        break;
6534
    case FOP(17, 17):
6535
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6536
        opn = "movcf.d";
6537
        break;
6538
    case FOP(18, 17):
6539
        {
6540
            int l1 = gen_new_label();
6541
            TCGv t0 = tcg_temp_new();
6542
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6543

    
6544
            gen_load_gpr(t0, ft);
6545
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6546
            gen_load_fpr64(ctx, fp0, fs);
6547
            gen_store_fpr64(ctx, fp0, fd);
6548
            tcg_temp_free_i64(fp0);
6549
            gen_set_label(l1);
6550
            tcg_temp_free(t0);
6551
        }
6552
        opn = "movz.d";
6553
        break;
6554
    case FOP(19, 17):
6555
        {
6556
            int l1 = gen_new_label();
6557
            TCGv t0 = tcg_temp_new();
6558
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6559

    
6560
            gen_load_gpr(t0, ft);
6561
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6562
            gen_load_fpr64(ctx, fp0, fs);
6563
            gen_store_fpr64(ctx, fp0, fd);
6564
            tcg_temp_free_i64(fp0);
6565
            gen_set_label(l1);
6566
            tcg_temp_free(t0);
6567
        }
6568
        opn = "movn.d";
6569
        break;
6570
    case FOP(21, 17):
6571
        check_cp1_64bitmode(ctx);
6572
        {
6573
            TCGv_i64 fp0 = tcg_temp_new_i64();
6574

    
6575
            gen_load_fpr64(ctx, fp0, fs);
6576
            gen_helper_float_recip_d(fp0, fp0);
6577
            gen_store_fpr64(ctx, fp0, fd);
6578
            tcg_temp_free_i64(fp0);
6579
        }
6580
        opn = "recip.d";
6581
        break;
6582
    case FOP(22, 17):
6583
        check_cp1_64bitmode(ctx);
6584
        {
6585
            TCGv_i64 fp0 = tcg_temp_new_i64();
6586

    
6587
            gen_load_fpr64(ctx, fp0, fs);
6588
            gen_helper_float_rsqrt_d(fp0, fp0);
6589
            gen_store_fpr64(ctx, fp0, fd);
6590
            tcg_temp_free_i64(fp0);
6591
        }
6592
        opn = "rsqrt.d";
6593
        break;
6594
    case FOP(28, 17):
6595
        check_cp1_64bitmode(ctx);
6596
        {
6597
            TCGv_i64 fp0 = tcg_temp_new_i64();
6598
            TCGv_i64 fp1 = tcg_temp_new_i64();
6599

    
6600
            gen_load_fpr64(ctx, fp0, fs);
6601
            gen_load_fpr64(ctx, fp1, ft);
6602
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6603
            tcg_temp_free_i64(fp1);
6604
            gen_store_fpr64(ctx, fp0, fd);
6605
            tcg_temp_free_i64(fp0);
6606
        }
6607
        opn = "recip2.d";
6608
        break;
6609
    case FOP(29, 17):
6610
        check_cp1_64bitmode(ctx);
6611
        {
6612
            TCGv_i64 fp0 = tcg_temp_new_i64();
6613

    
6614
            gen_load_fpr64(ctx, fp0, fs);
6615
            gen_helper_float_recip1_d(fp0, fp0);
6616
            gen_store_fpr64(ctx, fp0, fd);
6617
            tcg_temp_free_i64(fp0);
6618
        }
6619
        opn = "recip1.d";
6620
        break;
6621
    case FOP(30, 17):
6622
        check_cp1_64bitmode(ctx);
6623
        {
6624
            TCGv_i64 fp0 = tcg_temp_new_i64();
6625

    
6626
            gen_load_fpr64(ctx, fp0, fs);
6627
            gen_helper_float_rsqrt1_d(fp0, fp0);
6628
            gen_store_fpr64(ctx, fp0, fd);
6629
            tcg_temp_free_i64(fp0);
6630
        }
6631
        opn = "rsqrt1.d";
6632
        break;
6633
    case FOP(31, 17):
6634
        check_cp1_64bitmode(ctx);
6635
        {
6636
            TCGv_i64 fp0 = tcg_temp_new_i64();
6637
            TCGv_i64 fp1 = tcg_temp_new_i64();
6638

    
6639
            gen_load_fpr64(ctx, fp0, fs);
6640
            gen_load_fpr64(ctx, fp1, ft);
6641
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6642
            tcg_temp_free_i64(fp1);
6643
            gen_store_fpr64(ctx, fp0, fd);
6644
            tcg_temp_free_i64(fp0);
6645
        }
6646
        opn = "rsqrt2.d";
6647
        break;
6648
    case FOP(48, 17):
6649
    case FOP(49, 17):
6650
    case FOP(50, 17):
6651
    case FOP(51, 17):
6652
    case FOP(52, 17):
6653
    case FOP(53, 17):
6654
    case FOP(54, 17):
6655
    case FOP(55, 17):
6656
    case FOP(56, 17):
6657
    case FOP(57, 17):
6658
    case FOP(58, 17):
6659
    case FOP(59, 17):
6660
    case FOP(60, 17):
6661
    case FOP(61, 17):
6662
    case FOP(62, 17):
6663
    case FOP(63, 17):
6664
        {
6665
            TCGv_i64 fp0 = tcg_temp_new_i64();
6666
            TCGv_i64 fp1 = tcg_temp_new_i64();
6667

    
6668
            gen_load_fpr64(ctx, fp0, fs);
6669
            gen_load_fpr64(ctx, fp1, ft);
6670
            if (ctx->opcode & (1 << 6)) {
6671
                check_cop1x(ctx);
6672
                check_cp1_registers(ctx, fs | ft);
6673
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6674
                opn = condnames_abs[func-48];
6675
            } else {
6676
                check_cp1_registers(ctx, fs | ft);
6677
                gen_cmp_d(func-48, fp0, fp1, cc);
6678
                opn = condnames[func-48];
6679
            }
6680
            tcg_temp_free_i64(fp0);
6681
            tcg_temp_free_i64(fp1);
6682
        }
6683
        break;
6684
    case FOP(32, 17):
6685
        check_cp1_registers(ctx, fs);
6686
        {
6687
            TCGv_i32 fp32 = tcg_temp_new_i32();
6688
            TCGv_i64 fp64 = tcg_temp_new_i64();
6689

    
6690
            gen_load_fpr64(ctx, fp64, fs);
6691
            gen_helper_float_cvts_d(fp32, fp64);
6692
            tcg_temp_free_i64(fp64);
6693
            gen_store_fpr32(fp32, fd);
6694
            tcg_temp_free_i32(fp32);
6695
        }
6696
        opn = "cvt.s.d";
6697
        break;
6698
    case FOP(36, 17):
6699
        check_cp1_registers(ctx, fs);
6700
        {
6701
            TCGv_i32 fp32 = tcg_temp_new_i32();
6702
            TCGv_i64 fp64 = tcg_temp_new_i64();
6703

    
6704
            gen_load_fpr64(ctx, fp64, fs);
6705
            gen_helper_float_cvtw_d(fp32, fp64);
6706
            tcg_temp_free_i64(fp64);
6707
            gen_store_fpr32(fp32, fd);
6708
            tcg_temp_free_i32(fp32);
6709
        }
6710
        opn = "cvt.w.d";
6711
        break;
6712
    case FOP(37, 17):
6713
        check_cp1_64bitmode(ctx);
6714
        {
6715
            TCGv_i64 fp0 = tcg_temp_new_i64();
6716

    
6717
            gen_load_fpr64(ctx, fp0, fs);
6718
            gen_helper_float_cvtl_d(fp0, fp0);
6719
            gen_store_fpr64(ctx, fp0, fd);
6720
            tcg_temp_free_i64(fp0);
6721
        }
6722
        opn = "cvt.l.d";
6723
        break;
6724
    case FOP(32, 20):
6725
        {
6726
            TCGv_i32 fp0 = tcg_temp_new_i32();
6727

    
6728
            gen_load_fpr32(fp0, fs);
6729
            gen_helper_float_cvts_w(fp0, fp0);
6730
            gen_store_fpr32(fp0, fd);
6731
            tcg_temp_free_i32(fp0);
6732
        }
6733
        opn = "cvt.s.w";
6734
        break;
6735
    case FOP(33, 20):
6736
        check_cp1_registers(ctx, fd);
6737
        {
6738
            TCGv_i32 fp32 = tcg_temp_new_i32();
6739
            TCGv_i64 fp64 = tcg_temp_new_i64();
6740

    
6741
            gen_load_fpr32(fp32, fs);
6742
            gen_helper_float_cvtd_w(fp64, fp32);
6743
            tcg_temp_free_i32(fp32);
6744
            gen_store_fpr64(ctx, fp64, fd);
6745
            tcg_temp_free_i64(fp64);
6746
        }
6747
        opn = "cvt.d.w";
6748
        break;
6749
    case FOP(32, 21):
6750
        check_cp1_64bitmode(ctx);
6751
        {
6752
            TCGv_i32 fp32 = tcg_temp_new_i32();
6753
            TCGv_i64 fp64 = tcg_temp_new_i64();
6754

    
6755
            gen_load_fpr64(ctx, fp64, fs);
6756
            gen_helper_float_cvts_l(fp32, fp64);
6757
            tcg_temp_free_i64(fp64);
6758
            gen_store_fpr32(fp32, fd);
6759
            tcg_temp_free_i32(fp32);
6760
        }
6761
        opn = "cvt.s.l";
6762
        break;
6763
    case FOP(33, 21):
6764
        check_cp1_64bitmode(ctx);
6765
        {
6766
            TCGv_i64 fp0 = tcg_temp_new_i64();
6767

    
6768
            gen_load_fpr64(ctx, fp0, fs);
6769
            gen_helper_float_cvtd_l(fp0, fp0);
6770
            gen_store_fpr64(ctx, fp0, fd);
6771
            tcg_temp_free_i64(fp0);
6772
        }
6773
        opn = "cvt.d.l";
6774
        break;
6775
    case FOP(38, 20):
6776
        check_cp1_64bitmode(ctx);
6777
        {
6778
            TCGv_i64 fp0 = tcg_temp_new_i64();
6779

    
6780
            gen_load_fpr64(ctx, fp0, fs);
6781
            gen_helper_float_cvtps_pw(fp0, fp0);
6782
            gen_store_fpr64(ctx, fp0, fd);
6783
            tcg_temp_free_i64(fp0);
6784
        }
6785
        opn = "cvt.ps.pw";
6786
        break;
6787
    case FOP(0, 22):
6788
        check_cp1_64bitmode(ctx);
6789
        {
6790
            TCGv_i64 fp0 = tcg_temp_new_i64();
6791
            TCGv_i64 fp1 = tcg_temp_new_i64();
6792

    
6793
            gen_load_fpr64(ctx, fp0, fs);
6794
            gen_load_fpr64(ctx, fp1, ft);
6795
            gen_helper_float_add_ps(fp0, fp0, fp1);
6796
            tcg_temp_free_i64(fp1);
6797
            gen_store_fpr64(ctx, fp0, fd);
6798
            tcg_temp_free_i64(fp0);
6799
        }
6800
        opn = "add.ps";
6801
        break;
6802
    case FOP(1, 22):
6803
        check_cp1_64bitmode(ctx);
6804
        {
6805
            TCGv_i64 fp0 = tcg_temp_new_i64();
6806
            TCGv_i64 fp1 = tcg_temp_new_i64();
6807

    
6808
            gen_load_fpr64(ctx, fp0, fs);
6809
            gen_load_fpr64(ctx, fp1, ft);
6810
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6811
            tcg_temp_free_i64(fp1);
6812
            gen_store_fpr64(ctx, fp0, fd);
6813
            tcg_temp_free_i64(fp0);
6814
        }
6815
        opn = "sub.ps";
6816
        break;
6817
    case FOP(2, 22):
6818
        check_cp1_64bitmode(ctx);
6819
        {
6820
            TCGv_i64 fp0 = tcg_temp_new_i64();
6821
            TCGv_i64 fp1 = tcg_temp_new_i64();
6822

    
6823
            gen_load_fpr64(ctx, fp0, fs);
6824
            gen_load_fpr64(ctx, fp1, ft);
6825
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6826
            tcg_temp_free_i64(fp1);
6827
            gen_store_fpr64(ctx, fp0, fd);
6828
            tcg_temp_free_i64(fp0);
6829
        }
6830
        opn = "mul.ps";
6831
        break;
6832
    case FOP(5, 22):
6833
        check_cp1_64bitmode(ctx);
6834
        {
6835
            TCGv_i64 fp0 = tcg_temp_new_i64();
6836

    
6837
            gen_load_fpr64(ctx, fp0, fs);
6838
            gen_helper_float_abs_ps(fp0, fp0);
6839
            gen_store_fpr64(ctx, fp0, fd);
6840
            tcg_temp_free_i64(fp0);
6841
        }
6842
        opn = "abs.ps";
6843
        break;
6844
    case FOP(6, 22):
6845
        check_cp1_64bitmode(ctx);
6846
        {
6847
            TCGv_i64 fp0 = tcg_temp_new_i64();
6848

    
6849
            gen_load_fpr64(ctx, fp0, fs);
6850
            gen_store_fpr64(ctx, fp0, fd);
6851
            tcg_temp_free_i64(fp0);
6852
        }
6853
        opn = "mov.ps";
6854
        break;
6855
    case FOP(7, 22):
6856
        check_cp1_64bitmode(ctx);
6857
        {
6858
            TCGv_i64 fp0 = tcg_temp_new_i64();
6859

    
6860
            gen_load_fpr64(ctx, fp0, fs);
6861
            gen_helper_float_chs_ps(fp0, fp0);
6862
            gen_store_fpr64(ctx, fp0, fd);
6863
            tcg_temp_free_i64(fp0);
6864
        }
6865
        opn = "neg.ps";
6866
        break;
6867
    case FOP(17, 22):
6868
        check_cp1_64bitmode(ctx);
6869
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6870
        opn = "movcf.ps";
6871
        break;
6872
    case FOP(18, 22):
6873
        check_cp1_64bitmode(ctx);
6874
        {
6875
            int l1 = gen_new_label();
6876
            TCGv t0 = tcg_temp_new();
6877
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6878
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6879

    
6880
            gen_load_gpr(t0, ft);
6881
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6882
            gen_load_fpr32(fp0, fs);
6883
            gen_load_fpr32h(fph0, fs);
6884
            gen_store_fpr32(fp0, fd);
6885
            gen_store_fpr32h(fph0, fd);
6886
            tcg_temp_free_i32(fp0);
6887
            tcg_temp_free_i32(fph0);
6888
            gen_set_label(l1);
6889
            tcg_temp_free(t0);
6890
        }
6891
        opn = "movz.ps";
6892
        break;
6893
    case FOP(19, 22):
6894
        check_cp1_64bitmode(ctx);
6895
        {
6896
            int l1 = gen_new_label();
6897
            TCGv t0 = tcg_temp_new();
6898
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6899
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6900

    
6901
            gen_load_gpr(t0, ft);
6902
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6903
            gen_load_fpr32(fp0, fs);
6904
            gen_load_fpr32h(fph0, fs);
6905
            gen_store_fpr32(fp0, fd);
6906
            gen_store_fpr32h(fph0, fd);
6907
            tcg_temp_free_i32(fp0);
6908
            tcg_temp_free_i32(fph0);
6909
            gen_set_label(l1);
6910
            tcg_temp_free(t0);
6911
        }
6912
        opn = "movn.ps";
6913
        break;
6914
    case FOP(24, 22):
6915
        check_cp1_64bitmode(ctx);
6916
        {
6917
            TCGv_i64 fp0 = tcg_temp_new_i64();
6918
            TCGv_i64 fp1 = tcg_temp_new_i64();
6919

    
6920
            gen_load_fpr64(ctx, fp0, ft);
6921
            gen_load_fpr64(ctx, fp1, fs);
6922
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6923
            tcg_temp_free_i64(fp1);
6924
            gen_store_fpr64(ctx, fp0, fd);
6925
            tcg_temp_free_i64(fp0);
6926
        }
6927
        opn = "addr.ps";
6928
        break;
6929
    case FOP(26, 22):
6930
        check_cp1_64bitmode(ctx);
6931
        {
6932
            TCGv_i64 fp0 = tcg_temp_new_i64();
6933
            TCGv_i64 fp1 = tcg_temp_new_i64();
6934

    
6935
            gen_load_fpr64(ctx, fp0, ft);
6936
            gen_load_fpr64(ctx, fp1, fs);
6937
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
6938
            tcg_temp_free_i64(fp1);
6939
            gen_store_fpr64(ctx, fp0, fd);
6940
            tcg_temp_free_i64(fp0);
6941
        }
6942
        opn = "mulr.ps";
6943
        break;
6944
    case FOP(28, 22):
6945
        check_cp1_64bitmode(ctx);
6946
        {
6947
            TCGv_i64 fp0 = tcg_temp_new_i64();
6948
            TCGv_i64 fp1 = tcg_temp_new_i64();
6949

    
6950
            gen_load_fpr64(ctx, fp0, fs);
6951
            gen_load_fpr64(ctx, fp1, fd);
6952
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
6953
            tcg_temp_free_i64(fp1);
6954
            gen_store_fpr64(ctx, fp0, fd);
6955
            tcg_temp_free_i64(fp0);
6956
        }
6957
        opn = "recip2.ps";
6958
        break;
6959
    case FOP(29, 22):
6960
        check_cp1_64bitmode(ctx);
6961
        {
6962
            TCGv_i64 fp0 = tcg_temp_new_i64();
6963

    
6964
            gen_load_fpr64(ctx, fp0, fs);
6965
            gen_helper_float_recip1_ps(fp0, fp0);
6966
            gen_store_fpr64(ctx, fp0, fd);
6967
            tcg_temp_free_i64(fp0);
6968
        }
6969
        opn = "recip1.ps";
6970
        break;
6971
    case FOP(30, 22):
6972
        check_cp1_64bitmode(ctx);
6973
        {
6974
            TCGv_i64 fp0 = tcg_temp_new_i64();
6975

    
6976
            gen_load_fpr64(ctx, fp0, fs);
6977
            gen_helper_float_rsqrt1_ps(fp0, fp0);
6978
            gen_store_fpr64(ctx, fp0, fd);
6979
            tcg_temp_free_i64(fp0);
6980
        }
6981
        opn = "rsqrt1.ps";
6982
        break;
6983
    case FOP(31, 22):
6984
        check_cp1_64bitmode(ctx);
6985
        {
6986
            TCGv_i64 fp0 = tcg_temp_new_i64();
6987
            TCGv_i64 fp1 = tcg_temp_new_i64();
6988

    
6989
            gen_load_fpr64(ctx, fp0, fs);
6990
            gen_load_fpr64(ctx, fp1, ft);
6991
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
6992
            tcg_temp_free_i64(fp1);
6993
            gen_store_fpr64(ctx, fp0, fd);
6994
            tcg_temp_free_i64(fp0);
6995
        }
6996
        opn = "rsqrt2.ps";
6997
        break;
6998
    case FOP(32, 22):
6999
        check_cp1_64bitmode(ctx);
7000
        {
7001
            TCGv_i32 fp0 = tcg_temp_new_i32();
7002

    
7003
            gen_load_fpr32h(fp0, fs);
7004
            gen_helper_float_cvts_pu(fp0, fp0);
7005
            gen_store_fpr32(fp0, fd);
7006
            tcg_temp_free_i32(fp0);
7007
        }
7008
        opn = "cvt.s.pu";
7009
        break;
7010
    case FOP(36, 22):
7011
        check_cp1_64bitmode(ctx);
7012
        {
7013
            TCGv_i64 fp0 = tcg_temp_new_i64();
7014

    
7015
            gen_load_fpr64(ctx, fp0, fs);
7016
            gen_helper_float_cvtpw_ps(fp0, fp0);
7017
            gen_store_fpr64(ctx, fp0, fd);
7018
            tcg_temp_free_i64(fp0);
7019
        }
7020
        opn = "cvt.pw.ps";
7021
        break;
7022
    case FOP(40, 22):
7023
        check_cp1_64bitmode(ctx);
7024
        {
7025
            TCGv_i32 fp0 = tcg_temp_new_i32();
7026

    
7027
            gen_load_fpr32(fp0, fs);
7028
            gen_helper_float_cvts_pl(fp0, fp0);
7029
            gen_store_fpr32(fp0, fd);
7030
            tcg_temp_free_i32(fp0);
7031
        }
7032
        opn = "cvt.s.pl";
7033
        break;
7034
    case FOP(44, 22):
7035
        check_cp1_64bitmode(ctx);
7036
        {
7037
            TCGv_i32 fp0 = tcg_temp_new_i32();
7038
            TCGv_i32 fp1 = tcg_temp_new_i32();
7039

    
7040
            gen_load_fpr32(fp0, fs);
7041
            gen_load_fpr32(fp1, ft);
7042
            gen_store_fpr32h(fp0, fd);
7043
            gen_store_fpr32(fp1, fd);
7044
            tcg_temp_free_i32(fp0);
7045
            tcg_temp_free_i32(fp1);
7046
        }
7047
        opn = "pll.ps";
7048
        break;
7049
    case FOP(45, 22):
7050
        check_cp1_64bitmode(ctx);
7051
        {
7052
            TCGv_i32 fp0 = tcg_temp_new_i32();
7053
            TCGv_i32 fp1 = tcg_temp_new_i32();
7054

    
7055
            gen_load_fpr32(fp0, fs);
7056
            gen_load_fpr32h(fp1, ft);
7057
            gen_store_fpr32(fp1, fd);
7058
            gen_store_fpr32h(fp0, fd);
7059
            tcg_temp_free_i32(fp0);
7060
            tcg_temp_free_i32(fp1);
7061
        }
7062
        opn = "plu.ps";
7063
        break;
7064
    case FOP(46, 22):
7065
        check_cp1_64bitmode(ctx);
7066
        {
7067
            TCGv_i32 fp0 = tcg_temp_new_i32();
7068
            TCGv_i32 fp1 = tcg_temp_new_i32();
7069

    
7070
            gen_load_fpr32h(fp0, fs);
7071
            gen_load_fpr32(fp1, ft);
7072
            gen_store_fpr32(fp1, fd);
7073
            gen_store_fpr32h(fp0, fd);
7074
            tcg_temp_free_i32(fp0);
7075
            tcg_temp_free_i32(fp1);
7076
        }
7077
        opn = "pul.ps";
7078
        break;
7079
    case FOP(47, 22):
7080
        check_cp1_64bitmode(ctx);
7081
        {
7082
            TCGv_i32 fp0 = tcg_temp_new_i32();
7083
            TCGv_i32 fp1 = tcg_temp_new_i32();
7084

    
7085
            gen_load_fpr32h(fp0, fs);
7086
            gen_load_fpr32h(fp1, ft);
7087
            gen_store_fpr32(fp1, fd);
7088
            gen_store_fpr32h(fp0, fd);
7089
            tcg_temp_free_i32(fp0);
7090
            tcg_temp_free_i32(fp1);
7091
        }
7092
        opn = "puu.ps";
7093
        break;
7094
    case FOP(48, 22):
7095
    case FOP(49, 22):
7096
    case FOP(50, 22):
7097
    case FOP(51, 22):
7098
    case FOP(52, 22):
7099
    case FOP(53, 22):
7100
    case FOP(54, 22):
7101
    case FOP(55, 22):
7102
    case FOP(56, 22):
7103
    case FOP(57, 22):
7104
    case FOP(58, 22):
7105
    case FOP(59, 22):
7106
    case FOP(60, 22):
7107
    case FOP(61, 22):
7108
    case FOP(62, 22):
7109
    case FOP(63, 22):
7110
        check_cp1_64bitmode(ctx);
7111
        {
7112
            TCGv_i64 fp0 = tcg_temp_new_i64();
7113
            TCGv_i64 fp1 = tcg_temp_new_i64();
7114

    
7115
            gen_load_fpr64(ctx, fp0, fs);
7116
            gen_load_fpr64(ctx, fp1, ft);
7117
            if (ctx->opcode & (1 << 6)) {
7118
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7119
                opn = condnames_abs[func-48];
7120
            } else {
7121
                gen_cmp_ps(func-48, fp0, fp1, cc);
7122
                opn = condnames[func-48];
7123
            }
7124
            tcg_temp_free_i64(fp0);
7125
            tcg_temp_free_i64(fp1);
7126
        }
7127
        break;
7128
    default:
7129
        MIPS_INVAL(opn);
7130
        generate_exception (ctx, EXCP_RI);
7131
        return;
7132
    }
7133
    switch (optype) {
7134
    case BINOP:
7135
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7136
        break;
7137
    case CMPOP:
7138
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7139
        break;
7140
    default:
7141
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7142
        break;
7143
    }
7144
}
7145

    
7146
/* Coprocessor 3 (FPU) */
7147
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7148
                           int fd, int fs, int base, int index)
7149
{
7150
    const char *opn = "extended float load/store";
7151
    int store = 0;
7152
    TCGv t0 = tcg_temp_local_new();
7153
    TCGv t1 = tcg_temp_local_new();
7154

    
7155
    if (base == 0) {
7156
        gen_load_gpr(t0, index);
7157
    } else if (index == 0) {
7158
        gen_load_gpr(t0, base);
7159
    } else {
7160
        gen_load_gpr(t0, index);
7161
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7162
    }
7163
    /* Don't do NOP if destination is zero: we must perform the actual
7164
       memory access. */
7165
    switch (opc) {
7166
    case OPC_LWXC1:
7167
        check_cop1x(ctx);
7168
        {
7169
            TCGv_i32 fp0 = tcg_temp_new_i32();
7170

    
7171
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7172
            tcg_gen_trunc_tl_i32(fp0, t1);
7173
            gen_store_fpr32(fp0, fd);
7174
            tcg_temp_free_i32(fp0);
7175
        }
7176
        opn = "lwxc1";
7177
        break;
7178
    case OPC_LDXC1:
7179
        check_cop1x(ctx);
7180
        check_cp1_registers(ctx, fd);
7181
        {
7182
            TCGv_i64 fp0 = tcg_temp_new_i64();
7183

    
7184
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7185
            gen_store_fpr64(ctx, fp0, fd);
7186
            tcg_temp_free_i64(fp0);
7187
        }
7188
        opn = "ldxc1";
7189
        break;
7190
    case OPC_LUXC1:
7191
        check_cp1_64bitmode(ctx);
7192
        tcg_gen_andi_tl(t0, t0, ~0x7);
7193
        {
7194
            TCGv_i64 fp0 = tcg_temp_new_i64();
7195

    
7196
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7197
            gen_store_fpr64(ctx, fp0, fd);
7198
            tcg_temp_free_i64(fp0);
7199
        }
7200
        opn = "luxc1";
7201
        break;
7202
    case OPC_SWXC1:
7203
        check_cop1x(ctx);
7204
        {
7205
            TCGv_i32 fp0 = tcg_temp_new_i32();
7206

    
7207
            gen_load_fpr32(fp0, fs);
7208
            tcg_gen_extu_i32_tl(t1, fp0);
7209
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7210
            tcg_temp_free_i32(fp0);
7211
        }
7212
        opn = "swxc1";
7213
        store = 1;
7214
        break;
7215
    case OPC_SDXC1:
7216
        check_cop1x(ctx);
7217
        check_cp1_registers(ctx, fs);
7218
        {
7219
            TCGv_i64 fp0 = tcg_temp_new_i64();
7220

    
7221
            gen_load_fpr64(ctx, fp0, fs);
7222
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7223
            tcg_temp_free_i64(fp0);
7224
        }
7225
        opn = "sdxc1";
7226
        store = 1;
7227
        break;
7228
    case OPC_SUXC1:
7229
        check_cp1_64bitmode(ctx);
7230
        tcg_gen_andi_tl(t0, t0, ~0x7);
7231
        {
7232
            TCGv_i64 fp0 = tcg_temp_new_i64();
7233

    
7234
            gen_load_fpr64(ctx, fp0, fs);
7235
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7236
            tcg_temp_free_i64(fp0);
7237
        }
7238
        opn = "suxc1";
7239
        store = 1;
7240
        break;
7241
    default:
7242
        MIPS_INVAL(opn);
7243
        generate_exception(ctx, EXCP_RI);
7244
        tcg_temp_free(t0);
7245
        tcg_temp_free(t1);
7246
        return;
7247
    }
7248
    tcg_temp_free(t0);
7249
    tcg_temp_free(t1);
7250
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7251
               regnames[index], regnames[base]);
7252
}
7253

    
7254
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7255
                            int fd, int fr, int fs, int ft)
7256
{
7257
    const char *opn = "flt3_arith";
7258

    
7259
    switch (opc) {
7260
    case OPC_ALNV_PS:
7261
        check_cp1_64bitmode(ctx);
7262
        {
7263
            TCGv t0 = tcg_temp_local_new();
7264
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7265
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7266
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7267
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7268
            int l1 = gen_new_label();
7269
            int l2 = gen_new_label();
7270

    
7271
            gen_load_gpr(t0, fr);
7272
            tcg_gen_andi_tl(t0, t0, 0x7);
7273
            gen_load_fpr32(fp0, fs);
7274
            gen_load_fpr32h(fph0, fs);
7275
            gen_load_fpr32(fp1, ft);
7276
            gen_load_fpr32h(fph1, ft);
7277

    
7278
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7279
            gen_store_fpr32(fp0, fd);
7280
            gen_store_fpr32h(fph0, fd);
7281
            tcg_gen_br(l2);
7282
            gen_set_label(l1);
7283
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7284
            tcg_temp_free(t0);
7285
#ifdef TARGET_WORDS_BIGENDIAN
7286
            gen_store_fpr32(fph1, fd);
7287
            gen_store_fpr32h(fp0, fd);
7288
#else
7289
            gen_store_fpr32(fph0, fd);
7290
            gen_store_fpr32h(fp1, fd);
7291
#endif
7292
            gen_set_label(l2);
7293
            tcg_temp_free_i32(fp0);
7294
            tcg_temp_free_i32(fph0);
7295
            tcg_temp_free_i32(fp1);
7296
            tcg_temp_free_i32(fph1);
7297
        }
7298
        opn = "alnv.ps";
7299
        break;
7300
    case OPC_MADD_S:
7301
        check_cop1x(ctx);
7302
        {
7303
            TCGv_i32 fp0 = tcg_temp_new_i32();
7304
            TCGv_i32 fp1 = tcg_temp_new_i32();
7305
            TCGv_i32 fp2 = tcg_temp_new_i32();
7306

    
7307
            gen_load_fpr32(fp0, fs);
7308
            gen_load_fpr32(fp1, ft);
7309
            gen_load_fpr32(fp2, fr);
7310
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7311
            tcg_temp_free_i32(fp0);
7312
            tcg_temp_free_i32(fp1);
7313
            gen_store_fpr32(fp2, fd);
7314
            tcg_temp_free_i32(fp2);
7315
        }
7316
        opn = "madd.s";
7317
        break;
7318
    case OPC_MADD_D:
7319
        check_cop1x(ctx);
7320
        check_cp1_registers(ctx, fd | fs | ft | fr);
7321
        {
7322
            TCGv_i64 fp0 = tcg_temp_new_i64();
7323
            TCGv_i64 fp1 = tcg_temp_new_i64();
7324
            TCGv_i64 fp2 = tcg_temp_new_i64();
7325

    
7326
            gen_load_fpr64(ctx, fp0, fs);
7327
            gen_load_fpr64(ctx, fp1, ft);
7328
            gen_load_fpr64(ctx, fp2, fr);
7329
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7330
            tcg_temp_free_i64(fp0);
7331
            tcg_temp_free_i64(fp1);
7332
            gen_store_fpr64(ctx, fp2, fd);
7333
            tcg_temp_free_i64(fp2);
7334
        }
7335
        opn = "madd.d";
7336
        break;
7337
    case OPC_MADD_PS:
7338
        check_cp1_64bitmode(ctx);
7339
        {
7340
            TCGv_i64 fp0 = tcg_temp_new_i64();
7341
            TCGv_i64 fp1 = tcg_temp_new_i64();
7342
            TCGv_i64 fp2 = tcg_temp_new_i64();
7343

    
7344
            gen_load_fpr64(ctx, fp0, fs);
7345
            gen_load_fpr64(ctx, fp1, ft);
7346
            gen_load_fpr64(ctx, fp2, fr);
7347
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7348
            tcg_temp_free_i64(fp0);
7349
            tcg_temp_free_i64(fp1);
7350
            gen_store_fpr64(ctx, fp2, fd);
7351
            tcg_temp_free_i64(fp2);
7352
        }
7353
        opn = "madd.ps";
7354
        break;
7355
    case OPC_MSUB_S:
7356
        check_cop1x(ctx);
7357
        {
7358
            TCGv_i32 fp0 = tcg_temp_new_i32();
7359
            TCGv_i32 fp1 = tcg_temp_new_i32();
7360
            TCGv_i32 fp2 = tcg_temp_new_i32();
7361

    
7362
            gen_load_fpr32(fp0, fs);
7363
            gen_load_fpr32(fp1, ft);
7364
            gen_load_fpr32(fp2, fr);
7365
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7366
            tcg_temp_free_i32(fp0);
7367
            tcg_temp_free_i32(fp1);
7368
            gen_store_fpr32(fp2, fd);
7369
            tcg_temp_free_i32(fp2);
7370
        }
7371
        opn = "msub.s";
7372
        break;
7373
    case OPC_MSUB_D:
7374
        check_cop1x(ctx);
7375
        check_cp1_registers(ctx, fd | fs | ft | fr);
7376
        {
7377
            TCGv_i64 fp0 = tcg_temp_new_i64();
7378
            TCGv_i64 fp1 = tcg_temp_new_i64();
7379
            TCGv_i64 fp2 = tcg_temp_new_i64();
7380

    
7381
            gen_load_fpr64(ctx, fp0, fs);
7382
            gen_load_fpr64(ctx, fp1, ft);
7383
            gen_load_fpr64(ctx, fp2, fr);
7384
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7385
            tcg_temp_free_i64(fp0);
7386
            tcg_temp_free_i64(fp1);
7387
            gen_store_fpr64(ctx, fp2, fd);
7388
            tcg_temp_free_i64(fp2);
7389
        }
7390
        opn = "msub.d";
7391
        break;
7392
    case OPC_MSUB_PS:
7393
        check_cp1_64bitmode(ctx);
7394
        {
7395
            TCGv_i64 fp0 = tcg_temp_new_i64();
7396
            TCGv_i64 fp1 = tcg_temp_new_i64();
7397
            TCGv_i64 fp2 = tcg_temp_new_i64();
7398

    
7399
            gen_load_fpr64(ctx, fp0, fs);
7400
            gen_load_fpr64(ctx, fp1, ft);
7401
            gen_load_fpr64(ctx, fp2, fr);
7402
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7403
            tcg_temp_free_i64(fp0);
7404
            tcg_temp_free_i64(fp1);
7405
            gen_store_fpr64(ctx, fp2, fd);
7406
            tcg_temp_free_i64(fp2);
7407
        }
7408
        opn = "msub.ps";
7409
        break;
7410
    case OPC_NMADD_S:
7411
        check_cop1x(ctx);
7412
        {
7413
            TCGv_i32 fp0 = tcg_temp_new_i32();
7414
            TCGv_i32 fp1 = tcg_temp_new_i32();
7415
            TCGv_i32 fp2 = tcg_temp_new_i32();
7416

    
7417
            gen_load_fpr32(fp0, fs);
7418
            gen_load_fpr32(fp1, ft);
7419
            gen_load_fpr32(fp2, fr);
7420
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7421
            tcg_temp_free_i32(fp0);
7422
            tcg_temp_free_i32(fp1);
7423
            gen_store_fpr32(fp2, fd);
7424
            tcg_temp_free_i32(fp2);
7425
        }
7426
        opn = "nmadd.s";
7427
        break;
7428
    case OPC_NMADD_D:
7429
        check_cop1x(ctx);
7430
        check_cp1_registers(ctx, fd | fs | ft | fr);
7431
        {
7432
            TCGv_i64 fp0 = tcg_temp_new_i64();
7433
            TCGv_i64 fp1 = tcg_temp_new_i64();
7434
            TCGv_i64 fp2 = tcg_temp_new_i64();
7435

    
7436
            gen_load_fpr64(ctx, fp0, fs);
7437
            gen_load_fpr64(ctx, fp1, ft);
7438
            gen_load_fpr64(ctx, fp2, fr);
7439
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7440
            tcg_temp_free_i64(fp0);
7441
            tcg_temp_free_i64(fp1);
7442
            gen_store_fpr64(ctx, fp2, fd);
7443
            tcg_temp_free_i64(fp2);
7444
        }
7445
        opn = "nmadd.d";
7446
        break;
7447
    case OPC_NMADD_PS:
7448
        check_cp1_64bitmode(ctx);
7449
        {
7450
            TCGv_i64 fp0 = tcg_temp_new_i64();
7451
            TCGv_i64 fp1 = tcg_temp_new_i64();
7452
            TCGv_i64 fp2 = tcg_temp_new_i64();
7453

    
7454
            gen_load_fpr64(ctx, fp0, fs);
7455
            gen_load_fpr64(ctx, fp1, ft);
7456
            gen_load_fpr64(ctx, fp2, fr);
7457
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7458
            tcg_temp_free_i64(fp0);
7459
            tcg_temp_free_i64(fp1);
7460
            gen_store_fpr64(ctx, fp2, fd);
7461
            tcg_temp_free_i64(fp2);
7462
        }
7463
        opn = "nmadd.ps";
7464
        break;
7465
    case OPC_NMSUB_S:
7466
        check_cop1x(ctx);
7467
        {
7468
            TCGv_i32 fp0 = tcg_temp_new_i32();
7469
            TCGv_i32 fp1 = tcg_temp_new_i32();
7470
            TCGv_i32 fp2 = tcg_temp_new_i32();
7471

    
7472
            gen_load_fpr32(fp0, fs);
7473
            gen_load_fpr32(fp1, ft);
7474
            gen_load_fpr32(fp2, fr);
7475
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7476
            tcg_temp_free_i32(fp0);
7477
            tcg_temp_free_i32(fp1);
7478
            gen_store_fpr32(fp2, fd);
7479
            tcg_temp_free_i32(fp2);
7480
        }
7481
        opn = "nmsub.s";
7482
        break;
7483
    case OPC_NMSUB_D:
7484
        check_cop1x(ctx);
7485
        check_cp1_registers(ctx, fd | fs | ft | fr);
7486
        {
7487
            TCGv_i64 fp0 = tcg_temp_new_i64();
7488
            TCGv_i64 fp1 = tcg_temp_new_i64();
7489
            TCGv_i64 fp2 = tcg_temp_new_i64();
7490

    
7491
            gen_load_fpr64(ctx, fp0, fs);
7492
            gen_load_fpr64(ctx, fp1, ft);
7493
            gen_load_fpr64(ctx, fp2, fr);
7494
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7495
            tcg_temp_free_i64(fp0);
7496
            tcg_temp_free_i64(fp1);
7497
            gen_store_fpr64(ctx, fp2, fd);
7498
            tcg_temp_free_i64(fp2);
7499
        }
7500
        opn = "nmsub.d";
7501
        break;
7502
    case OPC_NMSUB_PS:
7503
        check_cp1_64bitmode(ctx);
7504
        {
7505
            TCGv_i64 fp0 = tcg_temp_new_i64();
7506
            TCGv_i64 fp1 = tcg_temp_new_i64();
7507
            TCGv_i64 fp2 = tcg_temp_new_i64();
7508

    
7509
            gen_load_fpr64(ctx, fp0, fs);
7510
            gen_load_fpr64(ctx, fp1, ft);
7511
            gen_load_fpr64(ctx, fp2, fr);
7512
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7513
            tcg_temp_free_i64(fp0);
7514
            tcg_temp_free_i64(fp1);
7515
            gen_store_fpr64(ctx, fp2, fd);
7516
            tcg_temp_free_i64(fp2);
7517
        }
7518
        opn = "nmsub.ps";
7519
        break;
7520
    default:
7521
        MIPS_INVAL(opn);
7522
        generate_exception (ctx, EXCP_RI);
7523
        return;
7524
    }
7525
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7526
               fregnames[fs], fregnames[ft]);
7527
}
7528

    
7529
/* ISA extensions (ASEs) */
7530
/* MIPS16 extension to MIPS32 */
7531
/* SmartMIPS extension to MIPS32 */
7532

    
7533
#if defined(TARGET_MIPS64)
7534

    
7535
/* MDMX extension to MIPS64 */
7536

    
7537
#endif
7538

    
7539
static void decode_opc (CPUState *env, DisasContext *ctx)
7540
{
7541
    int32_t offset;
7542
    int rs, rt, rd, sa;
7543
    uint32_t op, op1, op2;
7544
    int16_t imm;
7545

    
7546
    /* make sure instructions are on a word boundary */
7547
    if (ctx->pc & 0x3) {
7548
        env->CP0_BadVAddr = ctx->pc;
7549
        generate_exception(ctx, EXCP_AdEL);
7550
        return;
7551
    }
7552

    
7553
    /* Handle blikely not taken case */
7554
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7555
        int l1 = gen_new_label();
7556

    
7557
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7558
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7559
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7560
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7561
        gen_set_label(l1);
7562
    }
7563
    op = MASK_OP_MAJOR(ctx->opcode);
7564
    rs = (ctx->opcode >> 21) & 0x1f;
7565
    rt = (ctx->opcode >> 16) & 0x1f;
7566
    rd = (ctx->opcode >> 11) & 0x1f;
7567
    sa = (ctx->opcode >> 6) & 0x1f;
7568
    imm = (int16_t)ctx->opcode;
7569
    switch (op) {
7570
    case OPC_SPECIAL:
7571
        op1 = MASK_SPECIAL(ctx->opcode);
7572
        switch (op1) {
7573
        case OPC_SLL:          /* Arithmetic with immediate */
7574
        case OPC_SRL ... OPC_SRA:
7575
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7576
            break;
7577
        case OPC_MOVZ ... OPC_MOVN:
7578
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7579
        case OPC_SLLV:         /* Arithmetic */
7580
        case OPC_SRLV ... OPC_SRAV:
7581
        case OPC_ADD ... OPC_NOR:
7582
        case OPC_SLT ... OPC_SLTU:
7583
            gen_arith(env, ctx, op1, rd, rs, rt);
7584
            break;
7585
        case OPC_MULT ... OPC_DIVU:
7586
            if (sa) {
7587
                check_insn(env, ctx, INSN_VR54XX);
7588
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7589
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7590
            } else
7591
                gen_muldiv(ctx, op1, rs, rt);
7592
            break;
7593
        case OPC_JR ... OPC_JALR:
7594
            gen_compute_branch(ctx, op1, rs, rd, sa);
7595
            return;
7596
        case OPC_TGE ... OPC_TEQ: /* Traps */
7597
        case OPC_TNE:
7598
            gen_trap(ctx, op1, rs, rt, -1);
7599
            break;
7600
        case OPC_MFHI:          /* Move from HI/LO */
7601
        case OPC_MFLO:
7602
            gen_HILO(ctx, op1, rd);
7603
            break;
7604
        case OPC_MTHI:
7605
        case OPC_MTLO:          /* Move to HI/LO */
7606
            gen_HILO(ctx, op1, rs);
7607
            break;
7608
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7609
#ifdef MIPS_STRICT_STANDARD
7610
            MIPS_INVAL("PMON / selsl");
7611
            generate_exception(ctx, EXCP_RI);
7612
#else
7613
            gen_helper_0i(pmon, sa);
7614
#endif
7615
            break;
7616
        case OPC_SYSCALL:
7617
            generate_exception(ctx, EXCP_SYSCALL);
7618
            break;
7619
        case OPC_BREAK:
7620
            generate_exception(ctx, EXCP_BREAK);
7621
            break;
7622
        case OPC_SPIM:
7623
#ifdef MIPS_STRICT_STANDARD
7624
            MIPS_INVAL("SPIM");
7625
            generate_exception(ctx, EXCP_RI);
7626
#else
7627
           /* Implemented as RI exception for now. */
7628
            MIPS_INVAL("spim (unofficial)");
7629
            generate_exception(ctx, EXCP_RI);
7630
#endif
7631
            break;
7632
        case OPC_SYNC:
7633
            /* Treat as NOP. */
7634
            break;
7635

    
7636
        case OPC_MOVCI:
7637
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7638
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7639
                save_cpu_state(ctx, 1);
7640
                check_cp1_enabled(ctx);
7641
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7642
                          (ctx->opcode >> 16) & 1);
7643
            } else {
7644
                generate_exception_err(ctx, EXCP_CpU, 1);
7645
            }
7646
            break;
7647

    
7648
#if defined(TARGET_MIPS64)
7649
       /* MIPS64 specific opcodes */
7650
        case OPC_DSLL:
7651
        case OPC_DSRL ... OPC_DSRA:
7652
        case OPC_DSLL32:
7653
        case OPC_DSRL32 ... OPC_DSRA32:
7654
            check_insn(env, ctx, ISA_MIPS3);
7655
            check_mips_64(ctx);
7656
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7657
            break;
7658
        case OPC_DSLLV:
7659
        case OPC_DSRLV ... OPC_DSRAV:
7660
        case OPC_DADD ... OPC_DSUBU:
7661
            check_insn(env, ctx, ISA_MIPS3);
7662
            check_mips_64(ctx);
7663
            gen_arith(env, ctx, op1, rd, rs, rt);
7664
            break;
7665
        case OPC_DMULT ... OPC_DDIVU:
7666
            check_insn(env, ctx, ISA_MIPS3);
7667
            check_mips_64(ctx);
7668
            gen_muldiv(ctx, op1, rs, rt);
7669
            break;
7670
#endif
7671
        default:            /* Invalid */
7672
            MIPS_INVAL("special");
7673
            generate_exception(ctx, EXCP_RI);
7674
            break;
7675
        }
7676
        break;
7677
    case OPC_SPECIAL2:
7678
        op1 = MASK_SPECIAL2(ctx->opcode);
7679
        switch (op1) {
7680
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7681
        case OPC_MSUB ... OPC_MSUBU:
7682
            check_insn(env, ctx, ISA_MIPS32);
7683
            gen_muldiv(ctx, op1, rs, rt);
7684
            break;
7685
        case OPC_MUL:
7686
            gen_arith(env, ctx, op1, rd, rs, rt);
7687
            break;
7688
        case OPC_CLO:
7689
        case OPC_CLZ:
7690
            check_insn(env, ctx, ISA_MIPS32);
7691
            gen_cl(ctx, op1, rd, rs);
7692
            break;
7693
        case OPC_SDBBP:
7694
            /* XXX: not clear which exception should be raised
7695
             *      when in debug mode...
7696
             */
7697
            check_insn(env, ctx, ISA_MIPS32);
7698
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7699
                generate_exception(ctx, EXCP_DBp);
7700
            } else {
7701
                generate_exception(ctx, EXCP_DBp);
7702
            }
7703
            /* Treat as NOP. */
7704
            break;
7705
#if defined(TARGET_MIPS64)
7706
        case OPC_DCLO:
7707
        case OPC_DCLZ:
7708
            check_insn(env, ctx, ISA_MIPS64);
7709
            check_mips_64(ctx);
7710
            gen_cl(ctx, op1, rd, rs);
7711
            break;
7712
#endif
7713
        default:            /* Invalid */
7714
            MIPS_INVAL("special2");
7715
            generate_exception(ctx, EXCP_RI);
7716
            break;
7717
        }
7718
        break;
7719
    case OPC_SPECIAL3:
7720
        op1 = MASK_SPECIAL3(ctx->opcode);
7721
        switch (op1) {
7722
        case OPC_EXT:
7723
        case OPC_INS:
7724
            check_insn(env, ctx, ISA_MIPS32R2);
7725
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7726
            break;
7727
        case OPC_BSHFL:
7728
            check_insn(env, ctx, ISA_MIPS32R2);
7729
            op2 = MASK_BSHFL(ctx->opcode);
7730
            gen_bshfl(ctx, op2, rt, rd);
7731
            break;
7732
        case OPC_RDHWR:
7733
            check_insn(env, ctx, ISA_MIPS32R2);
7734
            {
7735
                TCGv t0 = tcg_temp_local_new();
7736

    
7737
                switch (rd) {
7738
                case 0:
7739
                    save_cpu_state(ctx, 1);
7740
                    gen_helper_rdhwr_cpunum(t0);
7741
                    break;
7742
                case 1:
7743
                    save_cpu_state(ctx, 1);
7744
                    gen_helper_rdhwr_synci_step(t0);
7745
                    break;
7746
                case 2:
7747
                    save_cpu_state(ctx, 1);
7748
                    gen_helper_rdhwr_cc(t0);
7749
                    break;
7750
                case 3:
7751
                    save_cpu_state(ctx, 1);
7752
                    gen_helper_rdhwr_ccres(t0);
7753
                    break;
7754
                case 29:
7755
#if defined(CONFIG_USER_ONLY)
7756
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7757
                    break;
7758
#else
7759
                    /* XXX: Some CPUs implement this in hardware.
7760
                       Not supported yet. */
7761
#endif
7762
                default:            /* Invalid */
7763
                    MIPS_INVAL("rdhwr");
7764
                    generate_exception(ctx, EXCP_RI);
7765
                    break;
7766
                }
7767
                gen_store_gpr(t0, rt);
7768
                tcg_temp_free(t0);
7769
            }
7770
            break;
7771
        case OPC_FORK:
7772
            check_insn(env, ctx, ASE_MT);
7773
            {
7774
                TCGv t0 = tcg_temp_local_new();
7775
                TCGv t1 = tcg_temp_local_new();
7776

    
7777
                gen_load_gpr(t0, rt);
7778
                gen_load_gpr(t1, rs);
7779
                gen_helper_fork(t0, t1);
7780
                tcg_temp_free(t0);
7781
                tcg_temp_free(t1);
7782
            }
7783
            break;
7784
        case OPC_YIELD:
7785
            check_insn(env, ctx, ASE_MT);
7786
            {
7787
                TCGv t0 = tcg_temp_local_new();
7788

    
7789
                gen_load_gpr(t0, rs);
7790
                gen_helper_yield(t0, t0);
7791
                gen_store_gpr(t0, rd);
7792
                tcg_temp_free(t0);
7793
            }
7794
            break;
7795
#if defined(TARGET_MIPS64)
7796
        case OPC_DEXTM ... OPC_DEXT:
7797
        case OPC_DINSM ... OPC_DINS:
7798
            check_insn(env, ctx, ISA_MIPS64R2);
7799
            check_mips_64(ctx);
7800
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7801
            break;
7802
        case OPC_DBSHFL:
7803
            check_insn(env, ctx, ISA_MIPS64R2);
7804
            check_mips_64(ctx);
7805
            op2 = MASK_DBSHFL(ctx->opcode);
7806
            gen_bshfl(ctx, op2, rt, rd);
7807
            break;
7808
#endif
7809
        default:            /* Invalid */
7810
            MIPS_INVAL("special3");
7811
            generate_exception(ctx, EXCP_RI);
7812
            break;
7813
        }
7814
        break;
7815
    case OPC_REGIMM:
7816
        op1 = MASK_REGIMM(ctx->opcode);
7817
        switch (op1) {
7818
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7819
        case OPC_BLTZAL ... OPC_BGEZALL:
7820
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7821
            return;
7822
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7823
        case OPC_TNEI:
7824
            gen_trap(ctx, op1, rs, -1, imm);
7825
            break;
7826
        case OPC_SYNCI:
7827
            check_insn(env, ctx, ISA_MIPS32R2);
7828
            /* Treat as NOP. */
7829
            break;
7830
        default:            /* Invalid */
7831
            MIPS_INVAL("regimm");
7832
            generate_exception(ctx, EXCP_RI);
7833
            break;
7834
        }
7835
        break;
7836
    case OPC_CP0:
7837
        check_cp0_enabled(ctx);
7838
        op1 = MASK_CP0(ctx->opcode);
7839
        switch (op1) {
7840
        case OPC_MFC0:
7841
        case OPC_MTC0:
7842
        case OPC_MFTR:
7843
        case OPC_MTTR:
7844
#if defined(TARGET_MIPS64)
7845
        case OPC_DMFC0:
7846
        case OPC_DMTC0:
7847
#endif
7848
#ifndef CONFIG_USER_ONLY
7849
            gen_cp0(env, ctx, op1, rt, rd);
7850
#endif /* !CONFIG_USER_ONLY */
7851
            break;
7852
        case OPC_C0_FIRST ... OPC_C0_LAST:
7853
#ifndef CONFIG_USER_ONLY
7854
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7855
#endif /* !CONFIG_USER_ONLY */
7856
            break;
7857
        case OPC_MFMC0:
7858
#ifndef CONFIG_USER_ONLY
7859
            {
7860
                TCGv t0 = tcg_temp_local_new();
7861

    
7862
                op2 = MASK_MFMC0(ctx->opcode);
7863
                switch (op2) {
7864
                case OPC_DMT:
7865
                    check_insn(env, ctx, ASE_MT);
7866
                    gen_helper_dmt(t0, t0);
7867
                    break;
7868
                case OPC_EMT:
7869
                    check_insn(env, ctx, ASE_MT);
7870
                    gen_helper_emt(t0, t0);
7871
                    break;
7872
                case OPC_DVPE:
7873
                    check_insn(env, ctx, ASE_MT);
7874
                    gen_helper_dvpe(t0, t0);
7875
                    break;
7876
                case OPC_EVPE:
7877
                    check_insn(env, ctx, ASE_MT);
7878
                    gen_helper_evpe(t0, t0);
7879
                    break;
7880
                case OPC_DI:
7881
                    check_insn(env, ctx, ISA_MIPS32R2);
7882
                    save_cpu_state(ctx, 1);
7883
                    gen_helper_di(t0);
7884
                    /* Stop translation as we may have switched the execution mode */
7885
                    ctx->bstate = BS_STOP;
7886
                    break;
7887
                case OPC_EI:
7888
                    check_insn(env, ctx, ISA_MIPS32R2);
7889
                    save_cpu_state(ctx, 1);
7890
                    gen_helper_ei(t0);
7891
                    /* Stop translation as we may have switched the execution mode */
7892
                    ctx->bstate = BS_STOP;
7893
                    break;
7894
                default:            /* Invalid */
7895
                    MIPS_INVAL("mfmc0");
7896
                    generate_exception(ctx, EXCP_RI);
7897
                    break;
7898
                }
7899
                gen_store_gpr(t0, rt);
7900
                tcg_temp_free(t0);
7901
            }
7902
#endif /* !CONFIG_USER_ONLY */
7903
            break;
7904
        case OPC_RDPGPR:
7905
            check_insn(env, ctx, ISA_MIPS32R2);
7906
            gen_load_srsgpr(rt, rd);
7907
            break;
7908
        case OPC_WRPGPR:
7909
            check_insn(env, ctx, ISA_MIPS32R2);
7910
            gen_store_srsgpr(rt, rd);
7911
            break;
7912
        default:
7913
            MIPS_INVAL("cp0");
7914
            generate_exception(ctx, EXCP_RI);
7915
            break;
7916
        }
7917
        break;
7918
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7919
         gen_arith_imm(env, ctx, op, rt, rs, imm);
7920
         break;
7921
    case OPC_J ... OPC_JAL: /* Jump */
7922
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7923
         gen_compute_branch(ctx, op, rs, rt, offset);
7924
         return;
7925
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
7926
    case OPC_BEQL ... OPC_BGTZL:
7927
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
7928
         return;
7929
    case OPC_LB ... OPC_LWR: /* Load and stores */
7930
    case OPC_SB ... OPC_SW:
7931
    case OPC_SWR:
7932
    case OPC_LL:
7933
    case OPC_SC:
7934
         gen_ldst(ctx, op, rt, rs, imm);
7935
         break;
7936
    case OPC_CACHE:
7937
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7938
        /* Treat as NOP. */
7939
        break;
7940
    case OPC_PREF:
7941
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7942
        /* Treat as NOP. */
7943
        break;
7944

    
7945
    /* Floating point (COP1). */
7946
    case OPC_LWC1:
7947
    case OPC_LDC1:
7948
    case OPC_SWC1:
7949
    case OPC_SDC1:
7950
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7951
            save_cpu_state(ctx, 1);
7952
            check_cp1_enabled(ctx);
7953
            gen_flt_ldst(ctx, op, rt, rs, imm);
7954
        } else {
7955
            generate_exception_err(ctx, EXCP_CpU, 1);
7956
        }
7957
        break;
7958

    
7959
    case OPC_CP1:
7960
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7961
            save_cpu_state(ctx, 1);
7962
            check_cp1_enabled(ctx);
7963
            op1 = MASK_CP1(ctx->opcode);
7964
            switch (op1) {
7965
            case OPC_MFHC1:
7966
            case OPC_MTHC1:
7967
                check_insn(env, ctx, ISA_MIPS32R2);
7968
            case OPC_MFC1:
7969
            case OPC_CFC1:
7970
            case OPC_MTC1:
7971
            case OPC_CTC1:
7972
                gen_cp1(ctx, op1, rt, rd);
7973
                break;
7974
#if defined(TARGET_MIPS64)
7975
            case OPC_DMFC1:
7976
            case OPC_DMTC1:
7977
                check_insn(env, ctx, ISA_MIPS3);
7978
                gen_cp1(ctx, op1, rt, rd);
7979
                break;
7980
#endif
7981
            case OPC_BC1ANY2:
7982
            case OPC_BC1ANY4:
7983
                check_cop1x(ctx);
7984
                check_insn(env, ctx, ASE_MIPS3D);
7985
                /* fall through */
7986
            case OPC_BC1:
7987
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7988
                                    (rt >> 2) & 0x7, imm << 2);
7989
                return;
7990
            case OPC_S_FMT:
7991
            case OPC_D_FMT:
7992
            case OPC_W_FMT:
7993
            case OPC_L_FMT:
7994
            case OPC_PS_FMT:
7995
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7996
                           (imm >> 8) & 0x7);
7997
                break;
7998
            default:
7999
                MIPS_INVAL("cp1");
8000
                generate_exception (ctx, EXCP_RI);
8001
                break;
8002
            }
8003
        } else {
8004
            generate_exception_err(ctx, EXCP_CpU, 1);
8005
        }
8006
        break;
8007

    
8008
    /* COP2.  */
8009
    case OPC_LWC2:
8010
    case OPC_LDC2:
8011
    case OPC_SWC2:
8012
    case OPC_SDC2:
8013
    case OPC_CP2:
8014
        /* COP2: Not implemented. */
8015
        generate_exception_err(ctx, EXCP_CpU, 2);
8016
        break;
8017

    
8018
    case OPC_CP3:
8019
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8020
            save_cpu_state(ctx, 1);
8021
            check_cp1_enabled(ctx);
8022
            op1 = MASK_CP3(ctx->opcode);
8023
            switch (op1) {
8024
            case OPC_LWXC1:
8025
            case OPC_LDXC1:
8026
            case OPC_LUXC1:
8027
            case OPC_SWXC1:
8028
            case OPC_SDXC1:
8029
            case OPC_SUXC1:
8030
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8031
                break;
8032
            case OPC_PREFX:
8033
                /* Treat as NOP. */
8034
                break;
8035
            case OPC_ALNV_PS:
8036
            case OPC_MADD_S:
8037
            case OPC_MADD_D:
8038
            case OPC_MADD_PS:
8039
            case OPC_MSUB_S:
8040
            case OPC_MSUB_D:
8041
            case OPC_MSUB_PS:
8042
            case OPC_NMADD_S:
8043
            case OPC_NMADD_D:
8044
            case OPC_NMADD_PS:
8045
            case OPC_NMSUB_S:
8046
            case OPC_NMSUB_D:
8047
            case OPC_NMSUB_PS:
8048
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8049
                break;
8050
            default:
8051
                MIPS_INVAL("cp3");
8052
                generate_exception (ctx, EXCP_RI);
8053
                break;
8054
            }
8055
        } else {
8056
            generate_exception_err(ctx, EXCP_CpU, 1);
8057
        }
8058
        break;
8059

    
8060
#if defined(TARGET_MIPS64)
8061
    /* MIPS64 opcodes */
8062
    case OPC_LWU:
8063
    case OPC_LDL ... OPC_LDR:
8064
    case OPC_SDL ... OPC_SDR:
8065
    case OPC_LLD:
8066
    case OPC_LD:
8067
    case OPC_SCD:
8068
    case OPC_SD:
8069
        check_insn(env, ctx, ISA_MIPS3);
8070
        check_mips_64(ctx);
8071
        gen_ldst(ctx, op, rt, rs, imm);
8072
        break;
8073
    case OPC_DADDI ... OPC_DADDIU:
8074
        check_insn(env, ctx, ISA_MIPS3);
8075
        check_mips_64(ctx);
8076
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8077
        break;
8078
#endif
8079
    case OPC_JALX:
8080
        check_insn(env, ctx, ASE_MIPS16);
8081
        /* MIPS16: Not implemented. */
8082
    case OPC_MDMX:
8083
        check_insn(env, ctx, ASE_MDMX);
8084
        /* MDMX: Not implemented. */
8085
    default:            /* Invalid */
8086
        MIPS_INVAL("major opcode");
8087
        generate_exception(ctx, EXCP_RI);
8088
        break;
8089
    }
8090
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8091
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8092
        /* Branches completion */
8093
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8094
        ctx->bstate = BS_BRANCH;
8095
        save_cpu_state(ctx, 0);
8096
        /* FIXME: Need to clear can_do_io.  */
8097
        switch (hflags) {
8098
        case MIPS_HFLAG_B:
8099
            /* unconditional branch */
8100
            MIPS_DEBUG("unconditional branch");
8101
            gen_goto_tb(ctx, 0, ctx->btarget);
8102
            break;
8103
        case MIPS_HFLAG_BL:
8104
            /* blikely taken case */
8105
            MIPS_DEBUG("blikely branch taken");
8106
            gen_goto_tb(ctx, 0, ctx->btarget);
8107
            break;
8108
        case MIPS_HFLAG_BC:
8109
            /* Conditional branch */
8110
            MIPS_DEBUG("conditional branch");
8111
            {
8112
                int l1 = gen_new_label();
8113

    
8114
                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8115
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8116
                gen_set_label(l1);
8117
                gen_goto_tb(ctx, 0, ctx->btarget);
8118
            }
8119
            break;
8120
        case MIPS_HFLAG_BR:
8121
            /* unconditional branch to register */
8122
            MIPS_DEBUG("branch to register");
8123
            tcg_gen_mov_tl(cpu_PC, btarget);
8124
            tcg_gen_exit_tb(0);
8125
            break;
8126
        default:
8127
            MIPS_DEBUG("unknown branch");
8128
            break;
8129
        }
8130
    }
8131
}
8132

    
8133
static inline void
8134
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8135
                                int search_pc)
8136
{
8137
    DisasContext ctx;
8138
    target_ulong pc_start;
8139
    uint16_t *gen_opc_end;
8140
    CPUBreakpoint *bp;
8141
    int j, lj = -1;
8142
    int num_insns;
8143
    int max_insns;
8144

    
8145
    if (search_pc)
8146
        qemu_log("search pc %d\n", search_pc);
8147

    
8148
    pc_start = tb->pc;
8149
    /* Leave some spare opc slots for branch handling. */
8150
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8151
    ctx.pc = pc_start;
8152
    ctx.saved_pc = -1;
8153
    ctx.tb = tb;
8154
    ctx.bstate = BS_NONE;
8155
    /* Restore delay slot state from the tb context.  */
8156
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8157
    restore_cpu_state(env, &ctx);
8158
#ifdef CONFIG_USER_ONLY
8159
        ctx.mem_idx = MIPS_HFLAG_UM;
8160
#else
8161
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8162
#endif
8163
    num_insns = 0;
8164
    max_insns = tb->cflags & CF_COUNT_MASK;
8165
    if (max_insns == 0)
8166
        max_insns = CF_COUNT_MASK;
8167
#ifdef DEBUG_DISAS
8168
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8169
    /* FIXME: This may print out stale hflags from env... */
8170
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8171
#endif
8172
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8173
    gen_icount_start();
8174
    while (ctx.bstate == BS_NONE) {
8175
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8176
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8177
                if (bp->pc == ctx.pc) {
8178
                    save_cpu_state(&ctx, 1);
8179
                    ctx.bstate = BS_BRANCH;
8180
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8181
                    /* Include the breakpoint location or the tb won't
8182
                     * be flushed when it must be.  */
8183
                    ctx.pc += 4;
8184
                    goto done_generating;
8185
                }
8186
            }
8187
        }
8188

    
8189
        if (search_pc) {
8190
            j = gen_opc_ptr - gen_opc_buf;
8191
            if (lj < j) {
8192
                lj++;
8193
                while (lj < j)
8194
                    gen_opc_instr_start[lj++] = 0;
8195
            }
8196
            gen_opc_pc[lj] = ctx.pc;
8197
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8198
            gen_opc_instr_start[lj] = 1;
8199
            gen_opc_icount[lj] = num_insns;
8200
        }
8201
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8202
            gen_io_start();
8203
        ctx.opcode = ldl_code(ctx.pc);
8204
        decode_opc(env, &ctx);
8205
        ctx.pc += 4;
8206
        num_insns++;
8207

    
8208
        if (env->singlestep_enabled)
8209
            break;
8210

    
8211
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8212
            break;
8213

    
8214
        if (gen_opc_ptr >= gen_opc_end)
8215
            break;
8216

    
8217
        if (num_insns >= max_insns)
8218
            break;
8219
#if defined (MIPS_SINGLE_STEP)
8220
        break;
8221
#endif
8222
    }
8223
    if (tb->cflags & CF_LAST_IO)
8224
        gen_io_end();
8225
    if (env->singlestep_enabled) {
8226
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8227
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8228
    } else {
8229
        switch (ctx.bstate) {
8230
        case BS_STOP:
8231
            gen_helper_interrupt_restart();
8232
            gen_goto_tb(&ctx, 0, ctx.pc);
8233
            break;
8234
        case BS_NONE:
8235
            save_cpu_state(&ctx, 0);
8236
            gen_goto_tb(&ctx, 0, ctx.pc);
8237
            break;
8238
        case BS_EXCP:
8239
            gen_helper_interrupt_restart();
8240
            tcg_gen_exit_tb(0);
8241
            break;
8242
        case BS_BRANCH:
8243
        default:
8244
            break;
8245
        }
8246
    }
8247
done_generating:
8248
    gen_icount_end(tb, num_insns);
8249
    *gen_opc_ptr = INDEX_op_end;
8250
    if (search_pc) {
8251
        j = gen_opc_ptr - gen_opc_buf;
8252
        lj++;
8253
        while (lj <= j)
8254
            gen_opc_instr_start[lj++] = 0;
8255
    } else {
8256
        tb->size = ctx.pc - pc_start;
8257
        tb->icount = num_insns;
8258
    }
8259
#ifdef DEBUG_DISAS
8260
    LOG_DISAS("\n");
8261
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8262
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8263
        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8264
        qemu_log("\n");
8265
    }
8266
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8267
#endif
8268
}
8269

    
8270
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8271
{
8272
    gen_intermediate_code_internal(env, tb, 0);
8273
}
8274

    
8275
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8276
{
8277
    gen_intermediate_code_internal(env, tb, 1);
8278
}
8279

    
8280
static void fpu_dump_state(CPUState *env, FILE *f,
8281
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8282
                           int flags)
8283
{
8284
    int i;
8285
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8286

    
8287
#define printfpr(fp)                                                        \
8288
    do {                                                                    \
8289
        if (is_fpu64)                                                       \
8290
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8291
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8292
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8293
        else {                                                              \
8294
            fpr_t tmp;                                                      \
8295
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8296
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8297
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8298
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8299
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8300
        }                                                                   \
8301
    } while(0)
8302

    
8303

    
8304
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8305
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8306
                get_float_exception_flags(&env->active_fpu.fp_status));
8307
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8308
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8309
        printfpr(&env->active_fpu.fpr[i]);
8310
    }
8311

    
8312
#undef printfpr
8313
}
8314

    
8315
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8316
/* Debug help: The architecture requires 32bit code to maintain proper
8317
   sign-extended values on 64bit machines.  */
8318

    
8319
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8320

    
8321
static void
8322
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8323
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8324
                                int flags)
8325
{
8326
    int i;
8327

    
8328
    if (!SIGN_EXT_P(env->active_tc.PC))
8329
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8330
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8331
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8332
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8333
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8334
    if (!SIGN_EXT_P(env->btarget))
8335
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8336

    
8337
    for (i = 0; i < 32; i++) {
8338
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8339
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8340
    }
8341

    
8342
    if (!SIGN_EXT_P(env->CP0_EPC))
8343
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8344
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8345
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8346
}
8347
#endif
8348

    
8349
void cpu_dump_state (CPUState *env, FILE *f,
8350
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8351
                     int flags)
8352
{
8353
    int i;
8354

    
8355
    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",
8356
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8357
                env->hflags, env->btarget, env->bcond);
8358
    for (i = 0; i < 32; i++) {
8359
        if ((i & 3) == 0)
8360
            cpu_fprintf(f, "GPR%02d:", i);
8361
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8362
        if ((i & 3) == 3)
8363
            cpu_fprintf(f, "\n");
8364
    }
8365

    
8366
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8367
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8368
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8369
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8370
    if (env->hflags & MIPS_HFLAG_FPU)
8371
        fpu_dump_state(env, f, cpu_fprintf, flags);
8372
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8373
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8374
#endif
8375
}
8376

    
8377
static void mips_tcg_init(void)
8378
{
8379
    int i;
8380
    static int inited;
8381

    
8382
    /* Initialize various static tables. */
8383
    if (inited)
8384
        return;
8385

    
8386
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8387
    for (i = 0; i < 32; i++)
8388
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8389
                                        offsetof(CPUState, active_tc.gpr[i]),
8390
                                        regnames[i]);
8391
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8392
                                offsetof(CPUState, active_tc.PC), "PC");
8393
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8394
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8395
                                       offsetof(CPUState, active_tc.HI[i]),
8396
                                       regnames_HI[i]);
8397
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8398
                                       offsetof(CPUState, active_tc.LO[i]),
8399
                                       regnames_LO[i]);
8400
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8401
                                        offsetof(CPUState, active_tc.ACX[i]),
8402
                                        regnames_ACX[i]);
8403
    }
8404
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8405
                                     offsetof(CPUState, active_tc.DSPControl),
8406
                                     "DSPControl");
8407
    bcond = tcg_global_mem_new(TCG_AREG0,
8408
                               offsetof(CPUState, bcond), "bcond");
8409
    btarget = tcg_global_mem_new(TCG_AREG0,
8410
                                 offsetof(CPUState, btarget), "btarget");
8411
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8412
                                    offsetof(CPUState, hflags), "hflags");
8413

    
8414
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8415
                                      offsetof(CPUState, active_fpu.fcr0),
8416
                                      "fcr0");
8417
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8418
                                       offsetof(CPUState, active_fpu.fcr31),
8419
                                       "fcr31");
8420

    
8421
    /* register helpers */
8422
#define GEN_HELPER 2
8423
#include "helper.h"
8424

    
8425
    inited = 1;
8426
}
8427

    
8428
#include "translate_init.c"
8429

    
8430
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8431
{
8432
    CPUMIPSState *env;
8433
    const mips_def_t *def;
8434

    
8435
    def = cpu_mips_find_by_name(cpu_model);
8436
    if (!def)
8437
        return NULL;
8438
    env = qemu_mallocz(sizeof(CPUMIPSState));
8439
    env->cpu_model = def;
8440

    
8441
    cpu_exec_init(env);
8442
    env->cpu_model_str = cpu_model;
8443
    mips_tcg_init();
8444
    cpu_reset(env);
8445
    return env;
8446
}
8447

    
8448
void cpu_reset (CPUMIPSState *env)
8449
{
8450
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8451
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8452
        log_cpu_state(env, 0);
8453
    }
8454

    
8455
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8456

    
8457
    tlb_flush(env, 1);
8458

    
8459
    /* Minimal init */
8460
#if defined(CONFIG_USER_ONLY)
8461
    env->hflags = MIPS_HFLAG_UM;
8462
#else
8463
    if (env->hflags & MIPS_HFLAG_BMASK) {
8464
        /* If the exception was raised from a delay slot,
8465
           come back to the jump.  */
8466
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8467
    } else {
8468
        env->CP0_ErrorEPC = env->active_tc.PC;
8469
    }
8470
    env->active_tc.PC = (int32_t)0xBFC00000;
8471
    env->CP0_Wired = 0;
8472
    /* SMP not implemented */
8473
    env->CP0_EBase = 0x80000000;
8474
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8475
    /* vectored interrupts not implemented, timer on int 7,
8476
       no performance counters. */
8477
    env->CP0_IntCtl = 0xe0000000;
8478
    {
8479
        int i;
8480

    
8481
        for (i = 0; i < 7; i++) {
8482
            env->CP0_WatchLo[i] = 0;
8483
            env->CP0_WatchHi[i] = 0x80000000;
8484
        }
8485
        env->CP0_WatchLo[7] = 0;
8486
        env->CP0_WatchHi[7] = 0;
8487
    }
8488
    /* Count register increments in debug mode, EJTAG version 1 */
8489
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8490
    env->hflags = MIPS_HFLAG_CP0;
8491
#endif
8492
    env->exception_index = EXCP_NONE;
8493
    cpu_mips_register(env, env->cpu_model);
8494
}
8495

    
8496
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8497
                unsigned long searched_pc, int pc_pos, void *puc)
8498
{
8499
    env->active_tc.PC = gen_opc_pc[pc_pos];
8500
    env->hflags &= ~MIPS_HFLAG_BMASK;
8501
    env->hflags |= gen_opc_hflags[pc_pos];
8502
}