Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 6958549d

History | View | Annotate | Download (247.1 kB)

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

    
438
#include "gen-icount.h"
439

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

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

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

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

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

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

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

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

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

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

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

    
504
static const char *fregnames_64[] =
505
    { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
506
      "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
507
      "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
508
      "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
509

    
510
static const char *fregnames_h[] =
511
    { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
512
      "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
513
      "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
514
      "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
515

    
516
#ifdef MIPS_DEBUG_DISAS
517
#define MIPS_DEBUG(fmt, args...)                                              \
518
do {                                                                          \
519
    if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
520
        fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
521
                ctx->pc, ctx->opcode , ##args);                               \
522
    }                                                                         \
523
} while (0)
524
#else
525
#define MIPS_DEBUG(fmt, args...) do { } while(0)
526
#endif
527

    
528
#define MIPS_INVAL(op)                                                        \
529
do {                                                                          \
530
    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
531
               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
532
} while (0)
533

    
534
/* General purpose registers moves. */
535
static inline void gen_load_gpr (TCGv t, int reg)
536
{
537
    if (reg == 0)
538
        tcg_gen_movi_tl(t, 0);
539
    else
540
        tcg_gen_mov_tl(t, cpu_gpr[reg]);
541
}
542

    
543
static inline void gen_store_gpr (TCGv t, int reg)
544
{
545
    if (reg != 0)
546
        tcg_gen_mov_tl(cpu_gpr[reg], t);
547
}
548

    
549
/* Moves to/from ACX register.  */
550
static inline void gen_load_ACX (TCGv t, int reg)
551
{
552
    tcg_gen_mov_tl(t, cpu_ACX[reg]);
553
}
554

    
555
static inline void gen_store_ACX (TCGv t, int reg)
556
{
557
    tcg_gen_mov_tl(cpu_ACX[reg], t);
558
}
559

    
560
/* Moves to/from shadow registers. */
561
static inline void gen_load_srsgpr (int from, int to)
562
{
563
    TCGv r_tmp1 = tcg_temp_new();
564

    
565
    if (from == 0)
566
        tcg_gen_movi_tl(r_tmp1, 0);
567
    else {
568
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
569
        TCGv_ptr addr = tcg_temp_new_ptr();
570

    
571
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
572
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
573
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
574
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
575
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
576
        tcg_gen_add_ptr(addr, cpu_env, addr);
577

    
578
        tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
579
        tcg_temp_free_ptr(addr);
580
        tcg_temp_free_i32(r_tmp2);
581
    }
582
    gen_store_gpr(r_tmp1, to);
583
    tcg_temp_free(r_tmp1);
584
}
585

    
586
static inline void gen_store_srsgpr (int from, int to)
587
{
588
    if (to != 0) {
589
        TCGv r_tmp1 = tcg_temp_new();
590
        TCGv_i32 r_tmp2 = tcg_temp_new_i32();
591
        TCGv_ptr addr = tcg_temp_new_ptr();
592

    
593
        gen_load_gpr(r_tmp1, from);
594
        tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
595
        tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
596
        tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
597
        tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
598
        tcg_gen_ext_i32_ptr(addr, r_tmp2);
599
        tcg_gen_add_ptr(addr, cpu_env, addr);
600

    
601
        tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
602
        tcg_temp_free_ptr(addr);
603
        tcg_temp_free_i32(r_tmp2);
604
        tcg_temp_free(r_tmp1);
605
    }
606
}
607

    
608
/* Floating point register moves. */
609
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
610
{
611
    tcg_gen_mov_i32(t, fpu_fpr32[reg]);
612
}
613

    
614
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
615
{
616
    tcg_gen_mov_i32(fpu_fpr32[reg], t);
617
}
618

    
619
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
620
{
621
    if (ctx->hflags & MIPS_HFLAG_F64)
622
        tcg_gen_mov_i64(t, fpu_fpr64[reg]);
623
    else {
624
        tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
625
    }
626
}
627

    
628
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
629
{
630
    if (ctx->hflags & MIPS_HFLAG_F64)
631
        tcg_gen_mov_i64(fpu_fpr64[reg], t);
632
    else {
633
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
634
        tcg_gen_shri_i64(t, t, 32);
635
        tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
636
    }
637
}
638

    
639
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
640
{
641
    tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
642
}
643

    
644
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
645
{
646
    tcg_gen_mov_i32(fpu_fpr32h[reg], t);
647
}
648

    
649
static inline void get_fp_cond (TCGv_i32 t)
650
{
651
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
652
    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
653

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

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

    
688
FOP_CONDS(, d, 64)
689
FOP_CONDS(abs, d, 64)
690
FOP_CONDS(, s, 32)
691
FOP_CONDS(abs, s, 32)
692
FOP_CONDS(, ps, 64)
693
FOP_CONDS(abs, ps, 64)
694
#undef FOP_CONDS
695

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

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

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

    
754
static inline void gen_save_pc(target_ulong pc)
755
{
756
    tcg_gen_movi_tl(cpu_PC, pc);
757
}
758

    
759
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
760
{
761
#if defined MIPS_DEBUG_DISAS
762
    if (loglevel & CPU_LOG_TB_IN_ASM) {
763
            fprintf(logfile, "hflags %08x saved %08x\n",
764
                    ctx->hflags, ctx->saved_hflags);
765
    }
766
#endif
767
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
768
        gen_save_pc(ctx->pc);
769
        ctx->saved_pc = ctx->pc;
770
    }
771
    if (ctx->hflags != ctx->saved_hflags) {
772
        TCGv_i32 r_tmp = tcg_temp_new_i32();
773

    
774
        tcg_gen_movi_i32(r_tmp, ctx->hflags);
775
        tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
776
        tcg_temp_free_i32(r_tmp);
777
        ctx->saved_hflags = ctx->hflags;
778
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
779
        case MIPS_HFLAG_BR:
780
            break;
781
        case MIPS_HFLAG_BC:
782
        case MIPS_HFLAG_BL:
783
        case MIPS_HFLAG_B:
784
            tcg_gen_movi_tl(btarget, ctx->btarget);
785
            break;
786
        }
787
    }
788
}
789

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

    
804
static inline void
805
generate_exception_err (DisasContext *ctx, int excp, int err)
806
{
807
    TCGv_i32 texcp = tcg_const_i32(excp);
808
    TCGv_i32 terr = tcg_const_i32(err);
809
    save_cpu_state(ctx, 1);
810
    gen_helper_raise_exception_err(texcp, terr);
811
    tcg_temp_free_i32(terr);
812
    tcg_temp_free_i32(texcp);
813
    gen_helper_interrupt_restart();
814
    tcg_gen_exit_tb(0);
815
}
816

    
817
static inline void
818
generate_exception (DisasContext *ctx, int excp)
819
{
820
    save_cpu_state(ctx, 1);
821
    gen_helper_0i(raise_exception, excp);
822
    gen_helper_interrupt_restart();
823
    tcg_gen_exit_tb(0);
824
}
825

    
826
/* Addresses computation */
827
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
828
{
829
    tcg_gen_add_tl(t0, t0, t1);
830

    
831
#if defined(TARGET_MIPS64)
832
    /* For compatibility with 32-bit code, data reference in user mode
833
       with Status_UX = 0 should be casted to 32-bit and sign extended.
834
       See the MIPS64 PRA manual, section 4.10. */
835
    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
836
        !(ctx->hflags & MIPS_HFLAG_UX)) {
837
        tcg_gen_ext32s_i64(t0, t0);
838
    }
839
#endif
840
}
841

    
842
static inline void check_cp0_enabled(DisasContext *ctx)
843
{
844
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
845
        generate_exception_err(ctx, EXCP_CpU, 1);
846
}
847

    
848
static inline void check_cp1_enabled(DisasContext *ctx)
849
{
850
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
851
        generate_exception_err(ctx, EXCP_CpU, 1);
852
}
853

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

    
858
static inline void check_cop1x(DisasContext *ctx)
859
{
860
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
861
        generate_exception(ctx, EXCP_RI);
862
}
863

    
864
/* Verify that the processor is running with 64-bit floating-point
865
   operations enabled.  */
866

    
867
static inline void check_cp1_64bitmode(DisasContext *ctx)
868
{
869
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
870
        generate_exception(ctx, EXCP_RI);
871
}
872

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

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

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

    
906
/* load/store instructions. */
907
#define OP_LD(insn,fname)                                        \
908
static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
909
{                                                                \
910
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
911
}
912
OP_LD(lb,ld8s);
913
OP_LD(lbu,ld8u);
914
OP_LD(lh,ld16s);
915
OP_LD(lhu,ld16u);
916
OP_LD(lw,ld32s);
917
#if defined(TARGET_MIPS64)
918
OP_LD(lwu,ld32u);
919
OP_LD(ld,ld64);
920
#endif
921
#undef OP_LD
922

    
923
#define OP_ST(insn,fname)                                        \
924
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
925
{                                                                \
926
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
927
}
928
OP_ST(sb,st8);
929
OP_ST(sh,st16);
930
OP_ST(sw,st32);
931
#if defined(TARGET_MIPS64)
932
OP_ST(sd,st64);
933
#endif
934
#undef OP_ST
935

    
936
#define OP_LD_ATOMIC(insn,fname)                                        \
937
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
938
{                                                                       \
939
    tcg_gen_mov_tl(t1, t0);                                             \
940
    tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
941
    tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
942
}
943
OP_LD_ATOMIC(ll,ld32s);
944
#if defined(TARGET_MIPS64)
945
OP_LD_ATOMIC(lld,ld64);
946
#endif
947
#undef OP_LD_ATOMIC
948

    
949
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
950
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
951
{                                                                       \
952
    TCGv r_tmp = tcg_temp_local_new();                       \
953
    int l1 = gen_new_label();                                           \
954
    int l2 = gen_new_label();                                           \
955
    int l3 = gen_new_label();                                           \
956
                                                                        \
957
    tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
958
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
959
    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
960
    generate_exception(ctx, EXCP_AdES);                                 \
961
    gen_set_label(l1);                                                  \
962
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
963
    tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
964
    tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
965
    tcg_gen_movi_tl(t0, 1);                                             \
966
    tcg_gen_br(l3);                                                     \
967
    gen_set_label(l2);                                                  \
968
    tcg_gen_movi_tl(t0, 0);                                             \
969
    gen_set_label(l3);                                                  \
970
    tcg_temp_free(r_tmp);                                               \
971
}
972
OP_ST_ATOMIC(sc,st32,0x3);
973
#if defined(TARGET_MIPS64)
974
OP_ST_ATOMIC(scd,st64,0x7);
975
#endif
976
#undef OP_ST_ATOMIC
977

    
978
/* Load and store */
979
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
980
                      int base, int16_t offset)
981
{
982
    const char *opn = "ldst";
983
    TCGv t0 = tcg_temp_local_new();
984
    TCGv t1 = tcg_temp_local_new();
985

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

    
1142
/* Load and store */
1143
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1144
                          int base, int16_t offset)
1145
{
1146
    const char *opn = "flt_ldst";
1147
    TCGv t0 = tcg_temp_local_new();
1148

    
1149
    if (base == 0) {
1150
        tcg_gen_movi_tl(t0, offset);
1151
    } else if (offset == 0) {
1152
        gen_load_gpr(t0, base);
1153
    } else {
1154
        TCGv t1 = tcg_temp_local_new();
1155

    
1156
        gen_load_gpr(t0, base);
1157
        tcg_gen_movi_tl(t1, offset);
1158
        gen_op_addr_add(ctx, t0, t1);
1159
        tcg_temp_free(t1);
1160
    }
1161
    /* Don't do NOP if destination is zero: we must perform the actual
1162
       memory access. */
1163
    switch (opc) {
1164
    case OPC_LWC1:
1165
        {
1166
            TCGv_i32 fp0 = tcg_temp_new_i32();
1167
            TCGv t1 = tcg_temp_new();
1168

    
1169
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1170
            tcg_gen_trunc_tl_i32(fp0, t1);
1171
            gen_store_fpr32(fp0, ft);
1172
            tcg_temp_free(t1);
1173
            tcg_temp_free_i32(fp0);
1174
        }
1175
        opn = "lwc1";
1176
        break;
1177
    case OPC_SWC1:
1178
        {
1179
            TCGv_i32 fp0 = tcg_temp_new_i32();
1180
            TCGv t1 = tcg_temp_new();
1181

    
1182
            gen_load_fpr32(fp0, ft);
1183
            tcg_gen_extu_i32_tl(t1, fp0);
1184
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1185
            tcg_temp_free(t1);
1186
            tcg_temp_free_i32(fp0);
1187
        }
1188
        opn = "swc1";
1189
        break;
1190
    case OPC_LDC1:
1191
        {
1192
            TCGv_i64 fp0 = tcg_temp_new_i64();
1193

    
1194
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1195
            gen_store_fpr64(ctx, fp0, ft);
1196
            tcg_temp_free_i64(fp0);
1197
        }
1198
        opn = "ldc1";
1199
        break;
1200
    case OPC_SDC1:
1201
        {
1202
            TCGv_i64 fp0 = tcg_temp_new_i64();
1203

    
1204
            gen_load_fpr64(ctx, fp0, ft);
1205
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1206
            tcg_temp_free_i64(fp0);
1207
        }
1208
        opn = "sdc1";
1209
        break;
1210
    default:
1211
        MIPS_INVAL(opn);
1212
        generate_exception(ctx, EXCP_RI);
1213
        goto out;
1214
    }
1215
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1216
 out:
1217
    tcg_temp_free(t0);
1218
}
1219

    
1220
/* Arithmetic with immediate operand */
1221
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1222
                           int rt, int rs, int16_t imm)
1223
{
1224
    target_ulong uimm;
1225
    const char *opn = "imm arith";
1226
    TCGv t0 = tcg_temp_local_new();
1227

    
1228
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1229
        /* If no destination, treat it as a NOP.
1230
           For addi, we must generate the overflow exception when needed. */
1231
        MIPS_DEBUG("NOP");
1232
        goto out;
1233
    }
1234
    uimm = (uint16_t)imm;
1235
    switch (opc) {
1236
    case OPC_ADDI:
1237
    case OPC_ADDIU:
1238
#if defined(TARGET_MIPS64)
1239
    case OPC_DADDI:
1240
    case OPC_DADDIU:
1241
#endif
1242
    case OPC_SLTI:
1243
    case OPC_SLTIU:
1244
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1245
        /* Fall through. */
1246
    case OPC_ANDI:
1247
    case OPC_ORI:
1248
    case OPC_XORI:
1249
        gen_load_gpr(t0, rs);
1250
        break;
1251
    case OPC_LUI:
1252
        tcg_gen_movi_tl(t0, imm << 16);
1253
        break;
1254
    case OPC_SLL:
1255
    case OPC_SRA:
1256
    case OPC_SRL:
1257
#if defined(TARGET_MIPS64)
1258
    case OPC_DSLL:
1259
    case OPC_DSRA:
1260
    case OPC_DSRL:
1261
    case OPC_DSLL32:
1262
    case OPC_DSRA32:
1263
    case OPC_DSRL32:
1264
#endif
1265
        uimm &= 0x1f;
1266
        gen_load_gpr(t0, rs);
1267
        break;
1268
    }
1269
    switch (opc) {
1270
    case OPC_ADDI:
1271
        {
1272
            TCGv r_tmp1 = tcg_temp_new();
1273
            TCGv r_tmp2 = tcg_temp_new();
1274
            int l1 = gen_new_label();
1275

    
1276
            save_cpu_state(ctx, 1);
1277
            tcg_gen_ext32s_tl(r_tmp1, t0);
1278
            tcg_gen_addi_tl(t0, r_tmp1, uimm);
1279

    
1280
            tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
1281
            tcg_gen_xori_tl(r_tmp2, t0, uimm);
1282
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1283
            tcg_temp_free(r_tmp2);
1284
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1285
            /* operands of same sign, result different sign */
1286
            generate_exception(ctx, EXCP_OVERFLOW);
1287
            gen_set_label(l1);
1288
            tcg_temp_free(r_tmp1);
1289

    
1290
            tcg_gen_ext32s_tl(t0, t0);
1291
        }
1292
        opn = "addi";
1293
        break;
1294
    case OPC_ADDIU:
1295
        tcg_gen_addi_tl(t0, t0, uimm);
1296
        tcg_gen_ext32s_tl(t0, t0);
1297
        opn = "addiu";
1298
        break;
1299
#if defined(TARGET_MIPS64)
1300
    case OPC_DADDI:
1301
        {
1302
            TCGv r_tmp1 = tcg_temp_new();
1303
            TCGv r_tmp2 = tcg_temp_new();
1304
            int l1 = gen_new_label();
1305

    
1306
            save_cpu_state(ctx, 1);
1307
            tcg_gen_mov_tl(r_tmp1, t0);
1308
            tcg_gen_addi_tl(t0, t0, uimm);
1309

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

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

    
1474
/* Arithmetic */
1475
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1476
                       int rd, int rs, int rt)
1477
{
1478
    const char *opn = "arith";
1479
    TCGv t0 = tcg_temp_local_new();
1480
    TCGv t1 = tcg_temp_local_new();
1481

    
1482
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1483
       && opc != OPC_DADD && opc != OPC_DSUB) {
1484
        /* If no destination, treat it as a NOP.
1485
           For add & sub, we must generate the overflow exception when needed. */
1486
        MIPS_DEBUG("NOP");
1487
        goto out;
1488
    }
1489
    gen_load_gpr(t0, rs);
1490
    /* Specialcase the conventional move operation. */
1491
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1492
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1493
        gen_store_gpr(t0, rd);
1494
        goto out;
1495
    }
1496
    gen_load_gpr(t1, rt);
1497
    switch (opc) {
1498
    case OPC_ADD:
1499
        {
1500
            TCGv r_tmp1 = tcg_temp_new();
1501
            TCGv r_tmp2 = tcg_temp_new();
1502
            int l1 = gen_new_label();
1503

    
1504
            save_cpu_state(ctx, 1);
1505
            tcg_gen_ext32s_tl(r_tmp1, t0);
1506
            tcg_gen_ext32s_tl(r_tmp2, t1);
1507
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1508

    
1509
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1510
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1511
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1512
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1513
            tcg_temp_free(r_tmp2);
1514
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1515
            /* operands of same sign, result different sign */
1516
            generate_exception(ctx, EXCP_OVERFLOW);
1517
            gen_set_label(l1);
1518
            tcg_temp_free(r_tmp1);
1519

    
1520
            tcg_gen_ext32s_tl(t0, t0);
1521
        }
1522
        opn = "add";
1523
        break;
1524
    case OPC_ADDU:
1525
        tcg_gen_add_tl(t0, t0, t1);
1526
        tcg_gen_ext32s_tl(t0, t0);
1527
        opn = "addu";
1528
        break;
1529
    case OPC_SUB:
1530
        {
1531
            TCGv r_tmp1 = tcg_temp_new();
1532
            TCGv r_tmp2 = tcg_temp_new();
1533
            int l1 = gen_new_label();
1534

    
1535
            save_cpu_state(ctx, 1);
1536
            tcg_gen_ext32s_tl(r_tmp1, t0);
1537
            tcg_gen_ext32s_tl(r_tmp2, t1);
1538
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1539

    
1540
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1541
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1542
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1543
            tcg_temp_free(r_tmp2);
1544
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1545
            /* operands of different sign, first operand and result different sign */
1546
            generate_exception(ctx, EXCP_OVERFLOW);
1547
            gen_set_label(l1);
1548
            tcg_temp_free(r_tmp1);
1549

    
1550
            tcg_gen_ext32s_tl(t0, t0);
1551
        }
1552
        opn = "sub";
1553
        break;
1554
    case OPC_SUBU:
1555
        tcg_gen_sub_tl(t0, t0, t1);
1556
        tcg_gen_ext32s_tl(t0, t0);
1557
        opn = "subu";
1558
        break;
1559
#if defined(TARGET_MIPS64)
1560
    case OPC_DADD:
1561
        {
1562
            TCGv r_tmp1 = tcg_temp_new();
1563
            TCGv r_tmp2 = tcg_temp_new();
1564
            int l1 = gen_new_label();
1565

    
1566
            save_cpu_state(ctx, 1);
1567
            tcg_gen_mov_tl(r_tmp1, t0);
1568
            tcg_gen_add_tl(t0, t0, t1);
1569

    
1570
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1571
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1572
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1573
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1574
            tcg_temp_free(r_tmp2);
1575
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1576
            /* operands of same sign, result different sign */
1577
            generate_exception(ctx, EXCP_OVERFLOW);
1578
            gen_set_label(l1);
1579
            tcg_temp_free(r_tmp1);
1580
        }
1581
        opn = "dadd";
1582
        break;
1583
    case OPC_DADDU:
1584
        tcg_gen_add_tl(t0, t0, t1);
1585
        opn = "daddu";
1586
        break;
1587
    case OPC_DSUB:
1588
        {
1589
            TCGv r_tmp1 = tcg_temp_new();
1590
            TCGv r_tmp2 = tcg_temp_new();
1591
            int l1 = gen_new_label();
1592

    
1593
            save_cpu_state(ctx, 1);
1594
            tcg_gen_mov_tl(r_tmp1, t0);
1595
            tcg_gen_sub_tl(t0, t0, t1);
1596

    
1597
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1598
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1599
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1600
            tcg_temp_free(r_tmp2);
1601
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1602
            /* operands of different sign, first operand and result different sign */
1603
            generate_exception(ctx, EXCP_OVERFLOW);
1604
            gen_set_label(l1);
1605
            tcg_temp_free(r_tmp1);
1606
        }
1607
        opn = "dsub";
1608
        break;
1609
    case OPC_DSUBU:
1610
        tcg_gen_sub_tl(t0, t0, t1);
1611
        opn = "dsubu";
1612
        break;
1613
#endif
1614
    case OPC_SLT:
1615
        gen_op_lt(t0, t1);
1616
        opn = "slt";
1617
        break;
1618
    case OPC_SLTU:
1619
        gen_op_ltu(t0, t1);
1620
        opn = "sltu";
1621
        break;
1622
    case OPC_AND:
1623
        tcg_gen_and_tl(t0, t0, t1);
1624
        opn = "and";
1625
        break;
1626
    case OPC_NOR:
1627
        tcg_gen_or_tl(t0, t0, t1);
1628
        tcg_gen_not_tl(t0, t0);
1629
        opn = "nor";
1630
        break;
1631
    case OPC_OR:
1632
        tcg_gen_or_tl(t0, t0, t1);
1633
        opn = "or";
1634
        break;
1635
    case OPC_XOR:
1636
        tcg_gen_xor_tl(t0, t0, t1);
1637
        opn = "xor";
1638
        break;
1639
    case OPC_MUL:
1640
        tcg_gen_mul_tl(t0, t0, t1);
1641
        tcg_gen_ext32s_tl(t0, t0);
1642
        opn = "mul";
1643
        break;
1644
    case OPC_MOVN:
1645
        {
1646
            int l1 = gen_new_label();
1647

    
1648
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1649
            gen_store_gpr(t0, rd);
1650
            gen_set_label(l1);
1651
        }
1652
        opn = "movn";
1653
        goto print;
1654
    case OPC_MOVZ:
1655
        {
1656
            int l1 = gen_new_label();
1657

    
1658
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1659
            gen_store_gpr(t0, rd);
1660
            gen_set_label(l1);
1661
        }
1662
        opn = "movz";
1663
        goto print;
1664
    case OPC_SLLV:
1665
        tcg_gen_andi_tl(t0, t0, 0x1f);
1666
        tcg_gen_shl_tl(t0, t1, t0);
1667
        tcg_gen_ext32s_tl(t0, t0);
1668
        opn = "sllv";
1669
        break;
1670
    case OPC_SRAV:
1671
        tcg_gen_ext32s_tl(t1, t1);
1672
        tcg_gen_andi_tl(t0, t0, 0x1f);
1673
        tcg_gen_sar_tl(t0, t1, t0);
1674
        opn = "srav";
1675
        break;
1676
    case OPC_SRLV:
1677
        switch ((ctx->opcode >> 6) & 0x1f) {
1678
        case 0:
1679
            tcg_gen_ext32u_tl(t1, t1);
1680
            tcg_gen_andi_tl(t0, t0, 0x1f);
1681
            tcg_gen_shr_tl(t0, t1, t0);
1682
            tcg_gen_ext32s_tl(t0, t0);
1683
            opn = "srlv";
1684
            break;
1685
        case 1:
1686
            /* rotrv is decoded as srlv on non-R2 CPUs */
1687
            if (env->insn_flags & ISA_MIPS32R2) {
1688
                int l1 = gen_new_label();
1689
                int l2 = gen_new_label();
1690

    
1691
                tcg_gen_andi_tl(t0, t0, 0x1f);
1692
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1693
                {
1694
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1695
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1696

    
1697
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1698
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1699
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1700
                    tcg_temp_free_i32(r_tmp1);
1701
                    tcg_temp_free_i32(r_tmp2);
1702
                    tcg_gen_br(l2);
1703
                }
1704
                gen_set_label(l1);
1705
                tcg_gen_mov_tl(t0, t1);
1706
                gen_set_label(l2);
1707
                opn = "rotrv";
1708
            } else {
1709
                tcg_gen_ext32u_tl(t1, t1);
1710
                tcg_gen_andi_tl(t0, t0, 0x1f);
1711
                tcg_gen_shr_tl(t0, t1, t0);
1712
                tcg_gen_ext32s_tl(t0, t0);
1713
                opn = "srlv";
1714
            }
1715
            break;
1716
        default:
1717
            MIPS_INVAL("invalid srlv flag");
1718
            generate_exception(ctx, EXCP_RI);
1719
            break;
1720
        }
1721
        break;
1722
#if defined(TARGET_MIPS64)
1723
    case OPC_DSLLV:
1724
        tcg_gen_andi_tl(t0, t0, 0x3f);
1725
        tcg_gen_shl_tl(t0, t1, t0);
1726
        opn = "dsllv";
1727
        break;
1728
    case OPC_DSRAV:
1729
        tcg_gen_andi_tl(t0, t0, 0x3f);
1730
        tcg_gen_sar_tl(t0, t1, t0);
1731
        opn = "dsrav";
1732
        break;
1733
    case OPC_DSRLV:
1734
        switch ((ctx->opcode >> 6) & 0x1f) {
1735
        case 0:
1736
            tcg_gen_andi_tl(t0, t0, 0x3f);
1737
            tcg_gen_shr_tl(t0, t1, t0);
1738
            opn = "dsrlv";
1739
            break;
1740
        case 1:
1741
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1742
            if (env->insn_flags & ISA_MIPS32R2) {
1743
                int l1 = gen_new_label();
1744
                int l2 = gen_new_label();
1745

    
1746
                tcg_gen_andi_tl(t0, t0, 0x3f);
1747
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1748
                {
1749
                    tcg_gen_rotr_tl(t0, t1, t0);
1750
                    tcg_gen_br(l2);
1751
                }
1752
                gen_set_label(l1);
1753
                tcg_gen_mov_tl(t0, t1);
1754
                gen_set_label(l2);
1755
                opn = "drotrv";
1756
            } else {
1757
                tcg_gen_andi_tl(t0, t0, 0x3f);
1758
                tcg_gen_shr_tl(t0, t1, t0);
1759
                opn = "dsrlv";
1760
            }
1761
            break;
1762
        default:
1763
            MIPS_INVAL("invalid dsrlv flag");
1764
            generate_exception(ctx, EXCP_RI);
1765
            break;
1766
        }
1767
        break;
1768
#endif
1769
    default:
1770
        MIPS_INVAL(opn);
1771
        generate_exception(ctx, EXCP_RI);
1772
        goto out;
1773
    }
1774
    gen_store_gpr(t0, rd);
1775
 print:
1776
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1777
 out:
1778
    tcg_temp_free(t0);
1779
    tcg_temp_free(t1);
1780
}
1781

    
1782
/* Arithmetic on HI/LO registers */
1783
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1784
{
1785
    const char *opn = "hilo";
1786
    TCGv t0 = tcg_temp_local_new();
1787

    
1788
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1789
        /* Treat as NOP. */
1790
        MIPS_DEBUG("NOP");
1791
        goto out;
1792
    }
1793
    switch (opc) {
1794
    case OPC_MFHI:
1795
        tcg_gen_mov_tl(t0, cpu_HI[0]);
1796
        gen_store_gpr(t0, reg);
1797
        opn = "mfhi";
1798
        break;
1799
    case OPC_MFLO:
1800
        tcg_gen_mov_tl(t0, cpu_LO[0]);
1801
        gen_store_gpr(t0, reg);
1802
        opn = "mflo";
1803
        break;
1804
    case OPC_MTHI:
1805
        gen_load_gpr(t0, reg);
1806
        tcg_gen_mov_tl(cpu_HI[0], t0);
1807
        opn = "mthi";
1808
        break;
1809
    case OPC_MTLO:
1810
        gen_load_gpr(t0, reg);
1811
        tcg_gen_mov_tl(cpu_LO[0], t0);
1812
        opn = "mtlo";
1813
        break;
1814
    default:
1815
        MIPS_INVAL(opn);
1816
        generate_exception(ctx, EXCP_RI);
1817
        goto out;
1818
    }
1819
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1820
 out:
1821
    tcg_temp_free(t0);
1822
}
1823

    
1824
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1825
                        int rs, int rt)
1826
{
1827
    const char *opn = "mul/div";
1828
    TCGv t0 = tcg_temp_local_new();
1829
    TCGv t1 = tcg_temp_local_new();
1830

    
1831
    gen_load_gpr(t0, rs);
1832
    gen_load_gpr(t1, rt);
1833
    switch (opc) {
1834
    case OPC_DIV:
1835
        {
1836
            int l1 = gen_new_label();
1837

    
1838
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1839
            {
1840
                int l2 = gen_new_label();
1841
                TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
1842
                TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
1843
                TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
1844

    
1845
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1846
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1847
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
1848
                tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
1849
                tcg_gen_ext32s_tl(cpu_LO[0], t0);
1850
                tcg_gen_movi_tl(cpu_HI[0], 0);
1851
                tcg_gen_br(l1);
1852
                gen_set_label(l2);
1853
                tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1854
                tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
1855
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1856
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
1857
                tcg_temp_free_i32(r_tmp1);
1858
                tcg_temp_free_i32(r_tmp2);
1859
                tcg_temp_free_i32(r_tmp3);
1860
            }
1861
            gen_set_label(l1);
1862
        }
1863
        opn = "div";
1864
        break;
1865
    case OPC_DIVU:
1866
        {
1867
            int l1 = gen_new_label();
1868

    
1869
            tcg_gen_ext32s_tl(t1, t1);
1870
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1871
            {
1872
                TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1873
                TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1874
                TCGv_i32 r_tmp3 = tcg_temp_new_i32();
1875

    
1876
                tcg_gen_trunc_tl_i32(r_tmp1, t0);
1877
                tcg_gen_trunc_tl_i32(r_tmp2, t1);
1878
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1879
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1880
                tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1881
                tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
1882
                tcg_temp_free_i32(r_tmp1);
1883
                tcg_temp_free_i32(r_tmp2);
1884
                tcg_temp_free_i32(r_tmp3);
1885
            }
1886
            gen_set_label(l1);
1887
        }
1888
        opn = "divu";
1889
        break;
1890
    case OPC_MULT:
1891
        {
1892
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1893
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1894

    
1895
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1896
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1897
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1898
            tcg_temp_free_i64(r_tmp2);
1899
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1900
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1901
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1902
            tcg_temp_free_i64(r_tmp1);
1903
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1904
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1905
        }
1906
        opn = "mult";
1907
        break;
1908
    case OPC_MULTU:
1909
        {
1910
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1911
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1912

    
1913
            tcg_gen_ext32u_tl(t0, t0);
1914
            tcg_gen_ext32u_tl(t1, t1);
1915
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1916
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1917
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1918
            tcg_temp_free_i64(r_tmp2);
1919
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1920
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1921
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1922
            tcg_temp_free_i64(r_tmp1);
1923
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1924
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
1925
        }
1926
        opn = "multu";
1927
        break;
1928
#if defined(TARGET_MIPS64)
1929
    case OPC_DDIV:
1930
        {
1931
            int l1 = gen_new_label();
1932

    
1933
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1934
            {
1935
                int l2 = gen_new_label();
1936

    
1937
                tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1938
                tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1939
                tcg_gen_mov_tl(cpu_LO[0], t0);
1940
                tcg_gen_movi_tl(cpu_HI[0], 0);
1941
                tcg_gen_br(l1);
1942
                gen_set_label(l2);
1943
                tcg_gen_div_i64(cpu_LO[0], t0, t1);
1944
                tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1945
            }
1946
            gen_set_label(l1);
1947
        }
1948
        opn = "ddiv";
1949
        break;
1950
    case OPC_DDIVU:
1951
        {
1952
            int l1 = gen_new_label();
1953

    
1954
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1955
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1956
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1957
            gen_set_label(l1);
1958
        }
1959
        opn = "ddivu";
1960
        break;
1961
    case OPC_DMULT:
1962
        gen_helper_dmult(t0, t1);
1963
        opn = "dmult";
1964
        break;
1965
    case OPC_DMULTU:
1966
        gen_helper_dmultu(t0, t1);
1967
        opn = "dmultu";
1968
        break;
1969
#endif
1970
    case OPC_MADD:
1971
        {
1972
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1973
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1974

    
1975
            tcg_gen_ext_tl_i64(r_tmp1, t0);
1976
            tcg_gen_ext_tl_i64(r_tmp2, t1);
1977
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1978
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1979
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1980
            tcg_temp_free_i64(r_tmp2);
1981
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
1982
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1983
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
1984
            tcg_temp_free_i64(r_tmp1);
1985
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
1986
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
1987
        }
1988
        opn = "madd";
1989
        break;
1990
    case OPC_MADDU:
1991
       {
1992
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1993
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1994

    
1995
            tcg_gen_ext32u_tl(t0, t0);
1996
            tcg_gen_ext32u_tl(t1, t1);
1997
            tcg_gen_extu_tl_i64(r_tmp1, t0);
1998
            tcg_gen_extu_tl_i64(r_tmp2, t1);
1999
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2000
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2001
            tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
2002
            tcg_temp_free_i64(r_tmp2);
2003
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2004
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2005
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2006
            tcg_temp_free_i64(r_tmp1);
2007
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2008
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2009
        }
2010
        opn = "maddu";
2011
        break;
2012
    case OPC_MSUB:
2013
        {
2014
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2015
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2016

    
2017
            tcg_gen_ext_tl_i64(r_tmp1, t0);
2018
            tcg_gen_ext_tl_i64(r_tmp2, t1);
2019
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2020
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2021
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2022
            tcg_temp_free_i64(r_tmp2);
2023
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2024
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2025
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2026
            tcg_temp_free_i64(r_tmp1);
2027
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2028
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2029
        }
2030
        opn = "msub";
2031
        break;
2032
    case OPC_MSUBU:
2033
        {
2034
            TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2035
            TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2036

    
2037
            tcg_gen_ext32u_tl(t0, t0);
2038
            tcg_gen_ext32u_tl(t1, t1);
2039
            tcg_gen_extu_tl_i64(r_tmp1, t0);
2040
            tcg_gen_extu_tl_i64(r_tmp2, t1);
2041
            tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2042
            tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2043
            tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2044
            tcg_temp_free_i64(r_tmp2);
2045
            tcg_gen_trunc_i64_tl(t0, r_tmp1);
2046
            tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2047
            tcg_gen_trunc_i64_tl(t1, r_tmp1);
2048
            tcg_temp_free_i64(r_tmp1);
2049
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2050
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2051
        }
2052
        opn = "msubu";
2053
        break;
2054
    default:
2055
        MIPS_INVAL(opn);
2056
        generate_exception(ctx, EXCP_RI);
2057
        goto out;
2058
    }
2059
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2060
 out:
2061
    tcg_temp_free(t0);
2062
    tcg_temp_free(t1);
2063
}
2064

    
2065
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2066
                            int rd, int rs, int rt)
2067
{
2068
    const char *opn = "mul vr54xx";
2069
    TCGv t0 = tcg_temp_local_new();
2070
    TCGv t1 = tcg_temp_local_new();
2071

    
2072
    gen_load_gpr(t0, rs);
2073
    gen_load_gpr(t1, rt);
2074

    
2075
    switch (opc) {
2076
    case OPC_VR54XX_MULS:
2077
        gen_helper_muls(t0, t0, t1);
2078
        opn = "muls";
2079
        break;
2080
    case OPC_VR54XX_MULSU:
2081
        gen_helper_mulsu(t0, t0, t1);
2082
        opn = "mulsu";
2083
        break;
2084
    case OPC_VR54XX_MACC:
2085
        gen_helper_macc(t0, t0, t1);
2086
        opn = "macc";
2087
        break;
2088
    case OPC_VR54XX_MACCU:
2089
        gen_helper_maccu(t0, t0, t1);
2090
        opn = "maccu";
2091
        break;
2092
    case OPC_VR54XX_MSAC:
2093
        gen_helper_msac(t0, t0, t1);
2094
        opn = "msac";
2095
        break;
2096
    case OPC_VR54XX_MSACU:
2097
        gen_helper_msacu(t0, t0, t1);
2098
        opn = "msacu";
2099
        break;
2100
    case OPC_VR54XX_MULHI:
2101
        gen_helper_mulhi(t0, t0, t1);
2102
        opn = "mulhi";
2103
        break;
2104
    case OPC_VR54XX_MULHIU:
2105
        gen_helper_mulhiu(t0, t0, t1);
2106
        opn = "mulhiu";
2107
        break;
2108
    case OPC_VR54XX_MULSHI:
2109
        gen_helper_mulshi(t0, t0, t1);
2110
        opn = "mulshi";
2111
        break;
2112
    case OPC_VR54XX_MULSHIU:
2113
        gen_helper_mulshiu(t0, t0, t1);
2114
        opn = "mulshiu";
2115
        break;
2116
    case OPC_VR54XX_MACCHI:
2117
        gen_helper_macchi(t0, t0, t1);
2118
        opn = "macchi";
2119
        break;
2120
    case OPC_VR54XX_MACCHIU:
2121
        gen_helper_macchiu(t0, t0, t1);
2122
        opn = "macchiu";
2123
        break;
2124
    case OPC_VR54XX_MSACHI:
2125
        gen_helper_msachi(t0, t0, t1);
2126
        opn = "msachi";
2127
        break;
2128
    case OPC_VR54XX_MSACHIU:
2129
        gen_helper_msachiu(t0, t0, t1);
2130
        opn = "msachiu";
2131
        break;
2132
    default:
2133
        MIPS_INVAL("mul vr54xx");
2134
        generate_exception(ctx, EXCP_RI);
2135
        goto out;
2136
    }
2137
    gen_store_gpr(t0, rd);
2138
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2139

    
2140
 out:
2141
    tcg_temp_free(t0);
2142
    tcg_temp_free(t1);
2143
}
2144

    
2145
static void gen_cl (DisasContext *ctx, uint32_t opc,
2146
                    int rd, int rs)
2147
{
2148
    const char *opn = "CLx";
2149
    TCGv t0 = tcg_temp_local_new();
2150

    
2151
    if (rd == 0) {
2152
        /* Treat as NOP. */
2153
        MIPS_DEBUG("NOP");
2154
        goto out;
2155
    }
2156
    gen_load_gpr(t0, rs);
2157
    switch (opc) {
2158
    case OPC_CLO:
2159
        gen_helper_clo(t0, t0);
2160
        opn = "clo";
2161
        break;
2162
    case OPC_CLZ:
2163
        gen_helper_clz(t0, t0);
2164
        opn = "clz";
2165
        break;
2166
#if defined(TARGET_MIPS64)
2167
    case OPC_DCLO:
2168
        gen_helper_dclo(t0, t0);
2169
        opn = "dclo";
2170
        break;
2171
    case OPC_DCLZ:
2172
        gen_helper_dclz(t0, t0);
2173
        opn = "dclz";
2174
        break;
2175
#endif
2176
    default:
2177
        MIPS_INVAL(opn);
2178
        generate_exception(ctx, EXCP_RI);
2179
        goto out;
2180
    }
2181
    gen_store_gpr(t0, rd);
2182
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2183

    
2184
 out:
2185
    tcg_temp_free(t0);
2186
}
2187

    
2188
/* Traps */
2189
static void gen_trap (DisasContext *ctx, uint32_t opc,
2190
                      int rs, int rt, int16_t imm)
2191
{
2192
    int cond;
2193
    TCGv t0 = tcg_temp_local_new();
2194
    TCGv t1 = tcg_temp_local_new();
2195

    
2196
    cond = 0;
2197
    /* Load needed operands */
2198
    switch (opc) {
2199
    case OPC_TEQ:
2200
    case OPC_TGE:
2201
    case OPC_TGEU:
2202
    case OPC_TLT:
2203
    case OPC_TLTU:
2204
    case OPC_TNE:
2205
        /* Compare two registers */
2206
        if (rs != rt) {
2207
            gen_load_gpr(t0, rs);
2208
            gen_load_gpr(t1, rt);
2209
            cond = 1;
2210
        }
2211
        break;
2212
    case OPC_TEQI:
2213
    case OPC_TGEI:
2214
    case OPC_TGEIU:
2215
    case OPC_TLTI:
2216
    case OPC_TLTIU:
2217
    case OPC_TNEI:
2218
        /* Compare register to immediate */
2219
        if (rs != 0 || imm != 0) {
2220
            gen_load_gpr(t0, rs);
2221
            tcg_gen_movi_tl(t1, (int32_t)imm);
2222
            cond = 1;
2223
        }
2224
        break;
2225
    }
2226
    if (cond == 0) {
2227
        switch (opc) {
2228
        case OPC_TEQ:   /* rs == rs */
2229
        case OPC_TEQI:  /* r0 == 0  */
2230
        case OPC_TGE:   /* rs >= rs */
2231
        case OPC_TGEI:  /* r0 >= 0  */
2232
        case OPC_TGEU:  /* rs >= rs unsigned */
2233
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2234
            /* Always trap */
2235
            tcg_gen_movi_tl(t0, 1);
2236
            break;
2237
        case OPC_TLT:   /* rs < rs           */
2238
        case OPC_TLTI:  /* r0 < 0            */
2239
        case OPC_TLTU:  /* rs < rs unsigned  */
2240
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2241
        case OPC_TNE:   /* rs != rs          */
2242
        case OPC_TNEI:  /* r0 != 0           */
2243
            /* Never trap: treat as NOP. */
2244
            goto out;
2245
        default:
2246
            MIPS_INVAL("trap");
2247
            generate_exception(ctx, EXCP_RI);
2248
            goto out;
2249
        }
2250
    } else {
2251
        switch (opc) {
2252
        case OPC_TEQ:
2253
        case OPC_TEQI:
2254
            gen_op_eq(t0, t1);
2255
            break;
2256
        case OPC_TGE:
2257
        case OPC_TGEI:
2258
            gen_op_ge(t0, t1);
2259
            break;
2260
        case OPC_TGEU:
2261
        case OPC_TGEIU:
2262
            gen_op_geu(t0, t1);
2263
            break;
2264
        case OPC_TLT:
2265
        case OPC_TLTI:
2266
            gen_op_lt(t0, t1);
2267
            break;
2268
        case OPC_TLTU:
2269
        case OPC_TLTIU:
2270
            gen_op_ltu(t0, t1);
2271
            break;
2272
        case OPC_TNE:
2273
        case OPC_TNEI:
2274
            gen_op_ne(t0, t1);
2275
            break;
2276
        default:
2277
            MIPS_INVAL("trap");
2278
            generate_exception(ctx, EXCP_RI);
2279
            goto out;
2280
        }
2281
    }
2282
    save_cpu_state(ctx, 1);
2283
    {
2284
        int l1 = gen_new_label();
2285

    
2286
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2287
        gen_helper_0i(raise_exception, EXCP_TRAP);
2288
        gen_set_label(l1);
2289
    }
2290
    ctx->bstate = BS_STOP;
2291
 out:
2292
    tcg_temp_free(t0);
2293
    tcg_temp_free(t1);
2294
}
2295

    
2296
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2297
{
2298
    TranslationBlock *tb;
2299
    tb = ctx->tb;
2300
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2301
        tcg_gen_goto_tb(n);
2302
        gen_save_pc(dest);
2303
        tcg_gen_exit_tb((long)tb + n);
2304
    } else {
2305
        gen_save_pc(dest);
2306
        tcg_gen_exit_tb(0);
2307
    }
2308
}
2309

    
2310
/* Branches (before delay slot) */
2311
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2312
                                int rs, int rt, int32_t offset)
2313
{
2314
    target_ulong btgt = -1;
2315
    int blink = 0;
2316
    int bcond_compute = 0;
2317
    TCGv t0 = tcg_temp_local_new();
2318
    TCGv t1 = tcg_temp_local_new();
2319

    
2320
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2321
#ifdef MIPS_DEBUG_DISAS
2322
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2323
            fprintf(logfile,
2324
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2325
                    ctx->pc);
2326
        }
2327
#endif
2328
        generate_exception(ctx, EXCP_RI);
2329
        goto out;
2330
    }
2331

    
2332
    /* Load needed operands */
2333
    switch (opc) {
2334
    case OPC_BEQ:
2335
    case OPC_BEQL:
2336
    case OPC_BNE:
2337
    case OPC_BNEL:
2338
        /* Compare two registers */
2339
        if (rs != rt) {
2340
            gen_load_gpr(t0, rs);
2341
            gen_load_gpr(t1, rt);
2342
            bcond_compute = 1;
2343
        }
2344
        btgt = ctx->pc + 4 + offset;
2345
        break;
2346
    case OPC_BGEZ:
2347
    case OPC_BGEZAL:
2348
    case OPC_BGEZALL:
2349
    case OPC_BGEZL:
2350
    case OPC_BGTZ:
2351
    case OPC_BGTZL:
2352
    case OPC_BLEZ:
2353
    case OPC_BLEZL:
2354
    case OPC_BLTZ:
2355
    case OPC_BLTZAL:
2356
    case OPC_BLTZALL:
2357
    case OPC_BLTZL:
2358
        /* Compare to zero */
2359
        if (rs != 0) {
2360
            gen_load_gpr(t0, rs);
2361
            bcond_compute = 1;
2362
        }
2363
        btgt = ctx->pc + 4 + offset;
2364
        break;
2365
    case OPC_J:
2366
    case OPC_JAL:
2367
        /* Jump to immediate */
2368
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2369
        break;
2370
    case OPC_JR:
2371
    case OPC_JALR:
2372
        /* Jump to register */
2373
        if (offset != 0 && offset != 16) {
2374
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2375
               others are reserved. */
2376
            MIPS_INVAL("jump hint");
2377
            generate_exception(ctx, EXCP_RI);
2378
            goto out;
2379
        }
2380
        gen_load_gpr(btarget, rs);
2381
        break;
2382
    default:
2383
        MIPS_INVAL("branch/jump");
2384
        generate_exception(ctx, EXCP_RI);
2385
        goto out;
2386
    }
2387
    if (bcond_compute == 0) {
2388
        /* No condition to be computed */
2389
        switch (opc) {
2390
        case OPC_BEQ:     /* rx == rx        */
2391
        case OPC_BEQL:    /* rx == rx likely */
2392
        case OPC_BGEZ:    /* 0 >= 0          */
2393
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2394
        case OPC_BLEZ:    /* 0 <= 0          */
2395
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2396
            /* Always take */
2397
            ctx->hflags |= MIPS_HFLAG_B;
2398
            MIPS_DEBUG("balways");
2399
            break;
2400
        case OPC_BGEZAL:  /* 0 >= 0          */
2401
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2402
            /* Always take and link */
2403
            blink = 31;
2404
            ctx->hflags |= MIPS_HFLAG_B;
2405
            MIPS_DEBUG("balways and link");
2406
            break;
2407
        case OPC_BNE:     /* rx != rx        */
2408
        case OPC_BGTZ:    /* 0 > 0           */
2409
        case OPC_BLTZ:    /* 0 < 0           */
2410
            /* Treat as NOP. */
2411
            MIPS_DEBUG("bnever (NOP)");
2412
            goto out;
2413
        case OPC_BLTZAL:  /* 0 < 0           */
2414
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2415
            gen_store_gpr(t0, 31);
2416
            MIPS_DEBUG("bnever and link");
2417
            goto out;
2418
        case OPC_BLTZALL: /* 0 < 0 likely */
2419
            tcg_gen_movi_tl(t0, ctx->pc + 8);
2420
            gen_store_gpr(t0, 31);
2421
            /* Skip the instruction in the delay slot */
2422
            MIPS_DEBUG("bnever, link and skip");
2423
            ctx->pc += 4;
2424
            goto out;
2425
        case OPC_BNEL:    /* rx != rx likely */
2426
        case OPC_BGTZL:   /* 0 > 0 likely */
2427
        case OPC_BLTZL:   /* 0 < 0 likely */
2428
            /* Skip the instruction in the delay slot */
2429
            MIPS_DEBUG("bnever and skip");
2430
            ctx->pc += 4;
2431
            goto out;
2432
        case OPC_J:
2433
            ctx->hflags |= MIPS_HFLAG_B;
2434
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2435
            break;
2436
        case OPC_JAL:
2437
            blink = 31;
2438
            ctx->hflags |= MIPS_HFLAG_B;
2439
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2440
            break;
2441
        case OPC_JR:
2442
            ctx->hflags |= MIPS_HFLAG_BR;
2443
            MIPS_DEBUG("jr %s", regnames[rs]);
2444
            break;
2445
        case OPC_JALR:
2446
            blink = rt;
2447
            ctx->hflags |= MIPS_HFLAG_BR;
2448
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2449
            break;
2450
        default:
2451
            MIPS_INVAL("branch/jump");
2452
            generate_exception(ctx, EXCP_RI);
2453
            goto out;
2454
        }
2455
    } else {
2456
        switch (opc) {
2457
        case OPC_BEQ:
2458
            gen_op_eq(t0, t1);
2459
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2460
                       regnames[rs], regnames[rt], btgt);
2461
            goto not_likely;
2462
        case OPC_BEQL:
2463
            gen_op_eq(t0, t1);
2464
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2465
                       regnames[rs], regnames[rt], btgt);
2466
            goto likely;
2467
        case OPC_BNE:
2468
            gen_op_ne(t0, t1);
2469
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2470
                       regnames[rs], regnames[rt], btgt);
2471
            goto not_likely;
2472
        case OPC_BNEL:
2473
            gen_op_ne(t0, t1);
2474
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2475
                       regnames[rs], regnames[rt], btgt);
2476
            goto likely;
2477
        case OPC_BGEZ:
2478
            gen_op_gez(t0);
2479
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2480
            goto not_likely;
2481
        case OPC_BGEZL:
2482
            gen_op_gez(t0);
2483
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2484
            goto likely;
2485
        case OPC_BGEZAL:
2486
            gen_op_gez(t0);
2487
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2488
            blink = 31;
2489
            goto not_likely;
2490
        case OPC_BGEZALL:
2491
            gen_op_gez(t0);
2492
            blink = 31;
2493
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2494
            goto likely;
2495
        case OPC_BGTZ:
2496
            gen_op_gtz(t0);
2497
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2498
            goto not_likely;
2499
        case OPC_BGTZL:
2500
            gen_op_gtz(t0);
2501
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2502
            goto likely;
2503
        case OPC_BLEZ:
2504
            gen_op_lez(t0);
2505
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2506
            goto not_likely;
2507
        case OPC_BLEZL:
2508
            gen_op_lez(t0);
2509
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2510
            goto likely;
2511
        case OPC_BLTZ:
2512
            gen_op_ltz(t0);
2513
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2514
            goto not_likely;
2515
        case OPC_BLTZL:
2516
            gen_op_ltz(t0);
2517
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2518
            goto likely;
2519
        case OPC_BLTZAL:
2520
            gen_op_ltz(t0);
2521
            blink = 31;
2522
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2523
        not_likely:
2524
            ctx->hflags |= MIPS_HFLAG_BC;
2525
            tcg_gen_trunc_tl_i32(bcond, t0);
2526
            break;
2527
        case OPC_BLTZALL:
2528
            gen_op_ltz(t0);
2529
            blink = 31;
2530
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2531
        likely:
2532
            ctx->hflags |= MIPS_HFLAG_BL;
2533
            tcg_gen_trunc_tl_i32(bcond, t0);
2534
            break;
2535
        default:
2536
            MIPS_INVAL("conditional branch/jump");
2537
            generate_exception(ctx, EXCP_RI);
2538
            goto out;
2539
        }
2540
    }
2541
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2542
               blink, ctx->hflags, btgt);
2543

    
2544
    ctx->btarget = btgt;
2545
    if (blink > 0) {
2546
        tcg_gen_movi_tl(t0, ctx->pc + 8);
2547
        gen_store_gpr(t0, blink);
2548
    }
2549

    
2550
 out:
2551
    tcg_temp_free(t0);
2552
    tcg_temp_free(t1);
2553
}
2554

    
2555
/* special3 bitfield operations */
2556
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2557
                        int rs, int lsb, int msb)
2558
{
2559
    TCGv t0 = tcg_temp_new();
2560
    TCGv t1 = tcg_temp_new();
2561
    target_ulong mask;
2562

    
2563
    gen_load_gpr(t1, rs);
2564
    switch (opc) {
2565
    case OPC_EXT:
2566
        if (lsb + msb > 31)
2567
            goto fail;
2568
        tcg_gen_shri_tl(t0, t1, lsb);
2569
        if (msb != 31) {
2570
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2571
        } else {
2572
            tcg_gen_ext32s_tl(t0, t0);
2573
        }
2574
        break;
2575
#if defined(TARGET_MIPS64)
2576
    case OPC_DEXTM:
2577
        tcg_gen_shri_tl(t0, t1, lsb);
2578
        if (msb != 31) {
2579
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2580
        }
2581
        break;
2582
    case OPC_DEXTU:
2583
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2584
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2585
        break;
2586
    case OPC_DEXT:
2587
        tcg_gen_shri_tl(t0, t1, lsb);
2588
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2589
        break;
2590
#endif
2591
    case OPC_INS:
2592
        if (lsb > msb)
2593
            goto fail;
2594
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2595
        gen_load_gpr(t0, rt);
2596
        tcg_gen_andi_tl(t0, t0, ~mask);
2597
        tcg_gen_shli_tl(t1, t1, lsb);
2598
        tcg_gen_andi_tl(t1, t1, mask);
2599
        tcg_gen_or_tl(t0, t0, t1);
2600
        tcg_gen_ext32s_tl(t0, t0);
2601
        break;
2602
#if defined(TARGET_MIPS64)
2603
    case OPC_DINSM:
2604
        if (lsb > msb)
2605
            goto fail;
2606
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2607
        gen_load_gpr(t0, rt);
2608
        tcg_gen_andi_tl(t0, t0, ~mask);
2609
        tcg_gen_shli_tl(t1, t1, lsb);
2610
        tcg_gen_andi_tl(t1, t1, mask);
2611
        tcg_gen_or_tl(t0, t0, t1);
2612
        break;
2613
    case OPC_DINSU:
2614
        if (lsb > msb)
2615
            goto fail;
2616
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2617
        gen_load_gpr(t0, rt);
2618
        tcg_gen_andi_tl(t0, t0, ~mask);
2619
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2620
        tcg_gen_andi_tl(t1, t1, mask);
2621
        tcg_gen_or_tl(t0, t0, t1);
2622
        break;
2623
    case OPC_DINS:
2624
        if (lsb > msb)
2625
            goto fail;
2626
        gen_load_gpr(t0, rt);
2627
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2628
        gen_load_gpr(t0, rt);
2629
        tcg_gen_andi_tl(t0, t0, ~mask);
2630
        tcg_gen_shli_tl(t1, t1, lsb);
2631
        tcg_gen_andi_tl(t1, t1, mask);
2632
        tcg_gen_or_tl(t0, t0, t1);
2633
        break;
2634
#endif
2635
    default:
2636
fail:
2637
        MIPS_INVAL("bitops");
2638
        generate_exception(ctx, EXCP_RI);
2639
        tcg_temp_free(t0);
2640
        tcg_temp_free(t1);
2641
        return;
2642
    }
2643
    gen_store_gpr(t0, rt);
2644
    tcg_temp_free(t0);
2645
    tcg_temp_free(t1);
2646
}
2647

    
2648
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2649
{
2650
    TCGv t0 = tcg_temp_new();
2651
    TCGv t1 = tcg_temp_new();
2652

    
2653
    gen_load_gpr(t1, rt);
2654
    switch (op2) {
2655
    case OPC_WSBH:
2656
        tcg_gen_shri_tl(t0, t1, 8);
2657
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
2658
        tcg_gen_shli_tl(t1, t1, 8);
2659
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
2660
        tcg_gen_or_tl(t0, t0, t1);
2661
        tcg_gen_ext32s_tl(t0, t0);
2662
        break;
2663
    case OPC_SEB:
2664
        tcg_gen_ext8s_tl(t0, t1);
2665
        break;
2666
    case OPC_SEH:
2667
        tcg_gen_ext16s_tl(t0, t1);
2668
        break;
2669
#if defined(TARGET_MIPS64)
2670
    case OPC_DSBH:
2671
        gen_load_gpr(t1, rt);
2672
        tcg_gen_shri_tl(t0, t1, 8);
2673
        tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
2674
        tcg_gen_shli_tl(t1, t1, 8);
2675
        tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
2676
        tcg_gen_or_tl(t0, t0, t1);
2677
        break;
2678
    case OPC_DSHD:
2679
        gen_load_gpr(t1, rt);
2680
        tcg_gen_shri_tl(t0, t1, 16);
2681
        tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
2682
        tcg_gen_shli_tl(t1, t1, 16);
2683
        tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
2684
        tcg_gen_or_tl(t1, t0, t1);
2685
        tcg_gen_shri_tl(t0, t1, 32);
2686
        tcg_gen_shli_tl(t1, t1, 32);
2687
        tcg_gen_or_tl(t0, t0, t1);
2688
        break;
2689
#endif
2690
    default:
2691
        MIPS_INVAL("bsfhl");
2692
        generate_exception(ctx, EXCP_RI);
2693
        tcg_temp_free(t0);
2694
        tcg_temp_free(t1);
2695
        return;
2696
    }
2697
    gen_store_gpr(t0, rd);
2698
    tcg_temp_free(t0);
2699
    tcg_temp_free(t1);
2700
}
2701

    
2702
#ifndef CONFIG_USER_ONLY
2703
/* CP0 (MMU and control) */
2704
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2705
{
2706
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2707

    
2708
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2709
    tcg_gen_ext_i32_tl(t, r_tmp);
2710
    tcg_temp_free_i32(r_tmp);
2711
}
2712

    
2713
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2714
{
2715
    tcg_gen_ld_tl(t, cpu_env, off);
2716
    tcg_gen_ext32s_tl(t, t);
2717
}
2718

    
2719
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2720
{
2721
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2722

    
2723
    tcg_gen_trunc_tl_i32(r_tmp, t);
2724
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2725
    tcg_temp_free_i32(r_tmp);
2726
}
2727

    
2728
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2729
{
2730
    tcg_gen_ext32s_tl(t, t);
2731
    tcg_gen_st_tl(t, cpu_env, off);
2732
}
2733

    
2734
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2735
{
2736
    const char *rn = "invalid";
2737

    
2738
    if (sel != 0)
2739
        check_insn(env, ctx, ISA_MIPS32);
2740

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

    
3311
die:
3312
#if defined MIPS_DEBUG_DISAS
3313
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3314
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3315
                rn, reg, sel);
3316
    }
3317
#endif
3318
    generate_exception(ctx, EXCP_RI);
3319
}
3320

    
3321
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3322
{
3323
    const char *rn = "invalid";
3324

    
3325
    if (sel != 0)
3326
        check_insn(env, ctx, ISA_MIPS32);
3327

    
3328
    if (use_icount)
3329
        gen_io_start();
3330

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

    
3920
die:
3921
#if defined MIPS_DEBUG_DISAS
3922
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3923
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3924
                rn, reg, sel);
3925
    }
3926
#endif
3927
    generate_exception(ctx, EXCP_RI);
3928
}
3929

    
3930
#if defined(TARGET_MIPS64)
3931
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3932
{
3933
    const char *rn = "invalid";
3934

    
3935
    if (sel != 0)
3936
        check_insn(env, ctx, ISA_MIPS64);
3937

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

    
4497
die:
4498
#if defined MIPS_DEBUG_DISAS
4499
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4500
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4501
                rn, reg, sel);
4502
    }
4503
#endif
4504
    generate_exception(ctx, EXCP_RI);
4505
}
4506

    
4507
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4508
{
4509
    const char *rn = "invalid";
4510

    
4511
    if (sel != 0)
4512
        check_insn(env, ctx, ISA_MIPS64);
4513

    
4514
    if (use_icount)
4515
        gen_io_start();
4516

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

    
5093
die:
5094
#if defined MIPS_DEBUG_DISAS
5095
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5096
        fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
5097
                rn, reg, sel);
5098
    }
5099
#endif
5100
    generate_exception(ctx, EXCP_RI);
5101
}
5102
#endif /* TARGET_MIPS64 */
5103

    
5104
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5105
                     int u, int sel, int h)
5106
{
5107
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5108
    TCGv t0 = tcg_temp_local_new();
5109

    
5110
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5111
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5112
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5113
        tcg_gen_movi_tl(t0, -1);
5114
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5115
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5116
        tcg_gen_movi_tl(t0, -1);
5117
    else if (u == 0) {
5118
        switch (rt) {
5119
        case 2:
5120
            switch (sel) {
5121
            case 1:
5122
                gen_helper_mftc0_tcstatus(t0);
5123
                break;
5124
            case 2:
5125
                gen_helper_mftc0_tcbind(t0);
5126
                break;
5127
            case 3:
5128
                gen_helper_mftc0_tcrestart(t0);
5129
                break;
5130
            case 4:
5131
                gen_helper_mftc0_tchalt(t0);
5132
                break;
5133
            case 5:
5134
                gen_helper_mftc0_tccontext(t0);
5135
                break;
5136
            case 6:
5137
                gen_helper_mftc0_tcschedule(t0);
5138
                break;
5139
            case 7:
5140
                gen_helper_mftc0_tcschefback(t0);
5141
                break;
5142
            default:
5143
                gen_mfc0(env, ctx, t0, rt, sel);
5144
                break;
5145
            }
5146
            break;
5147
        case 10:
5148
            switch (sel) {
5149
            case 0:
5150
                gen_helper_mftc0_entryhi(t0);
5151
                break;
5152
            default:
5153
                gen_mfc0(env, ctx, t0, rt, sel);
5154
                break;
5155
            }
5156
        case 12:
5157
            switch (sel) {
5158
            case 0:
5159
                gen_helper_mftc0_status(t0);
5160
                break;
5161
            default:
5162
                gen_mfc0(env, ctx, t0, rt, sel);
5163
                break;
5164
            }
5165
        case 23:
5166
            switch (sel) {
5167
            case 0:
5168
                gen_helper_mftc0_debug(t0);
5169
                break;
5170
            default:
5171
                gen_mfc0(env, ctx, t0, rt, sel);
5172
                break;
5173
            }
5174
            break;
5175
        default:
5176
            gen_mfc0(env, ctx, t0, rt, sel);
5177
        }
5178
    } else switch (sel) {
5179
    /* GPR registers. */
5180
    case 0:
5181
        gen_helper_1i(mftgpr, t0, rt);
5182
        break;
5183
    /* Auxiliary CPU registers */
5184
    case 1:
5185
        switch (rt) {
5186
        case 0:
5187
            gen_helper_1i(mftlo, t0, 0);
5188
            break;
5189
        case 1:
5190
            gen_helper_1i(mfthi, t0, 0);
5191
            break;
5192
        case 2:
5193
            gen_helper_1i(mftacx, t0, 0);
5194
            break;
5195
        case 4:
5196
            gen_helper_1i(mftlo, t0, 1);
5197
            break;
5198
        case 5:
5199
            gen_helper_1i(mfthi, t0, 1);
5200
            break;
5201
        case 6:
5202
            gen_helper_1i(mftacx, t0, 1);
5203
            break;
5204
        case 8:
5205
            gen_helper_1i(mftlo, t0, 2);
5206
            break;
5207
        case 9:
5208
            gen_helper_1i(mfthi, t0, 2);
5209
            break;
5210
        case 10:
5211
            gen_helper_1i(mftacx, t0, 2);
5212
            break;
5213
        case 12:
5214
            gen_helper_1i(mftlo, t0, 3);
5215
            break;
5216
        case 13:
5217
            gen_helper_1i(mfthi, t0, 3);
5218
            break;
5219
        case 14:
5220
            gen_helper_1i(mftacx, t0, 3);
5221
            break;
5222
        case 16:
5223
            gen_helper_mftdsp(t0);
5224
            break;
5225
        default:
5226
            goto die;
5227
        }
5228
        break;
5229
    /* Floating point (COP1). */
5230
    case 2:
5231
        /* XXX: For now we support only a single FPU context. */
5232
        if (h == 0) {
5233
            TCGv_i32 fp0 = tcg_temp_new_i32();
5234

    
5235
            gen_load_fpr32(fp0, rt);
5236
            tcg_gen_ext_i32_tl(t0, fp0);
5237
            tcg_temp_free_i32(fp0);
5238
        } else {
5239
            TCGv_i32 fp0 = tcg_temp_new_i32();
5240

    
5241
            gen_load_fpr32h(fp0, rt);
5242
            tcg_gen_ext_i32_tl(t0, fp0);
5243
            tcg_temp_free_i32(fp0);
5244
        }
5245
        break;
5246
    case 3:
5247
        /* XXX: For now we support only a single FPU context. */
5248
        gen_helper_1i(cfc1, t0, rt);
5249
        break;
5250
    /* COP2: Not implemented. */
5251
    case 4:
5252
    case 5:
5253
        /* fall through */
5254
    default:
5255
        goto die;
5256
    }
5257
#if defined MIPS_DEBUG_DISAS
5258
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5259
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5260
                rt, u, sel, h);
5261
    }
5262
#endif
5263
    gen_store_gpr(t0, rd);
5264
    tcg_temp_free(t0);
5265
    return;
5266

    
5267
die:
5268
    tcg_temp_free(t0);
5269
#if defined MIPS_DEBUG_DISAS
5270
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5271
        fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
5272
                rt, u, sel, h);
5273
    }
5274
#endif
5275
    generate_exception(ctx, EXCP_RI);
5276
}
5277

    
5278
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5279
                     int u, int sel, int h)
5280
{
5281
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5282
    TCGv t0 = tcg_temp_local_new();
5283

    
5284
    gen_load_gpr(t0, rt);
5285
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5286
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5287
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5288
        /* NOP */ ;
5289
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5290
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5291
        /* NOP */ ;
5292
    else if (u == 0) {
5293
        switch (rd) {
5294
        case 2:
5295
            switch (sel) {
5296
            case 1:
5297
                gen_helper_mttc0_tcstatus(t0);
5298
                break;
5299
            case 2:
5300
                gen_helper_mttc0_tcbind(t0);
5301
                break;
5302
            case 3:
5303
                gen_helper_mttc0_tcrestart(t0);
5304
                break;
5305
            case 4:
5306
                gen_helper_mttc0_tchalt(t0);
5307
                break;
5308
            case 5:
5309
                gen_helper_mttc0_tccontext(t0);
5310
                break;
5311
            case 6:
5312
                gen_helper_mttc0_tcschedule(t0);
5313
                break;
5314
            case 7:
5315
                gen_helper_mttc0_tcschefback(t0);
5316
                break;
5317
            default:
5318
                gen_mtc0(env, ctx, t0, rd, sel);
5319
                break;
5320
            }
5321
            break;
5322
        case 10:
5323
            switch (sel) {
5324
            case 0:
5325
                gen_helper_mttc0_entryhi(t0);
5326
                break;
5327
            default:
5328
                gen_mtc0(env, ctx, t0, rd, sel);
5329
                break;
5330
            }
5331
        case 12:
5332
            switch (sel) {
5333
            case 0:
5334
                gen_helper_mttc0_status(t0);
5335
                break;
5336
            default:
5337
                gen_mtc0(env, ctx, t0, rd, sel);
5338
                break;
5339
            }
5340
        case 23:
5341
            switch (sel) {
5342
            case 0:
5343
                gen_helper_mttc0_debug(t0);
5344
                break;
5345
            default:
5346
                gen_mtc0(env, ctx, t0, rd, sel);
5347
                break;
5348
            }
5349
            break;
5350
        default:
5351
            gen_mtc0(env, ctx, t0, rd, sel);
5352
        }
5353
    } else switch (sel) {
5354
    /* GPR registers. */
5355
    case 0:
5356
        gen_helper_1i(mttgpr, t0, rd);
5357
        break;
5358
    /* Auxiliary CPU registers */
5359
    case 1:
5360
        switch (rd) {
5361
        case 0:
5362
            gen_helper_1i(mttlo, t0, 0);
5363
            break;
5364
        case 1:
5365
            gen_helper_1i(mtthi, t0, 0);
5366
            break;
5367
        case 2:
5368
            gen_helper_1i(mttacx, t0, 0);
5369
            break;
5370
        case 4:
5371
            gen_helper_1i(mttlo, t0, 1);
5372
            break;
5373
        case 5:
5374
            gen_helper_1i(mtthi, t0, 1);
5375
            break;
5376
        case 6:
5377
            gen_helper_1i(mttacx, t0, 1);
5378
            break;
5379
        case 8:
5380
            gen_helper_1i(mttlo, t0, 2);
5381
            break;
5382
        case 9:
5383
            gen_helper_1i(mtthi, t0, 2);
5384
            break;
5385
        case 10:
5386
            gen_helper_1i(mttacx, t0, 2);
5387
            break;
5388
        case 12:
5389
            gen_helper_1i(mttlo, t0, 3);
5390
            break;
5391
        case 13:
5392
            gen_helper_1i(mtthi, t0, 3);
5393
            break;
5394
        case 14:
5395
            gen_helper_1i(mttacx, t0, 3);
5396
            break;
5397
        case 16:
5398
            gen_helper_mttdsp(t0);
5399
            break;
5400
        default:
5401
            goto die;
5402
        }
5403
        break;
5404
    /* Floating point (COP1). */
5405
    case 2:
5406
        /* XXX: For now we support only a single FPU context. */
5407
        if (h == 0) {
5408
            TCGv_i32 fp0 = tcg_temp_new_i32();
5409

    
5410
            tcg_gen_trunc_tl_i32(fp0, t0);
5411
            gen_store_fpr32(fp0, rd);
5412
            tcg_temp_free_i32(fp0);
5413
        } else {
5414
            TCGv_i32 fp0 = tcg_temp_new_i32();
5415

    
5416
            tcg_gen_trunc_tl_i32(fp0, t0);
5417
            gen_store_fpr32h(fp0, rd);
5418
            tcg_temp_free_i32(fp0);
5419
        }
5420
        break;
5421
    case 3:
5422
        /* XXX: For now we support only a single FPU context. */
5423
        gen_helper_1i(ctc1, t0, rd);
5424
        break;
5425
    /* COP2: Not implemented. */
5426
    case 4:
5427
    case 5:
5428
        /* fall through */
5429
    default:
5430
        goto die;
5431
    }
5432
#if defined MIPS_DEBUG_DISAS
5433
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5434
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5435
                rd, u, sel, h);
5436
    }
5437
#endif
5438
    tcg_temp_free(t0);
5439
    return;
5440

    
5441
die:
5442
    tcg_temp_free(t0);
5443
#if defined MIPS_DEBUG_DISAS
5444
    if (loglevel & CPU_LOG_TB_IN_ASM) {
5445
        fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
5446
                rd, u, sel, h);
5447
    }
5448
#endif
5449
    generate_exception(ctx, EXCP_RI);
5450
}
5451

    
5452
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5453
{
5454
    const char *opn = "ldst";
5455

    
5456
    switch (opc) {
5457
    case OPC_MFC0:
5458
        if (rt == 0) {
5459
            /* Treat as NOP. */
5460
            return;
5461
        }
5462
        {
5463
            TCGv t0 = tcg_temp_local_new();
5464

    
5465
            gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5466
            gen_store_gpr(t0, rt);
5467
            tcg_temp_free(t0);
5468
        }
5469
        opn = "mfc0";
5470
        break;
5471
    case OPC_MTC0:
5472
        {
5473
            TCGv t0 = tcg_temp_local_new();
5474

    
5475
            gen_load_gpr(t0, rt);
5476
            save_cpu_state(ctx, 1);
5477
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5478
            tcg_temp_free(t0);
5479
        }
5480
        opn = "mtc0";
5481
        break;
5482
#if defined(TARGET_MIPS64)
5483
    case OPC_DMFC0:
5484
        check_insn(env, ctx, ISA_MIPS3);
5485
        if (rt == 0) {
5486
            /* Treat as NOP. */
5487
            return;
5488
        }
5489
        {
5490
            TCGv t0 = tcg_temp_local_new();
5491

    
5492
            gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5493
            gen_store_gpr(t0, rt);
5494
            tcg_temp_free(t0);
5495
        }
5496
        opn = "dmfc0";
5497
        break;
5498
    case OPC_DMTC0:
5499
        check_insn(env, ctx, ISA_MIPS3);
5500
        {
5501
            TCGv t0 = tcg_temp_local_new();
5502

    
5503
            gen_load_gpr(t0, rt);
5504
            save_cpu_state(ctx, 1);
5505
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5506
            tcg_temp_free(t0);
5507
        }
5508
        opn = "dmtc0";
5509
        break;
5510
#endif
5511
    case OPC_MFTR:
5512
        check_insn(env, ctx, ASE_MT);
5513
        if (rd == 0) {
5514
            /* Treat as NOP. */
5515
            return;
5516
        }
5517
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5518
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5519
        opn = "mftr";
5520
        break;
5521
    case OPC_MTTR:
5522
        check_insn(env, ctx, ASE_MT);
5523
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5524
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5525
        opn = "mttr";
5526
        break;
5527
    case OPC_TLBWI:
5528
        opn = "tlbwi";
5529
        if (!env->tlb->do_tlbwi)
5530
            goto die;
5531
        gen_helper_tlbwi();
5532
        break;
5533
    case OPC_TLBWR:
5534
        opn = "tlbwr";
5535
        if (!env->tlb->do_tlbwr)
5536
            goto die;
5537
        gen_helper_tlbwr();
5538
        break;
5539
    case OPC_TLBP:
5540
        opn = "tlbp";
5541
        if (!env->tlb->do_tlbp)
5542
            goto die;
5543
        gen_helper_tlbp();
5544
        break;
5545
    case OPC_TLBR:
5546
        opn = "tlbr";
5547
        if (!env->tlb->do_tlbr)
5548
            goto die;
5549
        gen_helper_tlbr();
5550
        break;
5551
    case OPC_ERET:
5552
        opn = "eret";
5553
        check_insn(env, ctx, ISA_MIPS2);
5554
        save_cpu_state(ctx, 1);
5555
        gen_helper_eret();
5556
        ctx->bstate = BS_EXCP;
5557
        break;
5558
    case OPC_DERET:
5559
        opn = "deret";
5560
        check_insn(env, ctx, ISA_MIPS32);
5561
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5562
            MIPS_INVAL(opn);
5563
            generate_exception(ctx, EXCP_RI);
5564
        } else {
5565
            save_cpu_state(ctx, 1);
5566
            gen_helper_deret();
5567
            ctx->bstate = BS_EXCP;
5568
        }
5569
        break;
5570
    case OPC_WAIT:
5571
        opn = "wait";
5572
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5573
        /* If we get an exception, we want to restart at next instruction */
5574
        ctx->pc += 4;
5575
        save_cpu_state(ctx, 1);
5576
        ctx->pc -= 4;
5577
        gen_helper_wait();
5578
        ctx->bstate = BS_EXCP;
5579
        break;
5580
    default:
5581
 die:
5582
        MIPS_INVAL(opn);
5583
        generate_exception(ctx, EXCP_RI);
5584
        return;
5585
    }
5586
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5587
}
5588
#endif /* !CONFIG_USER_ONLY */
5589

    
5590
/* CP1 Branches (before delay slot) */
5591
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5592
                                 int32_t cc, int32_t offset)
5593
{
5594
    target_ulong btarget;
5595
    const char *opn = "cp1 cond branch";
5596
    TCGv_i32 t0 = tcg_temp_new_i32();
5597

    
5598
    if (cc != 0)
5599
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5600

    
5601
    btarget = ctx->pc + 4 + offset;
5602

    
5603
    switch (op) {
5604
    case OPC_BC1F:
5605
        {
5606
            int l1 = gen_new_label();
5607
            int l2 = gen_new_label();
5608

    
5609
            get_fp_cond(t0);
5610
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5611
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5612
            tcg_gen_movi_i32(bcond, 0);
5613
            tcg_gen_br(l2);
5614
            gen_set_label(l1);
5615
            tcg_gen_movi_i32(bcond, 1);
5616
            gen_set_label(l2);
5617
        }
5618
        opn = "bc1f";
5619
        goto not_likely;
5620
    case OPC_BC1FL:
5621
        {
5622
            int l1 = gen_new_label();
5623
            int l2 = gen_new_label();
5624

    
5625
            get_fp_cond(t0);
5626
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5627
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5628
            tcg_gen_movi_i32(bcond, 0);
5629
            tcg_gen_br(l2);
5630
            gen_set_label(l1);
5631
            tcg_gen_movi_i32(bcond, 1);
5632
            gen_set_label(l2);
5633
        }
5634
        opn = "bc1fl";
5635
        goto likely;
5636
    case OPC_BC1T:
5637
        {
5638
            int l1 = gen_new_label();
5639
            int l2 = gen_new_label();
5640

    
5641
            get_fp_cond(t0);
5642
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5643
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5644
            tcg_gen_movi_i32(bcond, 0);
5645
            tcg_gen_br(l2);
5646
            gen_set_label(l1);
5647
            tcg_gen_movi_i32(bcond, 1);
5648
            gen_set_label(l2);
5649
        }
5650
        opn = "bc1t";
5651
        goto not_likely;
5652
    case OPC_BC1TL:
5653
        {
5654
            int l1 = gen_new_label();
5655
            int l2 = gen_new_label();
5656

    
5657
            get_fp_cond(t0);
5658
            tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5659
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5660
            tcg_gen_movi_i32(bcond, 0);
5661
            tcg_gen_br(l2);
5662
            gen_set_label(l1);
5663
            tcg_gen_movi_i32(bcond, 1);
5664
            gen_set_label(l2);
5665
        }
5666
        opn = "bc1tl";
5667
    likely:
5668
        ctx->hflags |= MIPS_HFLAG_BL;
5669
        break;
5670
    case OPC_BC1FANY2:
5671
        {
5672
            int l1 = gen_new_label();
5673
            int l2 = gen_new_label();
5674

    
5675
            get_fp_cond(t0);
5676
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5677
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5678
            tcg_gen_movi_i32(bcond, 0);
5679
            tcg_gen_br(l2);
5680
            gen_set_label(l1);
5681
            tcg_gen_movi_i32(bcond, 1);
5682
            gen_set_label(l2);
5683
        }
5684
        opn = "bc1any2f";
5685
        goto not_likely;
5686
    case OPC_BC1TANY2:
5687
        {
5688
            int l1 = gen_new_label();
5689
            int l2 = gen_new_label();
5690

    
5691
            get_fp_cond(t0);
5692
            tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5693
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5694
            tcg_gen_movi_i32(bcond, 0);
5695
            tcg_gen_br(l2);
5696
            gen_set_label(l1);
5697
            tcg_gen_movi_i32(bcond, 1);
5698
            gen_set_label(l2);
5699
        }
5700
        opn = "bc1any2t";
5701
        goto not_likely;
5702
    case OPC_BC1FANY4:
5703
        {
5704
            int l1 = gen_new_label();
5705
            int l2 = gen_new_label();
5706

    
5707
            get_fp_cond(t0);
5708
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5709
            tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5710
            tcg_gen_movi_i32(bcond, 0);
5711
            tcg_gen_br(l2);
5712
            gen_set_label(l1);
5713
            tcg_gen_movi_i32(bcond, 1);
5714
            gen_set_label(l2);
5715
        }
5716
        opn = "bc1any4f";
5717
        goto not_likely;
5718
    case OPC_BC1TANY4:
5719
        {
5720
            int l1 = gen_new_label();
5721
            int l2 = gen_new_label();
5722

    
5723
            get_fp_cond(t0);
5724
            tcg_gen_andi_i32(t0, t0, 0xf << cc);
5725
            tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5726
            tcg_gen_movi_i32(bcond, 0);
5727
            tcg_gen_br(l2);
5728
            gen_set_label(l1);
5729
            tcg_gen_movi_i32(bcond, 1);
5730
            gen_set_label(l2);
5731
        }
5732
        opn = "bc1any4t";
5733
    not_likely:
5734
        ctx->hflags |= MIPS_HFLAG_BC;
5735
        break;
5736
    default:
5737
        MIPS_INVAL(opn);
5738
        generate_exception (ctx, EXCP_RI);
5739
        goto out;
5740
    }
5741
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5742
               ctx->hflags, btarget);
5743
    ctx->btarget = btarget;
5744

    
5745
 out:
5746
    tcg_temp_free_i32(t0);
5747
}
5748

    
5749
/* Coprocessor 1 (FPU) */
5750

    
5751
#define FOP(func, fmt) (((fmt) << 21) | (func))
5752

    
5753
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5754
{
5755
    const char *opn = "cp1 move";
5756
    TCGv t0 = tcg_temp_local_new();
5757

    
5758
    switch (opc) {
5759
    case OPC_MFC1:
5760
        {
5761
            TCGv_i32 fp0 = tcg_temp_new_i32();
5762

    
5763
            gen_load_fpr32(fp0, fs);
5764
            tcg_gen_ext_i32_tl(t0, fp0);
5765
            tcg_temp_free_i32(fp0);
5766
        }
5767
        gen_store_gpr(t0, rt);
5768
        opn = "mfc1";
5769
        break;
5770
    case OPC_MTC1:
5771
        gen_load_gpr(t0, rt);
5772
        {
5773
            TCGv_i32 fp0 = tcg_temp_new_i32();
5774

    
5775
            tcg_gen_trunc_tl_i32(fp0, t0);
5776
            gen_store_fpr32(fp0, fs);
5777
            tcg_temp_free_i32(fp0);
5778
        }
5779
        opn = "mtc1";
5780
        break;
5781
    case OPC_CFC1:
5782
        gen_helper_1i(cfc1, t0, fs);
5783
        gen_store_gpr(t0, rt);
5784
        opn = "cfc1";
5785
        break;
5786
    case OPC_CTC1:
5787
        gen_load_gpr(t0, rt);
5788
        gen_helper_1i(ctc1, t0, fs);
5789
        opn = "ctc1";
5790
        break;
5791
    case OPC_DMFC1:
5792
        {
5793
            TCGv_i64 fp0 = tcg_temp_new_i64();
5794

    
5795
            gen_load_fpr64(ctx, fp0, fs);
5796
            tcg_gen_trunc_i64_tl(t0, fp0);
5797
            tcg_temp_free_i64(fp0);
5798
        }
5799
        gen_store_gpr(t0, rt);
5800
        opn = "dmfc1";
5801
        break;
5802
    case OPC_DMTC1:
5803
        gen_load_gpr(t0, rt);
5804
        {
5805
            TCGv_i64 fp0 = tcg_temp_new_i64();
5806

    
5807
            tcg_gen_extu_tl_i64(fp0, t0);
5808
            gen_store_fpr64(ctx, fp0, fs);
5809
            tcg_temp_free_i64(fp0);
5810
        }
5811
        opn = "dmtc1";
5812
        break;
5813
    case OPC_MFHC1:
5814
        {
5815
            TCGv_i32 fp0 = tcg_temp_new_i32();
5816

    
5817
            gen_load_fpr32h(fp0, fs);
5818
            tcg_gen_ext_i32_tl(t0, fp0);
5819
            tcg_temp_free_i32(fp0);
5820
        }
5821
        gen_store_gpr(t0, rt);
5822
        opn = "mfhc1";
5823
        break;
5824
    case OPC_MTHC1:
5825
        gen_load_gpr(t0, rt);
5826
        {
5827
            TCGv_i32 fp0 = tcg_temp_new_i32();
5828

    
5829
            tcg_gen_trunc_tl_i32(fp0, t0);
5830
            gen_store_fpr32h(fp0, fs);
5831
            tcg_temp_free_i32(fp0);
5832
        }
5833
        opn = "mthc1";
5834
        break;
5835
    default:
5836
        MIPS_INVAL(opn);
5837
        generate_exception (ctx, EXCP_RI);
5838
        goto out;
5839
    }
5840
    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5841

    
5842
 out:
5843
    tcg_temp_free(t0);
5844
}
5845

    
5846
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5847
{
5848
    int l1 = gen_new_label();
5849
    uint32_t ccbit;
5850
    TCGCond cond;
5851
    TCGv t0 = tcg_temp_local_new();
5852
    TCGv_i32 r_tmp = tcg_temp_new_i32();
5853

    
5854
    if (cc)
5855
        ccbit = 1 << (24 + cc);
5856
    else
5857
        ccbit = 1 << 23;
5858
    if (tf)
5859
        cond = TCG_COND_EQ;
5860
    else
5861
        cond = TCG_COND_NE;
5862

    
5863
    gen_load_gpr(t0, rd);
5864
    tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5865
    tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5866
    tcg_temp_free_i32(r_tmp);
5867
    gen_load_gpr(t0, rs);
5868
    gen_set_label(l1);
5869
    gen_store_gpr(t0, rd);
5870
    tcg_temp_free(t0);
5871
}
5872

    
5873
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5874
{
5875
    uint32_t ccbit;
5876
    int cond;
5877
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5878
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5879
    int l1 = gen_new_label();
5880

    
5881
    if (cc)
5882
        ccbit = 1 << (24 + cc);
5883
    else
5884
        ccbit = 1 << 23;
5885

    
5886
    if (tf)
5887
        cond = TCG_COND_EQ;
5888
    else
5889
        cond = TCG_COND_NE;
5890

    
5891
    gen_load_fpr32(fp0, fd);
5892
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5893
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5894
    tcg_temp_free_i32(r_tmp1);
5895
    gen_load_fpr32(fp0, fs);
5896
    gen_set_label(l1);
5897
    gen_store_fpr32(fp0, fd);
5898
    tcg_temp_free_i32(fp0);
5899
}
5900

    
5901
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5902
{
5903
    uint32_t ccbit;
5904
    int cond;
5905
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5906
    TCGv_i64 fp0 = tcg_temp_local_new_i64();
5907
    int l1 = gen_new_label();
5908

    
5909
    if (cc)
5910
        ccbit = 1 << (24 + cc);
5911
    else
5912
        ccbit = 1 << 23;
5913

    
5914
    if (tf)
5915
        cond = TCG_COND_EQ;
5916
    else
5917
        cond = TCG_COND_NE;
5918

    
5919
    gen_load_fpr64(ctx, fp0, fd);
5920
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5921
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5922
    tcg_temp_free_i32(r_tmp1);
5923
    gen_load_fpr64(ctx, fp0, fs);
5924
    gen_set_label(l1);
5925
    gen_store_fpr64(ctx, fp0, fd);
5926
    tcg_temp_free_i64(fp0);
5927
}
5928

    
5929
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5930
{
5931
    uint32_t ccbit1, ccbit2;
5932
    int cond;
5933
    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5934
    TCGv_i32 fp0 = tcg_temp_local_new_i32();
5935
    int l1 = gen_new_label();
5936
    int l2 = gen_new_label();
5937

    
5938
    if (cc) {
5939
        ccbit1 = 1 << (24 + cc);
5940
        ccbit2 = 1 << (25 + cc);
5941
    } else {
5942
        ccbit1 = 1 << 23;
5943
        ccbit2 = 1 << 25;
5944
    }
5945

    
5946
    if (tf)
5947
        cond = TCG_COND_EQ;
5948
    else
5949
        cond = TCG_COND_NE;
5950

    
5951
    gen_load_fpr32(fp0, fd);
5952
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5953
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5954
    gen_load_fpr32(fp0, fs);
5955
    gen_set_label(l1);
5956
    gen_store_fpr32(fp0, fd);
5957

    
5958
    gen_load_fpr32h(fp0, fd);
5959
    tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5960
    tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5961
    gen_load_fpr32h(fp0, fs);
5962
    gen_set_label(l2);
5963
    gen_store_fpr32h(fp0, fd);
5964

    
5965
    tcg_temp_free_i32(r_tmp1);
5966
    tcg_temp_free_i32(fp0);
5967
}
5968

    
5969

    
5970
static void gen_farith (DisasContext *ctx, uint32_t op1,
5971
                        int ft, int fs, int fd, int cc)
5972
{
5973
    const char *opn = "farith";
5974
    const char *condnames[] = {
5975
            "c.f",
5976
            "c.un",
5977
            "c.eq",
5978
            "c.ueq",
5979
            "c.olt",
5980
            "c.ult",
5981
            "c.ole",
5982
            "c.ule",
5983
            "c.sf",
5984
            "c.ngle",
5985
            "c.seq",
5986
            "c.ngl",
5987
            "c.lt",
5988
            "c.nge",
5989
            "c.le",
5990
            "c.ngt",
5991
    };
5992
    const char *condnames_abs[] = {
5993
            "cabs.f",
5994
            "cabs.un",
5995
            "cabs.eq",
5996
            "cabs.ueq",
5997
            "cabs.olt",
5998
            "cabs.ult",
5999
            "cabs.ole",
6000
            "cabs.ule",
6001
            "cabs.sf",
6002
            "cabs.ngle",
6003
            "cabs.seq",
6004
            "cabs.ngl",
6005
            "cabs.lt",
6006
            "cabs.nge",
6007
            "cabs.le",
6008
            "cabs.ngt",
6009
    };
6010
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6011
    uint32_t func = ctx->opcode & 0x3f;
6012

    
6013
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6014
    case FOP(0, 16):
6015
        {
6016
            TCGv_i32 fp0 = tcg_temp_new_i32();
6017
            TCGv_i32 fp1 = tcg_temp_new_i32();
6018

    
6019
            gen_load_fpr32(fp0, fs);
6020
            gen_load_fpr32(fp1, ft);
6021
            gen_helper_float_add_s(fp0, fp0, fp1);
6022
            tcg_temp_free_i32(fp1);
6023
            gen_store_fpr32(fp0, fd);
6024
            tcg_temp_free_i32(fp0);
6025
        }
6026
        opn = "add.s";
6027
        optype = BINOP;
6028
        break;
6029
    case FOP(1, 16):
6030
        {
6031
            TCGv_i32 fp0 = tcg_temp_new_i32();
6032
            TCGv_i32 fp1 = tcg_temp_new_i32();
6033

    
6034
            gen_load_fpr32(fp0, fs);
6035
            gen_load_fpr32(fp1, ft);
6036
            gen_helper_float_sub_s(fp0, fp0, fp1);
6037
            tcg_temp_free_i32(fp1);
6038
            gen_store_fpr32(fp0, fd);
6039
            tcg_temp_free_i32(fp0);
6040
        }
6041
        opn = "sub.s";
6042
        optype = BINOP;
6043
        break;
6044
    case FOP(2, 16):
6045
        {
6046
            TCGv_i32 fp0 = tcg_temp_new_i32();
6047
            TCGv_i32 fp1 = tcg_temp_new_i32();
6048

    
6049
            gen_load_fpr32(fp0, fs);
6050
            gen_load_fpr32(fp1, ft);
6051
            gen_helper_float_mul_s(fp0, fp0, fp1);
6052
            tcg_temp_free_i32(fp1);
6053
            gen_store_fpr32(fp0, fd);
6054
            tcg_temp_free_i32(fp0);
6055
        }
6056
        opn = "mul.s";
6057
        optype = BINOP;
6058
        break;
6059
    case FOP(3, 16):
6060
        {
6061
            TCGv_i32 fp0 = tcg_temp_new_i32();
6062
            TCGv_i32 fp1 = tcg_temp_new_i32();
6063

    
6064
            gen_load_fpr32(fp0, fs);
6065
            gen_load_fpr32(fp1, ft);
6066
            gen_helper_float_div_s(fp0, fp0, fp1);
6067
            tcg_temp_free_i32(fp1);
6068
            gen_store_fpr32(fp0, fd);
6069
            tcg_temp_free_i32(fp0);
6070
        }
6071
        opn = "div.s";
6072
        optype = BINOP;
6073
        break;
6074
    case FOP(4, 16):
6075
        {
6076
            TCGv_i32 fp0 = tcg_temp_new_i32();
6077

    
6078
            gen_load_fpr32(fp0, fs);
6079
            gen_helper_float_sqrt_s(fp0, fp0);
6080
            gen_store_fpr32(fp0, fd);
6081
            tcg_temp_free_i32(fp0);
6082
        }
6083
        opn = "sqrt.s";
6084
        break;
6085
    case FOP(5, 16):
6086
        {
6087
            TCGv_i32 fp0 = tcg_temp_new_i32();
6088

    
6089
            gen_load_fpr32(fp0, fs);
6090
            gen_helper_float_abs_s(fp0, fp0);
6091
            gen_store_fpr32(fp0, fd);
6092
            tcg_temp_free_i32(fp0);
6093
        }
6094
        opn = "abs.s";
6095
        break;
6096
    case FOP(6, 16):
6097
        {
6098
            TCGv_i32 fp0 = tcg_temp_new_i32();
6099

    
6100
            gen_load_fpr32(fp0, fs);
6101
            gen_store_fpr32(fp0, fd);
6102
            tcg_temp_free_i32(fp0);
6103
        }
6104
        opn = "mov.s";
6105
        break;
6106
    case FOP(7, 16):
6107
        {
6108
            TCGv_i32 fp0 = tcg_temp_new_i32();
6109

    
6110
            gen_load_fpr32(fp0, fs);
6111
            gen_helper_float_chs_s(fp0, fp0);
6112
            gen_store_fpr32(fp0, fd);
6113
            tcg_temp_free_i32(fp0);
6114
        }
6115
        opn = "neg.s";
6116
        break;
6117
    case FOP(8, 16):
6118
        check_cp1_64bitmode(ctx);
6119
        {
6120
            TCGv_i32 fp32 = tcg_temp_new_i32();
6121
            TCGv_i64 fp64 = tcg_temp_new_i64();
6122

    
6123
            gen_load_fpr32(fp32, fs);
6124
            gen_helper_float_roundl_s(fp64, fp32);
6125
            tcg_temp_free_i32(fp32);
6126
            gen_store_fpr64(ctx, fp64, fd);
6127
            tcg_temp_free_i64(fp64);
6128
        }
6129
        opn = "round.l.s";
6130
        break;
6131
    case FOP(9, 16):
6132
        check_cp1_64bitmode(ctx);
6133
        {
6134
            TCGv_i32 fp32 = tcg_temp_new_i32();
6135
            TCGv_i64 fp64 = tcg_temp_new_i64();
6136

    
6137
            gen_load_fpr32(fp32, fs);
6138
            gen_helper_float_truncl_s(fp64, fp32);
6139
            tcg_temp_free_i32(fp32);
6140
            gen_store_fpr64(ctx, fp64, fd);
6141
            tcg_temp_free_i64(fp64);
6142
        }
6143
        opn = "trunc.l.s";
6144
        break;
6145
    case FOP(10, 16):
6146
        check_cp1_64bitmode(ctx);
6147
        {
6148
            TCGv_i32 fp32 = tcg_temp_new_i32();
6149
            TCGv_i64 fp64 = tcg_temp_new_i64();
6150

    
6151
            gen_load_fpr32(fp32, fs);
6152
            gen_helper_float_ceill_s(fp64, fp32);
6153
            tcg_temp_free_i32(fp32);
6154
            gen_store_fpr64(ctx, fp64, fd);
6155
            tcg_temp_free_i64(fp64);
6156
        }
6157
        opn = "ceil.l.s";
6158
        break;
6159
    case FOP(11, 16):
6160
        check_cp1_64bitmode(ctx);
6161
        {
6162
            TCGv_i32 fp32 = tcg_temp_new_i32();
6163
            TCGv_i64 fp64 = tcg_temp_new_i64();
6164

    
6165
            gen_load_fpr32(fp32, fs);
6166
            gen_helper_float_floorl_s(fp64, fp32);
6167
            tcg_temp_free_i32(fp32);
6168
            gen_store_fpr64(ctx, fp64, fd);
6169
            tcg_temp_free_i64(fp64);
6170
        }
6171
        opn = "floor.l.s";
6172
        break;
6173
    case FOP(12, 16):
6174
        {
6175
            TCGv_i32 fp0 = tcg_temp_new_i32();
6176

    
6177
            gen_load_fpr32(fp0, fs);
6178
            gen_helper_float_roundw_s(fp0, fp0);
6179
            gen_store_fpr32(fp0, fd);
6180
            tcg_temp_free_i32(fp0);
6181
        }
6182
        opn = "round.w.s";
6183
        break;
6184
    case FOP(13, 16):
6185
        {
6186
            TCGv_i32 fp0 = tcg_temp_new_i32();
6187

    
6188
            gen_load_fpr32(fp0, fs);
6189
            gen_helper_float_truncw_s(fp0, fp0);
6190
            gen_store_fpr32(fp0, fd);
6191
            tcg_temp_free_i32(fp0);
6192
        }
6193
        opn = "trunc.w.s";
6194
        break;
6195
    case FOP(14, 16):
6196
        {
6197
            TCGv_i32 fp0 = tcg_temp_new_i32();
6198

    
6199
            gen_load_fpr32(fp0, fs);
6200
            gen_helper_float_ceilw_s(fp0, fp0);
6201
            gen_store_fpr32(fp0, fd);
6202
            tcg_temp_free_i32(fp0);
6203
        }
6204
        opn = "ceil.w.s";
6205
        break;
6206
    case FOP(15, 16):
6207
        {
6208
            TCGv_i32 fp0 = tcg_temp_new_i32();
6209

    
6210
            gen_load_fpr32(fp0, fs);
6211
            gen_helper_float_floorw_s(fp0, fp0);
6212
            gen_store_fpr32(fp0, fd);
6213
            tcg_temp_free_i32(fp0);
6214
        }
6215
        opn = "floor.w.s";
6216
        break;
6217
    case FOP(17, 16):
6218
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6219
        opn = "movcf.s";
6220
        break;
6221
    case FOP(18, 16):
6222
        {
6223
            int l1 = gen_new_label();
6224
            TCGv t0 = tcg_temp_new();
6225
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6226

    
6227
            gen_load_gpr(t0, ft);
6228
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6229
            gen_load_fpr32(fp0, fs);
6230
            gen_store_fpr32(fp0, fd);
6231
            tcg_temp_free_i32(fp0);
6232
            gen_set_label(l1);
6233
            tcg_temp_free(t0);
6234
        }
6235
        opn = "movz.s";
6236
        break;
6237
    case FOP(19, 16):
6238
        {
6239
            int l1 = gen_new_label();
6240
            TCGv t0 = tcg_temp_new();
6241
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6242

    
6243
            gen_load_gpr(t0, ft);
6244
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6245
            gen_load_fpr32(fp0, fs);
6246
            gen_store_fpr32(fp0, fd);
6247
            tcg_temp_free_i32(fp0);
6248
            gen_set_label(l1);
6249
            tcg_temp_free(t0);
6250
        }
6251
        opn = "movn.s";
6252
        break;
6253
    case FOP(21, 16):
6254
        check_cop1x(ctx);
6255
        {
6256
            TCGv_i32 fp0 = tcg_temp_new_i32();
6257

    
6258
            gen_load_fpr32(fp0, fs);
6259
            gen_helper_float_recip_s(fp0, fp0);
6260
            gen_store_fpr32(fp0, fd);
6261
            tcg_temp_free_i32(fp0);
6262
        }
6263
        opn = "recip.s";
6264
        break;
6265
    case FOP(22, 16):
6266
        check_cop1x(ctx);
6267
        {
6268
            TCGv_i32 fp0 = tcg_temp_new_i32();
6269

    
6270
            gen_load_fpr32(fp0, fs);
6271
            gen_helper_float_rsqrt_s(fp0, fp0);
6272
            gen_store_fpr32(fp0, fd);
6273
            tcg_temp_free_i32(fp0);
6274
        }
6275
        opn = "rsqrt.s";
6276
        break;
6277
    case FOP(28, 16):
6278
        check_cp1_64bitmode(ctx);
6279
        {
6280
            TCGv_i32 fp0 = tcg_temp_new_i32();
6281
            TCGv_i32 fp1 = tcg_temp_new_i32();
6282

    
6283
            gen_load_fpr32(fp0, fs);
6284
            gen_load_fpr32(fp1, fd);
6285
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6286
            tcg_temp_free_i32(fp1);
6287
            gen_store_fpr32(fp0, fd);
6288
            tcg_temp_free_i32(fp0);
6289
        }
6290
        opn = "recip2.s";
6291
        break;
6292
    case FOP(29, 16):
6293
        check_cp1_64bitmode(ctx);
6294
        {
6295
            TCGv_i32 fp0 = tcg_temp_new_i32();
6296

    
6297
            gen_load_fpr32(fp0, fs);
6298
            gen_helper_float_recip1_s(fp0, fp0);
6299
            gen_store_fpr32(fp0, fd);
6300
            tcg_temp_free_i32(fp0);
6301
        }
6302
        opn = "recip1.s";
6303
        break;
6304
    case FOP(30, 16):
6305
        check_cp1_64bitmode(ctx);
6306
        {
6307
            TCGv_i32 fp0 = tcg_temp_new_i32();
6308

    
6309
            gen_load_fpr32(fp0, fs);
6310
            gen_helper_float_rsqrt1_s(fp0, fp0);
6311
            gen_store_fpr32(fp0, fd);
6312
            tcg_temp_free_i32(fp0);
6313
        }
6314
        opn = "rsqrt1.s";
6315
        break;
6316
    case FOP(31, 16):
6317
        check_cp1_64bitmode(ctx);
6318
        {
6319
            TCGv_i32 fp0 = tcg_temp_new_i32();
6320
            TCGv_i32 fp1 = tcg_temp_new_i32();
6321

    
6322
            gen_load_fpr32(fp0, fs);
6323
            gen_load_fpr32(fp1, ft);
6324
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6325
            tcg_temp_free_i32(fp1);
6326
            gen_store_fpr32(fp0, fd);
6327
            tcg_temp_free_i32(fp0);
6328
        }
6329
        opn = "rsqrt2.s";
6330
        break;
6331
    case FOP(33, 16):
6332
        check_cp1_registers(ctx, fd);
6333
        {
6334
            TCGv_i32 fp32 = tcg_temp_new_i32();
6335
            TCGv_i64 fp64 = tcg_temp_new_i64();
6336

    
6337
            gen_load_fpr32(fp32, fs);
6338
            gen_helper_float_cvtd_s(fp64, fp32);
6339
            tcg_temp_free_i32(fp32);
6340
            gen_store_fpr64(ctx, fp64, fd);
6341
            tcg_temp_free_i64(fp64);
6342
        }
6343
        opn = "cvt.d.s";
6344
        break;
6345
    case FOP(36, 16):
6346
        {
6347
            TCGv_i32 fp0 = tcg_temp_new_i32();
6348

    
6349
            gen_load_fpr32(fp0, fs);
6350
            gen_helper_float_cvtw_s(fp0, fp0);
6351
            gen_store_fpr32(fp0, fd);
6352
            tcg_temp_free_i32(fp0);
6353
        }
6354
        opn = "cvt.w.s";
6355
        break;
6356
    case FOP(37, 16):
6357
        check_cp1_64bitmode(ctx);
6358
        {
6359
            TCGv_i32 fp32 = tcg_temp_new_i32();
6360
            TCGv_i64 fp64 = tcg_temp_new_i64();
6361

    
6362
            gen_load_fpr32(fp32, fs);
6363
            gen_helper_float_cvtl_s(fp64, fp32);
6364
            tcg_temp_free_i32(fp32);
6365
            gen_store_fpr64(ctx, fp64, fd);
6366
            tcg_temp_free_i64(fp64);
6367
        }
6368
        opn = "cvt.l.s";
6369
        break;
6370
    case FOP(38, 16):
6371
        check_cp1_64bitmode(ctx);
6372
        {
6373
            TCGv_i64 fp64 = tcg_temp_new_i64();
6374
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6375
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6376

    
6377
            gen_load_fpr32(fp32_0, fs);
6378
            gen_load_fpr32(fp32_1, ft);
6379
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6380
            tcg_temp_free_i32(fp32_1);
6381
            tcg_temp_free_i32(fp32_0);
6382
            gen_store_fpr64(ctx, fp64, fd);
6383
            tcg_temp_free_i64(fp64);
6384
        }
6385
        opn = "cvt.ps.s";
6386
        break;
6387
    case FOP(48, 16):
6388
    case FOP(49, 16):
6389
    case FOP(50, 16):
6390
    case FOP(51, 16):
6391
    case FOP(52, 16):
6392
    case FOP(53, 16):
6393
    case FOP(54, 16):
6394
    case FOP(55, 16):
6395
    case FOP(56, 16):
6396
    case FOP(57, 16):
6397
    case FOP(58, 16):
6398
    case FOP(59, 16):
6399
    case FOP(60, 16):
6400
    case FOP(61, 16):
6401
    case FOP(62, 16):
6402
    case FOP(63, 16):
6403
        {
6404
            TCGv_i32 fp0 = tcg_temp_new_i32();
6405
            TCGv_i32 fp1 = tcg_temp_new_i32();
6406

    
6407
            gen_load_fpr32(fp0, fs);
6408
            gen_load_fpr32(fp1, ft);
6409
            if (ctx->opcode & (1 << 6)) {
6410
                check_cop1x(ctx);
6411
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6412
                opn = condnames_abs[func-48];
6413
            } else {
6414
                gen_cmp_s(func-48, fp0, fp1, cc);
6415
                opn = condnames[func-48];
6416
            }
6417
            tcg_temp_free_i32(fp0);
6418
            tcg_temp_free_i32(fp1);
6419
        }
6420
        break;
6421
    case FOP(0, 17):
6422
        check_cp1_registers(ctx, fs | ft | fd);
6423
        {
6424
            TCGv_i64 fp0 = tcg_temp_new_i64();
6425
            TCGv_i64 fp1 = tcg_temp_new_i64();
6426

    
6427
            gen_load_fpr64(ctx, fp0, fs);
6428
            gen_load_fpr64(ctx, fp1, ft);
6429
            gen_helper_float_add_d(fp0, fp0, fp1);
6430
            tcg_temp_free_i64(fp1);
6431
            gen_store_fpr64(ctx, fp0, fd);
6432
            tcg_temp_free_i64(fp0);
6433
        }
6434
        opn = "add.d";
6435
        optype = BINOP;
6436
        break;
6437
    case FOP(1, 17):
6438
        check_cp1_registers(ctx, fs | ft | fd);
6439
        {
6440
            TCGv_i64 fp0 = tcg_temp_new_i64();
6441
            TCGv_i64 fp1 = tcg_temp_new_i64();
6442

    
6443
            gen_load_fpr64(ctx, fp0, fs);
6444
            gen_load_fpr64(ctx, fp1, ft);
6445
            gen_helper_float_sub_d(fp0, fp0, fp1);
6446
            tcg_temp_free_i64(fp1);
6447
            gen_store_fpr64(ctx, fp0, fd);
6448
            tcg_temp_free_i64(fp0);
6449
        }
6450
        opn = "sub.d";
6451
        optype = BINOP;
6452
        break;
6453
    case FOP(2, 17):
6454
        check_cp1_registers(ctx, fs | ft | fd);
6455
        {
6456
            TCGv_i64 fp0 = tcg_temp_new_i64();
6457
            TCGv_i64 fp1 = tcg_temp_new_i64();
6458

    
6459
            gen_load_fpr64(ctx, fp0, fs);
6460
            gen_load_fpr64(ctx, fp1, ft);
6461
            gen_helper_float_mul_d(fp0, fp0, fp1);
6462
            tcg_temp_free_i64(fp1);
6463
            gen_store_fpr64(ctx, fp0, fd);
6464
            tcg_temp_free_i64(fp0);
6465
        }
6466
        opn = "mul.d";
6467
        optype = BINOP;
6468
        break;
6469
    case FOP(3, 17):
6470
        check_cp1_registers(ctx, fs | ft | fd);
6471
        {
6472
            TCGv_i64 fp0 = tcg_temp_new_i64();
6473
            TCGv_i64 fp1 = tcg_temp_new_i64();
6474

    
6475
            gen_load_fpr64(ctx, fp0, fs);
6476
            gen_load_fpr64(ctx, fp1, ft);
6477
            gen_helper_float_div_d(fp0, fp0, fp1);
6478
            tcg_temp_free_i64(fp1);
6479
            gen_store_fpr64(ctx, fp0, fd);
6480
            tcg_temp_free_i64(fp0);
6481
        }
6482
        opn = "div.d";
6483
        optype = BINOP;
6484
        break;
6485
    case FOP(4, 17):
6486
        check_cp1_registers(ctx, fs | fd);
6487
        {
6488
            TCGv_i64 fp0 = tcg_temp_new_i64();
6489

    
6490
            gen_load_fpr64(ctx, fp0, fs);
6491
            gen_helper_float_sqrt_d(fp0, fp0);
6492
            gen_store_fpr64(ctx, fp0, fd);
6493
            tcg_temp_free_i64(fp0);
6494
        }
6495
        opn = "sqrt.d";
6496
        break;
6497
    case FOP(5, 17):
6498
        check_cp1_registers(ctx, fs | fd);
6499
        {
6500
            TCGv_i64 fp0 = tcg_temp_new_i64();
6501

    
6502
            gen_load_fpr64(ctx, fp0, fs);
6503
            gen_helper_float_abs_d(fp0, fp0);
6504
            gen_store_fpr64(ctx, fp0, fd);
6505
            tcg_temp_free_i64(fp0);
6506
        }
6507
        opn = "abs.d";
6508
        break;
6509
    case FOP(6, 17):
6510
        check_cp1_registers(ctx, fs | fd);
6511
        {
6512
            TCGv_i64 fp0 = tcg_temp_new_i64();
6513

    
6514
            gen_load_fpr64(ctx, fp0, fs);
6515
            gen_store_fpr64(ctx, fp0, fd);
6516
            tcg_temp_free_i64(fp0);
6517
        }
6518
        opn = "mov.d";
6519
        break;
6520
    case FOP(7, 17):
6521
        check_cp1_registers(ctx, fs | fd);
6522
        {
6523
            TCGv_i64 fp0 = tcg_temp_new_i64();
6524

    
6525
            gen_load_fpr64(ctx, fp0, fs);
6526
            gen_helper_float_chs_d(fp0, fp0);
6527
            gen_store_fpr64(ctx, fp0, fd);
6528
            tcg_temp_free_i64(fp0);
6529
        }
6530
        opn = "neg.d";
6531
        break;
6532
    case FOP(8, 17):
6533
        check_cp1_64bitmode(ctx);
6534
        {
6535
            TCGv_i64 fp0 = tcg_temp_new_i64();
6536

    
6537
            gen_load_fpr64(ctx, fp0, fs);
6538
            gen_helper_float_roundl_d(fp0, fp0);
6539
            gen_store_fpr64(ctx, fp0, fd);
6540
            tcg_temp_free_i64(fp0);
6541
        }
6542
        opn = "round.l.d";
6543
        break;
6544
    case FOP(9, 17):
6545
        check_cp1_64bitmode(ctx);
6546
        {
6547
            TCGv_i64 fp0 = tcg_temp_new_i64();
6548

    
6549
            gen_load_fpr64(ctx, fp0, fs);
6550
            gen_helper_float_truncl_d(fp0, fp0);
6551
            gen_store_fpr64(ctx, fp0, fd);
6552
            tcg_temp_free_i64(fp0);
6553
        }
6554
        opn = "trunc.l.d";
6555
        break;
6556
    case FOP(10, 17):
6557
        check_cp1_64bitmode(ctx);
6558
        {
6559
            TCGv_i64 fp0 = tcg_temp_new_i64();
6560

    
6561
            gen_load_fpr64(ctx, fp0, fs);
6562
            gen_helper_float_ceill_d(fp0, fp0);
6563
            gen_store_fpr64(ctx, fp0, fd);
6564
            tcg_temp_free_i64(fp0);
6565
        }
6566
        opn = "ceil.l.d";
6567
        break;
6568
    case FOP(11, 17):
6569
        check_cp1_64bitmode(ctx);
6570
        {
6571
            TCGv_i64 fp0 = tcg_temp_new_i64();
6572

    
6573
            gen_load_fpr64(ctx, fp0, fs);
6574
            gen_helper_float_floorl_d(fp0, fp0);
6575
            gen_store_fpr64(ctx, fp0, fd);
6576
            tcg_temp_free_i64(fp0);
6577
        }
6578
        opn = "floor.l.d";
6579
        break;
6580
    case FOP(12, 17):
6581
        check_cp1_registers(ctx, fs);
6582
        {
6583
            TCGv_i32 fp32 = tcg_temp_new_i32();
6584
            TCGv_i64 fp64 = tcg_temp_new_i64();
6585

    
6586
            gen_load_fpr64(ctx, fp64, fs);
6587
            gen_helper_float_roundw_d(fp32, fp64);
6588
            tcg_temp_free_i64(fp64);
6589
            gen_store_fpr32(fp32, fd);
6590
            tcg_temp_free_i32(fp32);
6591
        }
6592
        opn = "round.w.d";
6593
        break;
6594
    case FOP(13, 17):
6595
        check_cp1_registers(ctx, fs);
6596
        {
6597
            TCGv_i32 fp32 = tcg_temp_new_i32();
6598
            TCGv_i64 fp64 = tcg_temp_new_i64();
6599

    
6600
            gen_load_fpr64(ctx, fp64, fs);
6601
            gen_helper_float_truncw_d(fp32, fp64);
6602
            tcg_temp_free_i64(fp64);
6603
            gen_store_fpr32(fp32, fd);
6604
            tcg_temp_free_i32(fp32);
6605
        }
6606
        opn = "trunc.w.d";
6607
        break;
6608
    case FOP(14, 17):
6609
        check_cp1_registers(ctx, fs);
6610
        {
6611
            TCGv_i32 fp32 = tcg_temp_new_i32();
6612
            TCGv_i64 fp64 = tcg_temp_new_i64();
6613

    
6614
            gen_load_fpr64(ctx, fp64, fs);
6615
            gen_helper_float_ceilw_d(fp32, fp64);
6616
            tcg_temp_free_i64(fp64);
6617
            gen_store_fpr32(fp32, fd);
6618
            tcg_temp_free_i32(fp32);
6619
        }
6620
        opn = "ceil.w.d";
6621
        break;
6622
    case FOP(15, 17):
6623
        check_cp1_registers(ctx, fs);
6624
        {
6625
            TCGv_i32 fp32 = tcg_temp_new_i32();
6626
            TCGv_i64 fp64 = tcg_temp_new_i64();
6627

    
6628
            gen_load_fpr64(ctx, fp64, fs);
6629
            gen_helper_float_floorw_d(fp32, fp64);
6630
            tcg_temp_free_i64(fp64);
6631
            gen_store_fpr32(fp32, fd);
6632
            tcg_temp_free_i32(fp32);
6633
        }
6634
        opn = "floor.w.d";
6635
        break;
6636
    case FOP(17, 17):
6637
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6638
        opn = "movcf.d";
6639
        break;
6640
    case FOP(18, 17):
6641
        {
6642
            int l1 = gen_new_label();
6643
            TCGv t0 = tcg_temp_new();
6644
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6645

    
6646
            gen_load_gpr(t0, ft);
6647
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6648
            gen_load_fpr64(ctx, fp0, fs);
6649
            gen_store_fpr64(ctx, fp0, fd);
6650
            tcg_temp_free_i64(fp0);
6651
            gen_set_label(l1);
6652
            tcg_temp_free(t0);
6653
        }
6654
        opn = "movz.d";
6655
        break;
6656
    case FOP(19, 17):
6657
        {
6658
            int l1 = gen_new_label();
6659
            TCGv t0 = tcg_temp_new();
6660
            TCGv_i64 fp0 = tcg_temp_local_new_i64();
6661

    
6662
            gen_load_gpr(t0, ft);
6663
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6664
            gen_load_fpr64(ctx, fp0, fs);
6665
            gen_store_fpr64(ctx, fp0, fd);
6666
            tcg_temp_free_i64(fp0);
6667
            gen_set_label(l1);
6668
            tcg_temp_free(t0);
6669
        }
6670
        opn = "movn.d";
6671
        break;
6672
    case FOP(21, 17):
6673
        check_cp1_64bitmode(ctx);
6674
        {
6675
            TCGv_i64 fp0 = tcg_temp_new_i64();
6676

    
6677
            gen_load_fpr64(ctx, fp0, fs);
6678
            gen_helper_float_recip_d(fp0, fp0);
6679
            gen_store_fpr64(ctx, fp0, fd);
6680
            tcg_temp_free_i64(fp0);
6681
        }
6682
        opn = "recip.d";
6683
        break;
6684
    case FOP(22, 17):
6685
        check_cp1_64bitmode(ctx);
6686
        {
6687
            TCGv_i64 fp0 = tcg_temp_new_i64();
6688

    
6689
            gen_load_fpr64(ctx, fp0, fs);
6690
            gen_helper_float_rsqrt_d(fp0, fp0);
6691
            gen_store_fpr64(ctx, fp0, fd);
6692
            tcg_temp_free_i64(fp0);
6693
        }
6694
        opn = "rsqrt.d";
6695
        break;
6696
    case FOP(28, 17):
6697
        check_cp1_64bitmode(ctx);
6698
        {
6699
            TCGv_i64 fp0 = tcg_temp_new_i64();
6700
            TCGv_i64 fp1 = tcg_temp_new_i64();
6701

    
6702
            gen_load_fpr64(ctx, fp0, fs);
6703
            gen_load_fpr64(ctx, fp1, ft);
6704
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6705
            tcg_temp_free_i64(fp1);
6706
            gen_store_fpr64(ctx, fp0, fd);
6707
            tcg_temp_free_i64(fp0);
6708
        }
6709
        opn = "recip2.d";
6710
        break;
6711
    case FOP(29, 17):
6712
        check_cp1_64bitmode(ctx);
6713
        {
6714
            TCGv_i64 fp0 = tcg_temp_new_i64();
6715

    
6716
            gen_load_fpr64(ctx, fp0, fs);
6717
            gen_helper_float_recip1_d(fp0, fp0);
6718
            gen_store_fpr64(ctx, fp0, fd);
6719
            tcg_temp_free_i64(fp0);
6720
        }
6721
        opn = "recip1.d";
6722
        break;
6723
    case FOP(30, 17):
6724
        check_cp1_64bitmode(ctx);
6725
        {
6726
            TCGv_i64 fp0 = tcg_temp_new_i64();
6727

    
6728
            gen_load_fpr64(ctx, fp0, fs);
6729
            gen_helper_float_rsqrt1_d(fp0, fp0);
6730
            gen_store_fpr64(ctx, fp0, fd);
6731
            tcg_temp_free_i64(fp0);
6732
        }
6733
        opn = "rsqrt1.d";
6734
        break;
6735
    case FOP(31, 17):
6736
        check_cp1_64bitmode(ctx);
6737
        {
6738
            TCGv_i64 fp0 = tcg_temp_new_i64();
6739
            TCGv_i64 fp1 = tcg_temp_new_i64();
6740

    
6741
            gen_load_fpr64(ctx, fp0, fs);
6742
            gen_load_fpr64(ctx, fp1, ft);
6743
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6744
            tcg_temp_free_i64(fp1);
6745
            gen_store_fpr64(ctx, fp0, fd);
6746
            tcg_temp_free_i64(fp0);
6747
        }
6748
        opn = "rsqrt2.d";
6749
        break;
6750
    case FOP(48, 17):
6751
    case FOP(49, 17):
6752
    case FOP(50, 17):
6753
    case FOP(51, 17):
6754
    case FOP(52, 17):
6755
    case FOP(53, 17):
6756
    case FOP(54, 17):
6757
    case FOP(55, 17):
6758
    case FOP(56, 17):
6759
    case FOP(57, 17):
6760
    case FOP(58, 17):
6761
    case FOP(59, 17):
6762
    case FOP(60, 17):
6763
    case FOP(61, 17):
6764
    case FOP(62, 17):
6765
    case FOP(63, 17):
6766
        {
6767
            TCGv_i64 fp0 = tcg_temp_new_i64();
6768
            TCGv_i64 fp1 = tcg_temp_new_i64();
6769

    
6770
            gen_load_fpr64(ctx, fp0, fs);
6771
            gen_load_fpr64(ctx, fp1, ft);
6772
            if (ctx->opcode & (1 << 6)) {
6773
                check_cop1x(ctx);
6774
                check_cp1_registers(ctx, fs | ft);
6775
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6776
                opn = condnames_abs[func-48];
6777
            } else {
6778
                check_cp1_registers(ctx, fs | ft);
6779
                gen_cmp_d(func-48, fp0, fp1, cc);
6780
                opn = condnames[func-48];
6781
            }
6782
            tcg_temp_free_i64(fp0);
6783
            tcg_temp_free_i64(fp1);
6784
        }
6785
        break;
6786
    case FOP(32, 17):
6787
        check_cp1_registers(ctx, fs);
6788
        {
6789
            TCGv_i32 fp32 = tcg_temp_new_i32();
6790
            TCGv_i64 fp64 = tcg_temp_new_i64();
6791

    
6792
            gen_load_fpr64(ctx, fp64, fs);
6793
            gen_helper_float_cvts_d(fp32, fp64);
6794
            tcg_temp_free_i64(fp64);
6795
            gen_store_fpr32(fp32, fd);
6796
            tcg_temp_free_i32(fp32);
6797
        }
6798
        opn = "cvt.s.d";
6799
        break;
6800
    case FOP(36, 17):
6801
        check_cp1_registers(ctx, fs);
6802
        {
6803
            TCGv_i32 fp32 = tcg_temp_new_i32();
6804
            TCGv_i64 fp64 = tcg_temp_new_i64();
6805

    
6806
            gen_load_fpr64(ctx, fp64, fs);
6807
            gen_helper_float_cvtw_d(fp32, fp64);
6808
            tcg_temp_free_i64(fp64);
6809
            gen_store_fpr32(fp32, fd);
6810
            tcg_temp_free_i32(fp32);
6811
        }
6812
        opn = "cvt.w.d";
6813
        break;
6814
    case FOP(37, 17):
6815
        check_cp1_64bitmode(ctx);
6816
        {
6817
            TCGv_i64 fp0 = tcg_temp_new_i64();
6818

    
6819
            gen_load_fpr64(ctx, fp0, fs);
6820
            gen_helper_float_cvtl_d(fp0, fp0);
6821
            gen_store_fpr64(ctx, fp0, fd);
6822
            tcg_temp_free_i64(fp0);
6823
        }
6824
        opn = "cvt.l.d";
6825
        break;
6826
    case FOP(32, 20):
6827
        {
6828
            TCGv_i32 fp0 = tcg_temp_new_i32();
6829

    
6830
            gen_load_fpr32(fp0, fs);
6831
            gen_helper_float_cvts_w(fp0, fp0);
6832
            gen_store_fpr32(fp0, fd);
6833
            tcg_temp_free_i32(fp0);
6834
        }
6835
        opn = "cvt.s.w";
6836
        break;
6837
    case FOP(33, 20):
6838
        check_cp1_registers(ctx, fd);
6839
        {
6840
            TCGv_i32 fp32 = tcg_temp_new_i32();
6841
            TCGv_i64 fp64 = tcg_temp_new_i64();
6842

    
6843
            gen_load_fpr32(fp32, fs);
6844
            gen_helper_float_cvtd_w(fp64, fp32);
6845
            tcg_temp_free_i32(fp32);
6846
            gen_store_fpr64(ctx, fp64, fd);
6847
            tcg_temp_free_i64(fp64);
6848
        }
6849
        opn = "cvt.d.w";
6850
        break;
6851
    case FOP(32, 21):
6852
        check_cp1_64bitmode(ctx);
6853
        {
6854
            TCGv_i32 fp32 = tcg_temp_new_i32();
6855
            TCGv_i64 fp64 = tcg_temp_new_i64();
6856

    
6857
            gen_load_fpr64(ctx, fp64, fs);
6858
            gen_helper_float_cvts_l(fp32, fp64);
6859
            tcg_temp_free_i64(fp64);
6860
            gen_store_fpr32(fp32, fd);
6861
            tcg_temp_free_i32(fp32);
6862
        }
6863
        opn = "cvt.s.l";
6864
        break;
6865
    case FOP(33, 21):
6866
        check_cp1_64bitmode(ctx);
6867
        {
6868
            TCGv_i64 fp0 = tcg_temp_new_i64();
6869

    
6870
            gen_load_fpr64(ctx, fp0, fs);
6871
            gen_helper_float_cvtd_l(fp0, fp0);
6872
            gen_store_fpr64(ctx, fp0, fd);
6873
            tcg_temp_free_i64(fp0);
6874
        }
6875
        opn = "cvt.d.l";
6876
        break;
6877
    case FOP(38, 20):
6878
        check_cp1_64bitmode(ctx);
6879
        {
6880
            TCGv_i64 fp0 = tcg_temp_new_i64();
6881

    
6882
            gen_load_fpr64(ctx, fp0, fs);
6883
            gen_helper_float_cvtps_pw(fp0, fp0);
6884
            gen_store_fpr64(ctx, fp0, fd);
6885
            tcg_temp_free_i64(fp0);
6886
        }
6887
        opn = "cvt.ps.pw";
6888
        break;
6889
    case FOP(0, 22):
6890
        check_cp1_64bitmode(ctx);
6891
        {
6892
            TCGv_i64 fp0 = tcg_temp_new_i64();
6893
            TCGv_i64 fp1 = tcg_temp_new_i64();
6894

    
6895
            gen_load_fpr64(ctx, fp0, fs);
6896
            gen_load_fpr64(ctx, fp1, ft);
6897
            gen_helper_float_add_ps(fp0, fp0, fp1);
6898
            tcg_temp_free_i64(fp1);
6899
            gen_store_fpr64(ctx, fp0, fd);
6900
            tcg_temp_free_i64(fp0);
6901
        }
6902
        opn = "add.ps";
6903
        break;
6904
    case FOP(1, 22):
6905
        check_cp1_64bitmode(ctx);
6906
        {
6907
            TCGv_i64 fp0 = tcg_temp_new_i64();
6908
            TCGv_i64 fp1 = tcg_temp_new_i64();
6909

    
6910
            gen_load_fpr64(ctx, fp0, fs);
6911
            gen_load_fpr64(ctx, fp1, ft);
6912
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6913
            tcg_temp_free_i64(fp1);
6914
            gen_store_fpr64(ctx, fp0, fd);
6915
            tcg_temp_free_i64(fp0);
6916
        }
6917
        opn = "sub.ps";
6918
        break;
6919
    case FOP(2, 22):
6920
        check_cp1_64bitmode(ctx);
6921
        {
6922
            TCGv_i64 fp0 = tcg_temp_new_i64();
6923
            TCGv_i64 fp1 = tcg_temp_new_i64();
6924

    
6925
            gen_load_fpr64(ctx, fp0, fs);
6926
            gen_load_fpr64(ctx, fp1, ft);
6927
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6928
            tcg_temp_free_i64(fp1);
6929
            gen_store_fpr64(ctx, fp0, fd);
6930
            tcg_temp_free_i64(fp0);
6931
        }
6932
        opn = "mul.ps";
6933
        break;
6934
    case FOP(5, 22):
6935
        check_cp1_64bitmode(ctx);
6936
        {
6937
            TCGv_i64 fp0 = tcg_temp_new_i64();
6938

    
6939
            gen_load_fpr64(ctx, fp0, fs);
6940
            gen_helper_float_abs_ps(fp0, fp0);
6941
            gen_store_fpr64(ctx, fp0, fd);
6942
            tcg_temp_free_i64(fp0);
6943
        }
6944
        opn = "abs.ps";
6945
        break;
6946
    case FOP(6, 22):
6947
        check_cp1_64bitmode(ctx);
6948
        {
6949
            TCGv_i64 fp0 = tcg_temp_new_i64();
6950

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

    
6962
            gen_load_fpr64(ctx, fp0, fs);
6963
            gen_helper_float_chs_ps(fp0, fp0);
6964
            gen_store_fpr64(ctx, fp0, fd);
6965
            tcg_temp_free_i64(fp0);
6966
        }
6967
        opn = "neg.ps";
6968
        break;
6969
    case FOP(17, 22):
6970
        check_cp1_64bitmode(ctx);
6971
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6972
        opn = "movcf.ps";
6973
        break;
6974
    case FOP(18, 22):
6975
        check_cp1_64bitmode(ctx);
6976
        {
6977
            int l1 = gen_new_label();
6978
            TCGv t0 = tcg_temp_new();
6979
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
6980
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
6981

    
6982
            gen_load_gpr(t0, ft);
6983
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6984
            gen_load_fpr32(fp0, fs);
6985
            gen_load_fpr32h(fph0, fs);
6986
            gen_store_fpr32(fp0, fd);
6987
            gen_store_fpr32h(fph0, fd);
6988
            tcg_temp_free_i32(fp0);
6989
            tcg_temp_free_i32(fph0);
6990
            gen_set_label(l1);
6991
            tcg_temp_free(t0);
6992
        }
6993
        opn = "movz.ps";
6994
        break;
6995
    case FOP(19, 22):
6996
        check_cp1_64bitmode(ctx);
6997
        {
6998
            int l1 = gen_new_label();
6999
            TCGv t0 = tcg_temp_new();
7000
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7001
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7002

    
7003
            gen_load_gpr(t0, ft);
7004
            tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
7005
            gen_load_fpr32(fp0, fs);
7006
            gen_load_fpr32h(fph0, fs);
7007
            gen_store_fpr32(fp0, fd);
7008
            gen_store_fpr32h(fph0, fd);
7009
            tcg_temp_free_i32(fp0);
7010
            tcg_temp_free_i32(fph0);
7011
            gen_set_label(l1);
7012
            tcg_temp_free(t0);
7013
        }
7014
        opn = "movn.ps";
7015
        break;
7016
    case FOP(24, 22):
7017
        check_cp1_64bitmode(ctx);
7018
        {
7019
            TCGv_i64 fp0 = tcg_temp_new_i64();
7020
            TCGv_i64 fp1 = tcg_temp_new_i64();
7021

    
7022
            gen_load_fpr64(ctx, fp0, ft);
7023
            gen_load_fpr64(ctx, fp1, fs);
7024
            gen_helper_float_addr_ps(fp0, fp0, fp1);
7025
            tcg_temp_free_i64(fp1);
7026
            gen_store_fpr64(ctx, fp0, fd);
7027
            tcg_temp_free_i64(fp0);
7028
        }
7029
        opn = "addr.ps";
7030
        break;
7031
    case FOP(26, 22):
7032
        check_cp1_64bitmode(ctx);
7033
        {
7034
            TCGv_i64 fp0 = tcg_temp_new_i64();
7035
            TCGv_i64 fp1 = tcg_temp_new_i64();
7036

    
7037
            gen_load_fpr64(ctx, fp0, ft);
7038
            gen_load_fpr64(ctx, fp1, fs);
7039
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7040
            tcg_temp_free_i64(fp1);
7041
            gen_store_fpr64(ctx, fp0, fd);
7042
            tcg_temp_free_i64(fp0);
7043
        }
7044
        opn = "mulr.ps";
7045
        break;
7046
    case FOP(28, 22):
7047
        check_cp1_64bitmode(ctx);
7048
        {
7049
            TCGv_i64 fp0 = tcg_temp_new_i64();
7050
            TCGv_i64 fp1 = tcg_temp_new_i64();
7051

    
7052
            gen_load_fpr64(ctx, fp0, fs);
7053
            gen_load_fpr64(ctx, fp1, fd);
7054
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7055
            tcg_temp_free_i64(fp1);
7056
            gen_store_fpr64(ctx, fp0, fd);
7057
            tcg_temp_free_i64(fp0);
7058
        }
7059
        opn = "recip2.ps";
7060
        break;
7061
    case FOP(29, 22):
7062
        check_cp1_64bitmode(ctx);
7063
        {
7064
            TCGv_i64 fp0 = tcg_temp_new_i64();
7065

    
7066
            gen_load_fpr64(ctx, fp0, fs);
7067
            gen_helper_float_recip1_ps(fp0, fp0);
7068
            gen_store_fpr64(ctx, fp0, fd);
7069
            tcg_temp_free_i64(fp0);
7070
        }
7071
        opn = "recip1.ps";
7072
        break;
7073
    case FOP(30, 22):
7074
        check_cp1_64bitmode(ctx);
7075
        {
7076
            TCGv_i64 fp0 = tcg_temp_new_i64();
7077

    
7078
            gen_load_fpr64(ctx, fp0, fs);
7079
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7080
            gen_store_fpr64(ctx, fp0, fd);
7081
            tcg_temp_free_i64(fp0);
7082
        }
7083
        opn = "rsqrt1.ps";
7084
        break;
7085
    case FOP(31, 22):
7086
        check_cp1_64bitmode(ctx);
7087
        {
7088
            TCGv_i64 fp0 = tcg_temp_new_i64();
7089
            TCGv_i64 fp1 = tcg_temp_new_i64();
7090

    
7091
            gen_load_fpr64(ctx, fp0, fs);
7092
            gen_load_fpr64(ctx, fp1, ft);
7093
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7094
            tcg_temp_free_i64(fp1);
7095
            gen_store_fpr64(ctx, fp0, fd);
7096
            tcg_temp_free_i64(fp0);
7097
        }
7098
        opn = "rsqrt2.ps";
7099
        break;
7100
    case FOP(32, 22):
7101
        check_cp1_64bitmode(ctx);
7102
        {
7103
            TCGv_i32 fp0 = tcg_temp_new_i32();
7104

    
7105
            gen_load_fpr32h(fp0, fs);
7106
            gen_helper_float_cvts_pu(fp0, fp0);
7107
            gen_store_fpr32(fp0, fd);
7108
            tcg_temp_free_i32(fp0);
7109
        }
7110
        opn = "cvt.s.pu";
7111
        break;
7112
    case FOP(36, 22):
7113
        check_cp1_64bitmode(ctx);
7114
        {
7115
            TCGv_i64 fp0 = tcg_temp_new_i64();
7116

    
7117
            gen_load_fpr64(ctx, fp0, fs);
7118
            gen_helper_float_cvtpw_ps(fp0, fp0);
7119
            gen_store_fpr64(ctx, fp0, fd);
7120
            tcg_temp_free_i64(fp0);
7121
        }
7122
        opn = "cvt.pw.ps";
7123
        break;
7124
    case FOP(40, 22):
7125
        check_cp1_64bitmode(ctx);
7126
        {
7127
            TCGv_i32 fp0 = tcg_temp_new_i32();
7128

    
7129
            gen_load_fpr32(fp0, fs);
7130
            gen_helper_float_cvts_pl(fp0, fp0);
7131
            gen_store_fpr32(fp0, fd);
7132
            tcg_temp_free_i32(fp0);
7133
        }
7134
        opn = "cvt.s.pl";
7135
        break;
7136
    case FOP(44, 22):
7137
        check_cp1_64bitmode(ctx);
7138
        {
7139
            TCGv_i32 fp0 = tcg_temp_new_i32();
7140
            TCGv_i32 fp1 = tcg_temp_new_i32();
7141

    
7142
            gen_load_fpr32(fp0, fs);
7143
            gen_load_fpr32(fp1, ft);
7144
            gen_store_fpr32h(fp0, fd);
7145
            gen_store_fpr32(fp1, fd);
7146
            tcg_temp_free_i32(fp0);
7147
            tcg_temp_free_i32(fp1);
7148
        }
7149
        opn = "pll.ps";
7150
        break;
7151
    case FOP(45, 22):
7152
        check_cp1_64bitmode(ctx);
7153
        {
7154
            TCGv_i32 fp0 = tcg_temp_new_i32();
7155
            TCGv_i32 fp1 = tcg_temp_new_i32();
7156

    
7157
            gen_load_fpr32(fp0, fs);
7158
            gen_load_fpr32h(fp1, ft);
7159
            gen_store_fpr32(fp1, fd);
7160
            gen_store_fpr32h(fp0, fd);
7161
            tcg_temp_free_i32(fp0);
7162
            tcg_temp_free_i32(fp1);
7163
        }
7164
        opn = "plu.ps";
7165
        break;
7166
    case FOP(46, 22):
7167
        check_cp1_64bitmode(ctx);
7168
        {
7169
            TCGv_i32 fp0 = tcg_temp_new_i32();
7170
            TCGv_i32 fp1 = tcg_temp_new_i32();
7171

    
7172
            gen_load_fpr32h(fp0, fs);
7173
            gen_load_fpr32(fp1, ft);
7174
            gen_store_fpr32(fp1, fd);
7175
            gen_store_fpr32h(fp0, fd);
7176
            tcg_temp_free_i32(fp0);
7177
            tcg_temp_free_i32(fp1);
7178
        }
7179
        opn = "pul.ps";
7180
        break;
7181
    case FOP(47, 22):
7182
        check_cp1_64bitmode(ctx);
7183
        {
7184
            TCGv_i32 fp0 = tcg_temp_new_i32();
7185
            TCGv_i32 fp1 = tcg_temp_new_i32();
7186

    
7187
            gen_load_fpr32h(fp0, fs);
7188
            gen_load_fpr32h(fp1, ft);
7189
            gen_store_fpr32(fp1, fd);
7190
            gen_store_fpr32h(fp0, fd);
7191
            tcg_temp_free_i32(fp0);
7192
            tcg_temp_free_i32(fp1);
7193
        }
7194
        opn = "puu.ps";
7195
        break;
7196
    case FOP(48, 22):
7197
    case FOP(49, 22):
7198
    case FOP(50, 22):
7199
    case FOP(51, 22):
7200
    case FOP(52, 22):
7201
    case FOP(53, 22):
7202
    case FOP(54, 22):
7203
    case FOP(55, 22):
7204
    case FOP(56, 22):
7205
    case FOP(57, 22):
7206
    case FOP(58, 22):
7207
    case FOP(59, 22):
7208
    case FOP(60, 22):
7209
    case FOP(61, 22):
7210
    case FOP(62, 22):
7211
    case FOP(63, 22):
7212
        check_cp1_64bitmode(ctx);
7213
        {
7214
            TCGv_i64 fp0 = tcg_temp_new_i64();
7215
            TCGv_i64 fp1 = tcg_temp_new_i64();
7216

    
7217
            gen_load_fpr64(ctx, fp0, fs);
7218
            gen_load_fpr64(ctx, fp1, ft);
7219
            if (ctx->opcode & (1 << 6)) {
7220
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7221
                opn = condnames_abs[func-48];
7222
            } else {
7223
                gen_cmp_ps(func-48, fp0, fp1, cc);
7224
                opn = condnames[func-48];
7225
            }
7226
            tcg_temp_free_i64(fp0);
7227
            tcg_temp_free_i64(fp1);
7228
        }
7229
        break;
7230
    default:
7231
        MIPS_INVAL(opn);
7232
        generate_exception (ctx, EXCP_RI);
7233
        return;
7234
    }
7235
    switch (optype) {
7236
    case BINOP:
7237
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7238
        break;
7239
    case CMPOP:
7240
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7241
        break;
7242
    default:
7243
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7244
        break;
7245
    }
7246
}
7247

    
7248
/* Coprocessor 3 (FPU) */
7249
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7250
                           int fd, int fs, int base, int index)
7251
{
7252
    const char *opn = "extended float load/store";
7253
    int store = 0;
7254
    TCGv t0 = tcg_temp_local_new();
7255
    TCGv t1 = tcg_temp_local_new();
7256

    
7257
    if (base == 0) {
7258
        gen_load_gpr(t0, index);
7259
    } else if (index == 0) {
7260
        gen_load_gpr(t0, base);
7261
    } else {
7262
        gen_load_gpr(t0, base);
7263
        gen_load_gpr(t1, index);
7264
        gen_op_addr_add(ctx, t0, t1);
7265
    }
7266
    /* Don't do NOP if destination is zero: we must perform the actual
7267
       memory access. */
7268
    switch (opc) {
7269
    case OPC_LWXC1:
7270
        check_cop1x(ctx);
7271
        {
7272
            TCGv_i32 fp0 = tcg_temp_new_i32();
7273

    
7274
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7275
            tcg_gen_trunc_tl_i32(fp0, t1);
7276
            gen_store_fpr32(fp0, fd);
7277
            tcg_temp_free_i32(fp0);
7278
        }
7279
        opn = "lwxc1";
7280
        break;
7281
    case OPC_LDXC1:
7282
        check_cop1x(ctx);
7283
        check_cp1_registers(ctx, fd);
7284
        {
7285
            TCGv_i64 fp0 = tcg_temp_new_i64();
7286

    
7287
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7288
            gen_store_fpr64(ctx, fp0, fd);
7289
            tcg_temp_free_i64(fp0);
7290
        }
7291
        opn = "ldxc1";
7292
        break;
7293
    case OPC_LUXC1:
7294
        check_cp1_64bitmode(ctx);
7295
        tcg_gen_andi_tl(t0, t0, ~0x7);
7296
        {
7297
            TCGv_i64 fp0 = tcg_temp_new_i64();
7298

    
7299
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7300
            gen_store_fpr64(ctx, fp0, fd);
7301
            tcg_temp_free_i64(fp0);
7302
        }
7303
        opn = "luxc1";
7304
        break;
7305
    case OPC_SWXC1:
7306
        check_cop1x(ctx);
7307
        {
7308
            TCGv_i32 fp0 = tcg_temp_new_i32();
7309

    
7310
            gen_load_fpr32(fp0, fs);
7311
            tcg_gen_extu_i32_tl(t1, fp0);
7312
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7313
            tcg_temp_free_i32(fp0);
7314
        }
7315
        opn = "swxc1";
7316
        store = 1;
7317
        break;
7318
    case OPC_SDXC1:
7319
        check_cop1x(ctx);
7320
        check_cp1_registers(ctx, fs);
7321
        {
7322
            TCGv_i64 fp0 = tcg_temp_new_i64();
7323

    
7324
            gen_load_fpr64(ctx, fp0, fs);
7325
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7326
            tcg_temp_free_i64(fp0);
7327
        }
7328
        opn = "sdxc1";
7329
        store = 1;
7330
        break;
7331
    case OPC_SUXC1:
7332
        check_cp1_64bitmode(ctx);
7333
        tcg_gen_andi_tl(t0, t0, ~0x7);
7334
        {
7335
            TCGv_i64 fp0 = tcg_temp_new_i64();
7336

    
7337
            gen_load_fpr64(ctx, fp0, fs);
7338
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7339
            tcg_temp_free_i64(fp0);
7340
        }
7341
        opn = "suxc1";
7342
        store = 1;
7343
        break;
7344
    default:
7345
        MIPS_INVAL(opn);
7346
        generate_exception(ctx, EXCP_RI);
7347
        tcg_temp_free(t0);
7348
        tcg_temp_free(t1);
7349
        return;
7350
    }
7351
    tcg_temp_free(t0);
7352
    tcg_temp_free(t1);
7353
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7354
               regnames[index], regnames[base]);
7355
}
7356

    
7357
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7358
                            int fd, int fr, int fs, int ft)
7359
{
7360
    const char *opn = "flt3_arith";
7361

    
7362
    switch (opc) {
7363
    case OPC_ALNV_PS:
7364
        check_cp1_64bitmode(ctx);
7365
        {
7366
            TCGv t0 = tcg_temp_local_new();
7367
            TCGv_i32 fp0 = tcg_temp_local_new_i32();
7368
            TCGv_i32 fph0 = tcg_temp_local_new_i32();
7369
            TCGv_i32 fp1 = tcg_temp_local_new_i32();
7370
            TCGv_i32 fph1 = tcg_temp_local_new_i32();
7371
            int l1 = gen_new_label();
7372
            int l2 = gen_new_label();
7373

    
7374
            gen_load_gpr(t0, fr);
7375
            tcg_gen_andi_tl(t0, t0, 0x7);
7376
            gen_load_fpr32(fp0, fs);
7377
            gen_load_fpr32h(fph0, fs);
7378
            gen_load_fpr32(fp1, ft);
7379
            gen_load_fpr32h(fph1, ft);
7380

    
7381
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7382
            gen_store_fpr32(fp0, fd);
7383
            gen_store_fpr32h(fph0, fd);
7384
            tcg_gen_br(l2);
7385
            gen_set_label(l1);
7386
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7387
            tcg_temp_free(t0);
7388
#ifdef TARGET_WORDS_BIGENDIAN
7389
            gen_store_fpr32(fph1, fd);
7390
            gen_store_fpr32h(fp0, fd);
7391
#else
7392
            gen_store_fpr32(fph0, fd);
7393
            gen_store_fpr32h(fp1, fd);
7394
#endif
7395
            gen_set_label(l2);
7396
            tcg_temp_free_i32(fp0);
7397
            tcg_temp_free_i32(fph0);
7398
            tcg_temp_free_i32(fp1);
7399
            tcg_temp_free_i32(fph1);
7400
        }
7401
        opn = "alnv.ps";
7402
        break;
7403
    case OPC_MADD_S:
7404
        check_cop1x(ctx);
7405
        {
7406
            TCGv_i32 fp0 = tcg_temp_new_i32();
7407
            TCGv_i32 fp1 = tcg_temp_new_i32();
7408
            TCGv_i32 fp2 = tcg_temp_new_i32();
7409

    
7410
            gen_load_fpr32(fp0, fs);
7411
            gen_load_fpr32(fp1, ft);
7412
            gen_load_fpr32(fp2, fr);
7413
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7414
            tcg_temp_free_i32(fp0);
7415
            tcg_temp_free_i32(fp1);
7416
            gen_store_fpr32(fp2, fd);
7417
            tcg_temp_free_i32(fp2);
7418
        }
7419
        opn = "madd.s";
7420
        break;
7421
    case OPC_MADD_D:
7422
        check_cop1x(ctx);
7423
        check_cp1_registers(ctx, fd | fs | ft | fr);
7424
        {
7425
            TCGv_i64 fp0 = tcg_temp_new_i64();
7426
            TCGv_i64 fp1 = tcg_temp_new_i64();
7427
            TCGv_i64 fp2 = tcg_temp_new_i64();
7428

    
7429
            gen_load_fpr64(ctx, fp0, fs);
7430
            gen_load_fpr64(ctx, fp1, ft);
7431
            gen_load_fpr64(ctx, fp2, fr);
7432
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7433
            tcg_temp_free_i64(fp0);
7434
            tcg_temp_free_i64(fp1);
7435
            gen_store_fpr64(ctx, fp2, fd);
7436
            tcg_temp_free_i64(fp2);
7437
        }
7438
        opn = "madd.d";
7439
        break;
7440
    case OPC_MADD_PS:
7441
        check_cp1_64bitmode(ctx);
7442
        {
7443
            TCGv_i64 fp0 = tcg_temp_new_i64();
7444
            TCGv_i64 fp1 = tcg_temp_new_i64();
7445
            TCGv_i64 fp2 = tcg_temp_new_i64();
7446

    
7447
            gen_load_fpr64(ctx, fp0, fs);
7448
            gen_load_fpr64(ctx, fp1, ft);
7449
            gen_load_fpr64(ctx, fp2, fr);
7450
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7451
            tcg_temp_free_i64(fp0);
7452
            tcg_temp_free_i64(fp1);
7453
            gen_store_fpr64(ctx, fp2, fd);
7454
            tcg_temp_free_i64(fp2);
7455
        }
7456
        opn = "madd.ps";
7457
        break;
7458
    case OPC_MSUB_S:
7459
        check_cop1x(ctx);
7460
        {
7461
            TCGv_i32 fp0 = tcg_temp_new_i32();
7462
            TCGv_i32 fp1 = tcg_temp_new_i32();
7463
            TCGv_i32 fp2 = tcg_temp_new_i32();
7464

    
7465
            gen_load_fpr32(fp0, fs);
7466
            gen_load_fpr32(fp1, ft);
7467
            gen_load_fpr32(fp2, fr);
7468
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7469
            tcg_temp_free_i32(fp0);
7470
            tcg_temp_free_i32(fp1);
7471
            gen_store_fpr32(fp2, fd);
7472
            tcg_temp_free_i32(fp2);
7473
        }
7474
        opn = "msub.s";
7475
        break;
7476
    case OPC_MSUB_D:
7477
        check_cop1x(ctx);
7478
        check_cp1_registers(ctx, fd | fs | ft | fr);
7479
        {
7480
            TCGv_i64 fp0 = tcg_temp_new_i64();
7481
            TCGv_i64 fp1 = tcg_temp_new_i64();
7482
            TCGv_i64 fp2 = tcg_temp_new_i64();
7483

    
7484
            gen_load_fpr64(ctx, fp0, fs);
7485
            gen_load_fpr64(ctx, fp1, ft);
7486
            gen_load_fpr64(ctx, fp2, fr);
7487
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7488
            tcg_temp_free_i64(fp0);
7489
            tcg_temp_free_i64(fp1);
7490
            gen_store_fpr64(ctx, fp2, fd);
7491
            tcg_temp_free_i64(fp2);
7492
        }
7493
        opn = "msub.d";
7494
        break;
7495
    case OPC_MSUB_PS:
7496
        check_cp1_64bitmode(ctx);
7497
        {
7498
            TCGv_i64 fp0 = tcg_temp_new_i64();
7499
            TCGv_i64 fp1 = tcg_temp_new_i64();
7500
            TCGv_i64 fp2 = tcg_temp_new_i64();
7501

    
7502
            gen_load_fpr64(ctx, fp0, fs);
7503
            gen_load_fpr64(ctx, fp1, ft);
7504
            gen_load_fpr64(ctx, fp2, fr);
7505
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7506
            tcg_temp_free_i64(fp0);
7507
            tcg_temp_free_i64(fp1);
7508
            gen_store_fpr64(ctx, fp2, fd);
7509
            tcg_temp_free_i64(fp2);
7510
        }
7511
        opn = "msub.ps";
7512
        break;
7513
    case OPC_NMADD_S:
7514
        check_cop1x(ctx);
7515
        {
7516
            TCGv_i32 fp0 = tcg_temp_new_i32();
7517
            TCGv_i32 fp1 = tcg_temp_new_i32();
7518
            TCGv_i32 fp2 = tcg_temp_new_i32();
7519

    
7520
            gen_load_fpr32(fp0, fs);
7521
            gen_load_fpr32(fp1, ft);
7522
            gen_load_fpr32(fp2, fr);
7523
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7524
            tcg_temp_free_i32(fp0);
7525
            tcg_temp_free_i32(fp1);
7526
            gen_store_fpr32(fp2, fd);
7527
            tcg_temp_free_i32(fp2);
7528
        }
7529
        opn = "nmadd.s";
7530
        break;
7531
    case OPC_NMADD_D:
7532
        check_cop1x(ctx);
7533
        check_cp1_registers(ctx, fd | fs | ft | fr);
7534
        {
7535
            TCGv_i64 fp0 = tcg_temp_new_i64();
7536
            TCGv_i64 fp1 = tcg_temp_new_i64();
7537
            TCGv_i64 fp2 = tcg_temp_new_i64();
7538

    
7539
            gen_load_fpr64(ctx, fp0, fs);
7540
            gen_load_fpr64(ctx, fp1, ft);
7541
            gen_load_fpr64(ctx, fp2, fr);
7542
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7543
            tcg_temp_free_i64(fp0);
7544
            tcg_temp_free_i64(fp1);
7545
            gen_store_fpr64(ctx, fp2, fd);
7546
            tcg_temp_free_i64(fp2);
7547
        }
7548
        opn = "nmadd.d";
7549
        break;
7550
    case OPC_NMADD_PS:
7551
        check_cp1_64bitmode(ctx);
7552
        {
7553
            TCGv_i64 fp0 = tcg_temp_new_i64();
7554
            TCGv_i64 fp1 = tcg_temp_new_i64();
7555
            TCGv_i64 fp2 = tcg_temp_new_i64();
7556

    
7557
            gen_load_fpr64(ctx, fp0, fs);
7558
            gen_load_fpr64(ctx, fp1, ft);
7559
            gen_load_fpr64(ctx, fp2, fr);
7560
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7561
            tcg_temp_free_i64(fp0);
7562
            tcg_temp_free_i64(fp1);
7563
            gen_store_fpr64(ctx, fp2, fd);
7564
            tcg_temp_free_i64(fp2);
7565
        }
7566
        opn = "nmadd.ps";
7567
        break;
7568
    case OPC_NMSUB_S:
7569
        check_cop1x(ctx);
7570
        {
7571
            TCGv_i32 fp0 = tcg_temp_new_i32();
7572
            TCGv_i32 fp1 = tcg_temp_new_i32();
7573
            TCGv_i32 fp2 = tcg_temp_new_i32();
7574

    
7575
            gen_load_fpr32(fp0, fs);
7576
            gen_load_fpr32(fp1, ft);
7577
            gen_load_fpr32(fp2, fr);
7578
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7579
            tcg_temp_free_i32(fp0);
7580
            tcg_temp_free_i32(fp1);
7581
            gen_store_fpr32(fp2, fd);
7582
            tcg_temp_free_i32(fp2);
7583
        }
7584
        opn = "nmsub.s";
7585
        break;
7586
    case OPC_NMSUB_D:
7587
        check_cop1x(ctx);
7588
        check_cp1_registers(ctx, fd | fs | ft | fr);
7589
        {
7590
            TCGv_i64 fp0 = tcg_temp_new_i64();
7591
            TCGv_i64 fp1 = tcg_temp_new_i64();
7592
            TCGv_i64 fp2 = tcg_temp_new_i64();
7593

    
7594
            gen_load_fpr64(ctx, fp0, fs);
7595
            gen_load_fpr64(ctx, fp1, ft);
7596
            gen_load_fpr64(ctx, fp2, fr);
7597
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7598
            tcg_temp_free_i64(fp0);
7599
            tcg_temp_free_i64(fp1);
7600
            gen_store_fpr64(ctx, fp2, fd);
7601
            tcg_temp_free_i64(fp2);
7602
        }
7603
        opn = "nmsub.d";
7604
        break;
7605
    case OPC_NMSUB_PS:
7606
        check_cp1_64bitmode(ctx);
7607
        {
7608
            TCGv_i64 fp0 = tcg_temp_new_i64();
7609
            TCGv_i64 fp1 = tcg_temp_new_i64();
7610
            TCGv_i64 fp2 = tcg_temp_new_i64();
7611

    
7612
            gen_load_fpr64(ctx, fp0, fs);
7613
            gen_load_fpr64(ctx, fp1, ft);
7614
            gen_load_fpr64(ctx, fp2, fr);
7615
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7616
            tcg_temp_free_i64(fp0);
7617
            tcg_temp_free_i64(fp1);
7618
            gen_store_fpr64(ctx, fp2, fd);
7619
            tcg_temp_free_i64(fp2);
7620
        }
7621
        opn = "nmsub.ps";
7622
        break;
7623
    default:
7624
        MIPS_INVAL(opn);
7625
        generate_exception (ctx, EXCP_RI);
7626
        return;
7627
    }
7628
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7629
               fregnames[fs], fregnames[ft]);
7630
}
7631

    
7632
/* ISA extensions (ASEs) */
7633
/* MIPS16 extension to MIPS32 */
7634
/* SmartMIPS extension to MIPS32 */
7635

    
7636
#if defined(TARGET_MIPS64)
7637

    
7638
/* MDMX extension to MIPS64 */
7639

    
7640
#endif
7641

    
7642
static void decode_opc (CPUState *env, DisasContext *ctx)
7643
{
7644
    int32_t offset;
7645
    int rs, rt, rd, sa;
7646
    uint32_t op, op1, op2;
7647
    int16_t imm;
7648

    
7649
    /* make sure instructions are on a word boundary */
7650
    if (ctx->pc & 0x3) {
7651
        env->CP0_BadVAddr = ctx->pc;
7652
        generate_exception(ctx, EXCP_AdEL);
7653
        return;
7654
    }
7655

    
7656
    /* Handle blikely not taken case */
7657
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7658
        int l1 = gen_new_label();
7659

    
7660
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7661
        tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7662
        {
7663
            TCGv_i32 r_tmp = tcg_temp_new_i32();
7664

    
7665
            tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7666
            tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7667
            tcg_temp_free_i32(r_tmp);
7668
        }
7669
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7670
        gen_set_label(l1);
7671
    }
7672
    op = MASK_OP_MAJOR(ctx->opcode);
7673
    rs = (ctx->opcode >> 21) & 0x1f;
7674
    rt = (ctx->opcode >> 16) & 0x1f;
7675
    rd = (ctx->opcode >> 11) & 0x1f;
7676
    sa = (ctx->opcode >> 6) & 0x1f;
7677
    imm = (int16_t)ctx->opcode;
7678
    switch (op) {
7679
    case OPC_SPECIAL:
7680
        op1 = MASK_SPECIAL(ctx->opcode);
7681
        switch (op1) {
7682
        case OPC_SLL:          /* Arithmetic with immediate */
7683
        case OPC_SRL ... OPC_SRA:
7684
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7685
            break;
7686
        case OPC_MOVZ ... OPC_MOVN:
7687
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7688
        case OPC_SLLV:         /* Arithmetic */
7689
        case OPC_SRLV ... OPC_SRAV:
7690
        case OPC_ADD ... OPC_NOR:
7691
        case OPC_SLT ... OPC_SLTU:
7692
            gen_arith(env, ctx, op1, rd, rs, rt);
7693
            break;
7694
        case OPC_MULT ... OPC_DIVU:
7695
            if (sa) {
7696
                check_insn(env, ctx, INSN_VR54XX);
7697
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7698
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7699
            } else
7700
                gen_muldiv(ctx, op1, rs, rt);
7701
            break;
7702
        case OPC_JR ... OPC_JALR:
7703
            gen_compute_branch(ctx, op1, rs, rd, sa);
7704
            return;
7705
        case OPC_TGE ... OPC_TEQ: /* Traps */
7706
        case OPC_TNE:
7707
            gen_trap(ctx, op1, rs, rt, -1);
7708
            break;
7709
        case OPC_MFHI:          /* Move from HI/LO */
7710
        case OPC_MFLO:
7711
            gen_HILO(ctx, op1, rd);
7712
            break;
7713
        case OPC_MTHI:
7714
        case OPC_MTLO:          /* Move to HI/LO */
7715
            gen_HILO(ctx, op1, rs);
7716
            break;
7717
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7718
#ifdef MIPS_STRICT_STANDARD
7719
            MIPS_INVAL("PMON / selsl");
7720
            generate_exception(ctx, EXCP_RI);
7721
#else
7722
            gen_helper_0i(pmon, sa);
7723
#endif
7724
            break;
7725
        case OPC_SYSCALL:
7726
            generate_exception(ctx, EXCP_SYSCALL);
7727
            break;
7728
        case OPC_BREAK:
7729
            generate_exception(ctx, EXCP_BREAK);
7730
            break;
7731
        case OPC_SPIM:
7732
#ifdef MIPS_STRICT_STANDARD
7733
            MIPS_INVAL("SPIM");
7734
            generate_exception(ctx, EXCP_RI);
7735
#else
7736
           /* Implemented as RI exception for now. */
7737
            MIPS_INVAL("spim (unofficial)");
7738
            generate_exception(ctx, EXCP_RI);
7739
#endif
7740
            break;
7741
        case OPC_SYNC:
7742
            /* Treat as NOP. */
7743
            break;
7744

    
7745
        case OPC_MOVCI:
7746
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7747
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7748
                save_cpu_state(ctx, 1);
7749
                check_cp1_enabled(ctx);
7750
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7751
                          (ctx->opcode >> 16) & 1);
7752
            } else {
7753
                generate_exception_err(ctx, EXCP_CpU, 1);
7754
            }
7755
            break;
7756

    
7757
#if defined(TARGET_MIPS64)
7758
       /* MIPS64 specific opcodes */
7759
        case OPC_DSLL:
7760
        case OPC_DSRL ... OPC_DSRA:
7761
        case OPC_DSLL32:
7762
        case OPC_DSRL32 ... OPC_DSRA32:
7763
            check_insn(env, ctx, ISA_MIPS3);
7764
            check_mips_64(ctx);
7765
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7766
            break;
7767
        case OPC_DSLLV:
7768
        case OPC_DSRLV ... OPC_DSRAV:
7769
        case OPC_DADD ... OPC_DSUBU:
7770
            check_insn(env, ctx, ISA_MIPS3);
7771
            check_mips_64(ctx);
7772
            gen_arith(env, ctx, op1, rd, rs, rt);
7773
            break;
7774
        case OPC_DMULT ... OPC_DDIVU:
7775
            check_insn(env, ctx, ISA_MIPS3);
7776
            check_mips_64(ctx);
7777
            gen_muldiv(ctx, op1, rs, rt);
7778
            break;
7779
#endif
7780
        default:            /* Invalid */
7781
            MIPS_INVAL("special");
7782
            generate_exception(ctx, EXCP_RI);
7783
            break;
7784
        }
7785
        break;
7786
    case OPC_SPECIAL2:
7787
        op1 = MASK_SPECIAL2(ctx->opcode);
7788
        switch (op1) {
7789
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7790
        case OPC_MSUB ... OPC_MSUBU:
7791
            check_insn(env, ctx, ISA_MIPS32);
7792
            gen_muldiv(ctx, op1, rs, rt);
7793
            break;
7794
        case OPC_MUL:
7795
            gen_arith(env, ctx, op1, rd, rs, rt);
7796
            break;
7797
        case OPC_CLZ ... OPC_CLO:
7798
            check_insn(env, ctx, ISA_MIPS32);
7799
            gen_cl(ctx, op1, rd, rs);
7800
            break;
7801
        case OPC_SDBBP:
7802
            /* XXX: not clear which exception should be raised
7803
             *      when in debug mode...
7804
             */
7805
            check_insn(env, ctx, ISA_MIPS32);
7806
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7807
                generate_exception(ctx, EXCP_DBp);
7808
            } else {
7809
                generate_exception(ctx, EXCP_DBp);
7810
            }
7811
            /* Treat as NOP. */
7812
            break;
7813
#if defined(TARGET_MIPS64)
7814
        case OPC_DCLZ ... OPC_DCLO:
7815
            check_insn(env, ctx, ISA_MIPS64);
7816
            check_mips_64(ctx);
7817
            gen_cl(ctx, op1, rd, rs);
7818
            break;
7819
#endif
7820
        default:            /* Invalid */
7821
            MIPS_INVAL("special2");
7822
            generate_exception(ctx, EXCP_RI);
7823
            break;
7824
        }
7825
        break;
7826
    case OPC_SPECIAL3:
7827
        op1 = MASK_SPECIAL3(ctx->opcode);
7828
        switch (op1) {
7829
        case OPC_EXT:
7830
        case OPC_INS:
7831
            check_insn(env, ctx, ISA_MIPS32R2);
7832
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7833
            break;
7834
        case OPC_BSHFL:
7835
            check_insn(env, ctx, ISA_MIPS32R2);
7836
            op2 = MASK_BSHFL(ctx->opcode);
7837
            gen_bshfl(ctx, op2, rt, rd);
7838
            break;
7839
        case OPC_RDHWR:
7840
            check_insn(env, ctx, ISA_MIPS32R2);
7841
            {
7842
                TCGv t0 = tcg_temp_local_new();
7843

    
7844
                switch (rd) {
7845
                case 0:
7846
                    save_cpu_state(ctx, 1);
7847
                    gen_helper_rdhwr_cpunum(t0);
7848
                    break;
7849
                case 1:
7850
                    save_cpu_state(ctx, 1);
7851
                    gen_helper_rdhwr_synci_step(t0);
7852
                    break;
7853
                case 2:
7854
                    save_cpu_state(ctx, 1);
7855
                    gen_helper_rdhwr_cc(t0);
7856
                    break;
7857
                case 3:
7858
                    save_cpu_state(ctx, 1);
7859
                    gen_helper_rdhwr_ccres(t0);
7860
                    break;
7861
                case 29:
7862
#if defined(CONFIG_USER_ONLY)
7863
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7864
                    break;
7865
#else
7866
                    /* XXX: Some CPUs implement this in hardware.
7867
                       Not supported yet. */
7868
#endif
7869
                default:            /* Invalid */
7870
                    MIPS_INVAL("rdhwr");
7871
                    generate_exception(ctx, EXCP_RI);
7872
                    break;
7873
                }
7874
                gen_store_gpr(t0, rt);
7875
                tcg_temp_free(t0);
7876
            }
7877
            break;
7878
        case OPC_FORK:
7879
            check_insn(env, ctx, ASE_MT);
7880
            {
7881
                TCGv t0 = tcg_temp_local_new();
7882
                TCGv t1 = tcg_temp_local_new();
7883

    
7884
                gen_load_gpr(t0, rt);
7885
                gen_load_gpr(t1, rs);
7886
                gen_helper_fork(t0, t1);
7887
                tcg_temp_free(t0);
7888
                tcg_temp_free(t1);
7889
            }
7890
            break;
7891
        case OPC_YIELD:
7892
            check_insn(env, ctx, ASE_MT);
7893
            {
7894
                TCGv t0 = tcg_temp_local_new();
7895

    
7896
                gen_load_gpr(t0, rs);
7897
                gen_helper_yield(t0, t0);
7898
                gen_store_gpr(t0, rd);
7899
                tcg_temp_free(t0);
7900
            }
7901
            break;
7902
#if defined(TARGET_MIPS64)
7903
        case OPC_DEXTM ... OPC_DEXT:
7904
        case OPC_DINSM ... OPC_DINS:
7905
            check_insn(env, ctx, ISA_MIPS64R2);
7906
            check_mips_64(ctx);
7907
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7908
            break;
7909
        case OPC_DBSHFL:
7910
            check_insn(env, ctx, ISA_MIPS64R2);
7911
            check_mips_64(ctx);
7912
            op2 = MASK_DBSHFL(ctx->opcode);
7913
            gen_bshfl(ctx, op2, rt, rd);
7914
            break;
7915
#endif
7916
        default:            /* Invalid */
7917
            MIPS_INVAL("special3");
7918
            generate_exception(ctx, EXCP_RI);
7919
            break;
7920
        }
7921
        break;
7922
    case OPC_REGIMM:
7923
        op1 = MASK_REGIMM(ctx->opcode);
7924
        switch (op1) {
7925
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7926
        case OPC_BLTZAL ... OPC_BGEZALL:
7927
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7928
            return;
7929
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7930
        case OPC_TNEI:
7931
            gen_trap(ctx, op1, rs, -1, imm);
7932
            break;
7933
        case OPC_SYNCI:
7934
            check_insn(env, ctx, ISA_MIPS32R2);
7935
            /* Treat as NOP. */
7936
            break;
7937
        default:            /* Invalid */
7938
            MIPS_INVAL("regimm");
7939
            generate_exception(ctx, EXCP_RI);
7940
            break;
7941
        }
7942
        break;
7943
    case OPC_CP0:
7944
        check_cp0_enabled(ctx);
7945
        op1 = MASK_CP0(ctx->opcode);
7946
        switch (op1) {
7947
        case OPC_MFC0:
7948
        case OPC_MTC0:
7949
        case OPC_MFTR:
7950
        case OPC_MTTR:
7951
#if defined(TARGET_MIPS64)
7952
        case OPC_DMFC0:
7953
        case OPC_DMTC0:
7954
#endif
7955
#ifndef CONFIG_USER_ONLY
7956
            gen_cp0(env, ctx, op1, rt, rd);
7957
#endif /* !CONFIG_USER_ONLY */
7958
            break;
7959
        case OPC_C0_FIRST ... OPC_C0_LAST:
7960
#ifndef CONFIG_USER_ONLY
7961
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7962
#endif /* !CONFIG_USER_ONLY */
7963
            break;
7964
        case OPC_MFMC0:
7965
#ifndef CONFIG_USER_ONLY
7966
            {
7967
                TCGv t0 = tcg_temp_local_new();
7968

    
7969
                op2 = MASK_MFMC0(ctx->opcode);
7970
                switch (op2) {
7971
                case OPC_DMT:
7972
                    check_insn(env, ctx, ASE_MT);
7973
                    gen_helper_dmt(t0, t0);
7974
                    break;
7975
                case OPC_EMT:
7976
                    check_insn(env, ctx, ASE_MT);
7977
                    gen_helper_emt(t0, t0);
7978
                    break;
7979
                case OPC_DVPE:
7980
                    check_insn(env, ctx, ASE_MT);
7981
                    gen_helper_dvpe(t0, t0);
7982
                    break;
7983
                case OPC_EVPE:
7984
                    check_insn(env, ctx, ASE_MT);
7985
                    gen_helper_evpe(t0, t0);
7986
                    break;
7987
                case OPC_DI:
7988
                    check_insn(env, ctx, ISA_MIPS32R2);
7989
                    save_cpu_state(ctx, 1);
7990
                    gen_helper_di(t0);
7991
                    /* Stop translation as we may have switched the execution mode */
7992
                    ctx->bstate = BS_STOP;
7993
                    break;
7994
                case OPC_EI:
7995
                    check_insn(env, ctx, ISA_MIPS32R2);
7996
                    save_cpu_state(ctx, 1);
7997
                    gen_helper_ei(t0);
7998
                    /* Stop translation as we may have switched the execution mode */
7999
                    ctx->bstate = BS_STOP;
8000
                    break;
8001
                default:            /* Invalid */
8002
                    MIPS_INVAL("mfmc0");
8003
                    generate_exception(ctx, EXCP_RI);
8004
                    break;
8005
                }
8006
                gen_store_gpr(t0, rt);
8007
                tcg_temp_free(t0);
8008
            }
8009
#endif /* !CONFIG_USER_ONLY */
8010
            break;
8011
        case OPC_RDPGPR:
8012
            check_insn(env, ctx, ISA_MIPS32R2);
8013
            gen_load_srsgpr(rt, rd);
8014
            break;
8015
        case OPC_WRPGPR:
8016
            check_insn(env, ctx, ISA_MIPS32R2);
8017
            gen_store_srsgpr(rt, rd);
8018
            break;
8019
        default:
8020
            MIPS_INVAL("cp0");
8021
            generate_exception(ctx, EXCP_RI);
8022
            break;
8023
        }
8024
        break;
8025
    case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
8026
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8027
         break;
8028
    case OPC_J ... OPC_JAL: /* Jump */
8029
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8030
         gen_compute_branch(ctx, op, rs, rt, offset);
8031
         return;
8032
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8033
    case OPC_BEQL ... OPC_BGTZL:
8034
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8035
         return;
8036
    case OPC_LB ... OPC_LWR: /* Load and stores */
8037
    case OPC_SB ... OPC_SW:
8038
    case OPC_SWR:
8039
    case OPC_LL:
8040
    case OPC_SC:
8041
         gen_ldst(ctx, op, rt, rs, imm);
8042
         break;
8043
    case OPC_CACHE:
8044
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8045
        /* Treat as NOP. */
8046
        break;
8047
    case OPC_PREF:
8048
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8049
        /* Treat as NOP. */
8050
        break;
8051

    
8052
    /* Floating point (COP1). */
8053
    case OPC_LWC1:
8054
    case OPC_LDC1:
8055
    case OPC_SWC1:
8056
    case OPC_SDC1:
8057
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8058
            save_cpu_state(ctx, 1);
8059
            check_cp1_enabled(ctx);
8060
            gen_flt_ldst(ctx, op, rt, rs, imm);
8061
        } else {
8062
            generate_exception_err(ctx, EXCP_CpU, 1);
8063
        }
8064
        break;
8065

    
8066
    case OPC_CP1:
8067
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8068
            save_cpu_state(ctx, 1);
8069
            check_cp1_enabled(ctx);
8070
            op1 = MASK_CP1(ctx->opcode);
8071
            switch (op1) {
8072
            case OPC_MFHC1:
8073
            case OPC_MTHC1:
8074
                check_insn(env, ctx, ISA_MIPS32R2);
8075
            case OPC_MFC1:
8076
            case OPC_CFC1:
8077
            case OPC_MTC1:
8078
            case OPC_CTC1:
8079
                gen_cp1(ctx, op1, rt, rd);
8080
                break;
8081
#if defined(TARGET_MIPS64)
8082
            case OPC_DMFC1:
8083
            case OPC_DMTC1:
8084
                check_insn(env, ctx, ISA_MIPS3);
8085
                gen_cp1(ctx, op1, rt, rd);
8086
                break;
8087
#endif
8088
            case OPC_BC1ANY2:
8089
            case OPC_BC1ANY4:
8090
                check_cop1x(ctx);
8091
                check_insn(env, ctx, ASE_MIPS3D);
8092
                /* fall through */
8093
            case OPC_BC1:
8094
                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8095
                                    (rt >> 2) & 0x7, imm << 2);
8096
                return;
8097
            case OPC_S_FMT:
8098
            case OPC_D_FMT:
8099
            case OPC_W_FMT:
8100
            case OPC_L_FMT:
8101
            case OPC_PS_FMT:
8102
                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8103
                           (imm >> 8) & 0x7);
8104
                break;
8105
            default:
8106
                MIPS_INVAL("cp1");
8107
                generate_exception (ctx, EXCP_RI);
8108
                break;
8109
            }
8110
        } else {
8111
            generate_exception_err(ctx, EXCP_CpU, 1);
8112
        }
8113
        break;
8114

    
8115
    /* COP2.  */
8116
    case OPC_LWC2:
8117
    case OPC_LDC2:
8118
    case OPC_SWC2:
8119
    case OPC_SDC2:
8120
    case OPC_CP2:
8121
        /* COP2: Not implemented. */
8122
        generate_exception_err(ctx, EXCP_CpU, 2);
8123
        break;
8124

    
8125
    case OPC_CP3:
8126
        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8127
            save_cpu_state(ctx, 1);
8128
            check_cp1_enabled(ctx);
8129
            op1 = MASK_CP3(ctx->opcode);
8130
            switch (op1) {
8131
            case OPC_LWXC1:
8132
            case OPC_LDXC1:
8133
            case OPC_LUXC1:
8134
            case OPC_SWXC1:
8135
            case OPC_SDXC1:
8136
            case OPC_SUXC1:
8137
                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8138
                break;
8139
            case OPC_PREFX:
8140
                /* Treat as NOP. */
8141
                break;
8142
            case OPC_ALNV_PS:
8143
            case OPC_MADD_S:
8144
            case OPC_MADD_D:
8145
            case OPC_MADD_PS:
8146
            case OPC_MSUB_S:
8147
            case OPC_MSUB_D:
8148
            case OPC_MSUB_PS:
8149
            case OPC_NMADD_S:
8150
            case OPC_NMADD_D:
8151
            case OPC_NMADD_PS:
8152
            case OPC_NMSUB_S:
8153
            case OPC_NMSUB_D:
8154
            case OPC_NMSUB_PS:
8155
                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8156
                break;
8157
            default:
8158
                MIPS_INVAL("cp3");
8159
                generate_exception (ctx, EXCP_RI);
8160
                break;
8161
            }
8162
        } else {
8163
            generate_exception_err(ctx, EXCP_CpU, 1);
8164
        }
8165
        break;
8166

    
8167
#if defined(TARGET_MIPS64)
8168
    /* MIPS64 opcodes */
8169
    case OPC_LWU:
8170
    case OPC_LDL ... OPC_LDR:
8171
    case OPC_SDL ... OPC_SDR:
8172
    case OPC_LLD:
8173
    case OPC_LD:
8174
    case OPC_SCD:
8175
    case OPC_SD:
8176
        check_insn(env, ctx, ISA_MIPS3);
8177
        check_mips_64(ctx);
8178
        gen_ldst(ctx, op, rt, rs, imm);
8179
        break;
8180
    case OPC_DADDI ... OPC_DADDIU:
8181
        check_insn(env, ctx, ISA_MIPS3);
8182
        check_mips_64(ctx);
8183
        gen_arith_imm(env, ctx, op, rt, rs, imm);
8184
        break;
8185
#endif
8186
    case OPC_JALX:
8187
        check_insn(env, ctx, ASE_MIPS16);
8188
        /* MIPS16: Not implemented. */
8189
    case OPC_MDMX:
8190
        check_insn(env, ctx, ASE_MDMX);
8191
        /* MDMX: Not implemented. */
8192
    default:            /* Invalid */
8193
        MIPS_INVAL("major opcode");
8194
        generate_exception(ctx, EXCP_RI);
8195
        break;
8196
    }
8197
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8198
        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8199
        /* Branches completion */
8200
        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8201
        ctx->bstate = BS_BRANCH;
8202
        save_cpu_state(ctx, 0);
8203
        /* FIXME: Need to clear can_do_io.  */
8204
        switch (hflags) {
8205
        case MIPS_HFLAG_B:
8206
            /* unconditional branch */
8207
            MIPS_DEBUG("unconditional branch");
8208
            gen_goto_tb(ctx, 0, ctx->btarget);
8209
            break;
8210
        case MIPS_HFLAG_BL:
8211
            /* blikely taken case */
8212
            MIPS_DEBUG("blikely branch taken");
8213
            gen_goto_tb(ctx, 0, ctx->btarget);
8214
            break;
8215
        case MIPS_HFLAG_BC:
8216
            /* Conditional branch */
8217
            MIPS_DEBUG("conditional branch");
8218
            {
8219
                int l1 = gen_new_label();
8220

    
8221
                tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8222
                gen_goto_tb(ctx, 1, ctx->pc + 4);
8223
                gen_set_label(l1);
8224
                gen_goto_tb(ctx, 0, ctx->btarget);
8225
            }
8226
            break;
8227
        case MIPS_HFLAG_BR:
8228
            /* unconditional branch to register */
8229
            MIPS_DEBUG("branch to register");
8230
            tcg_gen_mov_tl(cpu_PC, btarget);
8231
            tcg_gen_exit_tb(0);
8232
            break;
8233
        default:
8234
            MIPS_DEBUG("unknown branch");
8235
            break;
8236
        }
8237
    }
8238
}
8239

    
8240
static inline void
8241
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8242
                                int search_pc)
8243
{
8244
    DisasContext ctx;
8245
    target_ulong pc_start;
8246
    uint16_t *gen_opc_end;
8247
    CPUBreakpoint *bp;
8248
    int j, lj = -1;
8249
    int num_insns;
8250
    int max_insns;
8251

    
8252
    if (search_pc && loglevel)
8253
        fprintf (logfile, "search pc %d\n", search_pc);
8254

    
8255
    pc_start = tb->pc;
8256
    /* Leave some spare opc slots for branch handling. */
8257
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8258
    ctx.pc = pc_start;
8259
    ctx.saved_pc = -1;
8260
    ctx.tb = tb;
8261
    ctx.bstate = BS_NONE;
8262
    /* Restore delay slot state from the tb context.  */
8263
    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8264
    restore_cpu_state(env, &ctx);
8265
#ifdef CONFIG_USER_ONLY
8266
        ctx.mem_idx = MIPS_HFLAG_UM;
8267
#else
8268
        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8269
#endif
8270
    num_insns = 0;
8271
    max_insns = tb->cflags & CF_COUNT_MASK;
8272
    if (max_insns == 0)
8273
        max_insns = CF_COUNT_MASK;
8274
#ifdef DEBUG_DISAS
8275
    if (loglevel & CPU_LOG_TB_CPU) {
8276
        fprintf(logfile, "------------------------------------------------\n");
8277
        /* FIXME: This may print out stale hflags from env... */
8278
        cpu_dump_state(env, logfile, fprintf, 0);
8279
    }
8280
#endif
8281
#ifdef MIPS_DEBUG_DISAS
8282
    if (loglevel & CPU_LOG_TB_IN_ASM)
8283
        fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
8284
                tb, ctx.mem_idx, ctx.hflags);
8285
#endif
8286
    gen_icount_start();
8287
    while (ctx.bstate == BS_NONE) {
8288
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8289
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8290
                if (bp->pc == ctx.pc) {
8291
                    save_cpu_state(&ctx, 1);
8292
                    ctx.bstate = BS_BRANCH;
8293
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8294
                    /* Include the breakpoint location or the tb won't
8295
                     * be flushed when it must be.  */
8296
                    ctx.pc += 4;
8297
                    goto done_generating;
8298
                }
8299
            }
8300
        }
8301

    
8302
        if (search_pc) {
8303
            j = gen_opc_ptr - gen_opc_buf;
8304
            if (lj < j) {
8305
                lj++;
8306
                while (lj < j)
8307
                    gen_opc_instr_start[lj++] = 0;
8308
            }
8309
            gen_opc_pc[lj] = ctx.pc;
8310
            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8311
            gen_opc_instr_start[lj] = 1;
8312
            gen_opc_icount[lj] = num_insns;
8313
        }
8314
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8315
            gen_io_start();
8316
        ctx.opcode = ldl_code(ctx.pc);
8317
        decode_opc(env, &ctx);
8318
        ctx.pc += 4;
8319
        num_insns++;
8320

    
8321
        if (env->singlestep_enabled)
8322
            break;
8323

    
8324
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8325
            break;
8326

    
8327
        if (gen_opc_ptr >= gen_opc_end)
8328
            break;
8329

    
8330
        if (num_insns >= max_insns)
8331
            break;
8332
#if defined (MIPS_SINGLE_STEP)
8333
        break;
8334
#endif
8335
    }
8336
    if (tb->cflags & CF_LAST_IO)
8337
        gen_io_end();
8338
    if (env->singlestep_enabled) {
8339
        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8340
        gen_helper_0i(raise_exception, EXCP_DEBUG);
8341
    } else {
8342
        switch (ctx.bstate) {
8343
        case BS_STOP:
8344
            gen_helper_interrupt_restart();
8345
            gen_goto_tb(&ctx, 0, ctx.pc);
8346
            break;
8347
        case BS_NONE:
8348
            save_cpu_state(&ctx, 0);
8349
            gen_goto_tb(&ctx, 0, ctx.pc);
8350
            break;
8351
        case BS_EXCP:
8352
            gen_helper_interrupt_restart();
8353
            tcg_gen_exit_tb(0);
8354
            break;
8355
        case BS_BRANCH:
8356
        default:
8357
            break;
8358
        }
8359
    }
8360
done_generating:
8361
    gen_icount_end(tb, num_insns);
8362
    *gen_opc_ptr = INDEX_op_end;
8363
    if (search_pc) {
8364
        j = gen_opc_ptr - gen_opc_buf;
8365
        lj++;
8366
        while (lj <= j)
8367
            gen_opc_instr_start[lj++] = 0;
8368
    } else {
8369
        tb->size = ctx.pc - pc_start;
8370
        tb->icount = num_insns;
8371
    }
8372
#ifdef DEBUG_DISAS
8373
#if defined MIPS_DEBUG_DISAS
8374
    if (loglevel & CPU_LOG_TB_IN_ASM)
8375
        fprintf(logfile, "\n");
8376
#endif
8377
    if (loglevel & CPU_LOG_TB_IN_ASM) {
8378
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8379
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
8380
        fprintf(logfile, "\n");
8381
    }
8382
    if (loglevel & CPU_LOG_TB_CPU) {
8383
        fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8384
    }
8385
#endif
8386
}
8387

    
8388
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8389
{
8390
    gen_intermediate_code_internal(env, tb, 0);
8391
}
8392

    
8393
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8394
{
8395
    gen_intermediate_code_internal(env, tb, 1);
8396
}
8397

    
8398
static void fpu_dump_state(CPUState *env, FILE *f,
8399
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8400
                           int flags)
8401
{
8402
    int i;
8403
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8404

    
8405
#define printfpr(fp)                                                        \
8406
    do {                                                                    \
8407
        if (is_fpu64)                                                       \
8408
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8409
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8410
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8411
        else {                                                              \
8412
            fpr_t tmp;                                                      \
8413
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8414
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8415
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8416
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8417
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8418
        }                                                                   \
8419
    } while(0)
8420

    
8421

    
8422
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8423
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8424
                get_float_exception_flags(&env->active_fpu.fp_status));
8425
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8426
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8427
        printfpr(&env->active_fpu.fpr[i]);
8428
    }
8429

    
8430
#undef printfpr
8431
}
8432

    
8433
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8434
/* Debug help: The architecture requires 32bit code to maintain proper
8435
   sign-extended values on 64bit machines.  */
8436

    
8437
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8438

    
8439
static void
8440
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8441
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8442
                                int flags)
8443
{
8444
    int i;
8445

    
8446
    if (!SIGN_EXT_P(env->active_tc.PC))
8447
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8448
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8449
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8450
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8451
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8452
    if (!SIGN_EXT_P(env->btarget))
8453
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8454

    
8455
    for (i = 0; i < 32; i++) {
8456
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8457
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8458
    }
8459

    
8460
    if (!SIGN_EXT_P(env->CP0_EPC))
8461
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8462
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8463
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8464
}
8465
#endif
8466

    
8467
void cpu_dump_state (CPUState *env, FILE *f,
8468
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8469
                     int flags)
8470
{
8471
    int i;
8472

    
8473
    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",
8474
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8475
                env->hflags, env->btarget, env->bcond);
8476
    for (i = 0; i < 32; i++) {
8477
        if ((i & 3) == 0)
8478
            cpu_fprintf(f, "GPR%02d:", i);
8479
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8480
        if ((i & 3) == 3)
8481
            cpu_fprintf(f, "\n");
8482
    }
8483

    
8484
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8485
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8486
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8487
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8488
    if (env->hflags & MIPS_HFLAG_FPU)
8489
        fpu_dump_state(env, f, cpu_fprintf, flags);
8490
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8491
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8492
#endif
8493
}
8494

    
8495
static void mips_tcg_init(void)
8496
{
8497
    int i;
8498
    static int inited;
8499

    
8500
    /* Initialize various static tables. */
8501
    if (inited)
8502
        return;
8503

    
8504
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8505
    for (i = 0; i < 32; i++)
8506
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8507
                                        offsetof(CPUState, active_tc.gpr[i]),
8508
                                        regnames[i]);
8509
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8510
                                offsetof(CPUState, active_tc.PC), "PC");
8511
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8512
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8513
                                       offsetof(CPUState, active_tc.HI[i]),
8514
                                       regnames_HI[i]);
8515
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8516
                                       offsetof(CPUState, active_tc.LO[i]),
8517
                                       regnames_LO[i]);
8518
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8519
                                        offsetof(CPUState, active_tc.ACX[i]),
8520
                                        regnames_ACX[i]);
8521
    }
8522
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8523
                                     offsetof(CPUState, active_tc.DSPControl),
8524
                                     "DSPControl");
8525
    bcond = tcg_global_mem_new_i32(TCG_AREG0,
8526
                                   offsetof(CPUState, bcond), "bcond");
8527
    btarget = tcg_global_mem_new(TCG_AREG0,
8528
                                 offsetof(CPUState, btarget), "btarget");
8529
    for (i = 0; i < 32; i++)
8530
        fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
8531
            offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8532
            fregnames[i]);
8533
    for (i = 0; i < 32; i++)
8534
        fpu_fpr64[i] = tcg_global_mem_new_i64(TCG_AREG0,
8535
            offsetof(CPUState, active_fpu.fpr[i]),
8536
            fregnames_64[i]);
8537
    for (i = 0; i < 32; i++)
8538
        fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
8539
            offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8540
            fregnames_h[i]);
8541
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8542
                                      offsetof(CPUState, active_fpu.fcr0),
8543
                                      "fcr0");
8544
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8545
                                       offsetof(CPUState, active_fpu.fcr31),
8546
                                       "fcr31");
8547

    
8548
    /* register helpers */
8549
#define GEN_HELPER 2
8550
#include "helper.h"
8551

    
8552
    inited = 1;
8553
}
8554

    
8555
#include "translate_init.c"
8556

    
8557
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8558
{
8559
    CPUMIPSState *env;
8560
    const mips_def_t *def;
8561

    
8562
    def = cpu_mips_find_by_name(cpu_model);
8563
    if (!def)
8564
        return NULL;
8565
    env = qemu_mallocz(sizeof(CPUMIPSState));
8566
    if (!env)
8567
        return NULL;
8568
    env->cpu_model = def;
8569

    
8570
    cpu_exec_init(env);
8571
    env->cpu_model_str = cpu_model;
8572
    mips_tcg_init();
8573
    cpu_reset(env);
8574
    return env;
8575
}
8576

    
8577
void cpu_reset (CPUMIPSState *env)
8578
{
8579
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8580

    
8581
    tlb_flush(env, 1);
8582

    
8583
    /* Minimal init */
8584
#if defined(CONFIG_USER_ONLY)
8585
    env->hflags = MIPS_HFLAG_UM;
8586
#else
8587
    if (env->hflags & MIPS_HFLAG_BMASK) {
8588
        /* If the exception was raised from a delay slot,
8589
           come back to the jump.  */
8590
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8591
    } else {
8592
        env->CP0_ErrorEPC = env->active_tc.PC;
8593
    }
8594
    env->active_tc.PC = (int32_t)0xBFC00000;
8595
    env->CP0_Wired = 0;
8596
    /* SMP not implemented */
8597
    env->CP0_EBase = 0x80000000;
8598
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8599
    /* vectored interrupts not implemented, timer on int 7,
8600
       no performance counters. */
8601
    env->CP0_IntCtl = 0xe0000000;
8602
    {
8603
        int i;
8604

    
8605
        for (i = 0; i < 7; i++) {
8606
            env->CP0_WatchLo[i] = 0;
8607
            env->CP0_WatchHi[i] = 0x80000000;
8608
        }
8609
        env->CP0_WatchLo[7] = 0;
8610
        env->CP0_WatchHi[7] = 0;
8611
    }
8612
    /* Count register increments in debug mode, EJTAG version 1 */
8613
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8614
    env->hflags = MIPS_HFLAG_CP0;
8615
#endif
8616
    env->exception_index = EXCP_NONE;
8617
    cpu_mips_register(env, env->cpu_model);
8618
}
8619

    
8620
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8621
                unsigned long searched_pc, int pc_pos, void *puc)
8622
{
8623
    env->active_tc.PC = gen_opc_pc[pc_pos];
8624
    env->hflags &= ~MIPS_HFLAG_BMASK;
8625
    env->hflags |= gen_opc_hflags[pc_pos];
8626
}