Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (248.4 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 t0 = tcg_temp_new();
550

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

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

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

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

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

    
587
        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
588
        tcg_temp_free_ptr(addr);
589
        tcg_temp_free_i32(t2);
590
        tcg_temp_free(t0);
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
}
797

    
798
static inline void
799
generate_exception (DisasContext *ctx, int excp)
800
{
801
    save_cpu_state(ctx, 1);
802
    gen_helper_0i(raise_exception, excp);
803
}
804

    
805
/* Addresses computation */
806
static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
807
{
808
    tcg_gen_add_tl(t0, t0, t1);
809

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

    
821
static inline void check_cp0_enabled(DisasContext *ctx)
822
{
823
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
824
        generate_exception_err(ctx, EXCP_CpU, 1);
825
}
826

    
827
static inline void check_cp1_enabled(DisasContext *ctx)
828
{
829
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
830
        generate_exception_err(ctx, EXCP_CpU, 1);
831
}
832

    
833
/* Verify that the processor is running with COP1X instructions enabled.
834
   This is associated with the nabla symbol in the MIPS32 and MIPS64
835
   opcode tables.  */
836

    
837
static inline void check_cop1x(DisasContext *ctx)
838
{
839
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
840
        generate_exception(ctx, EXCP_RI);
841
}
842

    
843
/* Verify that the processor is running with 64-bit floating-point
844
   operations enabled.  */
845

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

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

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

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

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

    
902
#define OP_ST(insn,fname)                                                  \
903
static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
904
{                                                                          \
905
    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
906
}
907
OP_ST(sb,st8);
908
OP_ST(sh,st16);
909
OP_ST(sw,st32);
910
#if defined(TARGET_MIPS64)
911
OP_ST(sd,st64);
912
#endif
913
#undef OP_ST
914

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

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

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

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

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

    
1123
    t0 = tcg_temp_local_new();
1124

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

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

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

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

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

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

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

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

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

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

    
1251
            gen_load_gpr(t1, rs);
1252
            tcg_gen_addi_tl(t0, t1, uimm);
1253
            tcg_gen_ext32s_tl(t0, t0);
1254

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

    
1287
            gen_load_gpr(t1, rs);
1288
            tcg_gen_addi_tl(t0, t1, uimm);
1289

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

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

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

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

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

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

    
1395
    if (rt == 0) {
1396
        /* If no destination, treat it as a NOP. */
1397
        MIPS_DEBUG("NOP");
1398
        return;
1399
    }
1400

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

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

    
1522
/* Arithmetic */
1523
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1524
                       int rd, int rs, int rt)
1525
{
1526
    const char *opn = "arith";
1527

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

    
1536
    switch (opc) {
1537
    case OPC_ADD:
1538
        {
1539
            TCGv t0 = tcg_temp_local_new();
1540
            TCGv t1 = tcg_temp_new();
1541
            TCGv t2 = tcg_temp_new();
1542
            int l1 = gen_new_label();
1543

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

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

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

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

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

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

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

    
1737
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1738
}
1739

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2009
            tcg_gen_ext32s_tl(t0, t0);
2010
            tcg_gen_ext32s_tl(t1, t1);
2011
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2012
            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2013
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2014

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

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

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

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

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

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

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

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

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

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

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

    
2221
    gen_load_gpr(t0, rs);
2222
    gen_load_gpr(t1, rt);
2223

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

    
2289
 out:
2290
    tcg_temp_free(t0);
2291
    tcg_temp_free(t1);
2292
}
2293

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

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

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

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

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

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

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

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

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

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

    
2670
 out:
2671
    tcg_temp_free(t0);
2672
    tcg_temp_free(t1);
2673
}
2674

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

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

    
2768
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2769
{
2770
    TCGv t0;
2771

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

    
2778
    t0 = tcg_temp_new();
2779
    gen_load_gpr(t0, rt);
2780
    switch (op2) {
2781
    case OPC_WSBH:
2782
        {
2783
            TCGv t1 = tcg_temp_new();
2784

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

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

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

    
2838
#ifndef CONFIG_USER_ONLY
2839
/* CP0 (MMU and control) */
2840
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2841
{
2842
    TCGv_i32 t0 = tcg_temp_new_i32();
2843

    
2844
    tcg_gen_ld_i32(t0, cpu_env, off);
2845
    tcg_gen_ext_i32_tl(arg, t0);
2846
    tcg_temp_free_i32(t0);
2847
}
2848

    
2849
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2850
{
2851
    tcg_gen_ld_tl(arg, cpu_env, off);
2852
    tcg_gen_ext32s_tl(arg, arg);
2853
}
2854

    
2855
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2856
{
2857
    TCGv_i32 t0 = tcg_temp_new_i32();
2858

    
2859
    tcg_gen_trunc_tl_i32(t0, arg);
2860
    tcg_gen_st_i32(t0, cpu_env, off);
2861
    tcg_temp_free_i32(t0);
2862
}
2863

    
2864
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2865
{
2866
    tcg_gen_ext32s_tl(arg, arg);
2867
    tcg_gen_st_tl(arg, cpu_env, off);
2868
}
2869

    
2870
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2871
{
2872
    const char *rn = "invalid";
2873

    
2874
    if (sel != 0)
2875
        check_insn(env, ctx, ISA_MIPS32);
2876

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

    
3442
die:
3443
    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3444
    generate_exception(ctx, EXCP_RI);
3445
}
3446

    
3447
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3448
{
3449
    const char *rn = "invalid";
3450

    
3451
    if (sel != 0)
3452
        check_insn(env, ctx, ISA_MIPS32);
3453

    
3454
    if (use_icount)
3455
        gen_io_start();
3456

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

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

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

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

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

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

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

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

    
4616
    if (use_icount)
4617
        gen_io_start();
4618

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5761
/* Coprocessor 1 (FPU) */
5762

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5944

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
6477
            gen_load_fpr64(ctx, fp0, fs);
6478
            gen_helper_float_abs_d(fp0, fp0);
6479
            gen_store_fpr64(ctx, fp0, fd);
6480
            tcg_temp_free_i64(fp0);
6481
        }
6482
        opn = "abs.d";
6483
        break;
6484
    case FOP(6, 17):
6485
        check_cp1_registers(ctx, fs | fd);
6486
        {
6487
            TCGv_i64 fp0 = tcg_temp_new_i64();
6488

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

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

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

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

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

    
6548
            gen_load_fpr64(ctx, fp0, fs);
6549
            gen_helper_float_floorl_d(fp0, fp0);
6550
            gen_store_fpr64(ctx, fp0, fd);
6551
            tcg_temp_free_i64(fp0);
6552
        }
6553
        opn = "floor.l.d";
6554
        break;
6555
    case FOP(12, 17):
6556
        check_cp1_registers(ctx, fs);
6557
        {
6558
            TCGv_i32 fp32 = tcg_temp_new_i32();
6559
            TCGv_i64 fp64 = tcg_temp_new_i64();
6560

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7276
            gen_load_fpr32(fp0, fs);
7277
            tcg_gen_extu_i32_tl(t1, fp0);
7278
            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7279
            tcg_temp_free_i32(fp0);
7280
            tcg_temp_free(t1);
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
    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7314
               regnames[index], regnames[base]);
7315
}
7316

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7594
#if defined(TARGET_MIPS64)
7595

    
7596
/* MDMX extension to MIPS64 */
7597

    
7598
#endif
7599

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

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

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

    
7618
        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7619
        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7620
        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7621
        gen_goto_tb(ctx, 1, ctx->pc + 4);
7622
        gen_set_label(l1);
7623
    }
7624
    op = MASK_OP_MAJOR(ctx->opcode);
7625
    rs = (ctx->opcode >> 21) & 0x1f;
7626
    rt = (ctx->opcode >> 16) & 0x1f;
7627
    rd = (ctx->opcode >> 11) & 0x1f;
7628
    sa = (ctx->opcode >> 6) & 0x1f;
7629
    imm = (int16_t)ctx->opcode;
7630
    switch (op) {
7631
    case OPC_SPECIAL:
7632
        op1 = MASK_SPECIAL(ctx->opcode);
7633
        switch (op1) {
7634
        case OPC_SLL:          /* Shift with immediate */
7635
        case OPC_SRA:
7636
        case OPC_SRL:
7637
            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7638
            break;
7639
        case OPC_MOVN:         /* Conditional move */
7640
        case OPC_MOVZ:
7641
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7642
            gen_cond_move(env, op1, rd, rs, rt);
7643
            break;
7644
        case OPC_ADD ... OPC_SUBU:
7645
            gen_arith(env, ctx, op1, rd, rs, rt);
7646
            break;
7647
        case OPC_SLLV:         /* Shifts */
7648
        case OPC_SRLV:
7649
        case OPC_SRAV:
7650
            gen_shift(env, ctx, op1, rd, rs, rt);
7651
            break;
7652
        case OPC_SLT:          /* Set on less than */
7653
        case OPC_SLTU:
7654
            gen_slt(env, op1, rd, rs, rt);
7655
            break;
7656
        case OPC_AND:          /* Logic*/
7657
        case OPC_OR:
7658
        case OPC_NOR:
7659
        case OPC_XOR:
7660
            gen_logic(env, op1, rd, rs, rt);
7661
            break;
7662
        case OPC_MULT ... OPC_DIVU:
7663
            if (sa) {
7664
                check_insn(env, ctx, INSN_VR54XX);
7665
                op1 = MASK_MUL_VR54XX(ctx->opcode);
7666
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7667
            } else
7668
                gen_muldiv(ctx, op1, rs, rt);
7669
            break;
7670
        case OPC_JR ... OPC_JALR:
7671
            gen_compute_branch(ctx, op1, rs, rd, sa);
7672
            return;
7673
        case OPC_TGE ... OPC_TEQ: /* Traps */
7674
        case OPC_TNE:
7675
            gen_trap(ctx, op1, rs, rt, -1);
7676
            break;
7677
        case OPC_MFHI:          /* Move from HI/LO */
7678
        case OPC_MFLO:
7679
            gen_HILO(ctx, op1, rd);
7680
            break;
7681
        case OPC_MTHI:
7682
        case OPC_MTLO:          /* Move to HI/LO */
7683
            gen_HILO(ctx, op1, rs);
7684
            break;
7685
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7686
#ifdef MIPS_STRICT_STANDARD
7687
            MIPS_INVAL("PMON / selsl");
7688
            generate_exception(ctx, EXCP_RI);
7689
#else
7690
            gen_helper_0i(pmon, sa);
7691
#endif
7692
            break;
7693
        case OPC_SYSCALL:
7694
            generate_exception(ctx, EXCP_SYSCALL);
7695
            ctx->bstate = BS_STOP;
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
                    save_cpu_state(ctx, 1);
7976
                    gen_helper_di(t0);
7977
                    gen_store_gpr(t0, rt);
7978
                    /* Stop translation as we may have switched the execution mode */
7979
                    ctx->bstate = BS_STOP;
7980
                    break;
7981
                case OPC_EI:
7982
                    check_insn(env, ctx, ISA_MIPS32R2);
7983
                    save_cpu_state(ctx, 1);
7984
                    gen_helper_ei(t0);
7985
                    gen_store_gpr(t0, rt);
7986
                    /* Stop translation as we may have switched the execution mode */
7987
                    ctx->bstate = BS_STOP;
7988
                    break;
7989
                default:            /* Invalid */
7990
                    MIPS_INVAL("mfmc0");
7991
                    generate_exception(ctx, EXCP_RI);
7992
                    break;
7993
                }
7994
                tcg_temp_free(t0);
7995
            }
7996
#endif /* !CONFIG_USER_ONLY */
7997
            break;
7998
        case OPC_RDPGPR:
7999
            check_insn(env, ctx, ISA_MIPS32R2);
8000
            gen_load_srsgpr(rt, rd);
8001
            break;
8002
        case OPC_WRPGPR:
8003
            check_insn(env, ctx, ISA_MIPS32R2);
8004
            gen_store_srsgpr(rt, rd);
8005
            break;
8006
        default:
8007
            MIPS_INVAL("cp0");
8008
            generate_exception(ctx, EXCP_RI);
8009
            break;
8010
        }
8011
        break;
8012
    case OPC_ADDI: /* Arithmetic with immediate opcode */
8013
    case OPC_ADDIU:
8014
         gen_arith_imm(env, ctx, op, rt, rs, imm);
8015
         break;
8016
    case OPC_SLTI: /* Set on less than with immediate opcode */
8017
    case OPC_SLTIU:
8018
         gen_slt_imm(env, op, rt, rs, imm);
8019
         break;
8020
    case OPC_ANDI: /* Arithmetic with immediate opcode */
8021
    case OPC_LUI:
8022
    case OPC_ORI:
8023
    case OPC_XORI:
8024
         gen_logic_imm(env, op, rt, rs, imm);
8025
         break;
8026
    case OPC_J ... OPC_JAL: /* Jump */
8027
         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8028
         gen_compute_branch(ctx, op, rs, rt, offset);
8029
         return;
8030
    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8031
    case OPC_BEQL ... OPC_BGTZL:
8032
         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8033
         return;
8034
    case OPC_LB ... OPC_LWR: /* Load and stores */
8035
    case OPC_SB ... OPC_SW:
8036
    case OPC_SWR:
8037
    case OPC_LL:
8038
         gen_ldst(ctx, op, rt, rs, imm);
8039
         break;
8040
    case OPC_SC:
8041
         gen_st_cond(ctx, op, rt, rs, imm);
8042
         break;
8043
    case OPC_CACHE:
8044
        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8045
        /* Treat as NOP. */
8046
        break;
8047
    case OPC_PREF:
8048
        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8049
        /* Treat as NOP. */
8050
        break;
8051

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

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

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

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

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

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

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

    
8254
    if (search_pc)
8255
        qemu_log("search pc %d\n", search_pc);
8256

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

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

    
8317
        if (env->singlestep_enabled)
8318
            break;
8319

    
8320
        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8321
            break;
8322

    
8323
        if (gen_opc_ptr >= gen_opc_end)
8324
            break;
8325

    
8326
        if (num_insns >= max_insns)
8327
            break;
8328

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

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

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

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

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

    
8412

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

    
8421
#undef printfpr
8422
}
8423

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

    
8428
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8429

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

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

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

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

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

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

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

    
8486
static void mips_tcg_init(void)
8487
{
8488
    int i;
8489
    static int inited;
8490

    
8491
    /* Initialize various static tables. */
8492
    if (inited)
8493
        return;
8494

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

    
8524
    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8525
                                      offsetof(CPUState, active_fpu.fcr0),
8526
                                      "fcr0");
8527
    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8528
                                       offsetof(CPUState, active_fpu.fcr31),
8529
                                       "fcr31");
8530

    
8531
    /* register helpers */
8532
#define GEN_HELPER 2
8533
#include "helper.h"
8534

    
8535
    inited = 1;
8536
}
8537

    
8538
#include "translate_init.c"
8539

    
8540
CPUMIPSState *cpu_mips_init (const char *cpu_model)
8541
{
8542
    CPUMIPSState *env;
8543
    const mips_def_t *def;
8544

    
8545
    def = cpu_mips_find_by_name(cpu_model);
8546
    if (!def)
8547
        return NULL;
8548
    env = qemu_mallocz(sizeof(CPUMIPSState));
8549
    env->cpu_model = def;
8550

    
8551
    cpu_exec_init(env);
8552
    env->cpu_model_str = cpu_model;
8553
    mips_tcg_init();
8554
    cpu_reset(env);
8555
    qemu_init_vcpu(env);
8556
    return env;
8557
}
8558

    
8559
void cpu_reset (CPUMIPSState *env)
8560
{
8561
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8562
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8563
        log_cpu_state(env, 0);
8564
    }
8565

    
8566
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8567

    
8568
    tlb_flush(env, 1);
8569

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

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

    
8609
void gen_pc_load(CPUState *env, TranslationBlock *tb,
8610
                unsigned long searched_pc, int pc_pos, void *puc)
8611
{
8612
    env->active_tc.PC = gen_opc_pc[pc_pos];
8613
    env->hflags &= ~MIPS_HFLAG_BMASK;
8614
    env->hflags |= gen_opc_hflags[pc_pos];
8615
}