Statistics
| Branch: | Revision:

root / target-mips / translate.c @ df357f0e

History | View | Annotate | Download (248.3 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 same sign, 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
        } else if (rs != 0 && rt == 0) {
1608
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1609
        } else {
1610
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1611
        }
1612
        opn = "subu";
1613
        break;
1614
#if defined(TARGET_MIPS64)
1615
    case OPC_DADD:
1616
        {
1617
            TCGv t0 = tcg_temp_local_new();
1618
            TCGv t1 = tcg_temp_new();
1619
            TCGv t2 = tcg_temp_new();
1620
            int l1 = gen_new_label();
1621

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3453
    if (use_icount)
3454
        gen_io_start();
3455

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

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

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

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

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

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

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

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

    
4615
    if (use_icount)
4616
        gen_io_start();
4617

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5760
/* Coprocessor 1 (FPU) */
5761

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
5943

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
7593
#if defined(TARGET_MIPS64)
7594

    
7595
/* MDMX extension to MIPS64 */
7596

    
7597
#endif
7598

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8411

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

    
8420
#undef printfpr
8421
}
8422

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
8534
    inited = 1;
8535
}
8536

    
8537
#include "translate_init.c"
8538

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

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

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

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

    
8564
    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8565

    
8566
    tlb_flush(env, 1);
8567

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

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

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