Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 30a3848b

History | View | Annotate | Download (247.5 kB)

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

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

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

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

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

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

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

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

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

    
188
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
189

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
437
#include "gen-icount.h"
438

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
647
static inline int get_fp_bit (int cc)
648
{
649
    if (cc)
650
        return 24 + cc;
651
    else
652
        return 23;
653
}
654

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

    
680
FOP_CONDS(, d, 64)
681
FOP_CONDS(abs, d, 64)
682
FOP_CONDS(, s, 32)
683
FOP_CONDS(abs, s, 32)
684
FOP_CONDS(, ps, 64)
685
FOP_CONDS(abs, ps, 64)
686
#undef FOP_CONDS
687

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

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

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

    
746
static inline void gen_save_pc(target_ulong pc)
747
{
748
    tcg_gen_movi_tl(cpu_PC, pc);
749
}
750

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

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

    
787
static inline void
788
generate_exception_err (DisasContext *ctx, int excp, int err)
789
{
790
    TCGv_i32 texcp = tcg_const_i32(excp);
791
    TCGv_i32 terr = tcg_const_i32(err);
792
    save_cpu_state(ctx, 1);
793
    gen_helper_raise_exception_err(texcp, terr);
794
    tcg_temp_free_i32(terr);
795
    tcg_temp_free_i32(texcp);
796
    gen_helper_interrupt_restart();
797
    tcg_gen_exit_tb(0);
798
}
799

    
800
static inline void
801
generate_exception (DisasContext *ctx, int excp)
802
{
803
    save_cpu_state(ctx, 1);
804
    gen_helper_0i(raise_exception, excp);
805
    gen_helper_interrupt_restart();
806
    tcg_gen_exit_tb(0);
807
}
808

    
809
/* Addresses computation */
810
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
811
{
812
    tcg_gen_add_tl(t0, t0, t1);
813

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

    
825
static inline void check_cp0_enabled(DisasContext *ctx)
826
{
827
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
828
        generate_exception_err(ctx, EXCP_CpU, 1);
829
}
830

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

    
837
/* Verify that the processor is running with COP1X instructions enabled.
838
   This is associated with the nabla symbol in the MIPS32 and MIPS64
839
   opcode tables.  */
840

    
841
static inline void check_cop1x(DisasContext *ctx)
842
{
843
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
844
        generate_exception(ctx, EXCP_RI);
845
}
846

    
847
/* Verify that the processor is running with 64-bit floating-point
848
   operations enabled.  */
849

    
850
static inline void check_cp1_64bitmode(DisasContext *ctx)
851
{
852
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
853
        generate_exception(ctx, EXCP_RI);
854
}
855

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

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

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

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

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

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

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

    
961
/* Load and store */
962
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
963
                      int base, int16_t offset)
964
{
965
    const char *opn = "ldst";
966
    TCGv t0 = tcg_temp_new();
967
    TCGv t1 = tcg_temp_new();
968

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

    
1118
/* Store conditional */
1119
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1120
                         int base, int16_t offset)
1121
{
1122
    const char *opn = "st_cond";
1123
    TCGv t0, t1;
1124

    
1125
    t0 = tcg_temp_local_new();
1126

    
1127
    if (base == 0) {
1128
        tcg_gen_movi_tl(t0, offset);
1129
    } else if (offset == 0) {
1130
        gen_load_gpr(t0, base);
1131
    } else {
1132
        tcg_gen_movi_tl(t0, offset);
1133
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1134
    }
1135
    /* Don't do NOP if destination is zero: we must perform the actual
1136
       memory access. */
1137

    
1138
    t1 = tcg_temp_local_new();
1139
    gen_load_gpr(t1, rt);
1140
    switch (opc) {
1141
#if defined(TARGET_MIPS64)
1142
    case OPC_SCD:
1143
        save_cpu_state(ctx, 0);
1144
        op_ldst_scd(t0, t1, ctx);
1145
        opn = "scd";
1146
        break;
1147
#endif
1148
    case OPC_SC:
1149
        save_cpu_state(ctx, 0);
1150
        op_ldst_sc(t0, t1, ctx);
1151
        opn = "sc";
1152
        break;
1153
    }
1154
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1155
    tcg_temp_free(t1);
1156
    gen_store_gpr(t0, rt);
1157
    tcg_temp_free(t0);
1158
}
1159

    
1160
/* Load and store */
1161
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1162
                          int base, int16_t offset)
1163
{
1164
    const char *opn = "flt_ldst";
1165
    TCGv t0 = tcg_temp_new();
1166

    
1167
    if (base == 0) {
1168
        tcg_gen_movi_tl(t0, offset);
1169
    } else if (offset == 0) {
1170
        gen_load_gpr(t0, base);
1171
    } else {
1172
        tcg_gen_movi_tl(t0, offset);
1173
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1174
    }
1175
    /* Don't do NOP if destination is zero: we must perform the actual
1176
       memory access. */
1177
    switch (opc) {
1178
    case OPC_LWC1:
1179
        {
1180
            TCGv_i32 fp0 = tcg_temp_new_i32();
1181
            TCGv t1 = tcg_temp_new();
1182

    
1183
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
1184
            tcg_gen_trunc_tl_i32(fp0, t1);
1185
            gen_store_fpr32(fp0, ft);
1186
            tcg_temp_free(t1);
1187
            tcg_temp_free_i32(fp0);
1188
        }
1189
        opn = "lwc1";
1190
        break;
1191
    case OPC_SWC1:
1192
        {
1193
            TCGv_i32 fp0 = tcg_temp_new_i32();
1194
            TCGv t1 = tcg_temp_new();
1195

    
1196
            gen_load_fpr32(fp0, ft);
1197
            tcg_gen_extu_i32_tl(t1, fp0);
1198
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1199
            tcg_temp_free(t1);
1200
            tcg_temp_free_i32(fp0);
1201
        }
1202
        opn = "swc1";
1203
        break;
1204
    case OPC_LDC1:
1205
        {
1206
            TCGv_i64 fp0 = tcg_temp_new_i64();
1207

    
1208
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1209
            gen_store_fpr64(ctx, fp0, ft);
1210
            tcg_temp_free_i64(fp0);
1211
        }
1212
        opn = "ldc1";
1213
        break;
1214
    case OPC_SDC1:
1215
        {
1216
            TCGv_i64 fp0 = tcg_temp_new_i64();
1217

    
1218
            gen_load_fpr64(ctx, fp0, ft);
1219
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1220
            tcg_temp_free_i64(fp0);
1221
        }
1222
        opn = "sdc1";
1223
        break;
1224
    default:
1225
        MIPS_INVAL(opn);
1226
        generate_exception(ctx, EXCP_RI);
1227
        goto out;
1228
    }
1229
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1230
 out:
1231
    tcg_temp_free(t0);
1232
}
1233

    
1234
/* Arithmetic with immediate operand */
1235
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1236
                           int rt, int rs, int16_t imm)
1237
{
1238
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1239
    const char *opn = "imm arith";
1240

    
1241
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1242
        /* If no destination, treat it as a NOP.
1243
           For addi, we must generate the overflow exception when needed. */
1244
        MIPS_DEBUG("NOP");
1245
        return;
1246
    }
1247
    switch (opc) {
1248
    case OPC_ADDI:
1249
        {
1250
            TCGv t0 = tcg_temp_local_new();
1251
            TCGv t1 = tcg_temp_new();
1252
            TCGv t2 = tcg_temp_new();
1253
            int l1 = gen_new_label();
1254

    
1255
            gen_load_gpr(t1, rs);
1256
            tcg_gen_addi_tl(t0, t1, uimm);
1257
            tcg_gen_ext32s_tl(t0, t0);
1258

    
1259
            tcg_gen_xori_tl(t1, t1, ~uimm);
1260
            tcg_gen_xori_tl(t2, t0, uimm);
1261
            tcg_gen_and_tl(t1, t1, t2);
1262
            tcg_temp_free(t2);
1263
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1264
            tcg_temp_free(t1);
1265
            /* operands of same sign, result different sign */
1266
            generate_exception(ctx, EXCP_OVERFLOW);
1267
            gen_set_label(l1);
1268
            tcg_gen_ext32s_tl(t0, t0);
1269
            gen_store_gpr(t0, rt);
1270
            tcg_temp_free(t0);
1271
        }
1272
        opn = "addi";
1273
        break;
1274
    case OPC_ADDIU:
1275
        if (rs != 0) {
1276
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1277
            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1278
        } else {
1279
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1280
        }
1281
        opn = "addiu";
1282
        break;
1283
#if defined(TARGET_MIPS64)
1284
    case OPC_DADDI:
1285
        {
1286
            TCGv t0 = tcg_temp_local_new();
1287
            TCGv t1 = tcg_temp_new();
1288
            TCGv t2 = tcg_temp_new();
1289
            int l1 = gen_new_label();
1290

    
1291
            gen_load_gpr(t1, rs);
1292
            tcg_gen_addi_tl(t0, t1, uimm);
1293

    
1294
            tcg_gen_xori_tl(t1, t1, ~uimm);
1295
            tcg_gen_xori_tl(t2, t0, uimm);
1296
            tcg_gen_and_tl(t1, t1, t2);
1297
            tcg_temp_free(t2);
1298
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1299
            tcg_temp_free(t1);
1300
            /* operands of same sign, result different sign */
1301
            generate_exception(ctx, EXCP_OVERFLOW);
1302
            gen_set_label(l1);
1303
            gen_store_gpr(t0, rt);
1304
            tcg_temp_free(t0);
1305
        }
1306
        opn = "daddi";
1307
        break;
1308
    case OPC_DADDIU:
1309
        if (rs != 0) {
1310
            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1311
        } else {
1312
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1313
        }
1314
        opn = "daddiu";
1315
        break;
1316
#endif
1317
    }
1318
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1319
}
1320

    
1321
/* Logic with immediate operand */
1322
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1323
{
1324
    target_ulong uimm;
1325
    const char *opn = "imm logic";
1326

    
1327
    if (rt == 0) {
1328
        /* If no destination, treat it as a NOP. */
1329
        MIPS_DEBUG("NOP");
1330
        return;
1331
    }
1332
    uimm = (uint16_t)imm;
1333
    switch (opc) {
1334
    case OPC_ANDI:
1335
        if (likely(rs != 0))
1336
            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1337
        else
1338
            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1339
        opn = "andi";
1340
        break;
1341
    case OPC_ORI:
1342
        if (rs != 0)
1343
            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1344
        else
1345
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1346
        opn = "ori";
1347
        break;
1348
    case OPC_XORI:
1349
        if (likely(rs != 0))
1350
            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1351
        else
1352
            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1353
        opn = "xori";
1354
        break;
1355
    case OPC_LUI:
1356
        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1357
        opn = "lui";
1358
        break;
1359
    }
1360
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1361
}
1362

    
1363
/* Set on less than with immediate operand */
1364
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1365
{
1366
    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1367
    const char *opn = "imm arith";
1368
    TCGv t0;
1369

    
1370
    if (rt == 0) {
1371
        /* If no destination, treat it as a NOP. */
1372
        MIPS_DEBUG("NOP");
1373
        return;
1374
    }
1375
    t0 = tcg_temp_new();
1376
    gen_load_gpr(t0, rs);
1377
    switch (opc) {
1378
    case OPC_SLTI:
1379
        gen_op_lti(cpu_gpr[rt], t0, uimm);
1380
        opn = "slti";
1381
        break;
1382
    case OPC_SLTIU:
1383
        gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1384
        opn = "sltiu";
1385
        break;
1386
    }
1387
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1388
    tcg_temp_free(t0);
1389
}
1390

    
1391
/* Shifts with immediate operand */
1392
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1393
                          int rt, int rs, int16_t imm)
1394
{
1395
    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1396
    const char *opn = "imm shift";
1397
    TCGv t0;
1398

    
1399
    if (rt == 0) {
1400
        /* If no destination, treat it as a NOP. */
1401
        MIPS_DEBUG("NOP");
1402
        return;
1403
    }
1404

    
1405
    t0 = tcg_temp_new();
1406
    gen_load_gpr(t0, rs);
1407
    switch (opc) {
1408
    case OPC_SLL:
1409
        tcg_gen_shli_tl(t0, t0, uimm);
1410
        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1411
        opn = "sll";
1412
        break;
1413
    case OPC_SRA:
1414
        tcg_gen_ext32s_tl(t0, t0);
1415
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1416
        opn = "sra";
1417
        break;
1418
    case OPC_SRL:
1419
        switch ((ctx->opcode >> 21) & 0x1f) {
1420
        case 0:
1421
            if (uimm != 0) {
1422
                tcg_gen_ext32u_tl(t0, t0);
1423
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1424
            } else {
1425
                tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1426
            }
1427
            opn = "srl";
1428
            break;
1429
        case 1:
1430
            /* rotr is decoded as srl on non-R2 CPUs */
1431
            if (env->insn_flags & ISA_MIPS32R2) {
1432
                if (uimm != 0) {
1433
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1434

    
1435
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1436
                    tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
1437
                    tcg_gen_ext_i32_tl(cpu_gpr[rt], r_tmp1);
1438
                    tcg_temp_free_i32(r_tmp1);
1439
                }
1440
                opn = "rotr";
1441
            } else {
1442
                if (uimm != 0) {
1443
                    tcg_gen_ext32u_tl(t0, t0);
1444
                    tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1445
                } else {
1446
                    tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1447
                }
1448
                opn = "srl";
1449
            }
1450
            break;
1451
        default:
1452
            MIPS_INVAL("invalid srl flag");
1453
            generate_exception(ctx, EXCP_RI);
1454
            break;
1455
        }
1456
        break;
1457
#if defined(TARGET_MIPS64)
1458
    case OPC_DSLL:
1459
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1460
        opn = "dsll";
1461
        break;
1462
    case OPC_DSRA:
1463
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1464
        opn = "dsra";
1465
        break;
1466
    case OPC_DSRL:
1467
        switch ((ctx->opcode >> 21) & 0x1f) {
1468
        case 0:
1469
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1470
            opn = "dsrl";
1471
            break;
1472
        case 1:
1473
            /* drotr is decoded as dsrl on non-R2 CPUs */
1474
            if (env->insn_flags & ISA_MIPS32R2) {
1475
                if (uimm != 0) {
1476
                    tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1477
                }
1478
                opn = "drotr";
1479
            } else {
1480
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1481
                opn = "dsrl";
1482
            }
1483
            break;
1484
        default:
1485
            MIPS_INVAL("invalid dsrl flag");
1486
            generate_exception(ctx, EXCP_RI);
1487
            break;
1488
        }
1489
        break;
1490
    case OPC_DSLL32:
1491
        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1492
        opn = "dsll32";
1493
        break;
1494
    case OPC_DSRA32:
1495
        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1496
        opn = "dsra32";
1497
        break;
1498
    case OPC_DSRL32:
1499
        switch ((ctx->opcode >> 21) & 0x1f) {
1500
        case 0:
1501
            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1502
            opn = "dsrl32";
1503
            break;
1504
        case 1:
1505
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1506
            if (env->insn_flags & ISA_MIPS32R2) {
1507
                tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1508
                opn = "drotr32";
1509
            } else {
1510
                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1511
                opn = "dsrl32";
1512
            }
1513
            break;
1514
        default:
1515
            MIPS_INVAL("invalid dsrl32 flag");
1516
            generate_exception(ctx, EXCP_RI);
1517
            break;
1518
        }
1519
        break;
1520
#endif
1521
    }
1522
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1523
    tcg_temp_free(t0);
1524
}
1525

    
1526
/* Arithmetic */
1527
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1528
                       int rd, int rs, int rt)
1529
{
1530
    const char *opn = "arith";
1531

    
1532
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1533
       && opc != OPC_DADD && opc != OPC_DSUB) {
1534
        /* If no destination, treat it as a NOP.
1535
           For add & sub, we must generate the overflow exception when needed. */
1536
        MIPS_DEBUG("NOP");
1537
        return;
1538
    }
1539

    
1540
    switch (opc) {
1541
    case OPC_ADD:
1542
        {
1543
            TCGv t0 = tcg_temp_local_new();
1544
            TCGv t1 = tcg_temp_new();
1545
            TCGv t2 = tcg_temp_new();
1546
            int l1 = gen_new_label();
1547

    
1548
            gen_load_gpr(t1, rs);
1549
            gen_load_gpr(t2, rt);
1550
            tcg_gen_add_tl(t0, t1, t2);
1551
            tcg_gen_ext32s_tl(t0, t0);
1552
            tcg_gen_xor_tl(t1, t1, t2);
1553
            tcg_gen_not_tl(t1, t1);
1554
            tcg_gen_xor_tl(t2, t0, t2);
1555
            tcg_gen_and_tl(t1, t1, t2);
1556
            tcg_temp_free(t2);
1557
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1558
            tcg_temp_free(t1);
1559
            /* operands of same sign, result different sign */
1560
            generate_exception(ctx, EXCP_OVERFLOW);
1561
            gen_set_label(l1);
1562
            gen_store_gpr(t0, rd);
1563
            tcg_temp_free(t0);
1564
        }
1565
        opn = "add";
1566
        break;
1567
    case OPC_ADDU:
1568
        if (rs != 0 && rt != 0) {
1569
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1570
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1571
        } else if (rs == 0 && rt != 0) {
1572
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1573
        } else if (rs != 0 && rt == 0) {
1574
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1575
        } else {
1576
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1577
        }
1578
        opn = "addu";
1579
        break;
1580
    case OPC_SUB:
1581
        {
1582
            TCGv t0 = tcg_temp_local_new();
1583
            TCGv t1 = tcg_temp_new();
1584
            TCGv t2 = tcg_temp_new();
1585
            int l1 = gen_new_label();
1586

    
1587
            gen_load_gpr(t1, rs);
1588
            gen_load_gpr(t2, rt);
1589
            tcg_gen_sub_tl(t0, t1, t2);
1590
            tcg_gen_ext32s_tl(t0, t0);
1591
            tcg_gen_xor_tl(t2, t1, t2);
1592
            tcg_gen_xor_tl(t1, t0, t1);
1593
            tcg_gen_and_tl(t1, t1, t2);
1594
            tcg_temp_free(t2);
1595
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1596
            tcg_temp_free(t1);
1597
            /* operands of same sign, result different sign */
1598
            generate_exception(ctx, EXCP_OVERFLOW);
1599
            gen_set_label(l1);
1600
            gen_store_gpr(t0, rd);
1601
            tcg_temp_free(t0);
1602
        }
1603
        opn = "sub";
1604
        break;
1605
    case OPC_SUBU:
1606
        if (rs != 0 && rt != 0) {
1607
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1608
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1609
        } else if (rs == 0 && rt != 0) {
1610
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1611
        } else if (rs != 0 && rt == 0) {
1612
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1613
        } else {
1614
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1615
        }
1616
        opn = "subu";
1617
        break;
1618
#if defined(TARGET_MIPS64)
1619
    case OPC_DADD:
1620
        {
1621
            TCGv t0 = tcg_temp_local_new();
1622
            TCGv t1 = tcg_temp_new();
1623
            TCGv t2 = tcg_temp_new();
1624
            int l1 = gen_new_label();
1625

    
1626
            gen_load_gpr(t1, rs);
1627
            gen_load_gpr(t2, rt);
1628
            tcg_gen_add_tl(t0, t1, t2);
1629
            tcg_gen_xor_tl(t1, t1, t2);
1630
            tcg_gen_not_tl(t1, t1);
1631
            tcg_gen_xor_tl(t2, t0, t2);
1632
            tcg_gen_and_tl(t1, t1, t2);
1633
            tcg_temp_free(t2);
1634
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1635
            tcg_temp_free(t1);
1636
            /* operands of same sign, result different sign */
1637
            generate_exception(ctx, EXCP_OVERFLOW);
1638
            gen_set_label(l1);
1639
            gen_store_gpr(t0, rd);
1640
            tcg_temp_free(t0);
1641
        }
1642
        opn = "dadd";
1643
        break;
1644
    case OPC_DADDU:
1645
        if (rs != 0 && rt != 0) {
1646
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1647
        } else if (rs == 0 && rt != 0) {
1648
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1649
        } else if (rs != 0 && rt == 0) {
1650
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1651
        } else {
1652
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1653
        }
1654
        opn = "daddu";
1655
        break;
1656
    case OPC_DSUB:
1657
        {
1658
            TCGv t0 = tcg_temp_local_new();
1659
            TCGv t1 = tcg_temp_new();
1660
            TCGv t2 = tcg_temp_new();
1661
            int l1 = gen_new_label();
1662

    
1663
            gen_load_gpr(t1, rs);
1664
            gen_load_gpr(t2, rt);
1665
            tcg_gen_sub_tl(t0, t1, t2);
1666
            tcg_gen_xor_tl(t2, t1, t2);
1667
            tcg_gen_xor_tl(t1, t0, t1);
1668
            tcg_gen_and_tl(t1, t1, t2);
1669
            tcg_temp_free(t2);
1670
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1671
            tcg_temp_free(t1);
1672
            /* operands of same sign, result different sign */
1673
            generate_exception(ctx, EXCP_OVERFLOW);
1674
            gen_set_label(l1);
1675
            gen_store_gpr(t0, rd);
1676
            tcg_temp_free(t0);
1677
        }
1678
        opn = "dsub";
1679
        break;
1680
    case OPC_DSUBU:
1681
        if (rs != 0 && rt != 0) {
1682
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1683
        } else if (rs == 0 && rt != 0) {
1684
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1685
        } else if (rs != 0 && rt == 0) {
1686
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1687
        } else {
1688
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1689
        }
1690
        opn = "dsubu";
1691
        break;
1692
#endif
1693
    case OPC_MUL:
1694
        if (likely(rs != 0 && rt != 0)) {
1695
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1696
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1697
        } else {
1698
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1699
        }
1700
        opn = "mul";
1701
        break;
1702
    }
1703
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1704
}
1705

    
1706
/* Conditional move */
1707
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1708
{
1709
    const char *opn = "cond move";
1710
    int l1;
1711

    
1712
    if (rd == 0) {
1713
        /* If no destination, treat it as a NOP.
1714
           For add & sub, we must generate the overflow exception when needed. */
1715
        MIPS_DEBUG("NOP");
1716
        return;
1717
    }
1718

    
1719
    l1 = gen_new_label();
1720
    switch (opc) {
1721
    case OPC_MOVN:
1722
        if (likely(rt != 0))
1723
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1724
        else
1725
            tcg_gen_br(l1);
1726
        opn = "movn";
1727
        break;
1728
    case OPC_MOVZ:
1729
        if (likely(rt != 0))
1730
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1731
        opn = "movz";
1732
        break;
1733
    }
1734
    if (rs != 0)
1735
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1736
    else
1737
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1738
    gen_set_label(l1);
1739

    
1740
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1741
}
1742

    
1743
/* Logic */
1744
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1745
{
1746
    const char *opn = "logic";
1747

    
1748
    if (rd == 0) {
1749
        /* If no destination, treat it as a NOP. */
1750
        MIPS_DEBUG("NOP");
1751
        return;
1752
    }
1753

    
1754
    switch (opc) {
1755
    case OPC_AND:
1756
        if (likely(rs != 0 && rt != 0)) {
1757
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1758
        } else {
1759
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1760
        }
1761
        opn = "and";
1762
        break;
1763
    case OPC_NOR:
1764
        if (rs != 0 && rt != 0) {
1765
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1766
        } else if (rs == 0 && rt != 0) {
1767
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1768
        } else if (rs != 0 && rt == 0) {
1769
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1770
        } else {
1771
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1772
        }
1773
        opn = "nor";
1774
        break;
1775
    case OPC_OR:
1776
        if (likely(rs != 0 && rt != 0)) {
1777
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1778
        } else if (rs == 0 && rt != 0) {
1779
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1780
        } else if (rs != 0 && rt == 0) {
1781
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1782
        } else {
1783
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1784
        }
1785
        opn = "or";
1786
        break;
1787
    case OPC_XOR:
1788
        if (likely(rs != 0 && rt != 0)) {
1789
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1790
        } else if (rs == 0 && rt != 0) {
1791
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1792
        } else if (rs != 0 && rt == 0) {
1793
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1794
        } else {
1795
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1796
        }
1797
        opn = "xor";
1798
        break;
1799
    }
1800
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1801
}
1802

    
1803
/* Set on lower than */
1804
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1805
{
1806
    const char *opn = "slt";
1807
    TCGv t0, t1;
1808

    
1809
    if (rd == 0) {
1810
        /* If no destination, treat it as a NOP. */
1811
        MIPS_DEBUG("NOP");
1812
        return;
1813
    }
1814

    
1815
    t0 = tcg_temp_new();
1816
    t1 = tcg_temp_new();
1817
    gen_load_gpr(t0, rs);
1818
    gen_load_gpr(t1, rt);
1819
    switch (opc) {
1820
    case OPC_SLT:
1821
        gen_op_lt(cpu_gpr[rd], t0, t1);
1822
        opn = "slt";
1823
        break;
1824
    case OPC_SLTU:
1825
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1826
        opn = "sltu";
1827
        break;
1828
    }
1829
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1830
    tcg_temp_free(t0);
1831
    tcg_temp_free(t1);
1832
}
1833

    
1834
/* Shifts */
1835
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1836
                       int rd, int rs, int rt)
1837
{
1838
    const char *opn = "shifts";
1839
    TCGv t0, t1;
1840

    
1841
    if (rd == 0) {
1842
        /* If no destination, treat it as a NOP.
1843
           For add & sub, we must generate the overflow exception when needed. */
1844
        MIPS_DEBUG("NOP");
1845
        return;
1846
    }
1847

    
1848
    t0 = tcg_temp_new();
1849
    t1 = tcg_temp_new();
1850
    gen_load_gpr(t0, rs);
1851
    gen_load_gpr(t1, rt);
1852
    switch (opc) {
1853
    case OPC_SLLV:
1854
        tcg_gen_andi_tl(t0, t0, 0x1f);
1855
        tcg_gen_shl_tl(t0, t1, t0);
1856
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1857
        opn = "sllv";
1858
        break;
1859
    case OPC_SRAV:
1860
        tcg_gen_ext32s_tl(t1, t1);
1861
        tcg_gen_andi_tl(t0, t0, 0x1f);
1862
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1863
        opn = "srav";
1864
        break;
1865
    case OPC_SRLV:
1866
        switch ((ctx->opcode >> 6) & 0x1f) {
1867
        case 0:
1868
            tcg_gen_ext32u_tl(t1, t1);
1869
            tcg_gen_andi_tl(t0, t0, 0x1f);
1870
            tcg_gen_shr_tl(t0, t1, t0);
1871
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1872
            opn = "srlv";
1873
            break;
1874
        case 1:
1875
            /* rotrv is decoded as srlv on non-R2 CPUs */
1876
            if (env->insn_flags & ISA_MIPS32R2) {
1877
                TCGv_i32 t2 = tcg_temp_new_i32();
1878
                TCGv_i32 t3 = tcg_temp_new_i32();
1879

    
1880
                tcg_gen_trunc_tl_i32(t2, t0);
1881
                tcg_gen_trunc_tl_i32(t3, t1);
1882
                tcg_gen_andi_i32(t2, t2, 0x1f);
1883
                tcg_gen_rotr_i32(t2, t3, t2);
1884
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1885
                tcg_temp_free_i32(t2);
1886
                tcg_temp_free_i32(t3);
1887
                opn = "rotrv";
1888
            } else {
1889
                tcg_gen_ext32u_tl(t1, t1);
1890
                tcg_gen_andi_tl(t0, t0, 0x1f);
1891
                tcg_gen_shr_tl(t0, t1, t0);
1892
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1893
                opn = "srlv";
1894
            }
1895
            break;
1896
        default:
1897
            MIPS_INVAL("invalid srlv flag");
1898
            generate_exception(ctx, EXCP_RI);
1899
            break;
1900
        }
1901
        break;
1902
#if defined(TARGET_MIPS64)
1903
    case OPC_DSLLV:
1904
        tcg_gen_andi_tl(t0, t0, 0x3f);
1905
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1906
        opn = "dsllv";
1907
        break;
1908
    case OPC_DSRAV:
1909
        tcg_gen_andi_tl(t0, t0, 0x3f);
1910
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1911
        opn = "dsrav";
1912
        break;
1913
    case OPC_DSRLV:
1914
        switch ((ctx->opcode >> 6) & 0x1f) {
1915
        case 0:
1916
            tcg_gen_andi_tl(t0, t0, 0x3f);
1917
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1918
            opn = "dsrlv";
1919
            break;
1920
        case 1:
1921
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1922
            if (env->insn_flags & ISA_MIPS32R2) {
1923
                tcg_gen_andi_tl(t0, t0, 0x3f);
1924
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1925
                opn = "drotrv";
1926
            } else {
1927
                tcg_gen_andi_tl(t0, t0, 0x3f);
1928
                tcg_gen_shr_tl(t0, t1, t0);
1929
                opn = "dsrlv";
1930
            }
1931
            break;
1932
        default:
1933
            MIPS_INVAL("invalid dsrlv flag");
1934
            generate_exception(ctx, EXCP_RI);
1935
            break;
1936
        }
1937
        break;
1938
#endif
1939
    }
1940
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1941
    tcg_temp_free(t0);
1942
    tcg_temp_free(t1);
1943
}
1944

    
1945
/* Arithmetic on HI/LO registers */
1946
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1947
{
1948
    const char *opn = "hilo";
1949

    
1950
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1951
        /* Treat as NOP. */
1952
        MIPS_DEBUG("NOP");
1953
        return;
1954
    }
1955
    switch (opc) {
1956
    case OPC_MFHI:
1957
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1958
        opn = "mfhi";
1959
        break;
1960
    case OPC_MFLO:
1961
        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1962
        opn = "mflo";
1963
        break;
1964
    case OPC_MTHI:
1965
        if (reg != 0)
1966
            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1967
        else
1968
            tcg_gen_movi_tl(cpu_HI[0], 0);
1969
        opn = "mthi";
1970
        break;
1971
    case OPC_MTLO:
1972
        if (reg != 0)
1973
            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1974
        else
1975
            tcg_gen_movi_tl(cpu_LO[0], 0);
1976
        opn = "mtlo";
1977
        break;
1978
    }
1979
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1980
}
1981

    
1982
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1983
                        int rs, int rt)
1984
{
1985
    const char *opn = "mul/div";
1986
    TCGv t0, t1;
1987

    
1988
    switch (opc) {
1989
    case OPC_DIV:
1990
    case OPC_DIVU:
1991
#if defined(TARGET_MIPS64)
1992
    case OPC_DDIV:
1993
    case OPC_DDIVU:
1994
#endif
1995
        t0 = tcg_temp_local_new();
1996
        t1 = tcg_temp_local_new();
1997
        break;
1998
    default:
1999
        t0 = tcg_temp_new();
2000
        t1 = tcg_temp_new();
2001
        break;
2002
    }
2003

    
2004
    gen_load_gpr(t0, rs);
2005
    gen_load_gpr(t1, rt);
2006
    switch (opc) {
2007
    case OPC_DIV:
2008
        {
2009
            int l1 = gen_new_label();
2010
            int l2 = gen_new_label();
2011

    
2012
            tcg_gen_ext32s_tl(t0, t0);
2013
            tcg_gen_ext32s_tl(t1, t1);
2014
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2015
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2016
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2017

    
2018
            tcg_gen_mov_tl(cpu_LO[0], t0);
2019
            tcg_gen_movi_tl(cpu_HI[0], 0);
2020
            tcg_gen_br(l1);
2021
            gen_set_label(l2);
2022
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2023
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2024
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2025
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2026
            gen_set_label(l1);
2027
        }
2028
        opn = "div";
2029
        break;
2030
    case OPC_DIVU:
2031
        {
2032
            int l1 = gen_new_label();
2033

    
2034
            tcg_gen_ext32u_tl(t0, t0);
2035
            tcg_gen_ext32u_tl(t1, t1);
2036
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2037
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2038
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2039
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2040
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2041
            gen_set_label(l1);
2042
        }
2043
        opn = "divu";
2044
        break;
2045
    case OPC_MULT:
2046
        {
2047
            TCGv_i64 t2 = tcg_temp_new_i64();
2048
            TCGv_i64 t3 = tcg_temp_new_i64();
2049

    
2050
            tcg_gen_ext_tl_i64(t2, t0);
2051
            tcg_gen_ext_tl_i64(t3, t1);
2052
            tcg_gen_mul_i64(t2, t2, t3);
2053
            tcg_temp_free_i64(t3);
2054
            tcg_gen_trunc_i64_tl(t0, t2);
2055
            tcg_gen_shri_i64(t2, t2, 32);
2056
            tcg_gen_trunc_i64_tl(t1, t2);
2057
            tcg_temp_free_i64(t2);
2058
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2059
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2060
        }
2061
        opn = "mult";
2062
        break;
2063
    case OPC_MULTU:
2064
        {
2065
            TCGv_i64 t2 = tcg_temp_new_i64();
2066
            TCGv_i64 t3 = tcg_temp_new_i64();
2067

    
2068
            tcg_gen_ext32u_tl(t0, t0);
2069
            tcg_gen_ext32u_tl(t1, t1);
2070
            tcg_gen_extu_tl_i64(t2, t0);
2071
            tcg_gen_extu_tl_i64(t3, t1);
2072
            tcg_gen_mul_i64(t2, t2, t3);
2073
            tcg_temp_free_i64(t3);
2074
            tcg_gen_trunc_i64_tl(t0, t2);
2075
            tcg_gen_shri_i64(t2, t2, 32);
2076
            tcg_gen_trunc_i64_tl(t1, t2);
2077
            tcg_temp_free_i64(t2);
2078
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2079
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2080
        }
2081
        opn = "multu";
2082
        break;
2083
#if defined(TARGET_MIPS64)
2084
    case OPC_DDIV:
2085
        {
2086
            int l1 = gen_new_label();
2087
            int l2 = gen_new_label();
2088

    
2089
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2090
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2091
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2092
            tcg_gen_mov_tl(cpu_LO[0], t0);
2093
            tcg_gen_movi_tl(cpu_HI[0], 0);
2094
            tcg_gen_br(l1);
2095
            gen_set_label(l2);
2096
            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2097
            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2098
            gen_set_label(l1);
2099
        }
2100
        opn = "ddiv";
2101
        break;
2102
    case OPC_DDIVU:
2103
        {
2104
            int l1 = gen_new_label();
2105

    
2106
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2107
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2108
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2109
            gen_set_label(l1);
2110
        }
2111
        opn = "ddivu";
2112
        break;
2113
    case OPC_DMULT:
2114
        gen_helper_dmult(t0, t1);
2115
        opn = "dmult";
2116
        break;
2117
    case OPC_DMULTU:
2118
        gen_helper_dmultu(t0, t1);
2119
        opn = "dmultu";
2120
        break;
2121
#endif
2122
    case OPC_MADD:
2123
        {
2124
            TCGv_i64 t2 = tcg_temp_new_i64();
2125
            TCGv_i64 t3 = tcg_temp_new_i64();
2126

    
2127
            tcg_gen_ext_tl_i64(t2, t0);
2128
            tcg_gen_ext_tl_i64(t3, t1);
2129
            tcg_gen_mul_i64(t2, t2, t3);
2130
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2131
            tcg_gen_add_i64(t2, t2, t3);
2132
            tcg_temp_free_i64(t3);
2133
            tcg_gen_trunc_i64_tl(t0, t2);
2134
            tcg_gen_shri_i64(t2, t2, 32);
2135
            tcg_gen_trunc_i64_tl(t1, t2);
2136
            tcg_temp_free_i64(t2);
2137
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2138
            tcg_gen_ext32s_tl(cpu_LO[1], t1);
2139
        }
2140
        opn = "madd";
2141
        break;
2142
    case OPC_MADDU:
2143
       {
2144
            TCGv_i64 t2 = tcg_temp_new_i64();
2145
            TCGv_i64 t3 = tcg_temp_new_i64();
2146

    
2147
            tcg_gen_ext32u_tl(t0, t0);
2148
            tcg_gen_ext32u_tl(t1, t1);
2149
            tcg_gen_extu_tl_i64(t2, t0);
2150
            tcg_gen_extu_tl_i64(t3, t1);
2151
            tcg_gen_mul_i64(t2, t2, t3);
2152
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2153
            tcg_gen_add_i64(t2, t2, t3);
2154
            tcg_temp_free_i64(t3);
2155
            tcg_gen_trunc_i64_tl(t0, t2);
2156
            tcg_gen_shri_i64(t2, t2, 32);
2157
            tcg_gen_trunc_i64_tl(t1, t2);
2158
            tcg_temp_free_i64(t2);
2159
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2160
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2161
        }
2162
        opn = "maddu";
2163
        break;
2164
    case OPC_MSUB:
2165
        {
2166
            TCGv_i64 t2 = tcg_temp_new_i64();
2167
            TCGv_i64 t3 = tcg_temp_new_i64();
2168

    
2169
            tcg_gen_ext_tl_i64(t2, t0);
2170
            tcg_gen_ext_tl_i64(t3, t1);
2171
            tcg_gen_mul_i64(t2, t2, t3);
2172
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2173
            tcg_gen_sub_i64(t2, t2, t3);
2174
            tcg_temp_free_i64(t3);
2175
            tcg_gen_trunc_i64_tl(t0, t2);
2176
            tcg_gen_shri_i64(t2, t2, 32);
2177
            tcg_gen_trunc_i64_tl(t1, t2);
2178
            tcg_temp_free_i64(t2);
2179
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2180
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2181
        }
2182
        opn = "msub";
2183
        break;
2184
    case OPC_MSUBU:
2185
        {
2186
            TCGv_i64 t2 = tcg_temp_new_i64();
2187
            TCGv_i64 t3 = tcg_temp_new_i64();
2188

    
2189
            tcg_gen_ext32u_tl(t0, t0);
2190
            tcg_gen_ext32u_tl(t1, t1);
2191
            tcg_gen_extu_tl_i64(t2, t0);
2192
            tcg_gen_extu_tl_i64(t3, t1);
2193
            tcg_gen_mul_i64(t2, t2, t3);
2194
            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2195
            tcg_gen_sub_i64(t2, t2, t3);
2196
            tcg_temp_free_i64(t3);
2197
            tcg_gen_trunc_i64_tl(t0, t2);
2198
            tcg_gen_shri_i64(t2, t2, 32);
2199
            tcg_gen_trunc_i64_tl(t1, t2);
2200
            tcg_temp_free_i64(t2);
2201
            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2202
            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2203
        }
2204
        opn = "msubu";
2205
        break;
2206
    default:
2207
        MIPS_INVAL(opn);
2208
        generate_exception(ctx, EXCP_RI);
2209
        goto out;
2210
    }
2211
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2212
 out:
2213
    tcg_temp_free(t0);
2214
    tcg_temp_free(t1);
2215
}
2216

    
2217
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2218
                            int rd, int rs, int rt)
2219
{
2220
    const char *opn = "mul vr54xx";
2221
    TCGv t0 = tcg_temp_new();
2222
    TCGv t1 = tcg_temp_new();
2223

    
2224
    gen_load_gpr(t0, rs);
2225
    gen_load_gpr(t1, rt);
2226

    
2227
    switch (opc) {
2228
    case OPC_VR54XX_MULS:
2229
        gen_helper_muls(t0, t0, t1);
2230
        opn = "muls";
2231
        break;
2232
    case OPC_VR54XX_MULSU:
2233
        gen_helper_mulsu(t0, t0, t1);
2234
        opn = "mulsu";
2235
        break;
2236
    case OPC_VR54XX_MACC:
2237
        gen_helper_macc(t0, t0, t1);
2238
        opn = "macc";
2239
        break;
2240
    case OPC_VR54XX_MACCU:
2241
        gen_helper_maccu(t0, t0, t1);
2242
        opn = "maccu";
2243
        break;
2244
    case OPC_VR54XX_MSAC:
2245
        gen_helper_msac(t0, t0, t1);
2246
        opn = "msac";
2247
        break;
2248
    case OPC_VR54XX_MSACU:
2249
        gen_helper_msacu(t0, t0, t1);
2250
        opn = "msacu";
2251
        break;
2252
    case OPC_VR54XX_MULHI:
2253
        gen_helper_mulhi(t0, t0, t1);
2254
        opn = "mulhi";
2255
        break;
2256
    case OPC_VR54XX_MULHIU:
2257
        gen_helper_mulhiu(t0, t0, t1);
2258
        opn = "mulhiu";
2259
        break;
2260
    case OPC_VR54XX_MULSHI:
2261
        gen_helper_mulshi(t0, t0, t1);
2262
        opn = "mulshi";
2263
        break;
2264
    case OPC_VR54XX_MULSHIU:
2265
        gen_helper_mulshiu(t0, t0, t1);
2266
        opn = "mulshiu";
2267
        break;
2268
    case OPC_VR54XX_MACCHI:
2269
        gen_helper_macchi(t0, t0, t1);
2270
        opn = "macchi";
2271
        break;
2272
    case OPC_VR54XX_MACCHIU:
2273
        gen_helper_macchiu(t0, t0, t1);
2274
        opn = "macchiu";
2275
        break;
2276
    case OPC_VR54XX_MSACHI:
2277
        gen_helper_msachi(t0, t0, t1);
2278
        opn = "msachi";
2279
        break;
2280
    case OPC_VR54XX_MSACHIU:
2281
        gen_helper_msachiu(t0, t0, t1);
2282
        opn = "msachiu";
2283
        break;
2284
    default:
2285
        MIPS_INVAL("mul vr54xx");
2286
        generate_exception(ctx, EXCP_RI);
2287
        goto out;
2288
    }
2289
    gen_store_gpr(t0, rd);
2290
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2291

    
2292
 out:
2293
    tcg_temp_free(t0);
2294
    tcg_temp_free(t1);
2295
}
2296

    
2297
static void gen_cl (DisasContext *ctx, uint32_t opc,
2298
                    int rd, int rs)
2299
{
2300
    const char *opn = "CLx";
2301
    TCGv t0;
2302

    
2303
    if (rd == 0) {
2304
        /* Treat as NOP. */
2305
        MIPS_DEBUG("NOP");
2306
        return;
2307
    }
2308
    t0 = tcg_temp_new();
2309
    gen_load_gpr(t0, rs);
2310
    switch (opc) {
2311
    case OPC_CLO:
2312
        gen_helper_clo(cpu_gpr[rd], t0);
2313
        opn = "clo";
2314
        break;
2315
    case OPC_CLZ:
2316
        gen_helper_clz(cpu_gpr[rd], t0);
2317
        opn = "clz";
2318
        break;
2319
#if defined(TARGET_MIPS64)
2320
    case OPC_DCLO:
2321
        gen_helper_dclo(cpu_gpr[rd], t0);
2322
        opn = "dclo";
2323
        break;
2324
    case OPC_DCLZ:
2325
        gen_helper_dclz(cpu_gpr[rd], t0);
2326
        opn = "dclz";
2327
        break;
2328
#endif
2329
    }
2330
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2331
    tcg_temp_free(t0);
2332
}
2333

    
2334
/* Traps */
2335
static void gen_trap (DisasContext *ctx, uint32_t opc,
2336
                      int rs, int rt, int16_t imm)
2337
{
2338
    int cond;
2339
    TCGv t0 = tcg_temp_new();
2340
    TCGv t1 = tcg_temp_new();
2341

    
2342
    cond = 0;
2343
    /* Load needed operands */
2344
    switch (opc) {
2345
    case OPC_TEQ:
2346
    case OPC_TGE:
2347
    case OPC_TGEU:
2348
    case OPC_TLT:
2349
    case OPC_TLTU:
2350
    case OPC_TNE:
2351
        /* Compare two registers */
2352
        if (rs != rt) {
2353
            gen_load_gpr(t0, rs);
2354
            gen_load_gpr(t1, rt);
2355
            cond = 1;
2356
        }
2357
        break;
2358
    case OPC_TEQI:
2359
    case OPC_TGEI:
2360
    case OPC_TGEIU:
2361
    case OPC_TLTI:
2362
    case OPC_TLTIU:
2363
    case OPC_TNEI:
2364
        /* Compare register to immediate */
2365
        if (rs != 0 || imm != 0) {
2366
            gen_load_gpr(t0, rs);
2367
            tcg_gen_movi_tl(t1, (int32_t)imm);
2368
            cond = 1;
2369
        }
2370
        break;
2371
    }
2372
    if (cond == 0) {
2373
        switch (opc) {
2374
        case OPC_TEQ:   /* rs == rs */
2375
        case OPC_TEQI:  /* r0 == 0  */
2376
        case OPC_TGE:   /* rs >= rs */
2377
        case OPC_TGEI:  /* r0 >= 0  */
2378
        case OPC_TGEU:  /* rs >= rs unsigned */
2379
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2380
            /* Always trap */
2381
            generate_exception(ctx, EXCP_TRAP);
2382
            break;
2383
        case OPC_TLT:   /* rs < rs           */
2384
        case OPC_TLTI:  /* r0 < 0            */
2385
        case OPC_TLTU:  /* rs < rs unsigned  */
2386
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2387
        case OPC_TNE:   /* rs != rs          */
2388
        case OPC_TNEI:  /* r0 != 0           */
2389
            /* Never trap: treat as NOP. */
2390
            break;
2391
        }
2392
    } else {
2393
        int l1 = gen_new_label();
2394

    
2395
        switch (opc) {
2396
        case OPC_TEQ:
2397
        case OPC_TEQI:
2398
            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2399
            break;
2400
        case OPC_TGE:
2401
        case OPC_TGEI:
2402
            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2403
            break;
2404
        case OPC_TGEU:
2405
        case OPC_TGEIU:
2406
            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2407
            break;
2408
        case OPC_TLT:
2409
        case OPC_TLTI:
2410
            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2411
            break;
2412
        case OPC_TLTU:
2413
        case OPC_TLTIU:
2414
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2415
            break;
2416
        case OPC_TNE:
2417
        case OPC_TNEI:
2418
            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2419
            break;
2420
        }
2421
        generate_exception(ctx, EXCP_TRAP);
2422
        gen_set_label(l1);
2423
    }
2424
    tcg_temp_free(t0);
2425
    tcg_temp_free(t1);
2426
}
2427

    
2428
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2429
{
2430
    TranslationBlock *tb;
2431
    tb = ctx->tb;
2432
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2433
        tcg_gen_goto_tb(n);
2434
        gen_save_pc(dest);
2435
        tcg_gen_exit_tb((long)tb + n);
2436
    } else {
2437
        gen_save_pc(dest);
2438
        tcg_gen_exit_tb(0);
2439
    }
2440
}
2441

    
2442
/* Branches (before delay slot) */
2443
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2444
                                int rs, int rt, int32_t offset)
2445
{
2446
    target_ulong btgt = -1;
2447
    int blink = 0;
2448
    int bcond_compute = 0;
2449
    TCGv t0 = tcg_temp_new();
2450
    TCGv t1 = tcg_temp_new();
2451

    
2452
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2453
#ifdef MIPS_DEBUG_DISAS
2454
        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2455
#endif
2456
        generate_exception(ctx, EXCP_RI);
2457
        goto out;
2458
    }
2459

    
2460
    /* Load needed operands */
2461
    switch (opc) {
2462
    case OPC_BEQ:
2463
    case OPC_BEQL:
2464
    case OPC_BNE:
2465
    case OPC_BNEL:
2466
        /* Compare two registers */
2467
        if (rs != rt) {
2468
            gen_load_gpr(t0, rs);
2469
            gen_load_gpr(t1, rt);
2470
            bcond_compute = 1;
2471
        }
2472
        btgt = ctx->pc + 4 + offset;
2473
        break;
2474
    case OPC_BGEZ:
2475
    case OPC_BGEZAL:
2476
    case OPC_BGEZALL:
2477
    case OPC_BGEZL:
2478
    case OPC_BGTZ:
2479
    case OPC_BGTZL:
2480
    case OPC_BLEZ:
2481
    case OPC_BLEZL:
2482
    case OPC_BLTZ:
2483
    case OPC_BLTZAL:
2484
    case OPC_BLTZALL:
2485
    case OPC_BLTZL:
2486
        /* Compare to zero */
2487
        if (rs != 0) {
2488
            gen_load_gpr(t0, rs);
2489
            bcond_compute = 1;
2490
        }
2491
        btgt = ctx->pc + 4 + offset;
2492
        break;
2493
    case OPC_J:
2494
    case OPC_JAL:
2495
        /* Jump to immediate */
2496
        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2497
        break;
2498
    case OPC_JR:
2499
    case OPC_JALR:
2500
        /* Jump to register */
2501
        if (offset != 0 && offset != 16) {
2502
            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2503
               others are reserved. */
2504
            MIPS_INVAL("jump hint");
2505
            generate_exception(ctx, EXCP_RI);
2506
            goto out;
2507
        }
2508
        gen_load_gpr(btarget, rs);
2509
        break;
2510
    default:
2511
        MIPS_INVAL("branch/jump");
2512
        generate_exception(ctx, EXCP_RI);
2513
        goto out;
2514
    }
2515
    if (bcond_compute == 0) {
2516
        /* No condition to be computed */
2517
        switch (opc) {
2518
        case OPC_BEQ:     /* rx == rx        */
2519
        case OPC_BEQL:    /* rx == rx likely */
2520
        case OPC_BGEZ:    /* 0 >= 0          */
2521
        case OPC_BGEZL:   /* 0 >= 0 likely   */
2522
        case OPC_BLEZ:    /* 0 <= 0          */
2523
        case OPC_BLEZL:   /* 0 <= 0 likely   */
2524
            /* Always take */
2525
            ctx->hflags |= MIPS_HFLAG_B;
2526
            MIPS_DEBUG("balways");
2527
            break;
2528
        case OPC_BGEZAL:  /* 0 >= 0          */
2529
        case OPC_BGEZALL: /* 0 >= 0 likely   */
2530
            /* Always take and link */
2531
            blink = 31;
2532
            ctx->hflags |= MIPS_HFLAG_B;
2533
            MIPS_DEBUG("balways and link");
2534
            break;
2535
        case OPC_BNE:     /* rx != rx        */
2536
        case OPC_BGTZ:    /* 0 > 0           */
2537
        case OPC_BLTZ:    /* 0 < 0           */
2538
            /* Treat as NOP. */
2539
            MIPS_DEBUG("bnever (NOP)");
2540
            goto out;
2541
        case OPC_BLTZAL:  /* 0 < 0           */
2542
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2543
            MIPS_DEBUG("bnever and link");
2544
            goto out;
2545
        case OPC_BLTZALL: /* 0 < 0 likely */
2546
            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2547
            /* Skip the instruction in the delay slot */
2548
            MIPS_DEBUG("bnever, link and skip");
2549
            ctx->pc += 4;
2550
            goto out;
2551
        case OPC_BNEL:    /* rx != rx likely */
2552
        case OPC_BGTZL:   /* 0 > 0 likely */
2553
        case OPC_BLTZL:   /* 0 < 0 likely */
2554
            /* Skip the instruction in the delay slot */
2555
            MIPS_DEBUG("bnever and skip");
2556
            ctx->pc += 4;
2557
            goto out;
2558
        case OPC_J:
2559
            ctx->hflags |= MIPS_HFLAG_B;
2560
            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2561
            break;
2562
        case OPC_JAL:
2563
            blink = 31;
2564
            ctx->hflags |= MIPS_HFLAG_B;
2565
            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2566
            break;
2567
        case OPC_JR:
2568
            ctx->hflags |= MIPS_HFLAG_BR;
2569
            MIPS_DEBUG("jr %s", regnames[rs]);
2570
            break;
2571
        case OPC_JALR:
2572
            blink = rt;
2573
            ctx->hflags |= MIPS_HFLAG_BR;
2574
            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2575
            break;
2576
        default:
2577
            MIPS_INVAL("branch/jump");
2578
            generate_exception(ctx, EXCP_RI);
2579
            goto out;
2580
        }
2581
    } else {
2582
        switch (opc) {
2583
        case OPC_BEQ:
2584
            gen_op_eq(bcond, t0, t1);
2585
            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2586
                       regnames[rs], regnames[rt], btgt);
2587
            goto not_likely;
2588
        case OPC_BEQL:
2589
            gen_op_eq(bcond, t0, t1);
2590
            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2591
                       regnames[rs], regnames[rt], btgt);
2592
            goto likely;
2593
        case OPC_BNE:
2594
            gen_op_ne(bcond, t0, t1);
2595
            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2596
                       regnames[rs], regnames[rt], btgt);
2597
            goto not_likely;
2598
        case OPC_BNEL:
2599
            gen_op_ne(bcond, t0, t1);
2600
            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2601
                       regnames[rs], regnames[rt], btgt);
2602
            goto likely;
2603
        case OPC_BGEZ:
2604
            gen_op_gez(bcond, t0);
2605
            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2606
            goto not_likely;
2607
        case OPC_BGEZL:
2608
            gen_op_gez(bcond, t0);
2609
            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2610
            goto likely;
2611
        case OPC_BGEZAL:
2612
            gen_op_gez(bcond, t0);
2613
            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2614
            blink = 31;
2615
            goto not_likely;
2616
        case OPC_BGEZALL:
2617
            gen_op_gez(bcond, t0);
2618
            blink = 31;
2619
            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2620
            goto likely;
2621
        case OPC_BGTZ:
2622
            gen_op_gtz(bcond, t0);
2623
            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2624
            goto not_likely;
2625
        case OPC_BGTZL:
2626
            gen_op_gtz(bcond, t0);
2627
            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2628
            goto likely;
2629
        case OPC_BLEZ:
2630
            gen_op_lez(bcond, t0);
2631
            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2632
            goto not_likely;
2633
        case OPC_BLEZL:
2634
            gen_op_lez(bcond, t0);
2635
            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2636
            goto likely;
2637
        case OPC_BLTZ:
2638
            gen_op_ltz(bcond, t0);
2639
            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2640
            goto not_likely;
2641
        case OPC_BLTZL:
2642
            gen_op_ltz(bcond, t0);
2643
            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2644
            goto likely;
2645
        case OPC_BLTZAL:
2646
            gen_op_ltz(bcond, t0);
2647
            blink = 31;
2648
            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2649
        not_likely:
2650
            ctx->hflags |= MIPS_HFLAG_BC;
2651
            break;
2652
        case OPC_BLTZALL:
2653
            gen_op_ltz(bcond, t0);
2654
            blink = 31;
2655
            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2656
        likely:
2657
            ctx->hflags |= MIPS_HFLAG_BL;
2658
            break;
2659
        default:
2660
            MIPS_INVAL("conditional branch/jump");
2661
            generate_exception(ctx, EXCP_RI);
2662
            goto out;
2663
        }
2664
    }
2665
    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2666
               blink, ctx->hflags, btgt);
2667

    
2668
    ctx->btarget = btgt;
2669
    if (blink > 0) {
2670
        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2671
    }
2672

    
2673
 out:
2674
    tcg_temp_free(t0);
2675
    tcg_temp_free(t1);
2676
}
2677

    
2678
/* special3 bitfield operations */
2679
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2680
                        int rs, int lsb, int msb)
2681
{
2682
    TCGv t0 = tcg_temp_new();
2683
    TCGv t1 = tcg_temp_new();
2684
    target_ulong mask;
2685

    
2686
    gen_load_gpr(t1, rs);
2687
    switch (opc) {
2688
    case OPC_EXT:
2689
        if (lsb + msb > 31)
2690
            goto fail;
2691
        tcg_gen_shri_tl(t0, t1, lsb);
2692
        if (msb != 31) {
2693
            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2694
        } else {
2695
            tcg_gen_ext32s_tl(t0, t0);
2696
        }
2697
        break;
2698
#if defined(TARGET_MIPS64)
2699
    case OPC_DEXTM:
2700
        tcg_gen_shri_tl(t0, t1, lsb);
2701
        if (msb != 31) {
2702
            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2703
        }
2704
        break;
2705
    case OPC_DEXTU:
2706
        tcg_gen_shri_tl(t0, t1, lsb + 32);
2707
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2708
        break;
2709
    case OPC_DEXT:
2710
        tcg_gen_shri_tl(t0, t1, lsb);
2711
        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2712
        break;
2713
#endif
2714
    case OPC_INS:
2715
        if (lsb > msb)
2716
            goto fail;
2717
        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2718
        gen_load_gpr(t0, rt);
2719
        tcg_gen_andi_tl(t0, t0, ~mask);
2720
        tcg_gen_shli_tl(t1, t1, lsb);
2721
        tcg_gen_andi_tl(t1, t1, mask);
2722
        tcg_gen_or_tl(t0, t0, t1);
2723
        tcg_gen_ext32s_tl(t0, t0);
2724
        break;
2725
#if defined(TARGET_MIPS64)
2726
    case OPC_DINSM:
2727
        if (lsb > msb)
2728
            goto fail;
2729
        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2730
        gen_load_gpr(t0, rt);
2731
        tcg_gen_andi_tl(t0, t0, ~mask);
2732
        tcg_gen_shli_tl(t1, t1, lsb);
2733
        tcg_gen_andi_tl(t1, t1, mask);
2734
        tcg_gen_or_tl(t0, t0, t1);
2735
        break;
2736
    case OPC_DINSU:
2737
        if (lsb > msb)
2738
            goto fail;
2739
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2740
        gen_load_gpr(t0, rt);
2741
        tcg_gen_andi_tl(t0, t0, ~mask);
2742
        tcg_gen_shli_tl(t1, t1, lsb + 32);
2743
        tcg_gen_andi_tl(t1, t1, mask);
2744
        tcg_gen_or_tl(t0, t0, t1);
2745
        break;
2746
    case OPC_DINS:
2747
        if (lsb > msb)
2748
            goto fail;
2749
        gen_load_gpr(t0, rt);
2750
        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2751
        gen_load_gpr(t0, rt);
2752
        tcg_gen_andi_tl(t0, t0, ~mask);
2753
        tcg_gen_shli_tl(t1, t1, lsb);
2754
        tcg_gen_andi_tl(t1, t1, mask);
2755
        tcg_gen_or_tl(t0, t0, t1);
2756
        break;
2757
#endif
2758
    default:
2759
fail:
2760
        MIPS_INVAL("bitops");
2761
        generate_exception(ctx, EXCP_RI);
2762
        tcg_temp_free(t0);
2763
        tcg_temp_free(t1);
2764
        return;
2765
    }
2766
    gen_store_gpr(t0, rt);
2767
    tcg_temp_free(t0);
2768
    tcg_temp_free(t1);
2769
}
2770

    
2771
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2772
{
2773
    TCGv t0;
2774

    
2775
    if (rd == 0) {
2776
        /* If no destination, treat it as a NOP. */
2777
        MIPS_DEBUG("NOP");
2778
        return;
2779
    }
2780

    
2781
    t0 = tcg_temp_new();
2782
    gen_load_gpr(t0, rt);
2783
    switch (op2) {
2784
    case OPC_WSBH:
2785
        {
2786
            TCGv t1 = tcg_temp_new();
2787

    
2788
            tcg_gen_shri_tl(t1, t0, 8);
2789
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2790
            tcg_gen_shli_tl(t0, t0, 8);
2791
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2792
            tcg_gen_or_tl(t0, t0, t1);
2793
            tcg_temp_free(t1);
2794
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2795
        }
2796
        break;
2797
    case OPC_SEB:
2798
        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2799
        break;
2800
    case OPC_SEH:
2801
        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2802
        break;
2803
#if defined(TARGET_MIPS64)
2804
    case OPC_DSBH:
2805
        {
2806
            TCGv t1 = tcg_temp_new();
2807

    
2808
            tcg_gen_shri_tl(t1, t0, 8);
2809
            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2810
            tcg_gen_shli_tl(t0, t0, 8);
2811
            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2812
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2813
            tcg_temp_free(t1);
2814
        }
2815
        break;
2816
    case OPC_DSHD:
2817
        {
2818
            TCGv t1 = tcg_temp_new();
2819

    
2820
            tcg_gen_shri_tl(t1, t0, 16);
2821
            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2822
            tcg_gen_shli_tl(t0, t0, 16);
2823
            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2824
            tcg_gen_or_tl(t0, t0, t1);
2825
            tcg_gen_shri_tl(t1, t0, 32);
2826
            tcg_gen_shli_tl(t0, t0, 32);
2827
            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2828
            tcg_temp_free(t1);
2829
        }
2830
        break;
2831
#endif
2832
    default:
2833
        MIPS_INVAL("bsfhl");
2834
        generate_exception(ctx, EXCP_RI);
2835
        tcg_temp_free(t0);
2836
        return;
2837
    }
2838
    tcg_temp_free(t0);
2839
}
2840

    
2841
#ifndef CONFIG_USER_ONLY
2842
/* CP0 (MMU and control) */
2843
static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2844
{
2845
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2846

    
2847
    tcg_gen_ld_i32(r_tmp, cpu_env, off);
2848
    tcg_gen_ext_i32_tl(t, r_tmp);
2849
    tcg_temp_free_i32(r_tmp);
2850
}
2851

    
2852
static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2853
{
2854
    tcg_gen_ld_tl(t, cpu_env, off);
2855
    tcg_gen_ext32s_tl(t, t);
2856
}
2857

    
2858
static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2859
{
2860
    TCGv_i32 r_tmp = tcg_temp_new_i32();
2861

    
2862
    tcg_gen_trunc_tl_i32(r_tmp, t);
2863
    tcg_gen_st_i32(r_tmp, cpu_env, off);
2864
    tcg_temp_free_i32(r_tmp);
2865
}
2866

    
2867
static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2868
{
2869
    tcg_gen_ext32s_tl(t, t);
2870
    tcg_gen_st_tl(t, cpu_env, off);
2871
}
2872

    
2873
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2874
{
2875
    const char *rn = "invalid";
2876

    
2877
    if (sel != 0)
2878
        check_insn(env, ctx, ISA_MIPS32);
2879

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

    
3445
die:
3446
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3447
    generate_exception(ctx, EXCP_RI);
3448
}
3449

    
3450
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3451
{
3452
    const char *rn = "invalid";
3453

    
3454
    if (sel != 0)
3455
        check_insn(env, ctx, ISA_MIPS32);
3456

    
3457
    if (use_icount)
3458
        gen_io_start();
3459

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

    
4038
die:
4039
    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4040
    generate_exception(ctx, EXCP_RI);
4041
}
4042

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

    
4048
    if (sel != 0)
4049
        check_insn(env, ctx, ISA_MIPS64);
4050

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

    
4605
die:
4606
    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4607
    generate_exception(ctx, EXCP_RI);
4608
}
4609

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

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

    
4617
    if (use_icount)
4618
        gen_io_start();
4619

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

    
5191
die:
5192
    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5193
    generate_exception(ctx, EXCP_RI);
5194
}
5195
#endif /* TARGET_MIPS64 */
5196

    
5197
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5198
                     int u, int sel, int h)
5199
{
5200
    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5201
    TCGv t0 = tcg_temp_local_new();
5202

    
5203
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5204
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5205
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5206
        tcg_gen_movi_tl(t0, -1);
5207
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5208
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5209
        tcg_gen_movi_tl(t0, -1);
5210
    else if (u == 0) {
5211
        switch (rt) {
5212
        case 2:
5213
            switch (sel) {
5214
            case 1:
5215
                gen_helper_mftc0_tcstatus(t0);
5216
                break;
5217
            case 2:
5218
                gen_helper_mftc0_tcbind(t0);
5219
                break;
5220
            case 3:
5221
                gen_helper_mftc0_tcrestart(t0);
5222
                break;
5223
            case 4:
5224
                gen_helper_mftc0_tchalt(t0);
5225
                break;
5226
            case 5:
5227
                gen_helper_mftc0_tccontext(t0);
5228
                break;
5229
            case 6:
5230
                gen_helper_mftc0_tcschedule(t0);
5231
                break;
5232
            case 7:
5233
                gen_helper_mftc0_tcschefback(t0);
5234
                break;
5235
            default:
5236
                gen_mfc0(env, ctx, t0, rt, sel);
5237
                break;
5238
            }
5239
            break;
5240
        case 10:
5241
            switch (sel) {
5242
            case 0:
5243
                gen_helper_mftc0_entryhi(t0);
5244
                break;
5245
            default:
5246
                gen_mfc0(env, ctx, t0, rt, sel);
5247
                break;
5248
            }
5249
        case 12:
5250
            switch (sel) {
5251
            case 0:
5252
                gen_helper_mftc0_status(t0);
5253
                break;
5254
            default:
5255
                gen_mfc0(env, ctx, t0, rt, sel);
5256
                break;
5257
            }
5258
        case 23:
5259
            switch (sel) {
5260
            case 0:
5261
                gen_helper_mftc0_debug(t0);
5262
                break;
5263
            default:
5264
                gen_mfc0(env, ctx, t0, rt, sel);
5265
                break;
5266
            }
5267
            break;
5268
        default:
5269
            gen_mfc0(env, ctx, t0, rt, sel);
5270
        }
5271
    } else switch (sel) {
5272
    /* GPR registers. */
5273
    case 0:
5274
        gen_helper_1i(mftgpr, t0, rt);
5275
        break;
5276
    /* Auxiliary CPU registers */
5277
    case 1:
5278
        switch (rt) {
5279
        case 0:
5280
            gen_helper_1i(mftlo, t0, 0);
5281
            break;
5282
        case 1:
5283
            gen_helper_1i(mfthi, t0, 0);
5284
            break;
5285
        case 2:
5286
            gen_helper_1i(mftacx, t0, 0);
5287
            break;
5288
        case 4:
5289
            gen_helper_1i(mftlo, t0, 1);
5290
            break;
5291
        case 5:
5292
            gen_helper_1i(mfthi, t0, 1);
5293
            break;
5294
        case 6:
5295
            gen_helper_1i(mftacx, t0, 1);
5296
            break;
5297
        case 8:
5298
            gen_helper_1i(mftlo, t0, 2);
5299
            break;
5300
        case 9:
5301
            gen_helper_1i(mfthi, t0, 2);
5302
            break;
5303
        case 10:
5304
            gen_helper_1i(mftacx, t0, 2);
5305
            break;
5306
        case 12:
5307
            gen_helper_1i(mftlo, t0, 3);
5308
            break;
5309
        case 13:
5310
            gen_helper_1i(mfthi, t0, 3);
5311
            break;
5312
        case 14:
5313
            gen_helper_1i(mftacx, t0, 3);
5314
            break;
5315
        case 16:
5316
            gen_helper_mftdsp(t0);
5317
            break;
5318
        default:
5319
            goto die;
5320
        }
5321
        break;
5322
    /* Floating point (COP1). */
5323
    case 2:
5324
        /* XXX: For now we support only a single FPU context. */
5325
        if (h == 0) {
5326
            TCGv_i32 fp0 = tcg_temp_new_i32();
5327

    
5328
            gen_load_fpr32(fp0, rt);
5329
            tcg_gen_ext_i32_tl(t0, fp0);
5330
            tcg_temp_free_i32(fp0);
5331
        } else {
5332
            TCGv_i32 fp0 = tcg_temp_new_i32();
5333

    
5334
            gen_load_fpr32h(fp0, rt);
5335
            tcg_gen_ext_i32_tl(t0, fp0);
5336
            tcg_temp_free_i32(fp0);
5337
        }
5338
        break;
5339
    case 3:
5340
        /* XXX: For now we support only a single FPU context. */
5341
        gen_helper_1i(cfc1, t0, rt);
5342
        break;
5343
    /* COP2: Not implemented. */
5344
    case 4:
5345
    case 5:
5346
        /* fall through */
5347
    default:
5348
        goto die;
5349
    }
5350
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5351
    gen_store_gpr(t0, rd);
5352
    tcg_temp_free(t0);
5353
    return;
5354

    
5355
die:
5356
    tcg_temp_free(t0);
5357
    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5358
    generate_exception(ctx, EXCP_RI);
5359
}
5360

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

    
5367
    gen_load_gpr(t0, rt);
5368
    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5369
        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5370
         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5371
        /* NOP */ ;
5372
    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5373
             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5374
        /* NOP */ ;
5375
    else if (u == 0) {
5376
        switch (rd) {
5377
        case 2:
5378
            switch (sel) {
5379
            case 1:
5380
                gen_helper_mttc0_tcstatus(t0);
5381
                break;
5382
            case 2:
5383
                gen_helper_mttc0_tcbind(t0);
5384
                break;
5385
            case 3:
5386
                gen_helper_mttc0_tcrestart(t0);
5387
                break;
5388
            case 4:
5389
                gen_helper_mttc0_tchalt(t0);
5390
                break;
5391
            case 5:
5392
                gen_helper_mttc0_tccontext(t0);
5393
                break;
5394
            case 6:
5395
                gen_helper_mttc0_tcschedule(t0);
5396
                break;
5397
            case 7:
5398
                gen_helper_mttc0_tcschefback(t0);
5399
                break;
5400
            default:
5401
                gen_mtc0(env, ctx, t0, rd, sel);
5402
                break;
5403
            }
5404
            break;
5405
        case 10:
5406
            switch (sel) {
5407
            case 0:
5408
                gen_helper_mttc0_entryhi(t0);
5409
                break;
5410
            default:
5411
                gen_mtc0(env, ctx, t0, rd, sel);
5412
                break;
5413
            }
5414
        case 12:
5415
            switch (sel) {
5416
            case 0:
5417
                gen_helper_mttc0_status(t0);
5418
                break;
5419
            default:
5420
                gen_mtc0(env, ctx, t0, rd, sel);
5421
                break;
5422
            }
5423
        case 23:
5424
            switch (sel) {
5425
            case 0:
5426
                gen_helper_mttc0_debug(t0);
5427
                break;
5428
            default:
5429
                gen_mtc0(env, ctx, t0, rd, sel);
5430
                break;
5431
            }
5432
            break;
5433
        default:
5434
            gen_mtc0(env, ctx, t0, rd, sel);
5435
        }
5436
    } else switch (sel) {
5437
    /* GPR registers. */
5438
    case 0:
5439
        gen_helper_1i(mttgpr, t0, rd);
5440
        break;
5441
    /* Auxiliary CPU registers */
5442
    case 1:
5443
        switch (rd) {
5444
        case 0:
5445
            gen_helper_1i(mttlo, t0, 0);
5446
            break;
5447
        case 1:
5448
            gen_helper_1i(mtthi, t0, 0);
5449
            break;
5450
        case 2:
5451
            gen_helper_1i(mttacx, t0, 0);
5452
            break;
5453
        case 4:
5454
            gen_helper_1i(mttlo, t0, 1);
5455
            break;
5456
        case 5:
5457
            gen_helper_1i(mtthi, t0, 1);
5458
            break;
5459
        case 6:
5460
            gen_helper_1i(mttacx, t0, 1);
5461
            break;
5462
        case 8:
5463
            gen_helper_1i(mttlo, t0, 2);
5464
            break;
5465
        case 9:
5466
            gen_helper_1i(mtthi, t0, 2);
5467
            break;
5468
        case 10:
5469
            gen_helper_1i(mttacx, t0, 2);
5470
            break;
5471
        case 12:
5472
            gen_helper_1i(mttlo, t0, 3);
5473
            break;
5474
        case 13:
5475
            gen_helper_1i(mtthi, t0, 3);
5476
            break;
5477
        case 14:
5478
            gen_helper_1i(mttacx, t0, 3);
5479
            break;
5480
        case 16:
5481
            gen_helper_mttdsp(t0);
5482
            break;
5483
        default:
5484
            goto die;
5485
        }
5486
        break;
5487
    /* Floating point (COP1). */
5488
    case 2:
5489
        /* XXX: For now we support only a single FPU context. */
5490
        if (h == 0) {
5491
            TCGv_i32 fp0 = tcg_temp_new_i32();
5492

    
5493
            tcg_gen_trunc_tl_i32(fp0, t0);
5494
            gen_store_fpr32(fp0, rd);
5495
            tcg_temp_free_i32(fp0);
5496
        } else {
5497
            TCGv_i32 fp0 = tcg_temp_new_i32();
5498

    
5499
            tcg_gen_trunc_tl_i32(fp0, t0);
5500
            gen_store_fpr32h(fp0, rd);
5501
            tcg_temp_free_i32(fp0);
5502
        }
5503
        break;
5504
    case 3:
5505
        /* XXX: For now we support only a single FPU context. */
5506
        gen_helper_1i(ctc1, t0, rd);
5507
        break;
5508
    /* COP2: Not implemented. */
5509
    case 4:
5510
    case 5:
5511
        /* fall through */
5512
    default:
5513
        goto die;
5514
    }
5515
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5516
    tcg_temp_free(t0);
5517
    return;
5518

    
5519
die:
5520
    tcg_temp_free(t0);
5521
    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5522
    generate_exception(ctx, EXCP_RI);
5523
}
5524

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

    
5529
    switch (opc) {
5530
    case OPC_MFC0:
5531
        if (rt == 0) {
5532
            /* Treat as NOP. */
5533
            return;
5534
        }
5535
        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5536
        opn = "mfc0";
5537
        break;
5538
    case OPC_MTC0:
5539
        {
5540
            TCGv t0 = tcg_temp_new();
5541

    
5542
            gen_load_gpr(t0, rt);
5543
            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5544
            tcg_temp_free(t0);
5545
        }
5546
        opn = "mtc0";
5547
        break;
5548
#if defined(TARGET_MIPS64)
5549
    case OPC_DMFC0:
5550
        check_insn(env, ctx, ISA_MIPS3);
5551
        if (rt == 0) {
5552
            /* Treat as NOP. */
5553
            return;
5554
        }
5555
        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5556
        opn = "dmfc0";
5557
        break;
5558
    case OPC_DMTC0:
5559
        check_insn(env, ctx, ISA_MIPS3);
5560
        {
5561
            TCGv t0 = tcg_temp_new();
5562

    
5563
            gen_load_gpr(t0, rt);
5564
            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5565
            tcg_temp_free(t0);
5566
        }
5567
        opn = "dmtc0";
5568
        break;
5569
#endif
5570
    case OPC_MFTR:
5571
        check_insn(env, ctx, ASE_MT);
5572
        if (rd == 0) {
5573
            /* Treat as NOP. */
5574
            return;
5575
        }
5576
        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5577
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5578
        opn = "mftr";
5579
        break;
5580
    case OPC_MTTR:
5581
        check_insn(env, ctx, ASE_MT);
5582
        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5583
                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5584
        opn = "mttr";
5585
        break;
5586
    case OPC_TLBWI:
5587
        opn = "tlbwi";
5588
        if (!env->tlb->helper_tlbwi)
5589
            goto die;
5590
        gen_helper_tlbwi();
5591
        break;
5592
    case OPC_TLBWR:
5593
        opn = "tlbwr";
5594
        if (!env->tlb->helper_tlbwr)
5595
            goto die;
5596
        gen_helper_tlbwr();
5597
        break;
5598
    case OPC_TLBP:
5599
        opn = "tlbp";
5600
        if (!env->tlb->helper_tlbp)
5601
            goto die;
5602
        gen_helper_tlbp();
5603
        break;
5604
    case OPC_TLBR:
5605
        opn = "tlbr";
5606
        if (!env->tlb->helper_tlbr)
5607
            goto die;
5608
        gen_helper_tlbr();
5609
        break;
5610
    case OPC_ERET:
5611
        opn = "eret";
5612
        check_insn(env, ctx, ISA_MIPS2);
5613
        gen_helper_eret();
5614
        ctx->bstate = BS_EXCP;
5615
        break;
5616
    case OPC_DERET:
5617
        opn = "deret";
5618
        check_insn(env, ctx, ISA_MIPS32);
5619
        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5620
            MIPS_INVAL(opn);
5621
            generate_exception(ctx, EXCP_RI);
5622
        } else {
5623
            gen_helper_deret();
5624
            ctx->bstate = BS_EXCP;
5625
        }
5626
        break;
5627
    case OPC_WAIT:
5628
        opn = "wait";
5629
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5630
        /* If we get an exception, we want to restart at next instruction */
5631
        ctx->pc += 4;
5632
        save_cpu_state(ctx, 1);
5633
        ctx->pc -= 4;
5634
        gen_helper_wait();
5635
        ctx->bstate = BS_EXCP;
5636
        break;
5637
    default:
5638
 die:
5639
        MIPS_INVAL(opn);
5640
        generate_exception(ctx, EXCP_RI);
5641
        return;
5642
    }
5643
    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5644
}
5645
#endif /* !CONFIG_USER_ONLY */
5646

    
5647
/* CP1 Branches (before delay slot) */
5648
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5649
                                 int32_t cc, int32_t offset)
5650
{
5651
    target_ulong btarget;
5652
    const char *opn = "cp1 cond branch";
5653
    TCGv_i32 t0 = tcg_temp_new_i32();
5654

    
5655
    if (cc != 0)
5656
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5657

    
5658
    btarget = ctx->pc + 4 + offset;
5659

    
5660
    switch (op) {
5661
    case OPC_BC1F:
5662
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5663
        tcg_gen_not_i32(t0, t0);
5664
        tcg_gen_andi_i32(t0, t0, 1);
5665
        tcg_gen_extu_i32_tl(bcond, t0);
5666
        opn = "bc1f";
5667
        goto not_likely;
5668
    case OPC_BC1FL:
5669
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5670
        tcg_gen_not_i32(t0, t0);
5671
        tcg_gen_andi_i32(t0, t0, 1);
5672
        tcg_gen_extu_i32_tl(bcond, t0);
5673
        opn = "bc1fl";
5674
        goto likely;
5675
    case OPC_BC1T:
5676
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5677
        tcg_gen_andi_i32(t0, t0, 1);
5678
        tcg_gen_extu_i32_tl(bcond, t0);
5679
        opn = "bc1t";
5680
        goto not_likely;
5681
    case OPC_BC1TL:
5682
        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5683
        tcg_gen_andi_i32(t0, t0, 1);
5684
        tcg_gen_extu_i32_tl(bcond, t0);
5685
        opn = "bc1tl";
5686
    likely:
5687
        ctx->hflags |= MIPS_HFLAG_BL;
5688
        break;
5689
    case OPC_BC1FANY2:
5690
        {
5691
            TCGv_i32 t1 = tcg_temp_new_i32();
5692
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5693
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5694
            tcg_gen_or_i32(t0, t0, t1);
5695
            tcg_temp_free_i32(t1);
5696
            tcg_gen_not_i32(t0, t0);
5697
            tcg_gen_andi_i32(t0, t0, 1);
5698
            tcg_gen_extu_i32_tl(bcond, t0);
5699
        }
5700
        opn = "bc1any2f";
5701
        goto not_likely;
5702
    case OPC_BC1TANY2:
5703
        {
5704
            TCGv_i32 t1 = tcg_temp_new_i32();
5705
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5706
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5707
            tcg_gen_or_i32(t0, t0, t1);
5708
            tcg_temp_free_i32(t1);
5709
            tcg_gen_andi_i32(t0, t0, 1);
5710
            tcg_gen_extu_i32_tl(bcond, t0);
5711
        }
5712
        opn = "bc1any2t";
5713
        goto not_likely;
5714
    case OPC_BC1FANY4:
5715
        {
5716
            TCGv_i32 t1 = tcg_temp_new_i32();
5717
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5718
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5719
            tcg_gen_or_i32(t0, t0, t1);
5720
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5721
            tcg_gen_or_i32(t0, t0, t1);
5722
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5723
            tcg_gen_or_i32(t0, t0, t1);
5724
            tcg_temp_free_i32(t1);
5725
            tcg_gen_not_i32(t0, t0);
5726
            tcg_gen_andi_i32(t0, t0, 1);
5727
            tcg_gen_extu_i32_tl(bcond, t0);
5728
        }
5729
        opn = "bc1any4f";
5730
        goto not_likely;
5731
    case OPC_BC1TANY4:
5732
        {
5733
            TCGv_i32 t1 = tcg_temp_new_i32();
5734
            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5735
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5736
            tcg_gen_or_i32(t0, t0, t1);
5737
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5738
            tcg_gen_or_i32(t0, t0, t1);
5739
            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5740
            tcg_gen_or_i32(t0, t0, t1);
5741
            tcg_temp_free_i32(t1);
5742
            tcg_gen_andi_i32(t0, t0, 1);
5743
            tcg_gen_extu_i32_tl(bcond, t0);
5744
        }
5745
        opn = "bc1any4t";
5746
    not_likely:
5747
        ctx->hflags |= MIPS_HFLAG_BC;
5748
        break;
5749
    default:
5750
        MIPS_INVAL(opn);
5751
        generate_exception (ctx, EXCP_RI);
5752
        goto out;
5753
    }
5754
    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5755
               ctx->hflags, btarget);
5756
    ctx->btarget = btarget;
5757

    
5758
 out:
5759
    tcg_temp_free_i32(t0);
5760
}
5761

    
5762
/* Coprocessor 1 (FPU) */
5763

    
5764
#define FOP(func, fmt) (((fmt) << 21) | (func))
5765

    
5766
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5767
{
5768
    const char *opn = "cp1 move";
5769
    TCGv t0 = tcg_temp_new();
5770

    
5771
    switch (opc) {
5772
    case OPC_MFC1:
5773
        {
5774
            TCGv_i32 fp0 = tcg_temp_new_i32();
5775

    
5776
            gen_load_fpr32(fp0, fs);
5777
            tcg_gen_ext_i32_tl(t0, fp0);
5778
            tcg_temp_free_i32(fp0);
5779
        }
5780
        gen_store_gpr(t0, rt);
5781
        opn = "mfc1";
5782
        break;
5783
    case OPC_MTC1:
5784
        gen_load_gpr(t0, rt);
5785
        {
5786
            TCGv_i32 fp0 = tcg_temp_new_i32();
5787

    
5788
            tcg_gen_trunc_tl_i32(fp0, t0);
5789
            gen_store_fpr32(fp0, fs);
5790
            tcg_temp_free_i32(fp0);
5791
        }
5792
        opn = "mtc1";
5793
        break;
5794
    case OPC_CFC1:
5795
        gen_helper_1i(cfc1, t0, fs);
5796
        gen_store_gpr(t0, rt);
5797
        opn = "cfc1";
5798
        break;
5799
    case OPC_CTC1:
5800
        gen_load_gpr(t0, rt);
5801
        gen_helper_1i(ctc1, t0, fs);
5802
        opn = "ctc1";
5803
        break;
5804
#if defined(TARGET_MIPS64)
5805
    case OPC_DMFC1:
5806
        gen_load_fpr64(ctx, t0, fs);
5807
        gen_store_gpr(t0, rt);
5808
        opn = "dmfc1";
5809
        break;
5810
    case OPC_DMTC1:
5811
        gen_load_gpr(t0, rt);
5812
        gen_store_fpr64(ctx, t0, fs);
5813
        opn = "dmtc1";
5814
        break;
5815
#endif
5816
    case OPC_MFHC1:
5817
        {
5818
            TCGv_i32 fp0 = tcg_temp_new_i32();
5819

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

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

    
5845
 out:
5846
    tcg_temp_free(t0);
5847
}
5848

    
5849
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5850
{
5851
    int l1;
5852
    TCGCond cond;
5853
    TCGv_i32 t0;
5854

    
5855
    if (rd == 0) {
5856
        /* Treat as NOP. */
5857
        return;
5858
    }
5859

    
5860
    if (tf)
5861
        cond = TCG_COND_EQ;
5862
    else
5863
        cond = TCG_COND_NE;
5864

    
5865
    l1 = gen_new_label();
5866
    t0 = tcg_temp_new_i32();
5867
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5868
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5869
    tcg_temp_free_i32(t0);
5870
    if (rs == 0) {
5871
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5872
    } else {
5873
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5874
    }
5875
    gen_set_label(l1);
5876
}
5877

    
5878
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5879
{
5880
    int cond;
5881
    TCGv_i32 t0 = tcg_temp_new_i32();
5882
    int l1 = gen_new_label();
5883

    
5884
    if (tf)
5885
        cond = TCG_COND_EQ;
5886
    else
5887
        cond = TCG_COND_NE;
5888

    
5889
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5890
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5891
    gen_load_fpr32(t0, fs);
5892
    gen_store_fpr32(t0, fd);
5893
    gen_set_label(l1);
5894
    tcg_temp_free_i32(t0);
5895
}
5896

    
5897
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5898
{
5899
    int cond;
5900
    TCGv_i32 t0 = tcg_temp_new_i32();
5901
    TCGv_i64 fp0;
5902
    int l1 = gen_new_label();
5903

    
5904
    if (tf)
5905
        cond = TCG_COND_EQ;
5906
    else
5907
        cond = TCG_COND_NE;
5908

    
5909
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5910
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5911
    tcg_temp_free_i32(t0);
5912
    fp0 = tcg_temp_new_i64();
5913
    gen_load_fpr64(ctx, fp0, fs);
5914
    gen_store_fpr64(ctx, fp0, fd);
5915
    tcg_temp_free_i64(fp0);
5916
    gen_set_label(l1);
5917
}
5918

    
5919
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5920
{
5921
    int cond;
5922
    TCGv_i32 t0 = tcg_temp_new_i32();
5923
    int l1 = gen_new_label();
5924
    int l2 = gen_new_label();
5925

    
5926
    if (tf)
5927
        cond = TCG_COND_EQ;
5928
    else
5929
        cond = TCG_COND_NE;
5930

    
5931
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
5932
    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5933
    gen_load_fpr32(t0, fs);
5934
    gen_store_fpr32(t0, fd);
5935
    gen_set_label(l1);
5936

    
5937
    tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
5938
    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5939
    gen_load_fpr32h(t0, fs);
5940
    gen_store_fpr32h(t0, fd);
5941
    tcg_temp_free_i32(t0);
5942
    gen_set_label(l2);
5943
}
5944

    
5945

    
5946
static void gen_farith (DisasContext *ctx, uint32_t op1,
5947
                        int ft, int fs, int fd, int cc)
5948
{
5949
    const char *opn = "farith";
5950
    const char *condnames[] = {
5951
            "c.f",
5952
            "c.un",
5953
            "c.eq",
5954
            "c.ueq",
5955
            "c.olt",
5956
            "c.ult",
5957
            "c.ole",
5958
            "c.ule",
5959
            "c.sf",
5960
            "c.ngle",
5961
            "c.seq",
5962
            "c.ngl",
5963
            "c.lt",
5964
            "c.nge",
5965
            "c.le",
5966
            "c.ngt",
5967
    };
5968
    const char *condnames_abs[] = {
5969
            "cabs.f",
5970
            "cabs.un",
5971
            "cabs.eq",
5972
            "cabs.ueq",
5973
            "cabs.olt",
5974
            "cabs.ult",
5975
            "cabs.ole",
5976
            "cabs.ule",
5977
            "cabs.sf",
5978
            "cabs.ngle",
5979
            "cabs.seq",
5980
            "cabs.ngl",
5981
            "cabs.lt",
5982
            "cabs.nge",
5983
            "cabs.le",
5984
            "cabs.ngt",
5985
    };
5986
    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5987
    uint32_t func = ctx->opcode & 0x3f;
5988

    
5989
    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5990
    case FOP(0, 16):
5991
        {
5992
            TCGv_i32 fp0 = tcg_temp_new_i32();
5993
            TCGv_i32 fp1 = tcg_temp_new_i32();
5994

    
5995
            gen_load_fpr32(fp0, fs);
5996
            gen_load_fpr32(fp1, ft);
5997
            gen_helper_float_add_s(fp0, fp0, fp1);
5998
            tcg_temp_free_i32(fp1);
5999
            gen_store_fpr32(fp0, fd);
6000
            tcg_temp_free_i32(fp0);
6001
        }
6002
        opn = "add.s";
6003
        optype = BINOP;
6004
        break;
6005
    case FOP(1, 16):
6006
        {
6007
            TCGv_i32 fp0 = tcg_temp_new_i32();
6008
            TCGv_i32 fp1 = tcg_temp_new_i32();
6009

    
6010
            gen_load_fpr32(fp0, fs);
6011
            gen_load_fpr32(fp1, ft);
6012
            gen_helper_float_sub_s(fp0, fp0, fp1);
6013
            tcg_temp_free_i32(fp1);
6014
            gen_store_fpr32(fp0, fd);
6015
            tcg_temp_free_i32(fp0);
6016
        }
6017
        opn = "sub.s";
6018
        optype = BINOP;
6019
        break;
6020
    case FOP(2, 16):
6021
        {
6022
            TCGv_i32 fp0 = tcg_temp_new_i32();
6023
            TCGv_i32 fp1 = tcg_temp_new_i32();
6024

    
6025
            gen_load_fpr32(fp0, fs);
6026
            gen_load_fpr32(fp1, ft);
6027
            gen_helper_float_mul_s(fp0, fp0, fp1);
6028
            tcg_temp_free_i32(fp1);
6029
            gen_store_fpr32(fp0, fd);
6030
            tcg_temp_free_i32(fp0);
6031
        }
6032
        opn = "mul.s";
6033
        optype = BINOP;
6034
        break;
6035
    case FOP(3, 16):
6036
        {
6037
            TCGv_i32 fp0 = tcg_temp_new_i32();
6038
            TCGv_i32 fp1 = tcg_temp_new_i32();
6039

    
6040
            gen_load_fpr32(fp0, fs);
6041
            gen_load_fpr32(fp1, ft);
6042
            gen_helper_float_div_s(fp0, fp0, fp1);
6043
            tcg_temp_free_i32(fp1);
6044
            gen_store_fpr32(fp0, fd);
6045
            tcg_temp_free_i32(fp0);
6046
        }
6047
        opn = "div.s";
6048
        optype = BINOP;
6049
        break;
6050
    case FOP(4, 16):
6051
        {
6052
            TCGv_i32 fp0 = tcg_temp_new_i32();
6053

    
6054
            gen_load_fpr32(fp0, fs);
6055
            gen_helper_float_sqrt_s(fp0, fp0);
6056
            gen_store_fpr32(fp0, fd);
6057
            tcg_temp_free_i32(fp0);
6058
        }
6059
        opn = "sqrt.s";
6060
        break;
6061
    case FOP(5, 16):
6062
        {
6063
            TCGv_i32 fp0 = tcg_temp_new_i32();
6064

    
6065
            gen_load_fpr32(fp0, fs);
6066
            gen_helper_float_abs_s(fp0, fp0);
6067
            gen_store_fpr32(fp0, fd);
6068
            tcg_temp_free_i32(fp0);
6069
        }
6070
        opn = "abs.s";
6071
        break;
6072
    case FOP(6, 16):
6073
        {
6074
            TCGv_i32 fp0 = tcg_temp_new_i32();
6075

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

    
6086
            gen_load_fpr32(fp0, fs);
6087
            gen_helper_float_chs_s(fp0, fp0);
6088
            gen_store_fpr32(fp0, fd);
6089
            tcg_temp_free_i32(fp0);
6090
        }
6091
        opn = "neg.s";
6092
        break;
6093
    case FOP(8, 16):
6094
        check_cp1_64bitmode(ctx);
6095
        {
6096
            TCGv_i32 fp32 = tcg_temp_new_i32();
6097
            TCGv_i64 fp64 = tcg_temp_new_i64();
6098

    
6099
            gen_load_fpr32(fp32, fs);
6100
            gen_helper_float_roundl_s(fp64, fp32);
6101
            tcg_temp_free_i32(fp32);
6102
            gen_store_fpr64(ctx, fp64, fd);
6103
            tcg_temp_free_i64(fp64);
6104
        }
6105
        opn = "round.l.s";
6106
        break;
6107
    case FOP(9, 16):
6108
        check_cp1_64bitmode(ctx);
6109
        {
6110
            TCGv_i32 fp32 = tcg_temp_new_i32();
6111
            TCGv_i64 fp64 = tcg_temp_new_i64();
6112

    
6113
            gen_load_fpr32(fp32, fs);
6114
            gen_helper_float_truncl_s(fp64, fp32);
6115
            tcg_temp_free_i32(fp32);
6116
            gen_store_fpr64(ctx, fp64, fd);
6117
            tcg_temp_free_i64(fp64);
6118
        }
6119
        opn = "trunc.l.s";
6120
        break;
6121
    case FOP(10, 16):
6122
        check_cp1_64bitmode(ctx);
6123
        {
6124
            TCGv_i32 fp32 = tcg_temp_new_i32();
6125
            TCGv_i64 fp64 = tcg_temp_new_i64();
6126

    
6127
            gen_load_fpr32(fp32, fs);
6128
            gen_helper_float_ceill_s(fp64, fp32);
6129
            tcg_temp_free_i32(fp32);
6130
            gen_store_fpr64(ctx, fp64, fd);
6131
            tcg_temp_free_i64(fp64);
6132
        }
6133
        opn = "ceil.l.s";
6134
        break;
6135
    case FOP(11, 16):
6136
        check_cp1_64bitmode(ctx);
6137
        {
6138
            TCGv_i32 fp32 = tcg_temp_new_i32();
6139
            TCGv_i64 fp64 = tcg_temp_new_i64();
6140

    
6141
            gen_load_fpr32(fp32, fs);
6142
            gen_helper_float_floorl_s(fp64, fp32);
6143
            tcg_temp_free_i32(fp32);
6144
            gen_store_fpr64(ctx, fp64, fd);
6145
            tcg_temp_free_i64(fp64);
6146
        }
6147
        opn = "floor.l.s";
6148
        break;
6149
    case FOP(12, 16):
6150
        {
6151
            TCGv_i32 fp0 = tcg_temp_new_i32();
6152

    
6153
            gen_load_fpr32(fp0, fs);
6154
            gen_helper_float_roundw_s(fp0, fp0);
6155
            gen_store_fpr32(fp0, fd);
6156
            tcg_temp_free_i32(fp0);
6157
        }
6158
        opn = "round.w.s";
6159
        break;
6160
    case FOP(13, 16):
6161
        {
6162
            TCGv_i32 fp0 = tcg_temp_new_i32();
6163

    
6164
            gen_load_fpr32(fp0, fs);
6165
            gen_helper_float_truncw_s(fp0, fp0);
6166
            gen_store_fpr32(fp0, fd);
6167
            tcg_temp_free_i32(fp0);
6168
        }
6169
        opn = "trunc.w.s";
6170
        break;
6171
    case FOP(14, 16):
6172
        {
6173
            TCGv_i32 fp0 = tcg_temp_new_i32();
6174

    
6175
            gen_load_fpr32(fp0, fs);
6176
            gen_helper_float_ceilw_s(fp0, fp0);
6177
            gen_store_fpr32(fp0, fd);
6178
            tcg_temp_free_i32(fp0);
6179
        }
6180
        opn = "ceil.w.s";
6181
        break;
6182
    case FOP(15, 16):
6183
        {
6184
            TCGv_i32 fp0 = tcg_temp_new_i32();
6185

    
6186
            gen_load_fpr32(fp0, fs);
6187
            gen_helper_float_floorw_s(fp0, fp0);
6188
            gen_store_fpr32(fp0, fd);
6189
            tcg_temp_free_i32(fp0);
6190
        }
6191
        opn = "floor.w.s";
6192
        break;
6193
    case FOP(17, 16):
6194
        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6195
        opn = "movcf.s";
6196
        break;
6197
    case FOP(18, 16):
6198
        {
6199
            int l1 = gen_new_label();
6200
            TCGv_i32 fp0;
6201

    
6202
            if (ft != 0) {
6203
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6204
            }
6205
            fp0 = tcg_temp_new_i32();
6206
            gen_load_fpr32(fp0, fs);
6207
            gen_store_fpr32(fp0, fd);
6208
            tcg_temp_free_i32(fp0);
6209
            gen_set_label(l1);
6210
        }
6211
        opn = "movz.s";
6212
        break;
6213
    case FOP(19, 16):
6214
        {
6215
            int l1 = gen_new_label();
6216
            TCGv_i32 fp0;
6217

    
6218
            if (ft != 0) {
6219
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6220
                fp0 = tcg_temp_new_i32();
6221
                gen_load_fpr32(fp0, fs);
6222
                gen_store_fpr32(fp0, fd);
6223
                tcg_temp_free_i32(fp0);
6224
                gen_set_label(l1);
6225
            }
6226
        }
6227
        opn = "movn.s";
6228
        break;
6229
    case FOP(21, 16):
6230
        check_cop1x(ctx);
6231
        {
6232
            TCGv_i32 fp0 = tcg_temp_new_i32();
6233

    
6234
            gen_load_fpr32(fp0, fs);
6235
            gen_helper_float_recip_s(fp0, fp0);
6236
            gen_store_fpr32(fp0, fd);
6237
            tcg_temp_free_i32(fp0);
6238
        }
6239
        opn = "recip.s";
6240
        break;
6241
    case FOP(22, 16):
6242
        check_cop1x(ctx);
6243
        {
6244
            TCGv_i32 fp0 = tcg_temp_new_i32();
6245

    
6246
            gen_load_fpr32(fp0, fs);
6247
            gen_helper_float_rsqrt_s(fp0, fp0);
6248
            gen_store_fpr32(fp0, fd);
6249
            tcg_temp_free_i32(fp0);
6250
        }
6251
        opn = "rsqrt.s";
6252
        break;
6253
    case FOP(28, 16):
6254
        check_cp1_64bitmode(ctx);
6255
        {
6256
            TCGv_i32 fp0 = tcg_temp_new_i32();
6257
            TCGv_i32 fp1 = tcg_temp_new_i32();
6258

    
6259
            gen_load_fpr32(fp0, fs);
6260
            gen_load_fpr32(fp1, fd);
6261
            gen_helper_float_recip2_s(fp0, fp0, fp1);
6262
            tcg_temp_free_i32(fp1);
6263
            gen_store_fpr32(fp0, fd);
6264
            tcg_temp_free_i32(fp0);
6265
        }
6266
        opn = "recip2.s";
6267
        break;
6268
    case FOP(29, 16):
6269
        check_cp1_64bitmode(ctx);
6270
        {
6271
            TCGv_i32 fp0 = tcg_temp_new_i32();
6272

    
6273
            gen_load_fpr32(fp0, fs);
6274
            gen_helper_float_recip1_s(fp0, fp0);
6275
            gen_store_fpr32(fp0, fd);
6276
            tcg_temp_free_i32(fp0);
6277
        }
6278
        opn = "recip1.s";
6279
        break;
6280
    case FOP(30, 16):
6281
        check_cp1_64bitmode(ctx);
6282
        {
6283
            TCGv_i32 fp0 = tcg_temp_new_i32();
6284

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

    
6298
            gen_load_fpr32(fp0, fs);
6299
            gen_load_fpr32(fp1, ft);
6300
            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6301
            tcg_temp_free_i32(fp1);
6302
            gen_store_fpr32(fp0, fd);
6303
            tcg_temp_free_i32(fp0);
6304
        }
6305
        opn = "rsqrt2.s";
6306
        break;
6307
    case FOP(33, 16):
6308
        check_cp1_registers(ctx, fd);
6309
        {
6310
            TCGv_i32 fp32 = tcg_temp_new_i32();
6311
            TCGv_i64 fp64 = tcg_temp_new_i64();
6312

    
6313
            gen_load_fpr32(fp32, fs);
6314
            gen_helper_float_cvtd_s(fp64, fp32);
6315
            tcg_temp_free_i32(fp32);
6316
            gen_store_fpr64(ctx, fp64, fd);
6317
            tcg_temp_free_i64(fp64);
6318
        }
6319
        opn = "cvt.d.s";
6320
        break;
6321
    case FOP(36, 16):
6322
        {
6323
            TCGv_i32 fp0 = tcg_temp_new_i32();
6324

    
6325
            gen_load_fpr32(fp0, fs);
6326
            gen_helper_float_cvtw_s(fp0, fp0);
6327
            gen_store_fpr32(fp0, fd);
6328
            tcg_temp_free_i32(fp0);
6329
        }
6330
        opn = "cvt.w.s";
6331
        break;
6332
    case FOP(37, 16):
6333
        check_cp1_64bitmode(ctx);
6334
        {
6335
            TCGv_i32 fp32 = tcg_temp_new_i32();
6336
            TCGv_i64 fp64 = tcg_temp_new_i64();
6337

    
6338
            gen_load_fpr32(fp32, fs);
6339
            gen_helper_float_cvtl_s(fp64, fp32);
6340
            tcg_temp_free_i32(fp32);
6341
            gen_store_fpr64(ctx, fp64, fd);
6342
            tcg_temp_free_i64(fp64);
6343
        }
6344
        opn = "cvt.l.s";
6345
        break;
6346
    case FOP(38, 16):
6347
        check_cp1_64bitmode(ctx);
6348
        {
6349
            TCGv_i64 fp64 = tcg_temp_new_i64();
6350
            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6351
            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6352

    
6353
            gen_load_fpr32(fp32_0, fs);
6354
            gen_load_fpr32(fp32_1, ft);
6355
            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6356
            tcg_temp_free_i32(fp32_1);
6357
            tcg_temp_free_i32(fp32_0);
6358
            gen_store_fpr64(ctx, fp64, fd);
6359
            tcg_temp_free_i64(fp64);
6360
        }
6361
        opn = "cvt.ps.s";
6362
        break;
6363
    case FOP(48, 16):
6364
    case FOP(49, 16):
6365
    case FOP(50, 16):
6366
    case FOP(51, 16):
6367
    case FOP(52, 16):
6368
    case FOP(53, 16):
6369
    case FOP(54, 16):
6370
    case FOP(55, 16):
6371
    case FOP(56, 16):
6372
    case FOP(57, 16):
6373
    case FOP(58, 16):
6374
    case FOP(59, 16):
6375
    case FOP(60, 16):
6376
    case FOP(61, 16):
6377
    case FOP(62, 16):
6378
    case FOP(63, 16):
6379
        {
6380
            TCGv_i32 fp0 = tcg_temp_new_i32();
6381
            TCGv_i32 fp1 = tcg_temp_new_i32();
6382

    
6383
            gen_load_fpr32(fp0, fs);
6384
            gen_load_fpr32(fp1, ft);
6385
            if (ctx->opcode & (1 << 6)) {
6386
                check_cop1x(ctx);
6387
                gen_cmpabs_s(func-48, fp0, fp1, cc);
6388
                opn = condnames_abs[func-48];
6389
            } else {
6390
                gen_cmp_s(func-48, fp0, fp1, cc);
6391
                opn = condnames[func-48];
6392
            }
6393
            tcg_temp_free_i32(fp0);
6394
            tcg_temp_free_i32(fp1);
6395
        }
6396
        break;
6397
    case FOP(0, 17):
6398
        check_cp1_registers(ctx, fs | ft | fd);
6399
        {
6400
            TCGv_i64 fp0 = tcg_temp_new_i64();
6401
            TCGv_i64 fp1 = tcg_temp_new_i64();
6402

    
6403
            gen_load_fpr64(ctx, fp0, fs);
6404
            gen_load_fpr64(ctx, fp1, ft);
6405
            gen_helper_float_add_d(fp0, fp0, fp1);
6406
            tcg_temp_free_i64(fp1);
6407
            gen_store_fpr64(ctx, fp0, fd);
6408
            tcg_temp_free_i64(fp0);
6409
        }
6410
        opn = "add.d";
6411
        optype = BINOP;
6412
        break;
6413
    case FOP(1, 17):
6414
        check_cp1_registers(ctx, fs | ft | fd);
6415
        {
6416
            TCGv_i64 fp0 = tcg_temp_new_i64();
6417
            TCGv_i64 fp1 = tcg_temp_new_i64();
6418

    
6419
            gen_load_fpr64(ctx, fp0, fs);
6420
            gen_load_fpr64(ctx, fp1, ft);
6421
            gen_helper_float_sub_d(fp0, fp0, fp1);
6422
            tcg_temp_free_i64(fp1);
6423
            gen_store_fpr64(ctx, fp0, fd);
6424
            tcg_temp_free_i64(fp0);
6425
        }
6426
        opn = "sub.d";
6427
        optype = BINOP;
6428
        break;
6429
    case FOP(2, 17):
6430
        check_cp1_registers(ctx, fs | ft | fd);
6431
        {
6432
            TCGv_i64 fp0 = tcg_temp_new_i64();
6433
            TCGv_i64 fp1 = tcg_temp_new_i64();
6434

    
6435
            gen_load_fpr64(ctx, fp0, fs);
6436
            gen_load_fpr64(ctx, fp1, ft);
6437
            gen_helper_float_mul_d(fp0, fp0, fp1);
6438
            tcg_temp_free_i64(fp1);
6439
            gen_store_fpr64(ctx, fp0, fd);
6440
            tcg_temp_free_i64(fp0);
6441
        }
6442
        opn = "mul.d";
6443
        optype = BINOP;
6444
        break;
6445
    case FOP(3, 17):
6446
        check_cp1_registers(ctx, fs | ft | fd);
6447
        {
6448
            TCGv_i64 fp0 = tcg_temp_new_i64();
6449
            TCGv_i64 fp1 = tcg_temp_new_i64();
6450

    
6451
            gen_load_fpr64(ctx, fp0, fs);
6452
            gen_load_fpr64(ctx, fp1, ft);
6453
            gen_helper_float_div_d(fp0, fp0, fp1);
6454
            tcg_temp_free_i64(fp1);
6455
            gen_store_fpr64(ctx, fp0, fd);
6456
            tcg_temp_free_i64(fp0);
6457
        }
6458
        opn = "div.d";
6459
        optype = BINOP;
6460
        break;
6461
    case FOP(4, 17):
6462
        check_cp1_registers(ctx, fs | fd);
6463
        {
6464
            TCGv_i64 fp0 = tcg_temp_new_i64();
6465

    
6466
            gen_load_fpr64(ctx, fp0, fs);
6467
            gen_helper_float_sqrt_d(fp0, fp0);
6468
            gen_store_fpr64(ctx, fp0, fd);
6469
            tcg_temp_free_i64(fp0);
6470
        }
6471
        opn = "sqrt.d";
6472
        break;
6473
    case FOP(5, 17):
6474
        check_cp1_registers(ctx, fs | fd);
6475
        {
6476
            TCGv_i64 fp0 = tcg_temp_new_i64();
6477

    
6478
            gen_load_fpr64(ctx, fp0, fs);
6479
            gen_helper_float_abs_d(fp0, fp0);
6480
            gen_store_fpr64(ctx, fp0, fd);
6481
            tcg_temp_free_i64(fp0);
6482
        }
6483
        opn = "abs.d";
6484
        break;
6485
    case FOP(6, 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_store_fpr64(ctx, fp0, fd);
6492
            tcg_temp_free_i64(fp0);
6493
        }
6494
        opn = "mov.d";
6495
        break;
6496
    case FOP(7, 17):
6497
        check_cp1_registers(ctx, fs | fd);
6498
        {
6499
            TCGv_i64 fp0 = tcg_temp_new_i64();
6500

    
6501
            gen_load_fpr64(ctx, fp0, fs);
6502
            gen_helper_float_chs_d(fp0, fp0);
6503
            gen_store_fpr64(ctx, fp0, fd);
6504
            tcg_temp_free_i64(fp0);
6505
        }
6506
        opn = "neg.d";
6507
        break;
6508
    case FOP(8, 17):
6509
        check_cp1_64bitmode(ctx);
6510
        {
6511
            TCGv_i64 fp0 = tcg_temp_new_i64();
6512

    
6513
            gen_load_fpr64(ctx, fp0, fs);
6514
            gen_helper_float_roundl_d(fp0, fp0);
6515
            gen_store_fpr64(ctx, fp0, fd);
6516
            tcg_temp_free_i64(fp0);
6517
        }
6518
        opn = "round.l.d";
6519
        break;
6520
    case FOP(9, 17):
6521
        check_cp1_64bitmode(ctx);
6522
        {
6523
            TCGv_i64 fp0 = tcg_temp_new_i64();
6524

    
6525
            gen_load_fpr64(ctx, fp0, fs);
6526
            gen_helper_float_truncl_d(fp0, fp0);
6527
            gen_store_fpr64(ctx, fp0, fd);
6528
            tcg_temp_free_i64(fp0);
6529
        }
6530
        opn = "trunc.l.d";
6531
        break;
6532
    case FOP(10, 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_ceill_d(fp0, fp0);
6539
            gen_store_fpr64(ctx, fp0, fd);
6540
            tcg_temp_free_i64(fp0);
6541
        }
6542
        opn = "ceil.l.d";
6543
        break;
6544
    case FOP(11, 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_floorl_d(fp0, fp0);
6551
            gen_store_fpr64(ctx, fp0, fd);
6552
            tcg_temp_free_i64(fp0);
6553
        }
6554
        opn = "floor.l.d";
6555
        break;
6556
    case FOP(12, 17):
6557
        check_cp1_registers(ctx, fs);
6558
        {
6559
            TCGv_i32 fp32 = tcg_temp_new_i32();
6560
            TCGv_i64 fp64 = tcg_temp_new_i64();
6561

    
6562
            gen_load_fpr64(ctx, fp64, fs);
6563
            gen_helper_float_roundw_d(fp32, fp64);
6564
            tcg_temp_free_i64(fp64);
6565
            gen_store_fpr32(fp32, fd);
6566
            tcg_temp_free_i32(fp32);
6567
        }
6568
        opn = "round.w.d";
6569
        break;
6570
    case FOP(13, 17):
6571
        check_cp1_registers(ctx, fs);
6572
        {
6573
            TCGv_i32 fp32 = tcg_temp_new_i32();
6574
            TCGv_i64 fp64 = tcg_temp_new_i64();
6575

    
6576
            gen_load_fpr64(ctx, fp64, fs);
6577
            gen_helper_float_truncw_d(fp32, fp64);
6578
            tcg_temp_free_i64(fp64);
6579
            gen_store_fpr32(fp32, fd);
6580
            tcg_temp_free_i32(fp32);
6581
        }
6582
        opn = "trunc.w.d";
6583
        break;
6584
    case FOP(14, 17):
6585
        check_cp1_registers(ctx, fs);
6586
        {
6587
            TCGv_i32 fp32 = tcg_temp_new_i32();
6588
            TCGv_i64 fp64 = tcg_temp_new_i64();
6589

    
6590
            gen_load_fpr64(ctx, fp64, fs);
6591
            gen_helper_float_ceilw_d(fp32, fp64);
6592
            tcg_temp_free_i64(fp64);
6593
            gen_store_fpr32(fp32, fd);
6594
            tcg_temp_free_i32(fp32);
6595
        }
6596
        opn = "ceil.w.d";
6597
        break;
6598
    case FOP(15, 17):
6599
        check_cp1_registers(ctx, fs);
6600
        {
6601
            TCGv_i32 fp32 = tcg_temp_new_i32();
6602
            TCGv_i64 fp64 = tcg_temp_new_i64();
6603

    
6604
            gen_load_fpr64(ctx, fp64, fs);
6605
            gen_helper_float_floorw_d(fp32, fp64);
6606
            tcg_temp_free_i64(fp64);
6607
            gen_store_fpr32(fp32, fd);
6608
            tcg_temp_free_i32(fp32);
6609
        }
6610
        opn = "floor.w.d";
6611
        break;
6612
    case FOP(17, 17):
6613
        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6614
        opn = "movcf.d";
6615
        break;
6616
    case FOP(18, 17):
6617
        {
6618
            int l1 = gen_new_label();
6619
            TCGv_i64 fp0;
6620

    
6621
            if (ft != 0) {
6622
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6623
            }
6624
            fp0 = tcg_temp_new_i64();
6625
            gen_load_fpr64(ctx, fp0, fs);
6626
            gen_store_fpr64(ctx, fp0, fd);
6627
            tcg_temp_free_i64(fp0);
6628
            gen_set_label(l1);
6629
        }
6630
        opn = "movz.d";
6631
        break;
6632
    case FOP(19, 17):
6633
        {
6634
            int l1 = gen_new_label();
6635
            TCGv_i64 fp0;
6636

    
6637
            if (ft != 0) {
6638
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6639
                fp0 = tcg_temp_new_i64();
6640
                gen_load_fpr64(ctx, fp0, fs);
6641
                gen_store_fpr64(ctx, fp0, fd);
6642
                tcg_temp_free_i64(fp0);
6643
                gen_set_label(l1);
6644
            }
6645
        }
6646
        opn = "movn.d";
6647
        break;
6648
    case FOP(21, 17):
6649
        check_cp1_64bitmode(ctx);
6650
        {
6651
            TCGv_i64 fp0 = tcg_temp_new_i64();
6652

    
6653
            gen_load_fpr64(ctx, fp0, fs);
6654
            gen_helper_float_recip_d(fp0, fp0);
6655
            gen_store_fpr64(ctx, fp0, fd);
6656
            tcg_temp_free_i64(fp0);
6657
        }
6658
        opn = "recip.d";
6659
        break;
6660
    case FOP(22, 17):
6661
        check_cp1_64bitmode(ctx);
6662
        {
6663
            TCGv_i64 fp0 = tcg_temp_new_i64();
6664

    
6665
            gen_load_fpr64(ctx, fp0, fs);
6666
            gen_helper_float_rsqrt_d(fp0, fp0);
6667
            gen_store_fpr64(ctx, fp0, fd);
6668
            tcg_temp_free_i64(fp0);
6669
        }
6670
        opn = "rsqrt.d";
6671
        break;
6672
    case FOP(28, 17):
6673
        check_cp1_64bitmode(ctx);
6674
        {
6675
            TCGv_i64 fp0 = tcg_temp_new_i64();
6676
            TCGv_i64 fp1 = tcg_temp_new_i64();
6677

    
6678
            gen_load_fpr64(ctx, fp0, fs);
6679
            gen_load_fpr64(ctx, fp1, ft);
6680
            gen_helper_float_recip2_d(fp0, fp0, fp1);
6681
            tcg_temp_free_i64(fp1);
6682
            gen_store_fpr64(ctx, fp0, fd);
6683
            tcg_temp_free_i64(fp0);
6684
        }
6685
        opn = "recip2.d";
6686
        break;
6687
    case FOP(29, 17):
6688
        check_cp1_64bitmode(ctx);
6689
        {
6690
            TCGv_i64 fp0 = tcg_temp_new_i64();
6691

    
6692
            gen_load_fpr64(ctx, fp0, fs);
6693
            gen_helper_float_recip1_d(fp0, fp0);
6694
            gen_store_fpr64(ctx, fp0, fd);
6695
            tcg_temp_free_i64(fp0);
6696
        }
6697
        opn = "recip1.d";
6698
        break;
6699
    case FOP(30, 17):
6700
        check_cp1_64bitmode(ctx);
6701
        {
6702
            TCGv_i64 fp0 = tcg_temp_new_i64();
6703

    
6704
            gen_load_fpr64(ctx, fp0, fs);
6705
            gen_helper_float_rsqrt1_d(fp0, fp0);
6706
            gen_store_fpr64(ctx, fp0, fd);
6707
            tcg_temp_free_i64(fp0);
6708
        }
6709
        opn = "rsqrt1.d";
6710
        break;
6711
    case FOP(31, 17):
6712
        check_cp1_64bitmode(ctx);
6713
        {
6714
            TCGv_i64 fp0 = tcg_temp_new_i64();
6715
            TCGv_i64 fp1 = tcg_temp_new_i64();
6716

    
6717
            gen_load_fpr64(ctx, fp0, fs);
6718
            gen_load_fpr64(ctx, fp1, ft);
6719
            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6720
            tcg_temp_free_i64(fp1);
6721
            gen_store_fpr64(ctx, fp0, fd);
6722
            tcg_temp_free_i64(fp0);
6723
        }
6724
        opn = "rsqrt2.d";
6725
        break;
6726
    case FOP(48, 17):
6727
    case FOP(49, 17):
6728
    case FOP(50, 17):
6729
    case FOP(51, 17):
6730
    case FOP(52, 17):
6731
    case FOP(53, 17):
6732
    case FOP(54, 17):
6733
    case FOP(55, 17):
6734
    case FOP(56, 17):
6735
    case FOP(57, 17):
6736
    case FOP(58, 17):
6737
    case FOP(59, 17):
6738
    case FOP(60, 17):
6739
    case FOP(61, 17):
6740
    case FOP(62, 17):
6741
    case FOP(63, 17):
6742
        {
6743
            TCGv_i64 fp0 = tcg_temp_new_i64();
6744
            TCGv_i64 fp1 = tcg_temp_new_i64();
6745

    
6746
            gen_load_fpr64(ctx, fp0, fs);
6747
            gen_load_fpr64(ctx, fp1, ft);
6748
            if (ctx->opcode & (1 << 6)) {
6749
                check_cop1x(ctx);
6750
                check_cp1_registers(ctx, fs | ft);
6751
                gen_cmpabs_d(func-48, fp0, fp1, cc);
6752
                opn = condnames_abs[func-48];
6753
            } else {
6754
                check_cp1_registers(ctx, fs | ft);
6755
                gen_cmp_d(func-48, fp0, fp1, cc);
6756
                opn = condnames[func-48];
6757
            }
6758
            tcg_temp_free_i64(fp0);
6759
            tcg_temp_free_i64(fp1);
6760
        }
6761
        break;
6762
    case FOP(32, 17):
6763
        check_cp1_registers(ctx, fs);
6764
        {
6765
            TCGv_i32 fp32 = tcg_temp_new_i32();
6766
            TCGv_i64 fp64 = tcg_temp_new_i64();
6767

    
6768
            gen_load_fpr64(ctx, fp64, fs);
6769
            gen_helper_float_cvts_d(fp32, fp64);
6770
            tcg_temp_free_i64(fp64);
6771
            gen_store_fpr32(fp32, fd);
6772
            tcg_temp_free_i32(fp32);
6773
        }
6774
        opn = "cvt.s.d";
6775
        break;
6776
    case FOP(36, 17):
6777
        check_cp1_registers(ctx, fs);
6778
        {
6779
            TCGv_i32 fp32 = tcg_temp_new_i32();
6780
            TCGv_i64 fp64 = tcg_temp_new_i64();
6781

    
6782
            gen_load_fpr64(ctx, fp64, fs);
6783
            gen_helper_float_cvtw_d(fp32, fp64);
6784
            tcg_temp_free_i64(fp64);
6785
            gen_store_fpr32(fp32, fd);
6786
            tcg_temp_free_i32(fp32);
6787
        }
6788
        opn = "cvt.w.d";
6789
        break;
6790
    case FOP(37, 17):
6791
        check_cp1_64bitmode(ctx);
6792
        {
6793
            TCGv_i64 fp0 = tcg_temp_new_i64();
6794

    
6795
            gen_load_fpr64(ctx, fp0, fs);
6796
            gen_helper_float_cvtl_d(fp0, fp0);
6797
            gen_store_fpr64(ctx, fp0, fd);
6798
            tcg_temp_free_i64(fp0);
6799
        }
6800
        opn = "cvt.l.d";
6801
        break;
6802
    case FOP(32, 20):
6803
        {
6804
            TCGv_i32 fp0 = tcg_temp_new_i32();
6805

    
6806
            gen_load_fpr32(fp0, fs);
6807
            gen_helper_float_cvts_w(fp0, fp0);
6808
            gen_store_fpr32(fp0, fd);
6809
            tcg_temp_free_i32(fp0);
6810
        }
6811
        opn = "cvt.s.w";
6812
        break;
6813
    case FOP(33, 20):
6814
        check_cp1_registers(ctx, fd);
6815
        {
6816
            TCGv_i32 fp32 = tcg_temp_new_i32();
6817
            TCGv_i64 fp64 = tcg_temp_new_i64();
6818

    
6819
            gen_load_fpr32(fp32, fs);
6820
            gen_helper_float_cvtd_w(fp64, fp32);
6821
            tcg_temp_free_i32(fp32);
6822
            gen_store_fpr64(ctx, fp64, fd);
6823
            tcg_temp_free_i64(fp64);
6824
        }
6825
        opn = "cvt.d.w";
6826
        break;
6827
    case FOP(32, 21):
6828
        check_cp1_64bitmode(ctx);
6829
        {
6830
            TCGv_i32 fp32 = tcg_temp_new_i32();
6831
            TCGv_i64 fp64 = tcg_temp_new_i64();
6832

    
6833
            gen_load_fpr64(ctx, fp64, fs);
6834
            gen_helper_float_cvts_l(fp32, fp64);
6835
            tcg_temp_free_i64(fp64);
6836
            gen_store_fpr32(fp32, fd);
6837
            tcg_temp_free_i32(fp32);
6838
        }
6839
        opn = "cvt.s.l";
6840
        break;
6841
    case FOP(33, 21):
6842
        check_cp1_64bitmode(ctx);
6843
        {
6844
            TCGv_i64 fp0 = tcg_temp_new_i64();
6845

    
6846
            gen_load_fpr64(ctx, fp0, fs);
6847
            gen_helper_float_cvtd_l(fp0, fp0);
6848
            gen_store_fpr64(ctx, fp0, fd);
6849
            tcg_temp_free_i64(fp0);
6850
        }
6851
        opn = "cvt.d.l";
6852
        break;
6853
    case FOP(38, 20):
6854
        check_cp1_64bitmode(ctx);
6855
        {
6856
            TCGv_i64 fp0 = tcg_temp_new_i64();
6857

    
6858
            gen_load_fpr64(ctx, fp0, fs);
6859
            gen_helper_float_cvtps_pw(fp0, fp0);
6860
            gen_store_fpr64(ctx, fp0, fd);
6861
            tcg_temp_free_i64(fp0);
6862
        }
6863
        opn = "cvt.ps.pw";
6864
        break;
6865
    case FOP(0, 22):
6866
        check_cp1_64bitmode(ctx);
6867
        {
6868
            TCGv_i64 fp0 = tcg_temp_new_i64();
6869
            TCGv_i64 fp1 = tcg_temp_new_i64();
6870

    
6871
            gen_load_fpr64(ctx, fp0, fs);
6872
            gen_load_fpr64(ctx, fp1, ft);
6873
            gen_helper_float_add_ps(fp0, fp0, fp1);
6874
            tcg_temp_free_i64(fp1);
6875
            gen_store_fpr64(ctx, fp0, fd);
6876
            tcg_temp_free_i64(fp0);
6877
        }
6878
        opn = "add.ps";
6879
        break;
6880
    case FOP(1, 22):
6881
        check_cp1_64bitmode(ctx);
6882
        {
6883
            TCGv_i64 fp0 = tcg_temp_new_i64();
6884
            TCGv_i64 fp1 = tcg_temp_new_i64();
6885

    
6886
            gen_load_fpr64(ctx, fp0, fs);
6887
            gen_load_fpr64(ctx, fp1, ft);
6888
            gen_helper_float_sub_ps(fp0, fp0, fp1);
6889
            tcg_temp_free_i64(fp1);
6890
            gen_store_fpr64(ctx, fp0, fd);
6891
            tcg_temp_free_i64(fp0);
6892
        }
6893
        opn = "sub.ps";
6894
        break;
6895
    case FOP(2, 22):
6896
        check_cp1_64bitmode(ctx);
6897
        {
6898
            TCGv_i64 fp0 = tcg_temp_new_i64();
6899
            TCGv_i64 fp1 = tcg_temp_new_i64();
6900

    
6901
            gen_load_fpr64(ctx, fp0, fs);
6902
            gen_load_fpr64(ctx, fp1, ft);
6903
            gen_helper_float_mul_ps(fp0, fp0, fp1);
6904
            tcg_temp_free_i64(fp1);
6905
            gen_store_fpr64(ctx, fp0, fd);
6906
            tcg_temp_free_i64(fp0);
6907
        }
6908
        opn = "mul.ps";
6909
        break;
6910
    case FOP(5, 22):
6911
        check_cp1_64bitmode(ctx);
6912
        {
6913
            TCGv_i64 fp0 = tcg_temp_new_i64();
6914

    
6915
            gen_load_fpr64(ctx, fp0, fs);
6916
            gen_helper_float_abs_ps(fp0, fp0);
6917
            gen_store_fpr64(ctx, fp0, fd);
6918
            tcg_temp_free_i64(fp0);
6919
        }
6920
        opn = "abs.ps";
6921
        break;
6922
    case FOP(6, 22):
6923
        check_cp1_64bitmode(ctx);
6924
        {
6925
            TCGv_i64 fp0 = tcg_temp_new_i64();
6926

    
6927
            gen_load_fpr64(ctx, fp0, fs);
6928
            gen_store_fpr64(ctx, fp0, fd);
6929
            tcg_temp_free_i64(fp0);
6930
        }
6931
        opn = "mov.ps";
6932
        break;
6933
    case FOP(7, 22):
6934
        check_cp1_64bitmode(ctx);
6935
        {
6936
            TCGv_i64 fp0 = tcg_temp_new_i64();
6937

    
6938
            gen_load_fpr64(ctx, fp0, fs);
6939
            gen_helper_float_chs_ps(fp0, fp0);
6940
            gen_store_fpr64(ctx, fp0, fd);
6941
            tcg_temp_free_i64(fp0);
6942
        }
6943
        opn = "neg.ps";
6944
        break;
6945
    case FOP(17, 22):
6946
        check_cp1_64bitmode(ctx);
6947
        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6948
        opn = "movcf.ps";
6949
        break;
6950
    case FOP(18, 22):
6951
        check_cp1_64bitmode(ctx);
6952
        {
6953
            int l1 = gen_new_label();
6954
            TCGv_i64 fp0;
6955

    
6956
            if (ft != 0)
6957
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6958
            fp0 = tcg_temp_new_i64();
6959
            gen_load_fpr64(ctx, fp0, fs);
6960
            gen_store_fpr64(ctx, fp0, fd);
6961
            tcg_temp_free_i64(fp0);
6962
            gen_set_label(l1);
6963
        }
6964
        opn = "movz.ps";
6965
        break;
6966
    case FOP(19, 22):
6967
        check_cp1_64bitmode(ctx);
6968
        {
6969
            int l1 = gen_new_label();
6970
            TCGv_i64 fp0;
6971

    
6972
            if (ft != 0) {
6973
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6974
                fp0 = tcg_temp_new_i64();
6975
                gen_load_fpr64(ctx, fp0, fs);
6976
                gen_store_fpr64(ctx, fp0, fd);
6977
                tcg_temp_free_i64(fp0);
6978
                gen_set_label(l1);
6979
            }
6980
        }
6981
        opn = "movn.ps";
6982
        break;
6983
    case FOP(24, 22):
6984
        check_cp1_64bitmode(ctx);
6985
        {
6986
            TCGv_i64 fp0 = tcg_temp_new_i64();
6987
            TCGv_i64 fp1 = tcg_temp_new_i64();
6988

    
6989
            gen_load_fpr64(ctx, fp0, ft);
6990
            gen_load_fpr64(ctx, fp1, fs);
6991
            gen_helper_float_addr_ps(fp0, fp0, fp1);
6992
            tcg_temp_free_i64(fp1);
6993
            gen_store_fpr64(ctx, fp0, fd);
6994
            tcg_temp_free_i64(fp0);
6995
        }
6996
        opn = "addr.ps";
6997
        break;
6998
    case FOP(26, 22):
6999
        check_cp1_64bitmode(ctx);
7000
        {
7001
            TCGv_i64 fp0 = tcg_temp_new_i64();
7002
            TCGv_i64 fp1 = tcg_temp_new_i64();
7003

    
7004
            gen_load_fpr64(ctx, fp0, ft);
7005
            gen_load_fpr64(ctx, fp1, fs);
7006
            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7007
            tcg_temp_free_i64(fp1);
7008
            gen_store_fpr64(ctx, fp0, fd);
7009
            tcg_temp_free_i64(fp0);
7010
        }
7011
        opn = "mulr.ps";
7012
        break;
7013
    case FOP(28, 22):
7014
        check_cp1_64bitmode(ctx);
7015
        {
7016
            TCGv_i64 fp0 = tcg_temp_new_i64();
7017
            TCGv_i64 fp1 = tcg_temp_new_i64();
7018

    
7019
            gen_load_fpr64(ctx, fp0, fs);
7020
            gen_load_fpr64(ctx, fp1, fd);
7021
            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7022
            tcg_temp_free_i64(fp1);
7023
            gen_store_fpr64(ctx, fp0, fd);
7024
            tcg_temp_free_i64(fp0);
7025
        }
7026
        opn = "recip2.ps";
7027
        break;
7028
    case FOP(29, 22):
7029
        check_cp1_64bitmode(ctx);
7030
        {
7031
            TCGv_i64 fp0 = tcg_temp_new_i64();
7032

    
7033
            gen_load_fpr64(ctx, fp0, fs);
7034
            gen_helper_float_recip1_ps(fp0, fp0);
7035
            gen_store_fpr64(ctx, fp0, fd);
7036
            tcg_temp_free_i64(fp0);
7037
        }
7038
        opn = "recip1.ps";
7039
        break;
7040
    case FOP(30, 22):
7041
        check_cp1_64bitmode(ctx);
7042
        {
7043
            TCGv_i64 fp0 = tcg_temp_new_i64();
7044

    
7045
            gen_load_fpr64(ctx, fp0, fs);
7046
            gen_helper_float_rsqrt1_ps(fp0, fp0);
7047
            gen_store_fpr64(ctx, fp0, fd);
7048
            tcg_temp_free_i64(fp0);
7049
        }
7050
        opn = "rsqrt1.ps";
7051
        break;
7052
    case FOP(31, 22):
7053
        check_cp1_64bitmode(ctx);
7054
        {
7055
            TCGv_i64 fp0 = tcg_temp_new_i64();
7056
            TCGv_i64 fp1 = tcg_temp_new_i64();
7057

    
7058
            gen_load_fpr64(ctx, fp0, fs);
7059
            gen_load_fpr64(ctx, fp1, ft);
7060
            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7061
            tcg_temp_free_i64(fp1);
7062
            gen_store_fpr64(ctx, fp0, fd);
7063
            tcg_temp_free_i64(fp0);
7064
        }
7065
        opn = "rsqrt2.ps";
7066
        break;
7067
    case FOP(32, 22):
7068
        check_cp1_64bitmode(ctx);
7069
        {
7070
            TCGv_i32 fp0 = tcg_temp_new_i32();
7071

    
7072
            gen_load_fpr32h(fp0, fs);
7073
            gen_helper_float_cvts_pu(fp0, fp0);
7074
            gen_store_fpr32(fp0, fd);
7075
            tcg_temp_free_i32(fp0);
7076
        }
7077
        opn = "cvt.s.pu";
7078
        break;
7079
    case FOP(36, 22):
7080
        check_cp1_64bitmode(ctx);
7081
        {
7082
            TCGv_i64 fp0 = tcg_temp_new_i64();
7083

    
7084
            gen_load_fpr64(ctx, fp0, fs);
7085
            gen_helper_float_cvtpw_ps(fp0, fp0);
7086
            gen_store_fpr64(ctx, fp0, fd);
7087
            tcg_temp_free_i64(fp0);
7088
        }
7089
        opn = "cvt.pw.ps";
7090
        break;
7091
    case FOP(40, 22):
7092
        check_cp1_64bitmode(ctx);
7093
        {
7094
            TCGv_i32 fp0 = tcg_temp_new_i32();
7095

    
7096
            gen_load_fpr32(fp0, fs);
7097
            gen_helper_float_cvts_pl(fp0, fp0);
7098
            gen_store_fpr32(fp0, fd);
7099
            tcg_temp_free_i32(fp0);
7100
        }
7101
        opn = "cvt.s.pl";
7102
        break;
7103
    case FOP(44, 22):
7104
        check_cp1_64bitmode(ctx);
7105
        {
7106
            TCGv_i32 fp0 = tcg_temp_new_i32();
7107
            TCGv_i32 fp1 = tcg_temp_new_i32();
7108

    
7109
            gen_load_fpr32(fp0, fs);
7110
            gen_load_fpr32(fp1, ft);
7111
            gen_store_fpr32h(fp0, fd);
7112
            gen_store_fpr32(fp1, fd);
7113
            tcg_temp_free_i32(fp0);
7114
            tcg_temp_free_i32(fp1);
7115
        }
7116
        opn = "pll.ps";
7117
        break;
7118
    case FOP(45, 22):
7119
        check_cp1_64bitmode(ctx);
7120
        {
7121
            TCGv_i32 fp0 = tcg_temp_new_i32();
7122
            TCGv_i32 fp1 = tcg_temp_new_i32();
7123

    
7124
            gen_load_fpr32(fp0, fs);
7125
            gen_load_fpr32h(fp1, ft);
7126
            gen_store_fpr32(fp1, fd);
7127
            gen_store_fpr32h(fp0, fd);
7128
            tcg_temp_free_i32(fp0);
7129
            tcg_temp_free_i32(fp1);
7130
        }
7131
        opn = "plu.ps";
7132
        break;
7133
    case FOP(46, 22):
7134
        check_cp1_64bitmode(ctx);
7135
        {
7136
            TCGv_i32 fp0 = tcg_temp_new_i32();
7137
            TCGv_i32 fp1 = tcg_temp_new_i32();
7138

    
7139
            gen_load_fpr32h(fp0, fs);
7140
            gen_load_fpr32(fp1, ft);
7141
            gen_store_fpr32(fp1, fd);
7142
            gen_store_fpr32h(fp0, fd);
7143
            tcg_temp_free_i32(fp0);
7144
            tcg_temp_free_i32(fp1);
7145
        }
7146
        opn = "pul.ps";
7147
        break;
7148
    case FOP(47, 22):
7149
        check_cp1_64bitmode(ctx);
7150
        {
7151
            TCGv_i32 fp0 = tcg_temp_new_i32();
7152
            TCGv_i32 fp1 = tcg_temp_new_i32();
7153

    
7154
            gen_load_fpr32h(fp0, fs);
7155
            gen_load_fpr32h(fp1, ft);
7156
            gen_store_fpr32(fp1, fd);
7157
            gen_store_fpr32h(fp0, fd);
7158
            tcg_temp_free_i32(fp0);
7159
            tcg_temp_free_i32(fp1);
7160
        }
7161
        opn = "puu.ps";
7162
        break;
7163
    case FOP(48, 22):
7164
    case FOP(49, 22):
7165
    case FOP(50, 22):
7166
    case FOP(51, 22):
7167
    case FOP(52, 22):
7168
    case FOP(53, 22):
7169
    case FOP(54, 22):
7170
    case FOP(55, 22):
7171
    case FOP(56, 22):
7172
    case FOP(57, 22):
7173
    case FOP(58, 22):
7174
    case FOP(59, 22):
7175
    case FOP(60, 22):
7176
    case FOP(61, 22):
7177
    case FOP(62, 22):
7178
    case FOP(63, 22):
7179
        check_cp1_64bitmode(ctx);
7180
        {
7181
            TCGv_i64 fp0 = tcg_temp_new_i64();
7182
            TCGv_i64 fp1 = tcg_temp_new_i64();
7183

    
7184
            gen_load_fpr64(ctx, fp0, fs);
7185
            gen_load_fpr64(ctx, fp1, ft);
7186
            if (ctx->opcode & (1 << 6)) {
7187
                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7188
                opn = condnames_abs[func-48];
7189
            } else {
7190
                gen_cmp_ps(func-48, fp0, fp1, cc);
7191
                opn = condnames[func-48];
7192
            }
7193
            tcg_temp_free_i64(fp0);
7194
            tcg_temp_free_i64(fp1);
7195
        }
7196
        break;
7197
    default:
7198
        MIPS_INVAL(opn);
7199
        generate_exception (ctx, EXCP_RI);
7200
        return;
7201
    }
7202
    switch (optype) {
7203
    case BINOP:
7204
        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7205
        break;
7206
    case CMPOP:
7207
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7208
        break;
7209
    default:
7210
        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7211
        break;
7212
    }
7213
}
7214

    
7215
/* Coprocessor 3 (FPU) */
7216
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7217
                           int fd, int fs, int base, int index)
7218
{
7219
    const char *opn = "extended float load/store";
7220
    int store = 0;
7221
    TCGv t0 = tcg_temp_new();
7222
    TCGv t1 = tcg_temp_new();
7223

    
7224
    if (base == 0) {
7225
        gen_load_gpr(t0, index);
7226
    } else if (index == 0) {
7227
        gen_load_gpr(t0, base);
7228
    } else {
7229
        gen_load_gpr(t0, index);
7230
        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7231
    }
7232
    /* Don't do NOP if destination is zero: we must perform the actual
7233
       memory access. */
7234
    save_cpu_state(ctx, 0);
7235
    switch (opc) {
7236
    case OPC_LWXC1:
7237
        check_cop1x(ctx);
7238
        {
7239
            TCGv_i32 fp0 = tcg_temp_new_i32();
7240

    
7241
            tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7242
            tcg_gen_trunc_tl_i32(fp0, t1);
7243
            gen_store_fpr32(fp0, fd);
7244
            tcg_temp_free_i32(fp0);
7245
        }
7246
        opn = "lwxc1";
7247
        break;
7248
    case OPC_LDXC1:
7249
        check_cop1x(ctx);
7250
        check_cp1_registers(ctx, fd);
7251
        {
7252
            TCGv_i64 fp0 = tcg_temp_new_i64();
7253

    
7254
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7255
            gen_store_fpr64(ctx, fp0, fd);
7256
            tcg_temp_free_i64(fp0);
7257
        }
7258
        opn = "ldxc1";
7259
        break;
7260
    case OPC_LUXC1:
7261
        check_cp1_64bitmode(ctx);
7262
        tcg_gen_andi_tl(t0, t0, ~0x7);
7263
        {
7264
            TCGv_i64 fp0 = tcg_temp_new_i64();
7265

    
7266
            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7267
            gen_store_fpr64(ctx, fp0, fd);
7268
            tcg_temp_free_i64(fp0);
7269
        }
7270
        opn = "luxc1";
7271
        break;
7272
    case OPC_SWXC1:
7273
        check_cop1x(ctx);
7274
        {
7275
            TCGv_i32 fp0 = tcg_temp_new_i32();
7276

    
7277
            gen_load_fpr32(fp0, fs);
7278
            tcg_gen_extu_i32_tl(t1, fp0);
7279
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7280
            tcg_temp_free_i32(fp0);
7281
        }
7282
        opn = "swxc1";
7283
        store = 1;
7284
        break;
7285
    case OPC_SDXC1:
7286
        check_cop1x(ctx);
7287
        check_cp1_registers(ctx, fs);
7288
        {
7289
            TCGv_i64 fp0 = tcg_temp_new_i64();
7290

    
7291
            gen_load_fpr64(ctx, fp0, fs);
7292
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7293
            tcg_temp_free_i64(fp0);
7294
        }
7295
        opn = "sdxc1";
7296
        store = 1;
7297
        break;
7298
    case OPC_SUXC1:
7299
        check_cp1_64bitmode(ctx);
7300
        tcg_gen_andi_tl(t0, t0, ~0x7);
7301
        {
7302
            TCGv_i64 fp0 = tcg_temp_new_i64();
7303

    
7304
            gen_load_fpr64(ctx, fp0, fs);
7305
            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7306
            tcg_temp_free_i64(fp0);
7307
        }
7308
        opn = "suxc1";
7309
        store = 1;
7310
        break;
7311
    }
7312
    tcg_temp_free(t0);
7313
    tcg_temp_free(t1);
7314
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7315
               regnames[index], regnames[base]);
7316
}
7317

    
7318
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7319
                            int fd, int fr, int fs, int ft)
7320
{
7321
    const char *opn = "flt3_arith";
7322

    
7323
    switch (opc) {
7324
    case OPC_ALNV_PS:
7325
        check_cp1_64bitmode(ctx);
7326
        {
7327
            TCGv t0 = tcg_temp_local_new();
7328
            TCGv_i32 fp = tcg_temp_new_i32();
7329
            TCGv_i32 fph = tcg_temp_new_i32();
7330
            int l1 = gen_new_label();
7331
            int l2 = gen_new_label();
7332

    
7333
            gen_load_gpr(t0, fr);
7334
            tcg_gen_andi_tl(t0, t0, 0x7);
7335

    
7336
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7337
            gen_load_fpr32(fp, fs);
7338
            gen_load_fpr32h(fph, fs);
7339
            gen_store_fpr32(fp, fd);
7340
            gen_store_fpr32h(fph, fd);
7341
            tcg_gen_br(l2);
7342
            gen_set_label(l1);
7343
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7344
            tcg_temp_free(t0);
7345
#ifdef TARGET_WORDS_BIGENDIAN
7346
            gen_load_fpr32(fp, fs);
7347
            gen_load_fpr32h(fph, ft);
7348
            gen_store_fpr32h(fp, fd);
7349
            gen_store_fpr32(fph, fd);
7350
#else
7351
            gen_load_fpr32h(fph, fs);
7352
            gen_load_fpr32(fp, ft);
7353
            gen_store_fpr32(fph, fd);
7354
            gen_store_fpr32h(fp, fd);
7355
#endif
7356
            gen_set_label(l2);
7357
            tcg_temp_free_i32(fp);
7358
            tcg_temp_free_i32(fph);
7359
        }
7360
        opn = "alnv.ps";
7361
        break;
7362
    case OPC_MADD_S:
7363
        check_cop1x(ctx);
7364
        {
7365
            TCGv_i32 fp0 = tcg_temp_new_i32();
7366
            TCGv_i32 fp1 = tcg_temp_new_i32();
7367
            TCGv_i32 fp2 = tcg_temp_new_i32();
7368

    
7369
            gen_load_fpr32(fp0, fs);
7370
            gen_load_fpr32(fp1, ft);
7371
            gen_load_fpr32(fp2, fr);
7372
            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7373
            tcg_temp_free_i32(fp0);
7374
            tcg_temp_free_i32(fp1);
7375
            gen_store_fpr32(fp2, fd);
7376
            tcg_temp_free_i32(fp2);
7377
        }
7378
        opn = "madd.s";
7379
        break;
7380
    case OPC_MADD_D:
7381
        check_cop1x(ctx);
7382
        check_cp1_registers(ctx, fd | fs | ft | fr);
7383
        {
7384
            TCGv_i64 fp0 = tcg_temp_new_i64();
7385
            TCGv_i64 fp1 = tcg_temp_new_i64();
7386
            TCGv_i64 fp2 = tcg_temp_new_i64();
7387

    
7388
            gen_load_fpr64(ctx, fp0, fs);
7389
            gen_load_fpr64(ctx, fp1, ft);
7390
            gen_load_fpr64(ctx, fp2, fr);
7391
            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7392
            tcg_temp_free_i64(fp0);
7393
            tcg_temp_free_i64(fp1);
7394
            gen_store_fpr64(ctx, fp2, fd);
7395
            tcg_temp_free_i64(fp2);
7396
        }
7397
        opn = "madd.d";
7398
        break;
7399
    case OPC_MADD_PS:
7400
        check_cp1_64bitmode(ctx);
7401
        {
7402
            TCGv_i64 fp0 = tcg_temp_new_i64();
7403
            TCGv_i64 fp1 = tcg_temp_new_i64();
7404
            TCGv_i64 fp2 = tcg_temp_new_i64();
7405

    
7406
            gen_load_fpr64(ctx, fp0, fs);
7407
            gen_load_fpr64(ctx, fp1, ft);
7408
            gen_load_fpr64(ctx, fp2, fr);
7409
            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7410
            tcg_temp_free_i64(fp0);
7411
            tcg_temp_free_i64(fp1);
7412
            gen_store_fpr64(ctx, fp2, fd);
7413
            tcg_temp_free_i64(fp2);
7414
        }
7415
        opn = "madd.ps";
7416
        break;
7417
    case OPC_MSUB_S:
7418
        check_cop1x(ctx);
7419
        {
7420
            TCGv_i32 fp0 = tcg_temp_new_i32();
7421
            TCGv_i32 fp1 = tcg_temp_new_i32();
7422
            TCGv_i32 fp2 = tcg_temp_new_i32();
7423

    
7424
            gen_load_fpr32(fp0, fs);
7425
            gen_load_fpr32(fp1, ft);
7426
            gen_load_fpr32(fp2, fr);
7427
            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7428
            tcg_temp_free_i32(fp0);
7429
            tcg_temp_free_i32(fp1);
7430
            gen_store_fpr32(fp2, fd);
7431
            tcg_temp_free_i32(fp2);
7432
        }
7433
        opn = "msub.s";
7434
        break;
7435
    case OPC_MSUB_D:
7436
        check_cop1x(ctx);
7437
        check_cp1_registers(ctx, fd | fs | ft | fr);
7438
        {
7439
            TCGv_i64 fp0 = tcg_temp_new_i64();
7440
            TCGv_i64 fp1 = tcg_temp_new_i64();
7441
            TCGv_i64 fp2 = tcg_temp_new_i64();
7442

    
7443
            gen_load_fpr64(ctx, fp0, fs);
7444
            gen_load_fpr64(ctx, fp1, ft);
7445
            gen_load_fpr64(ctx, fp2, fr);
7446
            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7447
            tcg_temp_free_i64(fp0);
7448
            tcg_temp_free_i64(fp1);
7449
            gen_store_fpr64(ctx, fp2, fd);
7450
            tcg_temp_free_i64(fp2);
7451
        }
7452
        opn = "msub.d";
7453
        break;
7454
    case OPC_MSUB_PS:
7455
        check_cp1_64bitmode(ctx);
7456
        {
7457
            TCGv_i64 fp0 = tcg_temp_new_i64();
7458
            TCGv_i64 fp1 = tcg_temp_new_i64();
7459
            TCGv_i64 fp2 = tcg_temp_new_i64();
7460

    
7461
            gen_load_fpr64(ctx, fp0, fs);
7462
            gen_load_fpr64(ctx, fp1, ft);
7463
            gen_load_fpr64(ctx, fp2, fr);
7464
            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7465
            tcg_temp_free_i64(fp0);
7466
            tcg_temp_free_i64(fp1);
7467
            gen_store_fpr64(ctx, fp2, fd);
7468
            tcg_temp_free_i64(fp2);
7469
        }
7470
        opn = "msub.ps";
7471
        break;
7472
    case OPC_NMADD_S:
7473
        check_cop1x(ctx);
7474
        {
7475
            TCGv_i32 fp0 = tcg_temp_new_i32();
7476
            TCGv_i32 fp1 = tcg_temp_new_i32();
7477
            TCGv_i32 fp2 = tcg_temp_new_i32();
7478

    
7479
            gen_load_fpr32(fp0, fs);
7480
            gen_load_fpr32(fp1, ft);
7481
            gen_load_fpr32(fp2, fr);
7482
            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7483
            tcg_temp_free_i32(fp0);
7484
            tcg_temp_free_i32(fp1);
7485
            gen_store_fpr32(fp2, fd);
7486
            tcg_temp_free_i32(fp2);
7487
        }
7488
        opn = "nmadd.s";
7489
        break;
7490
    case OPC_NMADD_D:
7491
        check_cop1x(ctx);
7492
        check_cp1_registers(ctx, fd | fs | ft | fr);
7493
        {
7494
            TCGv_i64 fp0 = tcg_temp_new_i64();
7495
            TCGv_i64 fp1 = tcg_temp_new_i64();
7496
            TCGv_i64 fp2 = tcg_temp_new_i64();
7497

    
7498
            gen_load_fpr64(ctx, fp0, fs);
7499
            gen_load_fpr64(ctx, fp1, ft);
7500
            gen_load_fpr64(ctx, fp2, fr);
7501
            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7502
            tcg_temp_free_i64(fp0);
7503
            tcg_temp_free_i64(fp1);
7504
            gen_store_fpr64(ctx, fp2, fd);
7505
            tcg_temp_free_i64(fp2);
7506
        }
7507
        opn = "nmadd.d";
7508
        break;
7509
    case OPC_NMADD_PS:
7510
        check_cp1_64bitmode(ctx);
7511
        {
7512
            TCGv_i64 fp0 = tcg_temp_new_i64();
7513
            TCGv_i64 fp1 = tcg_temp_new_i64();
7514
            TCGv_i64 fp2 = tcg_temp_new_i64();
7515

    
7516
            gen_load_fpr64(ctx, fp0, fs);
7517
            gen_load_fpr64(ctx, fp1, ft);
7518
            gen_load_fpr64(ctx, fp2, fr);
7519
            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7520
            tcg_temp_free_i64(fp0);
7521
            tcg_temp_free_i64(fp1);
7522
            gen_store_fpr64(ctx, fp2, fd);
7523
            tcg_temp_free_i64(fp2);
7524
        }
7525
        opn = "nmadd.ps";
7526
        break;
7527
    case OPC_NMSUB_S:
7528
        check_cop1x(ctx);
7529
        {
7530
            TCGv_i32 fp0 = tcg_temp_new_i32();
7531
            TCGv_i32 fp1 = tcg_temp_new_i32();
7532
            TCGv_i32 fp2 = tcg_temp_new_i32();
7533

    
7534
            gen_load_fpr32(fp0, fs);
7535
            gen_load_fpr32(fp1, ft);
7536
            gen_load_fpr32(fp2, fr);
7537
            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7538
            tcg_temp_free_i32(fp0);
7539
            tcg_temp_free_i32(fp1);
7540
            gen_store_fpr32(fp2, fd);
7541
            tcg_temp_free_i32(fp2);
7542
        }
7543
        opn = "nmsub.s";
7544
        break;
7545
    case OPC_NMSUB_D:
7546
        check_cop1x(ctx);
7547
        check_cp1_registers(ctx, fd | fs | ft | fr);
7548
        {
7549
            TCGv_i64 fp0 = tcg_temp_new_i64();
7550
            TCGv_i64 fp1 = tcg_temp_new_i64();
7551
            TCGv_i64 fp2 = tcg_temp_new_i64();
7552

    
7553
            gen_load_fpr64(ctx, fp0, fs);
7554
            gen_load_fpr64(ctx, fp1, ft);
7555
            gen_load_fpr64(ctx, fp2, fr);
7556
            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7557
            tcg_temp_free_i64(fp0);
7558
            tcg_temp_free_i64(fp1);
7559
            gen_store_fpr64(ctx, fp2, fd);
7560
            tcg_temp_free_i64(fp2);
7561
        }
7562
        opn = "nmsub.d";
7563
        break;
7564
    case OPC_NMSUB_PS:
7565
        check_cp1_64bitmode(ctx);
7566
        {
7567
            TCGv_i64 fp0 = tcg_temp_new_i64();
7568
            TCGv_i64 fp1 = tcg_temp_new_i64();
7569
            TCGv_i64 fp2 = tcg_temp_new_i64();
7570

    
7571
            gen_load_fpr64(ctx, fp0, fs);
7572
            gen_load_fpr64(ctx, fp1, ft);
7573
            gen_load_fpr64(ctx, fp2, fr);
7574
            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7575
            tcg_temp_free_i64(fp0);
7576
            tcg_temp_free_i64(fp1);
7577
            gen_store_fpr64(ctx, fp2, fd);
7578
            tcg_temp_free_i64(fp2);
7579
        }
7580
        opn = "nmsub.ps";
7581
        break;
7582
    default:
7583
        MIPS_INVAL(opn);
7584
        generate_exception (ctx, EXCP_RI);
7585
        return;
7586
    }
7587
    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7588
               fregnames[fs], fregnames[ft]);
7589
}
7590

    
7591
/* ISA extensions (ASEs) */
7592
/* MIPS16 extension to MIPS32 */
7593
/* SmartMIPS extension to MIPS32 */
7594

    
7595
#if defined(TARGET_MIPS64)
7596

    
7597
/* MDMX extension to MIPS64 */
7598

    
7599
#endif
7600

    
7601
static void decode_opc (CPUState *env, DisasContext *ctx)
7602
{
7603
    int32_t offset;
7604
    int rs, rt, rd, sa;
7605
    uint32_t op, op1, op2;
7606
    int16_t imm;
7607

    
7608
    /* make sure instructions are on a word boundary */
7609
    if (ctx->pc & 0x3) {
7610
        env->CP0_BadVAddr = ctx->pc;
7611
        generate_exception(ctx, EXCP_AdEL);
7612
        return;
7613
    }
7614

    
7615
    /* Handle blikely not taken case */
7616
    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7617
        int l1 = gen_new_label();
7618

    
7619
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7620
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7621
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7622
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7623
        gen_set_label(l1);
7624
    }
7625
    op = MASK_OP_MAJOR(ctx->opcode);
7626
    rs = (ctx->opcode >> 21) & 0x1f;
7627
    rt = (ctx->opcode >> 16) & 0x1f;
7628
    rd = (ctx->opcode >> 11) & 0x1f;
7629
    sa = (ctx->opcode >> 6) & 0x1f;
7630
    imm = (int16_t)ctx->opcode;
7631
    switch (op) {
7632
    case OPC_SPECIAL:
7633
        op1 = MASK_SPECIAL(ctx->opcode);
7634
        switch (op1) {
7635
        case OPC_SLL:          /* Shift with immediate */
7636
        case OPC_SRA:
7637
        case OPC_SRL:
7638
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7639
            break;
7640
        case OPC_MOVN:         /* Conditional move */
7641
        case OPC_MOVZ:
7642
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7643
            gen_cond_move(env, op1, rd, rs, rt);
7644
            break;
7645
        case OPC_ADD ... OPC_SUBU:
7646
            gen_arith(env, ctx, op1, rd, rs, rt);
7647
            break;
7648
        case OPC_SLLV:         /* Shifts */
7649
        case OPC_SRLV:
7650
        case OPC_SRAV:
7651
            gen_shift(env, ctx, op1, rd, rs, rt);
7652
            break;
7653
        case OPC_SLT:          /* Set on less than */
7654
        case OPC_SLTU:
7655
            gen_slt(env, op1, rd, rs, rt);
7656
            break;
7657
        case OPC_AND:          /* Logic*/
7658
        case OPC_OR:
7659
        case OPC_NOR:
7660
        case OPC_XOR:
7661
            gen_logic(env, op1, rd, rs, rt);
7662
            break;
7663
        case OPC_MULT ... OPC_DIVU:
7664
            if (sa) {
7665
                check_insn(env, ctx, INSN_VR54XX);
7666
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7667
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7668
            } else
7669
                gen_muldiv(ctx, op1, rs, rt);
7670
            break;
7671
        case OPC_JR ... OPC_JALR:
7672
            gen_compute_branch(ctx, op1, rs, rd, sa);
7673
            return;
7674
        case OPC_TGE ... OPC_TEQ: /* Traps */
7675
        case OPC_TNE:
7676
            gen_trap(ctx, op1, rs, rt, -1);
7677
            break;
7678
        case OPC_MFHI:          /* Move from HI/LO */
7679
        case OPC_MFLO:
7680
            gen_HILO(ctx, op1, rd);
7681
            break;
7682
        case OPC_MTHI:
7683
        case OPC_MTLO:          /* Move to HI/LO */
7684
            gen_HILO(ctx, op1, rs);
7685
            break;
7686
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7687
#ifdef MIPS_STRICT_STANDARD
7688
            MIPS_INVAL("PMON / selsl");
7689
            generate_exception(ctx, EXCP_RI);
7690
#else
7691
            gen_helper_0i(pmon, sa);
7692
#endif
7693
            break;
7694
        case OPC_SYSCALL:
7695
            generate_exception(ctx, EXCP_SYSCALL);
7696
            break;
7697
        case OPC_BREAK:
7698
            generate_exception(ctx, EXCP_BREAK);
7699
            break;
7700
        case OPC_SPIM:
7701
#ifdef MIPS_STRICT_STANDARD
7702
            MIPS_INVAL("SPIM");
7703
            generate_exception(ctx, EXCP_RI);
7704
#else
7705
           /* Implemented as RI exception for now. */
7706
            MIPS_INVAL("spim (unofficial)");
7707
            generate_exception(ctx, EXCP_RI);
7708
#endif
7709
            break;
7710
        case OPC_SYNC:
7711
            /* Treat as NOP. */
7712
            break;
7713

    
7714
        case OPC_MOVCI:
7715
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7716
            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7717
                check_cp1_enabled(ctx);
7718
                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7719
                          (ctx->opcode >> 16) & 1);
7720
            } else {
7721
                generate_exception_err(ctx, EXCP_CpU, 1);
7722
            }
7723
            break;
7724

    
7725
#if defined(TARGET_MIPS64)
7726
       /* MIPS64 specific opcodes */
7727
        case OPC_DSLL:
7728
        case OPC_DSRA:
7729
        case OPC_DSRL:
7730
        case OPC_DSLL32:
7731
        case OPC_DSRA32:
7732
        case OPC_DSRL32:
7733
            check_insn(env, ctx, ISA_MIPS3);
7734
            check_mips_64(ctx);
7735
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7736
            break;
7737
        case OPC_DADD ... OPC_DSUBU:
7738
            check_insn(env, ctx, ISA_MIPS3);
7739
            check_mips_64(ctx);
7740
            gen_arith(env, ctx, op1, rd, rs, rt);
7741
            break;
7742
        case OPC_DSLLV:
7743
        case OPC_DSRAV:
7744
        case OPC_DSRLV:
7745
            check_insn(env, ctx, ISA_MIPS3);
7746
            check_mips_64(ctx);
7747
            gen_shift(env, ctx, op1, rd, rs, rt);
7748
            break;
7749
        case OPC_DMULT ... OPC_DDIVU:
7750
            check_insn(env, ctx, ISA_MIPS3);
7751
            check_mips_64(ctx);
7752
            gen_muldiv(ctx, op1, rs, rt);
7753
            break;
7754
#endif
7755
        default:            /* Invalid */
7756
            MIPS_INVAL("special");
7757
            generate_exception(ctx, EXCP_RI);
7758
            break;
7759
        }
7760
        break;
7761
    case OPC_SPECIAL2:
7762
        op1 = MASK_SPECIAL2(ctx->opcode);
7763
        switch (op1) {
7764
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7765
        case OPC_MSUB ... OPC_MSUBU:
7766
            check_insn(env, ctx, ISA_MIPS32);
7767
            gen_muldiv(ctx, op1, rs, rt);
7768
            break;
7769
        case OPC_MUL:
7770
            gen_arith(env, ctx, op1, rd, rs, rt);
7771
            break;
7772
        case OPC_CLO:
7773
        case OPC_CLZ:
7774
            check_insn(env, ctx, ISA_MIPS32);
7775
            gen_cl(ctx, op1, rd, rs);
7776
            break;
7777
        case OPC_SDBBP:
7778
            /* XXX: not clear which exception should be raised
7779
             *      when in debug mode...
7780
             */
7781
            check_insn(env, ctx, ISA_MIPS32);
7782
            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7783
                generate_exception(ctx, EXCP_DBp);
7784
            } else {
7785
                generate_exception(ctx, EXCP_DBp);
7786
            }
7787
            /* Treat as NOP. */
7788
            break;
7789
#if defined(TARGET_MIPS64)
7790
        case OPC_DCLO:
7791
        case OPC_DCLZ:
7792
            check_insn(env, ctx, ISA_MIPS64);
7793
            check_mips_64(ctx);
7794
            gen_cl(ctx, op1, rd, rs);
7795
            break;
7796
#endif
7797
        default:            /* Invalid */
7798
            MIPS_INVAL("special2");
7799
            generate_exception(ctx, EXCP_RI);
7800
            break;
7801
        }
7802
        break;
7803
    case OPC_SPECIAL3:
7804
        op1 = MASK_SPECIAL3(ctx->opcode);
7805
        switch (op1) {
7806
        case OPC_EXT:
7807
        case OPC_INS:
7808
            check_insn(env, ctx, ISA_MIPS32R2);
7809
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7810
            break;
7811
        case OPC_BSHFL:
7812
            check_insn(env, ctx, ISA_MIPS32R2);
7813
            op2 = MASK_BSHFL(ctx->opcode);
7814
            gen_bshfl(ctx, op2, rt, rd);
7815
            break;
7816
        case OPC_RDHWR:
7817
            check_insn(env, ctx, ISA_MIPS32R2);
7818
            {
7819
                TCGv t0 = tcg_temp_new();
7820

    
7821
                switch (rd) {
7822
                case 0:
7823
                    save_cpu_state(ctx, 1);
7824
                    gen_helper_rdhwr_cpunum(t0);
7825
                    gen_store_gpr(t0, rt);
7826
                    break;
7827
                case 1:
7828
                    save_cpu_state(ctx, 1);
7829
                    gen_helper_rdhwr_synci_step(t0);
7830
                    gen_store_gpr(t0, rt);
7831
                    break;
7832
                case 2:
7833
                    save_cpu_state(ctx, 1);
7834
                    gen_helper_rdhwr_cc(t0);
7835
                    gen_store_gpr(t0, rt);
7836
                    break;
7837
                case 3:
7838
                    save_cpu_state(ctx, 1);
7839
                    gen_helper_rdhwr_ccres(t0);
7840
                    gen_store_gpr(t0, rt);
7841
                    break;
7842
                case 29:
7843
#if defined(CONFIG_USER_ONLY)
7844
                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7845
                    gen_store_gpr(t0, rt);
7846
                    break;
7847
#else
7848
                    /* XXX: Some CPUs implement this in hardware.
7849
                       Not supported yet. */
7850
#endif
7851
                default:            /* Invalid */
7852
                    MIPS_INVAL("rdhwr");
7853
                    generate_exception(ctx, EXCP_RI);
7854
                    break;
7855
                }
7856
                tcg_temp_free(t0);
7857
            }
7858
            break;
7859
        case OPC_FORK:
7860
            check_insn(env, ctx, ASE_MT);
7861
            {
7862
                TCGv t0 = tcg_temp_new();
7863
                TCGv t1 = tcg_temp_new();
7864

    
7865
                gen_load_gpr(t0, rt);
7866
                gen_load_gpr(t1, rs);
7867
                gen_helper_fork(t0, t1);
7868
                tcg_temp_free(t0);
7869
                tcg_temp_free(t1);
7870
            }
7871
            break;
7872
        case OPC_YIELD:
7873
            check_insn(env, ctx, ASE_MT);
7874
            {
7875
                TCGv t0 = tcg_temp_new();
7876

    
7877
                save_cpu_state(ctx, 1);
7878
                gen_load_gpr(t0, rs);
7879
                gen_helper_yield(t0, t0);
7880
                gen_store_gpr(t0, rd);
7881
                tcg_temp_free(t0);
7882
            }
7883
            break;
7884
#if defined(TARGET_MIPS64)
7885
        case OPC_DEXTM ... OPC_DEXT:
7886
        case OPC_DINSM ... OPC_DINS:
7887
            check_insn(env, ctx, ISA_MIPS64R2);
7888
            check_mips_64(ctx);
7889
            gen_bitops(ctx, op1, rt, rs, sa, rd);
7890
            break;
7891
        case OPC_DBSHFL:
7892
            check_insn(env, ctx, ISA_MIPS64R2);
7893
            check_mips_64(ctx);
7894
            op2 = MASK_DBSHFL(ctx->opcode);
7895
            gen_bshfl(ctx, op2, rt, rd);
7896
            break;
7897
#endif
7898
        default:            /* Invalid */
7899
            MIPS_INVAL("special3");
7900
            generate_exception(ctx, EXCP_RI);
7901
            break;
7902
        }
7903
        break;
7904
    case OPC_REGIMM:
7905
        op1 = MASK_REGIMM(ctx->opcode);
7906
        switch (op1) {
7907
        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7908
        case OPC_BLTZAL ... OPC_BGEZALL:
7909
            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7910
            return;
7911
        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7912
        case OPC_TNEI:
7913
            gen_trap(ctx, op1, rs, -1, imm);
7914
            break;
7915
        case OPC_SYNCI:
7916
            check_insn(env, ctx, ISA_MIPS32R2);
7917
            /* Treat as NOP. */
7918
            break;
7919
        default:            /* Invalid */
7920
            MIPS_INVAL("regimm");
7921
            generate_exception(ctx, EXCP_RI);
7922
            break;
7923
        }
7924
        break;
7925
    case OPC_CP0:
7926
        check_cp0_enabled(ctx);
7927
        op1 = MASK_CP0(ctx->opcode);
7928
        switch (op1) {
7929
        case OPC_MFC0:
7930
        case OPC_MTC0:
7931
        case OPC_MFTR:
7932
        case OPC_MTTR:
7933
#if defined(TARGET_MIPS64)
7934
        case OPC_DMFC0:
7935
        case OPC_DMTC0:
7936
#endif
7937
#ifndef CONFIG_USER_ONLY
7938
            gen_cp0(env, ctx, op1, rt, rd);
7939
#endif /* !CONFIG_USER_ONLY */
7940
            break;
7941
        case OPC_C0_FIRST ... OPC_C0_LAST:
7942
#ifndef CONFIG_USER_ONLY
7943
            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7944
#endif /* !CONFIG_USER_ONLY */
7945
            break;
7946
        case OPC_MFMC0:
7947
#ifndef CONFIG_USER_ONLY
7948
            {
7949
                TCGv t0 = tcg_temp_new();
7950

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

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

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

    
8111
    /* COP2.  */
8112
    case OPC_LWC2:
8113
    case OPC_LDC2:
8114
    case OPC_SWC2:
8115
    case OPC_SDC2:
8116
    case OPC_CP2:
8117
        /* COP2: Not implemented. */
8118
        generate_exception_err(ctx, EXCP_CpU, 2);
8119
        break;
8120

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

    
8162
#if defined(TARGET_MIPS64)
8163
    /* MIPS64 opcodes */
8164
    case OPC_LWU:
8165
    case OPC_LDL ... OPC_LDR:
8166
    case OPC_SDL ... OPC_SDR:
8167
    case OPC_LLD:
8168
    case OPC_LD:
8169
    case OPC_SD:
8170
        check_insn(env, ctx, ISA_MIPS3);
8171
        check_mips_64(ctx);
8172
        gen_ldst(ctx, op, rt, rs, imm);
8173
        break;
8174
    case OPC_SCD:
8175
        check_insn(env, ctx, ISA_MIPS3);
8176
        check_mips_64(ctx);
8177
        gen_st_cond(ctx, op, rt, rs, imm);
8178
        break;
8179
    case OPC_DADDI:
8180
    case 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_tl(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)
8253
        qemu_log("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
    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8276
    /* FIXME: This may print out stale hflags from env... */
8277
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8278
#endif
8279
    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8280
    gen_icount_start();
8281
    while (ctx.bstate == BS_NONE) {
8282
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8283
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8284
                if (bp->pc == ctx.pc) {
8285
                    save_cpu_state(&ctx, 1);
8286
                    ctx.bstate = BS_BRANCH;
8287
                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8288
                    /* Include the breakpoint location or the tb won't
8289
                     * be flushed when it must be.  */
8290
                    ctx.pc += 4;
8291
                    goto done_generating;
8292
                }
8293
            }
8294
        }
8295

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

    
8315
        if (env->singlestep_enabled)
8316
            break;
8317

    
8318
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8319
            break;
8320

    
8321
        if (gen_opc_ptr >= gen_opc_end)
8322
            break;
8323

    
8324
        if (num_insns >= max_insns)
8325
            break;
8326

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

    
8377
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8378
{
8379
    gen_intermediate_code_internal(env, tb, 0);
8380
}
8381

    
8382
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8383
{
8384
    gen_intermediate_code_internal(env, tb, 1);
8385
}
8386

    
8387
static void fpu_dump_state(CPUState *env, FILE *f,
8388
                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8389
                           int flags)
8390
{
8391
    int i;
8392
    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8393

    
8394
#define printfpr(fp)                                                        \
8395
    do {                                                                    \
8396
        if (is_fpu64)                                                       \
8397
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8398
                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8399
                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8400
        else {                                                              \
8401
            fpr_t tmp;                                                      \
8402
            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8403
            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8404
            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8405
                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8406
                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8407
        }                                                                   \
8408
    } while(0)
8409

    
8410

    
8411
    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8412
                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8413
                get_float_exception_flags(&env->active_fpu.fp_status));
8414
    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8415
        fpu_fprintf(f, "%3s: ", fregnames[i]);
8416
        printfpr(&env->active_fpu.fpr[i]);
8417
    }
8418

    
8419
#undef printfpr
8420
}
8421

    
8422
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8423
/* Debug help: The architecture requires 32bit code to maintain proper
8424
   sign-extended values on 64bit machines.  */
8425

    
8426
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8427

    
8428
static void
8429
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8430
                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8431
                                int flags)
8432
{
8433
    int i;
8434

    
8435
    if (!SIGN_EXT_P(env->active_tc.PC))
8436
        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8437
    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8438
        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8439
    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8440
        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8441
    if (!SIGN_EXT_P(env->btarget))
8442
        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8443

    
8444
    for (i = 0; i < 32; i++) {
8445
        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8446
            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8447
    }
8448

    
8449
    if (!SIGN_EXT_P(env->CP0_EPC))
8450
        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8451
    if (!SIGN_EXT_P(env->CP0_LLAddr))
8452
        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8453
}
8454
#endif
8455

    
8456
void cpu_dump_state (CPUState *env, FILE *f,
8457
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8458
                     int flags)
8459
{
8460
    int i;
8461

    
8462
    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",
8463
                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8464
                env->hflags, env->btarget, env->bcond);
8465
    for (i = 0; i < 32; i++) {
8466
        if ((i & 3) == 0)
8467
            cpu_fprintf(f, "GPR%02d:", i);
8468
        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8469
        if ((i & 3) == 3)
8470
            cpu_fprintf(f, "\n");
8471
    }
8472

    
8473
    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8474
                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8475
    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8476
                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8477
    if (env->hflags & MIPS_HFLAG_FPU)
8478
        fpu_dump_state(env, f, cpu_fprintf, flags);
8479
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8480
    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8481
#endif
8482
}
8483

    
8484
static void mips_tcg_init(void)
8485
{
8486
    int i;
8487
    static int inited;
8488

    
8489
    /* Initialize various static tables. */
8490
    if (inited)
8491
        return;
8492

    
8493
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8494
    for (i = 1; i < 32; i++)
8495
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8496
                                        offsetof(CPUState, active_tc.gpr[i]),
8497
                                        regnames[i]);
8498
    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8499
                                offsetof(CPUState, active_tc.PC), "PC");
8500
    for (i = 0; i < MIPS_DSP_ACC; i++) {
8501
        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8502
                                       offsetof(CPUState, active_tc.HI[i]),
8503
                                       regnames_HI[i]);
8504
        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8505
                                       offsetof(CPUState, active_tc.LO[i]),
8506
                                       regnames_LO[i]);
8507
        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8508
                                        offsetof(CPUState, active_tc.ACX[i]),
8509
                                        regnames_ACX[i]);
8510
    }
8511
    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8512
                                     offsetof(CPUState, active_tc.DSPControl),
8513
                                     "DSPControl");
8514
    bcond = tcg_global_mem_new(TCG_AREG0,
8515
                               offsetof(CPUState, bcond), "bcond");
8516
    btarget = tcg_global_mem_new(TCG_AREG0,
8517
                                 offsetof(CPUState, btarget), "btarget");
8518
    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8519
                                    offsetof(CPUState, hflags), "hflags");
8520

    
8521
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8522
                                      offsetof(CPUState, active_fpu.fcr0),
8523
                                      "fcr0");
8524
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8525
                                       offsetof(CPUState, active_fpu.fcr31),
8526
                                       "fcr31");
8527

    
8528
    /* register helpers */
8529
#define GEN_HELPER 2
8530
#include "helper.h"
8531

    
8532
    inited = 1;
8533
}
8534

    
8535
#include "translate_init.c"
8536

    
8537
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8538
{
8539
    CPUMIPSState *env;
8540
    const mips_def_t *def;
8541

    
8542
    def = cpu_mips_find_by_name(cpu_model);
8543
    if (!def)
8544
        return NULL;
8545
    env = qemu_mallocz(sizeof(CPUMIPSState));
8546
    env->cpu_model = def;
8547

    
8548
    cpu_exec_init(env);
8549
    env->cpu_model_str = cpu_model;
8550
    mips_tcg_init();
8551
    cpu_reset(env);
8552
    return env;
8553
}
8554

    
8555
void cpu_reset (CPUMIPSState *env)
8556
{
8557
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8558
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8559
        log_cpu_state(env, 0);
8560
    }
8561

    
8562
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8563

    
8564
    tlb_flush(env, 1);
8565

    
8566
    /* Minimal init */
8567
#if defined(CONFIG_USER_ONLY)
8568
    env->hflags = MIPS_HFLAG_UM;
8569
#else
8570
    if (env->hflags & MIPS_HFLAG_BMASK) {
8571
        /* If the exception was raised from a delay slot,
8572
           come back to the jump.  */
8573
        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8574
    } else {
8575
        env->CP0_ErrorEPC = env->active_tc.PC;
8576
    }
8577
    env->active_tc.PC = (int32_t)0xBFC00000;
8578
    env->CP0_Wired = 0;
8579
    /* SMP not implemented */
8580
    env->CP0_EBase = 0x80000000;
8581
    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8582
    /* vectored interrupts not implemented, timer on int 7,
8583
       no performance counters. */
8584
    env->CP0_IntCtl = 0xe0000000;
8585
    {
8586
        int i;
8587

    
8588
        for (i = 0; i < 7; i++) {
8589
            env->CP0_WatchLo[i] = 0;
8590
            env->CP0_WatchHi[i] = 0x80000000;
8591
        }
8592
        env->CP0_WatchLo[7] = 0;
8593
        env->CP0_WatchHi[7] = 0;
8594
    }
8595
    /* Count register increments in debug mode, EJTAG version 1 */
8596
    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8597
    env->hflags = MIPS_HFLAG_CP0;
8598
#endif
8599
    env->exception_index = EXCP_NONE;
8600
    cpu_mips_register(env, env->cpu_model);
8601
}
8602

    
8603
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8604
                unsigned long searched_pc, int pc_pos, void *puc)
8605
{
8606
    env->active_tc.PC = gen_opc_pc[pc_pos];
8607
    env->hflags &= ~MIPS_HFLAG_BMASK;
8608
    env->hflags |= gen_opc_hflags[pc_pos];
8609
}