Statistics
| Branch: | Revision:

root / target-mips / translate.c @ 90cb786c

History | View | Annotate | Download (219.7 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "helper.h"
33
#include "tcg-op.h"
34
#include "qemu-common.h"
35

    
36
//#define MIPS_DEBUG_DISAS
37
//#define MIPS_DEBUG_SIGN_EXTENSIONS
38
//#define MIPS_SINGLE_STEP
39

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

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

    
118
/* MIPS special opcodes */
119
#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
120

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

    
184
    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
185

    
186
    /* Special */
187
    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
188
    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
189
    OPC_BREAK    = 0x0D | OPC_SPECIAL,
190
    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
191
    OPC_SYNC     = 0x0F | OPC_SPECIAL,
192

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

    
202
/* Multiplication variants of the vr54xx. */
203
#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
204

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

    
222
/* REGIMM (rt field) opcodes */
223
#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
224

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

    
243
/* Special2 opcodes */
244
#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
245

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

    
262
/* Special3 opcodes */
263
#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
264

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

    
281
/* BSHFL opcodes */
282
#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
283

    
284
enum {
285
    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
286
    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
287
    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
288
};
289

    
290
/* DBSHFL opcodes */
291
#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
292

    
293
enum {
294
    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
295
    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
296
};
297

    
298
/* Coprocessor 0 (rs field) */
299
#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
300

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

    
316
/* MFMC0 opcodes */
317
#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
318

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

    
328
/* Coprocessor 0 (with rs == C0) */
329
#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
330

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

    
342
/* Coprocessor 1 (rs field) */
343
#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
344

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

    
366
#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
367
#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
368

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

    
376
enum {
377
    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
378
    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
379
};
380

    
381
enum {
382
    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
383
    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
384
};
385

    
386
#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
387

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

    
400
#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
401

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

    
425
/* global register indices */
426
static TCGv cpu_env, current_tc_gprs, current_tc_hi, cpu_T[2];
427

    
428
/* The code generator doesn't like lots of temporaries, so maintain our own
429
   cache for reuse within a function.  */
430
#define MAX_TEMPS 4
431
static int num_temps;
432
static TCGv temps[MAX_TEMPS];
433

    
434
/* Allocate a temporary variable.  */
435
static TCGv new_tmp(void)
436
{
437
    TCGv tmp;
438
    if (num_temps == MAX_TEMPS)
439
        abort();
440

    
441
    if (GET_TCGV(temps[num_temps]))
442
      return temps[num_temps++];
443

    
444
    tmp = tcg_temp_new(TCG_TYPE_I32);
445
    temps[num_temps++] = tmp;
446
    return tmp;
447
}
448

    
449
/* Release a temporary variable.  */
450
static void dead_tmp(TCGv tmp)
451
{
452
    int i;
453
    num_temps--;
454
    i = num_temps;
455
    if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
456
        return;
457

    
458
    /* Shuffle this temp to the last slot.  */
459
    while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
460
        i--;
461
    while (i < num_temps) {
462
        temps[i] = temps[i + 1];
463
        i++;
464
    }
465
    temps[i] = tmp;
466
}
467

    
468
typedef struct DisasContext {
469
    struct TranslationBlock *tb;
470
    target_ulong pc, saved_pc;
471
    uint32_t opcode;
472
    uint32_t fp_status;
473
    /* Routine used to access memory */
474
    int mem_idx;
475
    uint32_t hflags, saved_hflags;
476
    int bstate;
477
    target_ulong btarget;
478
} DisasContext;
479

    
480
enum {
481
    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
482
                      * exception condition
483
                      */
484
    BS_STOP     = 1, /* We want to stop translation for any reason */
485
    BS_BRANCH   = 2, /* We reached a branch condition     */
486
    BS_EXCP     = 3, /* We reached an exception condition */
487
};
488

    
489
static const char *regnames[] =
490
    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
491
      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
492
      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
493
      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
494

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

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

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

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

    
528
static inline void gen_store_gpr (TCGv t, int reg)
529
{
530
    if (reg != 0)
531
        tcg_gen_st_tl(t, current_tc_gprs, sizeof(target_ulong) * reg);
532
}
533

    
534
/* Moves to/from HI and LO registers.  */
535
static inline void gen_load_LO (TCGv t, int reg)
536
{
537
    tcg_gen_ld_tl(t, current_tc_hi,
538
                  offsetof(CPUState, LO)
539
                  - offsetof(CPUState, HI)
540
                  + sizeof(target_ulong) * reg);
541
}
542

    
543
static inline void gen_store_LO (TCGv t, int reg)
544
{
545
    tcg_gen_st_tl(t, current_tc_hi,
546
                  offsetof(CPUState, LO)
547
                  - offsetof(CPUState, HI)
548
                  + sizeof(target_ulong) * reg);
549
}
550

    
551
static inline void gen_load_HI (TCGv t, int reg)
552
{
553
    tcg_gen_ld_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
554
}
555

    
556
static inline void gen_store_HI (TCGv t, int reg)
557
{
558
    tcg_gen_st_tl(t, current_tc_hi, sizeof(target_ulong) * reg);
559
}
560

    
561
/* Moves to/from shadow registers. */
562
static inline void gen_load_srsgpr (TCGv t, int reg)
563
{
564
    if (reg == 0)
565
        tcg_gen_movi_tl(t, 0);
566
    else {
567
        TCGv r_tmp = new_tmp();
568

    
569
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
570
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
571
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
572
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
573
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
574

    
575
        tcg_gen_ld_tl(t, r_tmp, sizeof(target_ulong) * reg);
576
        dead_tmp(r_tmp);
577
    }
578
}
579

    
580
static inline void gen_store_srsgpr (TCGv t, int reg)
581
{
582
    if (reg != 0) {
583
        TCGv r_tmp = new_tmp();
584

    
585
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
586
        tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
587
        tcg_gen_andi_i32(r_tmp, r_tmp, 0xf);
588
        tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32);
589
        tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
590

    
591
        tcg_gen_st_tl(t, r_tmp, sizeof(target_ulong) * reg);
592
        dead_tmp(r_tmp);
593
    }
594
}
595

    
596
/* Floating point register moves. */
597
#define FGEN32(func, NAME)                       \
598
static GenOpFunc *NAME ## _table [32] = {        \
599
NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
600
NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
601
NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
602
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
603
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
604
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
605
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
606
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
607
};                                               \
608
static always_inline void func(int n)            \
609
{                                                \
610
    NAME ## _table[n]();                         \
611
}
612

    
613
FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
614
FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
615

    
616
FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
617
FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
618

    
619
FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
620
FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
621

    
622
FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
623
FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
624

    
625
FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
626
FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
627

    
628
FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
629
FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
630

    
631
FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
632
FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
633

    
634
FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
635
FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
636

    
637
FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
638
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
639

    
640
#define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
641
do {                                                                          \
642
    glue(gen_op_load_fpr_, FTn)(Fn);                                          \
643
} while (0)
644

    
645
#define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
646
do {                                                                          \
647
    glue(gen_op_store_fpr_, FTn)(Fn);                                         \
648
} while (0)
649

    
650
#define FOP_CONDS(type, fmt)                                            \
651
static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
652
    gen_op_cmp ## type ## _ ## fmt ## _f,                               \
653
    gen_op_cmp ## type ## _ ## fmt ## _un,                              \
654
    gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
655
    gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
656
    gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
657
    gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
658
    gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
659
    gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
660
    gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
661
    gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
662
    gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
663
    gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
664
    gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
665
    gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
666
    gen_op_cmp ## type ## _ ## fmt ## _le,                              \
667
    gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
668
};                                                                      \
669
static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
670
{                                                                       \
671
    gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
672
}
673

    
674
FOP_CONDS(, d)
675
FOP_CONDS(abs, d)
676
FOP_CONDS(, s)
677
FOP_CONDS(abs, s)
678
FOP_CONDS(, ps)
679
FOP_CONDS(abs, ps)
680

    
681
/* Tests */
682
#define OP_COND(name, cond)                                   \
683
void glue(gen_op_, name) (void)                               \
684
{                                                             \
685
    int l1 = gen_new_label();                                 \
686
    int l2 = gen_new_label();                                 \
687
                                                              \
688
    tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1);          \
689
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
690
    tcg_gen_br(l2);                                           \
691
    gen_set_label(l1);                                        \
692
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
693
    gen_set_label(l2);                                        \
694
}
695
OP_COND(eq, TCG_COND_EQ);
696
OP_COND(ne, TCG_COND_NE);
697
OP_COND(ge, TCG_COND_GE);
698
OP_COND(geu, TCG_COND_GEU);
699
OP_COND(lt, TCG_COND_LT);
700
OP_COND(ltu, TCG_COND_LTU);
701
#undef OP_COND
702

    
703
#define OP_CONDI(name, cond)                                  \
704
void glue(gen_op_, name) (target_ulong val)                   \
705
{                                                             \
706
    int l1 = gen_new_label();                                 \
707
    int l2 = gen_new_label();                                 \
708
                                                              \
709
    tcg_gen_brcondi_tl(cond, cpu_T[0], val, l1);              \
710
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
711
    tcg_gen_br(l2);                                           \
712
    gen_set_label(l1);                                        \
713
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
714
    gen_set_label(l2);                                        \
715
}
716
OP_CONDI(lti, TCG_COND_LT);
717
OP_CONDI(ltiu, TCG_COND_LTU);
718
#undef OP_CONDI
719

    
720
#define OP_CONDZ(name, cond)                                  \
721
void glue(gen_op_, name) (void)                               \
722
{                                                             \
723
    int l1 = gen_new_label();                                 \
724
    int l2 = gen_new_label();                                 \
725
                                                              \
726
    tcg_gen_brcondi_tl(cond, cpu_T[0], 0, l1);                \
727
    tcg_gen_movi_tl(cpu_T[0], 0);                             \
728
    tcg_gen_br(l2);                                           \
729
    gen_set_label(l1);                                        \
730
    tcg_gen_movi_tl(cpu_T[0], 1);                             \
731
    gen_set_label(l2);                                        \
732
}
733
OP_CONDZ(gez, TCG_COND_GE);
734
OP_CONDZ(gtz, TCG_COND_GT);
735
OP_CONDZ(lez, TCG_COND_LE);
736
OP_CONDZ(ltz, TCG_COND_LT);
737
#undef OP_CONDZ
738

    
739
static inline void gen_save_pc(target_ulong pc)
740
{
741
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
742
    TCGv r_tc_off = new_tmp();
743
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
744
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
745

    
746
    tcg_gen_movi_tl(r_tmp, pc);
747
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
748
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
749
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
750
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
751
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
752
    dead_tmp(r_tc_off);
753
}
754

    
755
static inline void gen_breg_pc(void)
756
{
757
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
758
    TCGv r_tc_off = new_tmp();
759
    TCGv r_tc_off_tl = tcg_temp_new(TCG_TYPE_TL);
760
    TCGv r_ptr = tcg_temp_new(TCG_TYPE_PTR);
761

    
762
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
763
    tcg_gen_ld_i32(r_tc_off, cpu_env, offsetof(CPUState, current_tc));
764
    tcg_gen_muli_i32(r_tc_off, r_tc_off, sizeof(target_ulong));
765
    tcg_gen_ext_i32_ptr(r_tc_off_tl, r_tc_off);
766
    tcg_gen_add_ptr(r_ptr, cpu_env, r_tc_off_tl);
767
    tcg_gen_st_tl(r_tmp, r_ptr, offsetof(CPUState, PC));
768
    dead_tmp(r_tc_off);
769
}
770

    
771
static inline void gen_save_btarget(target_ulong btarget)
772
{
773
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
774

    
775
    tcg_gen_movi_tl(r_tmp, btarget);
776
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
777
}
778

    
779
static always_inline void gen_save_breg_target(int reg)
780
{
781
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);
782

    
783
    gen_load_gpr(r_tmp, reg);
784
    tcg_gen_st_tl(r_tmp, cpu_env, offsetof(CPUState, btarget));
785
}
786

    
787
static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
788
{
789
#if defined MIPS_DEBUG_DISAS
790
    if (loglevel & CPU_LOG_TB_IN_ASM) {
791
            fprintf(logfile, "hflags %08x saved %08x\n",
792
                    ctx->hflags, ctx->saved_hflags);
793
    }
794
#endif
795
    if (do_save_pc && ctx->pc != ctx->saved_pc) {
796
        gen_save_pc(ctx->pc);
797
        ctx->saved_pc = ctx->pc;
798
    }
799
    if (ctx->hflags != ctx->saved_hflags) {
800
        gen_op_save_state(ctx->hflags);
801
        ctx->saved_hflags = ctx->hflags;
802
        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
803
        case MIPS_HFLAG_BR:
804
            break;
805
        case MIPS_HFLAG_BC:
806
        case MIPS_HFLAG_BL:
807
        case MIPS_HFLAG_B:
808
            gen_save_btarget(ctx->btarget);
809
            break;
810
        }
811
    }
812
}
813

    
814
static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
815
{
816
    ctx->saved_hflags = ctx->hflags;
817
    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
818
    case MIPS_HFLAG_BR:
819
        break;
820
    case MIPS_HFLAG_BC:
821
    case MIPS_HFLAG_BL:
822
    case MIPS_HFLAG_B:
823
        ctx->btarget = env->btarget;
824
        break;
825
    }
826
}
827

    
828
static always_inline void
829
generate_exception_err (DisasContext *ctx, int excp, int err)
830
{
831
    save_cpu_state(ctx, 1);
832
    tcg_gen_helper_0_2(do_raise_exception_err, tcg_const_i32(excp), tcg_const_i32(err));
833
    tcg_gen_helper_0_0(do_interrupt_restart);
834
    tcg_gen_exit_tb(0);
835
}
836

    
837
static always_inline void
838
generate_exception (DisasContext *ctx, int excp)
839
{
840
    save_cpu_state(ctx, 1);
841
    tcg_gen_helper_0_1(do_raise_exception, tcg_const_i32(excp));
842
    tcg_gen_helper_0_0(do_interrupt_restart);
843
    tcg_gen_exit_tb(0);
844
}
845

    
846
/* Addresses computation */
847
static inline void gen_op_addr_add (void)
848
{
849
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
850

    
851
#if defined(TARGET_MIPS64)
852
    /* For compatibility with 32-bit code, data reference in user mode
853
       with Status_UX = 0 should be casted to 32-bit and sign extended.
854
       See the MIPS64 PRA manual, section 4.10. */
855
    {
856
        TCGv r_tmp = new_tmp();
857
        int l1 = gen_new_label();
858

    
859
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
860
        tcg_gen_andi_i32(r_tmp, r_tmp, MIPS_HFLAG_KSU);
861
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, MIPS_HFLAG_UM, l1);
862
        tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
863
        tcg_gen_andi_i32(r_tmp, r_tmp, (1 << CP0St_UX));
864
        tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp, 0, l1);
865
        tcg_gen_ext32s_i64(cpu_T[0], cpu_T[0]);
866
        gen_set_label(l1);
867
        dead_tmp(r_tmp);
868
    }
869
#endif
870
}
871

    
872
static always_inline void check_cp0_enabled(DisasContext *ctx)
873
{
874
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
875
        generate_exception_err(ctx, EXCP_CpU, 1);
876
}
877

    
878
static always_inline void check_cp1_enabled(DisasContext *ctx)
879
{
880
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
881
        generate_exception_err(ctx, EXCP_CpU, 1);
882
}
883

    
884
/* Verify that the processor is running with COP1X instructions enabled.
885
   This is associated with the nabla symbol in the MIPS32 and MIPS64
886
   opcode tables.  */
887

    
888
static always_inline void check_cop1x(DisasContext *ctx)
889
{
890
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
891
        generate_exception(ctx, EXCP_RI);
892
}
893

    
894
/* Verify that the processor is running with 64-bit floating-point
895
   operations enabled.  */
896

    
897
static always_inline void check_cp1_64bitmode(DisasContext *ctx)
898
{
899
    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
900
        generate_exception(ctx, EXCP_RI);
901
}
902

    
903
/*
904
 * Verify if floating point register is valid; an operation is not defined
905
 * if bit 0 of any register specification is set and the FR bit in the
906
 * Status register equals zero, since the register numbers specify an
907
 * even-odd pair of adjacent coprocessor general registers. When the FR bit
908
 * in the Status register equals one, both even and odd register numbers
909
 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
910
 *
911
 * Multiple 64 bit wide registers can be checked by calling
912
 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
913
 */
914
void check_cp1_registers(DisasContext *ctx, int regs)
915
{
916
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
917
        generate_exception(ctx, EXCP_RI);
918
}
919

    
920
/* This code generates a "reserved instruction" exception if the
921
   CPU does not support the instruction set corresponding to flags. */
922
static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
923
{
924
    if (unlikely(!(env->insn_flags & flags)))
925
        generate_exception(ctx, EXCP_RI);
926
}
927

    
928
/* This code generates a "reserved instruction" exception if 64-bit
929
   instructions are not enabled. */
930
static always_inline void check_mips_64(DisasContext *ctx)
931
{
932
    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
933
        generate_exception(ctx, EXCP_RI);
934
}
935

    
936
/* load/store instructions. */
937
#if defined(CONFIG_USER_ONLY)
938
#define op_ldst(name)        gen_op_##name##_raw()
939
#define OP_LD_TABLE(width)
940
#define OP_ST_TABLE(width)
941
#else
942
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
943
#define OP_LD_TABLE(width)                                                    \
944
static GenOpFunc *gen_op_l##width[] = {                                       \
945
    &gen_op_l##width##_kernel,                                                \
946
    &gen_op_l##width##_super,                                                 \
947
    &gen_op_l##width##_user,                                                  \
948
}
949
#define OP_ST_TABLE(width)                                                    \
950
static GenOpFunc *gen_op_s##width[] = {                                       \
951
    &gen_op_s##width##_kernel,                                                \
952
    &gen_op_s##width##_super,                                                 \
953
    &gen_op_s##width##_user,                                                  \
954
}
955
#endif
956

    
957
#if defined(TARGET_MIPS64)
958
OP_LD_TABLE(dl);
959
OP_LD_TABLE(dr);
960
OP_ST_TABLE(dl);
961
OP_ST_TABLE(dr);
962
#endif
963
OP_LD_TABLE(wl);
964
OP_LD_TABLE(wr);
965
OP_ST_TABLE(wl);
966
OP_ST_TABLE(wr);
967
OP_LD_TABLE(wc1);
968
OP_ST_TABLE(wc1);
969
OP_LD_TABLE(dc1);
970
OP_ST_TABLE(dc1);
971
OP_LD_TABLE(uxc1);
972
OP_ST_TABLE(uxc1);
973

    
974
#define OP_LD(insn,fname)                                        \
975
void inline op_ldst_##insn(DisasContext *ctx)                    \
976
{                                                                \
977
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
978
}
979
OP_LD(lb,ld8s);
980
OP_LD(lbu,ld8u);
981
OP_LD(lh,ld16s);
982
OP_LD(lhu,ld16u);
983
OP_LD(lw,ld32s);
984
#if defined(TARGET_MIPS64)
985
OP_LD(lwu,ld32u);
986
OP_LD(ld,ld64);
987
#endif
988
#undef OP_LD
989

    
990
#define OP_ST(insn,fname)                                        \
991
void inline op_ldst_##insn(DisasContext *ctx)                    \
992
{                                                                \
993
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
994
}
995
OP_ST(sb,st8);
996
OP_ST(sh,st16);
997
OP_ST(sw,st32);
998
#if defined(TARGET_MIPS64)
999
OP_ST(sd,st64);
1000
#endif
1001
#undef OP_ST
1002

    
1003
#define OP_LD_ATOMIC(insn,fname)                                        \
1004
void inline op_ldst_##insn(DisasContext *ctx)                           \
1005
{                                                                       \
1006
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
1007
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
1008
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
1009
}
1010
OP_LD_ATOMIC(ll,ld32s);
1011
#if defined(TARGET_MIPS64)
1012
OP_LD_ATOMIC(lld,ld64);
1013
#endif
1014
#undef OP_LD_ATOMIC
1015

    
1016
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
1017
void inline op_ldst_##insn(DisasContext *ctx)                           \
1018
{                                                                       \
1019
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_TL);                             \
1020
    int l1 = gen_new_label();                                           \
1021
    int l2 = gen_new_label();                                           \
1022
    int l3 = gen_new_label();                                           \
1023
                                                                        \
1024
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
1025
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
1026
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
1027
    generate_exception(ctx, EXCP_AdES);                                 \
1028
    gen_set_label(l1);                                                  \
1029
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
1030
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
1031
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
1032
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
1033
    tcg_gen_br(l3);                                                     \
1034
    gen_set_label(l2);                                                  \
1035
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
1036
    gen_set_label(l3);                                                  \
1037
}
1038
OP_ST_ATOMIC(sc,st32,0x3);
1039
#if defined(TARGET_MIPS64)
1040
OP_ST_ATOMIC(scd,st64,0x7);
1041
#endif
1042
#undef OP_ST_ATOMIC
1043

    
1044
void inline op_ldst_lwc1(DisasContext *ctx)
1045
{
1046
    op_ldst(lwc1);
1047
}
1048

    
1049
void inline op_ldst_ldc1(DisasContext *ctx)
1050
{
1051
    op_ldst(ldc1);
1052
}
1053

    
1054
void inline op_ldst_swc1(DisasContext *ctx)
1055
{
1056
    op_ldst(swc1);
1057
}
1058

    
1059
void inline op_ldst_sdc1(DisasContext *ctx)
1060
{
1061
    op_ldst(sdc1);
1062
}
1063

    
1064
/* Load and store */
1065
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1066
                      int base, int16_t offset)
1067
{
1068
    const char *opn = "ldst";
1069

    
1070
    if (base == 0) {
1071
        tcg_gen_movi_tl(cpu_T[0], offset);
1072
    } else if (offset == 0) {
1073
        gen_load_gpr(cpu_T[0], base);
1074
    } else {
1075
        gen_load_gpr(cpu_T[0], base);
1076
        tcg_gen_movi_tl(cpu_T[1], offset);
1077
        gen_op_addr_add();
1078
    }
1079
    /* Don't do NOP if destination is zero: we must perform the actual
1080
       memory access. */
1081
    switch (opc) {
1082
#if defined(TARGET_MIPS64)
1083
    case OPC_LWU:
1084
        op_ldst_lwu(ctx);
1085
        gen_store_gpr(cpu_T[0], rt);
1086
        opn = "lwu";
1087
        break;
1088
    case OPC_LD:
1089
        op_ldst_ld(ctx);
1090
        gen_store_gpr(cpu_T[0], rt);
1091
        opn = "ld";
1092
        break;
1093
    case OPC_LLD:
1094
        op_ldst_lld(ctx);
1095
        gen_store_gpr(cpu_T[0], rt);
1096
        opn = "lld";
1097
        break;
1098
    case OPC_SD:
1099
        gen_load_gpr(cpu_T[1], rt);
1100
        op_ldst_sd(ctx);
1101
        opn = "sd";
1102
        break;
1103
    case OPC_SCD:
1104
        save_cpu_state(ctx, 1);
1105
        gen_load_gpr(cpu_T[1], rt);
1106
        op_ldst_scd(ctx);
1107
        gen_store_gpr(cpu_T[0], rt);
1108
        opn = "scd";
1109
        break;
1110
    case OPC_LDL:
1111
        gen_load_gpr(cpu_T[1], rt);
1112
        op_ldst(ldl);
1113
        gen_store_gpr(cpu_T[1], rt);
1114
        opn = "ldl";
1115
        break;
1116
    case OPC_SDL:
1117
        gen_load_gpr(cpu_T[1], rt);
1118
        op_ldst(sdl);
1119
        opn = "sdl";
1120
        break;
1121
    case OPC_LDR:
1122
        gen_load_gpr(cpu_T[1], rt);
1123
        op_ldst(ldr);
1124
        gen_store_gpr(cpu_T[1], rt);
1125
        opn = "ldr";
1126
        break;
1127
    case OPC_SDR:
1128
        gen_load_gpr(cpu_T[1], rt);
1129
        op_ldst(sdr);
1130
        opn = "sdr";
1131
        break;
1132
#endif
1133
    case OPC_LW:
1134
        op_ldst_lw(ctx);
1135
        gen_store_gpr(cpu_T[0], rt);
1136
        opn = "lw";
1137
        break;
1138
    case OPC_SW:
1139
        gen_load_gpr(cpu_T[1], rt);
1140
        op_ldst_sw(ctx);
1141
        opn = "sw";
1142
        break;
1143
    case OPC_LH:
1144
        op_ldst_lh(ctx);
1145
        gen_store_gpr(cpu_T[0], rt);
1146
        opn = "lh";
1147
        break;
1148
    case OPC_SH:
1149
        gen_load_gpr(cpu_T[1], rt);
1150
        op_ldst_sh(ctx);
1151
        opn = "sh";
1152
        break;
1153
    case OPC_LHU:
1154
        op_ldst_lhu(ctx);
1155
        gen_store_gpr(cpu_T[0], rt);
1156
        opn = "lhu";
1157
        break;
1158
    case OPC_LB:
1159
        op_ldst_lb(ctx);
1160
        gen_store_gpr(cpu_T[0], rt);
1161
        opn = "lb";
1162
        break;
1163
    case OPC_SB:
1164
        gen_load_gpr(cpu_T[1], rt);
1165
        op_ldst_sb(ctx);
1166
        opn = "sb";
1167
        break;
1168
    case OPC_LBU:
1169
        op_ldst_lbu(ctx);
1170
        gen_store_gpr(cpu_T[0], rt);
1171
        opn = "lbu";
1172
        break;
1173
    case OPC_LWL:
1174
        gen_load_gpr(cpu_T[1], rt);
1175
        op_ldst(lwl);
1176
        gen_store_gpr(cpu_T[1], rt);
1177
        opn = "lwl";
1178
        break;
1179
    case OPC_SWL:
1180
        gen_load_gpr(cpu_T[1], rt);
1181
        op_ldst(swl);
1182
        opn = "swr";
1183
        break;
1184
    case OPC_LWR:
1185
        gen_load_gpr(cpu_T[1], rt);
1186
        op_ldst(lwr);
1187
        gen_store_gpr(cpu_T[1], rt);
1188
        opn = "lwr";
1189
        break;
1190
    case OPC_SWR:
1191
        gen_load_gpr(cpu_T[1], rt);
1192
        op_ldst(swr);
1193
        opn = "swr";
1194
        break;
1195
    case OPC_LL:
1196
        op_ldst_ll(ctx);
1197
        gen_store_gpr(cpu_T[0], rt);
1198
        opn = "ll";
1199
        break;
1200
    case OPC_SC:
1201
        save_cpu_state(ctx, 1);
1202
        gen_load_gpr(cpu_T[1], rt);
1203
        op_ldst_sc(ctx);
1204
        gen_store_gpr(cpu_T[0], rt);
1205
        opn = "sc";
1206
        break;
1207
    default:
1208
        MIPS_INVAL(opn);
1209
        generate_exception(ctx, EXCP_RI);
1210
        return;
1211
    }
1212
    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1213
}
1214

    
1215
/* Load and store */
1216
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1217
                      int base, int16_t offset)
1218
{
1219
    const char *opn = "flt_ldst";
1220

    
1221
    if (base == 0) {
1222
        tcg_gen_movi_tl(cpu_T[0], offset);
1223
    } else if (offset == 0) {
1224
        gen_load_gpr(cpu_T[0], base);
1225
    } else {
1226
        gen_load_gpr(cpu_T[0], base);
1227
        tcg_gen_movi_tl(cpu_T[1], offset);
1228
        gen_op_addr_add();
1229
    }
1230
    /* Don't do NOP if destination is zero: we must perform the actual
1231
       memory access. */
1232
    switch (opc) {
1233
    case OPC_LWC1:
1234
        op_ldst_lwc1(ctx);
1235
        GEN_STORE_FTN_FREG(ft, WT0);
1236
        opn = "lwc1";
1237
        break;
1238
    case OPC_SWC1:
1239
        GEN_LOAD_FREG_FTN(WT0, ft);
1240
        op_ldst_swc1(ctx);
1241
        opn = "swc1";
1242
        break;
1243
    case OPC_LDC1:
1244
        op_ldst_ldc1(ctx);
1245
        GEN_STORE_FTN_FREG(ft, DT0);
1246
        opn = "ldc1";
1247
        break;
1248
    case OPC_SDC1:
1249
        GEN_LOAD_FREG_FTN(DT0, ft);
1250
        op_ldst_sdc1(ctx);
1251
        opn = "sdc1";
1252
        break;
1253
    default:
1254
        MIPS_INVAL(opn);
1255
        generate_exception(ctx, EXCP_RI);
1256
        return;
1257
    }
1258
    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1259
}
1260

    
1261
/* Arithmetic with immediate operand */
1262
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1263
                           int rt, int rs, int16_t imm)
1264
{
1265
    target_ulong uimm;
1266
    const char *opn = "imm arith";
1267

    
1268
    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1269
        /* If no destination, treat it as a NOP.
1270
           For addi, we must generate the overflow exception when needed. */
1271
        MIPS_DEBUG("NOP");
1272
        return;
1273
    }
1274
    uimm = (uint16_t)imm;
1275
    switch (opc) {
1276
    case OPC_ADDI:
1277
    case OPC_ADDIU:
1278
#if defined(TARGET_MIPS64)
1279
    case OPC_DADDI:
1280
    case OPC_DADDIU:
1281
#endif
1282
    case OPC_SLTI:
1283
    case OPC_SLTIU:
1284
        uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1285
        tcg_gen_movi_tl(cpu_T[1], uimm);
1286
        /* Fall through. */
1287
    case OPC_ANDI:
1288
    case OPC_ORI:
1289
    case OPC_XORI:
1290
        gen_load_gpr(cpu_T[0], rs);
1291
        break;
1292
    case OPC_LUI:
1293
        tcg_gen_movi_tl(cpu_T[0], imm << 16);
1294
        break;
1295
    case OPC_SLL:
1296
    case OPC_SRA:
1297
    case OPC_SRL:
1298
#if defined(TARGET_MIPS64)
1299
    case OPC_DSLL:
1300
    case OPC_DSRA:
1301
    case OPC_DSRL:
1302
    case OPC_DSLL32:
1303
    case OPC_DSRA32:
1304
    case OPC_DSRL32:
1305
#endif
1306
        uimm &= 0x1f;
1307
        gen_load_gpr(cpu_T[0], rs);
1308
        break;
1309
    }
1310
    switch (opc) {
1311
    case OPC_ADDI:
1312
        {
1313
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1314
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1315
            int l1 = gen_new_label();
1316

    
1317
            save_cpu_state(ctx, 1);
1318
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1319
            tcg_gen_addi_tl(cpu_T[0], r_tmp1, uimm);
1320

    
1321
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1322
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1323
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1324
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1325
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1326
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1327
            /* operands of same sign, result different sign */
1328
            generate_exception(ctx, EXCP_OVERFLOW);
1329
            gen_set_label(l1);
1330

    
1331
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1332
        }
1333
        opn = "addi";
1334
        break;
1335
    case OPC_ADDIU:
1336
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1337
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1338
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1339
        opn = "addiu";
1340
        break;
1341
#if defined(TARGET_MIPS64)
1342
    case OPC_DADDI:
1343
        {
1344
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1345
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1346
            int l1 = gen_new_label();
1347

    
1348
            save_cpu_state(ctx, 1);
1349
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1350
            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1351

    
1352
            tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm);
1353
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1354
            tcg_gen_xori_tl(r_tmp2, cpu_T[0], uimm);
1355
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1356
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1357
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1358
            /* operands of same sign, result different sign */
1359
            generate_exception(ctx, EXCP_OVERFLOW);
1360
            gen_set_label(l1);
1361
        }
1362
        opn = "daddi";
1363
        break;
1364
    case OPC_DADDIU:
1365
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], uimm);
1366
        opn = "daddiu";
1367
        break;
1368
#endif
1369
    case OPC_SLTI:
1370
        gen_op_lti(uimm);
1371
        opn = "slti";
1372
        break;
1373
    case OPC_SLTIU:
1374
        gen_op_ltiu(uimm);
1375
        opn = "sltiu";
1376
        break;
1377
    case OPC_ANDI:
1378
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], uimm);
1379
        opn = "andi";
1380
        break;
1381
    case OPC_ORI:
1382
        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], uimm);
1383
        opn = "ori";
1384
        break;
1385
    case OPC_XORI:
1386
        tcg_gen_xori_tl(cpu_T[0], cpu_T[0], uimm);
1387
        opn = "xori";
1388
        break;
1389
    case OPC_LUI:
1390
        opn = "lui";
1391
        break;
1392
    case OPC_SLL:
1393
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1394
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1395
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1396
        opn = "sll";
1397
        break;
1398
    case OPC_SRA:
1399
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1400
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1401
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1402
        opn = "sra";
1403
        break;
1404
    case OPC_SRL:
1405
        switch ((ctx->opcode >> 21) & 0x1f) {
1406
        case 0:
1407
            tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1408
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1409
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1410
            opn = "srl";
1411
            break;
1412
        case 1:
1413
            /* rotr is decoded as srl on non-R2 CPUs */
1414
            if (env->insn_flags & ISA_MIPS32R2) {
1415
                if (uimm != 0) {
1416
                    TCGv r_tmp1 = new_tmp();
1417
                    TCGv r_tmp2 = new_tmp();
1418

    
1419
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1420
                    tcg_gen_movi_i32(r_tmp2, 0x20);
1421
                    tcg_gen_subi_i32(r_tmp2, r_tmp2, uimm);
1422
                    tcg_gen_shl_i32(r_tmp2, r_tmp1, r_tmp2);
1423
                    tcg_gen_shri_i32(r_tmp1, r_tmp1, uimm);
1424
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp2);
1425
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1426
                    dead_tmp(r_tmp1);
1427
                    dead_tmp(r_tmp2);
1428
                }
1429
                opn = "rotr";
1430
            } else {
1431
                tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1432
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1433
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1434
                opn = "srl";
1435
            }
1436
            break;
1437
        default:
1438
            MIPS_INVAL("invalid srl flag");
1439
            generate_exception(ctx, EXCP_RI);
1440
            break;
1441
        }
1442
        break;
1443
#if defined(TARGET_MIPS64)
1444
    case OPC_DSLL:
1445
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm);
1446
        opn = "dsll";
1447
        break;
1448
    case OPC_DSRA:
1449
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm);
1450
        opn = "dsra";
1451
        break;
1452
    case OPC_DSRL:
1453
        switch ((ctx->opcode >> 21) & 0x1f) {
1454
        case 0:
1455
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1456
            opn = "dsrl";
1457
            break;
1458
        case 1:
1459
            /* drotr is decoded as dsrl on non-R2 CPUs */
1460
            if (env->insn_flags & ISA_MIPS32R2) {
1461
                if (uimm != 0) {
1462
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1463

    
1464
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1465
                    tcg_gen_subi_tl(r_tmp1, r_tmp1, uimm);
1466
                    tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1467
                    tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1468
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1469
                }
1470
                opn = "drotr";
1471
            } else {
1472
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm);
1473
                opn = "dsrl";
1474
            }
1475
            break;
1476
        default:
1477
            MIPS_INVAL("invalid dsrl flag");
1478
            generate_exception(ctx, EXCP_RI);
1479
            break;
1480
        }
1481
        break;
1482
    case OPC_DSLL32:
1483
        tcg_gen_shli_tl(cpu_T[0], cpu_T[0], uimm + 32);
1484
        opn = "dsll32";
1485
        break;
1486
    case OPC_DSRA32:
1487
        tcg_gen_sari_tl(cpu_T[0], cpu_T[0], uimm + 32);
1488
        opn = "dsra32";
1489
        break;
1490
    case OPC_DSRL32:
1491
        switch ((ctx->opcode >> 21) & 0x1f) {
1492
        case 0:
1493
            tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1494
            opn = "dsrl32";
1495
            break;
1496
        case 1:
1497
            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1498
            if (env->insn_flags & ISA_MIPS32R2) {
1499
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1500
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1501

    
1502
                tcg_gen_movi_tl(r_tmp1, 0x40);
1503
                tcg_gen_movi_tl(r_tmp2, 32);
1504
                tcg_gen_addi_tl(r_tmp2, r_tmp2, uimm);
1505
                tcg_gen_sub_tl(r_tmp1, r_tmp1, r_tmp2);
1506
                tcg_gen_shl_tl(r_tmp1, cpu_T[0], r_tmp1);
1507
                tcg_gen_shr_tl(cpu_T[0], cpu_T[0], r_tmp2);
1508
                tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1509
                opn = "drotr32";
1510
            } else {
1511
                tcg_gen_shri_tl(cpu_T[0], cpu_T[0], uimm + 32);
1512
                opn = "dsrl32";
1513
            }
1514
            break;
1515
        default:
1516
            MIPS_INVAL("invalid dsrl32 flag");
1517
            generate_exception(ctx, EXCP_RI);
1518
            break;
1519
        }
1520
        break;
1521
#endif
1522
    default:
1523
        MIPS_INVAL(opn);
1524
        generate_exception(ctx, EXCP_RI);
1525
        return;
1526
    }
1527
    gen_store_gpr(cpu_T[0], rt);
1528
    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1529
}
1530

    
1531
/* Arithmetic */
1532
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1533
                       int rd, int rs, int rt)
1534
{
1535
    const char *opn = "arith";
1536

    
1537
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1538
       && opc != OPC_DADD && opc != OPC_DSUB) {
1539
        /* If no destination, treat it as a NOP.
1540
           For add & sub, we must generate the overflow exception when needed. */
1541
        MIPS_DEBUG("NOP");
1542
        return;
1543
    }
1544
    gen_load_gpr(cpu_T[0], rs);
1545
    /* Specialcase the conventional move operation. */
1546
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1547
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1548
        gen_store_gpr(cpu_T[0], rd);
1549
        return;
1550
    }
1551
    gen_load_gpr(cpu_T[1], rt);
1552
    switch (opc) {
1553
    case OPC_ADD:
1554
        {
1555
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1556
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1557
            int l1 = gen_new_label();
1558

    
1559
            save_cpu_state(ctx, 1);
1560
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1561
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1562
            tcg_gen_add_tl(cpu_T[0], r_tmp1, r_tmp2);
1563

    
1564
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1565
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1566
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1567
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1568
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1569
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1570
            /* operands of same sign, result different sign */
1571
            generate_exception(ctx, EXCP_OVERFLOW);
1572
            gen_set_label(l1);
1573

    
1574
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1575
        }
1576
        opn = "add";
1577
        break;
1578
    case OPC_ADDU:
1579
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1580
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1581
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1582
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1583
        opn = "addu";
1584
        break;
1585
    case OPC_SUB:
1586
        {
1587
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1588
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1589
            int l1 = gen_new_label();
1590

    
1591
            save_cpu_state(ctx, 1);
1592
            tcg_gen_ext32s_tl(r_tmp1, cpu_T[0]);
1593
            tcg_gen_ext32s_tl(r_tmp2, cpu_T[1]);
1594
            tcg_gen_sub_tl(cpu_T[0], r_tmp1, r_tmp2);
1595

    
1596
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1597
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1598
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1599
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 31);
1600
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1601
            /* operands of different sign, first operand and result different sign */
1602
            generate_exception(ctx, EXCP_OVERFLOW);
1603
            gen_set_label(l1);
1604

    
1605
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1606
        }
1607
        opn = "sub";
1608
        break;
1609
    case OPC_SUBU:
1610
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1611
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1612
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1613
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1614
        opn = "subu";
1615
        break;
1616
#if defined(TARGET_MIPS64)
1617
    case OPC_DADD:
1618
        {
1619
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1620
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1621
            int l1 = gen_new_label();
1622

    
1623
            save_cpu_state(ctx, 1);
1624
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1625
            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1626

    
1627
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[1]);
1628
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1629
            tcg_gen_xor_tl(r_tmp2, cpu_T[0], cpu_T[1]);
1630
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1631
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1632
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1633
            /* operands of same sign, result different sign */
1634
            generate_exception(ctx, EXCP_OVERFLOW);
1635
            gen_set_label(l1);
1636
        }
1637
        opn = "dadd";
1638
        break;
1639
    case OPC_DADDU:
1640
        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1641
        opn = "daddu";
1642
        break;
1643
    case OPC_DSUB:
1644
        {
1645
            TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1646
            TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1647
            int l1 = gen_new_label();
1648

    
1649
            save_cpu_state(ctx, 1);
1650
            tcg_gen_mov_tl(r_tmp1, cpu_T[0]);
1651
            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1652

    
1653
            tcg_gen_xor_tl(r_tmp2, r_tmp1, cpu_T[1]);
1654
            tcg_gen_xor_tl(r_tmp1, r_tmp1, cpu_T[0]);
1655
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1656
            tcg_gen_shri_tl(r_tmp1, r_tmp1, 63);
1657
            tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1);
1658
            /* operands of different sign, first operand and result different sign */
1659
            generate_exception(ctx, EXCP_OVERFLOW);
1660
            gen_set_label(l1);
1661
        }
1662
        opn = "dsub";
1663
        break;
1664
    case OPC_DSUBU:
1665
        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1666
        opn = "dsubu";
1667
        break;
1668
#endif
1669
    case OPC_SLT:
1670
        gen_op_lt();
1671
        opn = "slt";
1672
        break;
1673
    case OPC_SLTU:
1674
        gen_op_ltu();
1675
        opn = "sltu";
1676
        break;
1677
    case OPC_AND:
1678
        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1679
        opn = "and";
1680
        break;
1681
    case OPC_NOR:
1682
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1683
        tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
1684
        opn = "nor";
1685
        break;
1686
    case OPC_OR:
1687
        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1688
        opn = "or";
1689
        break;
1690
    case OPC_XOR:
1691
        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1692
        opn = "xor";
1693
        break;
1694
    case OPC_MUL:
1695
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1696
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1697
        tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1698
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1699
        opn = "mul";
1700
        break;
1701
    case OPC_MOVN:
1702
        {
1703
            int l1 = gen_new_label();
1704

    
1705
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1706
            gen_store_gpr(cpu_T[0], rd);
1707
            gen_set_label(l1);
1708
        }
1709
        opn = "movn";
1710
        goto print;
1711
    case OPC_MOVZ:
1712
        {
1713
            int l1 = gen_new_label();
1714

    
1715
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], 0, l1);
1716
            gen_store_gpr(cpu_T[0], rd);
1717
            gen_set_label(l1);
1718
        }
1719
        opn = "movz";
1720
        goto print;
1721
    case OPC_SLLV:
1722
        tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
1723
        tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1724
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1725
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1726
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1727
        opn = "sllv";
1728
        break;
1729
    case OPC_SRAV:
1730
        tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1731
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1732
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1733
        tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1734
        opn = "srav";
1735
        break;
1736
    case OPC_SRLV:
1737
        switch ((ctx->opcode >> 6) & 0x1f) {
1738
        case 0:
1739
            tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1740
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1741
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1742
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1743
            opn = "srlv";
1744
            break;
1745
        case 1:
1746
            /* rotrv is decoded as srlv on non-R2 CPUs */
1747
            if (env->insn_flags & ISA_MIPS32R2) {
1748
                int l1 = gen_new_label();
1749
                int l2 = gen_new_label();
1750

    
1751
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1752
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1753
                {
1754
                    TCGv r_tmp1 = new_tmp();
1755
                    TCGv r_tmp2 = new_tmp();
1756
                    TCGv r_tmp3 = new_tmp();
1757

    
1758
                    tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1759
                    tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1760
                    tcg_gen_movi_i32(r_tmp3, 0x20);
1761
                    tcg_gen_sub_i32(r_tmp3, r_tmp3, r_tmp1);
1762
                    tcg_gen_shl_i32(r_tmp3, r_tmp2, r_tmp3);
1763
                    tcg_gen_shr_i32(r_tmp1, r_tmp2, r_tmp1);
1764
                    tcg_gen_or_i32(r_tmp1, r_tmp1, r_tmp3);
1765
                    tcg_gen_ext_i32_tl(r_tmp1, cpu_T[0]);
1766
                    dead_tmp(r_tmp1);
1767
                    dead_tmp(r_tmp2);
1768
                    dead_tmp(r_tmp3);
1769
                    tcg_gen_br(l2);
1770
                }
1771
                gen_set_label(l1);
1772
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1773
                gen_set_label(l2);
1774
                opn = "rotrv";
1775
            } else {
1776
                tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
1777
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x1f);
1778
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1779
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1780
                opn = "srlv";
1781
            }
1782
            break;
1783
        default:
1784
            MIPS_INVAL("invalid srlv flag");
1785
            generate_exception(ctx, EXCP_RI);
1786
            break;
1787
        }
1788
        break;
1789
#if defined(TARGET_MIPS64)
1790
    case OPC_DSLLV:
1791
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1792
        tcg_gen_shl_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1793
        opn = "dsllv";
1794
        break;
1795
    case OPC_DSRAV:
1796
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1797
        tcg_gen_sar_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1798
        opn = "dsrav";
1799
        break;
1800
    case OPC_DSRLV:
1801
        switch ((ctx->opcode >> 6) & 0x1f) {
1802
        case 0:
1803
            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1804
            tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1805
            opn = "dsrlv";
1806
            break;
1807
        case 1:
1808
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1809
            if (env->insn_flags & ISA_MIPS32R2) {
1810
                int l1 = gen_new_label();
1811
                int l2 = gen_new_label();
1812

    
1813
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1814
                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1);
1815
                {
1816
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL);
1817

    
1818
                    tcg_gen_movi_tl(r_tmp1, 0x40);
1819
                    tcg_gen_sub_tl(r_tmp1, r_tmp1, cpu_T[0]);
1820
                    tcg_gen_shl_tl(r_tmp1, cpu_T[1], r_tmp1);
1821
                    tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1822
                    tcg_gen_or_tl(cpu_T[0], cpu_T[0], r_tmp1);
1823
                    tcg_gen_br(l2);
1824
                }
1825
                gen_set_label(l1);
1826
                tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
1827
                gen_set_label(l2);
1828
                opn = "drotrv";
1829
            } else {
1830
                tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x3f);
1831
                tcg_gen_shr_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
1832
                opn = "dsrlv";
1833
            }
1834
            break;
1835
        default:
1836
            MIPS_INVAL("invalid dsrlv flag");
1837
            generate_exception(ctx, EXCP_RI);
1838
            break;
1839
        }
1840
        break;
1841
#endif
1842
    default:
1843
        MIPS_INVAL(opn);
1844
        generate_exception(ctx, EXCP_RI);
1845
        return;
1846
    }
1847
    gen_store_gpr(cpu_T[0], rd);
1848
 print:
1849
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1850
}
1851

    
1852
/* Arithmetic on HI/LO registers */
1853
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1854
{
1855
    const char *opn = "hilo";
1856

    
1857
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1858
        /* Treat as NOP. */
1859
        MIPS_DEBUG("NOP");
1860
        return;
1861
    }
1862
    switch (opc) {
1863
    case OPC_MFHI:
1864
        gen_load_HI(cpu_T[0], 0);
1865
        gen_store_gpr(cpu_T[0], reg);
1866
        opn = "mfhi";
1867
        break;
1868
    case OPC_MFLO:
1869
        gen_load_LO(cpu_T[0], 0);
1870
        gen_store_gpr(cpu_T[0], reg);
1871
        opn = "mflo";
1872
        break;
1873
    case OPC_MTHI:
1874
        gen_load_gpr(cpu_T[0], reg);
1875
        gen_store_HI(cpu_T[0], 0);
1876
        opn = "mthi";
1877
        break;
1878
    case OPC_MTLO:
1879
        gen_load_gpr(cpu_T[0], reg);
1880
        gen_store_LO(cpu_T[0], 0);
1881
        opn = "mtlo";
1882
        break;
1883
    default:
1884
        MIPS_INVAL(opn);
1885
        generate_exception(ctx, EXCP_RI);
1886
        return;
1887
    }
1888
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
1889
}
1890

    
1891
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1892
                        int rs, int rt)
1893
{
1894
    const char *opn = "mul/div";
1895

    
1896
    gen_load_gpr(cpu_T[0], rs);
1897
    gen_load_gpr(cpu_T[1], rt);
1898
    switch (opc) {
1899
    case OPC_DIV:
1900
        {
1901
            int l1 = gen_new_label();
1902

    
1903
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1904
            {
1905
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1906
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1907

    
1908
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1909
                tcg_gen_ext32s_tl(cpu_T[1], cpu_T[1]);
1910
                tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1911
                tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1912
                tcg_gen_ext32s_tl(r_tmp1, r_tmp1);
1913
                tcg_gen_ext32s_tl(r_tmp2, r_tmp2);
1914
                gen_store_LO(r_tmp1, 0);
1915
                gen_store_HI(r_tmp2, 0);
1916
            }
1917
            gen_set_label(l1);
1918
        }
1919
        opn = "div";
1920
        break;
1921
    case OPC_DIVU:
1922
        {
1923
            int l1 = gen_new_label();
1924

    
1925
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1926
            {
1927
                TCGv r_tmp1 = new_tmp();
1928
                TCGv r_tmp2 = new_tmp();
1929
                TCGv r_tmp3 = new_tmp();
1930

    
1931
                tcg_gen_trunc_tl_i32(r_tmp1, cpu_T[0]);
1932
                tcg_gen_trunc_tl_i32(r_tmp2, cpu_T[1]);
1933
                tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1934
                tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1935
                tcg_gen_ext_i32_tl(cpu_T[0], r_tmp3);
1936
                tcg_gen_ext_i32_tl(cpu_T[1], r_tmp1);
1937
                gen_store_LO(cpu_T[0], 0);
1938
                gen_store_HI(cpu_T[1], 0);
1939
                dead_tmp(r_tmp1);
1940
                dead_tmp(r_tmp2);
1941
                dead_tmp(r_tmp3);
1942
            }
1943
            gen_set_label(l1);
1944
        }
1945
        opn = "divu";
1946
        break;
1947
    case OPC_MULT:
1948
        gen_op_mult();
1949
        opn = "mult";
1950
        break;
1951
    case OPC_MULTU:
1952
        gen_op_multu();
1953
        opn = "multu";
1954
        break;
1955
#if defined(TARGET_MIPS64)
1956
    case OPC_DDIV:
1957
        {
1958
            int l1 = gen_new_label();
1959

    
1960
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1961
            {
1962
                int l2 = gen_new_label();
1963

    
1964
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 1ULL << 63, l2);
1965
                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[1], -1ULL, l2);
1966
                {
1967
                    tcg_gen_movi_tl(cpu_T[1], 0);
1968
                    gen_store_LO(cpu_T[0], 0);
1969
                    gen_store_HI(cpu_T[1], 0);
1970
                    tcg_gen_br(l1);
1971
                }
1972
                gen_set_label(l2);
1973
                {
1974
                    TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1975
                    TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1976

    
1977
                    tcg_gen_div_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1978
                    tcg_gen_rem_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1979
                    gen_store_LO(r_tmp1, 0);
1980
                    gen_store_HI(r_tmp2, 0);
1981
                }
1982
            }
1983
            gen_set_label(l1);
1984
        }
1985
        opn = "ddiv";
1986
        break;
1987
    case OPC_DDIVU:
1988
        {
1989
            int l1 = gen_new_label();
1990

    
1991
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[1], 0, l1);
1992
            {
1993
                TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I64);
1994
                TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I64);
1995

    
1996
                tcg_gen_divu_i64(r_tmp1, cpu_T[0], cpu_T[1]);
1997
                tcg_gen_remu_i64(r_tmp2, cpu_T[0], cpu_T[1]);
1998
                gen_store_LO(r_tmp1, 0);
1999
                gen_store_HI(r_tmp2, 0);
2000
            }
2001
            gen_set_label(l1);
2002
        }
2003
        opn = "ddivu";
2004
        break;
2005
    case OPC_DMULT:
2006
        gen_op_dmult();
2007
        opn = "dmult";
2008
        break;
2009
    case OPC_DMULTU:
2010
        gen_op_dmultu();
2011
        opn = "dmultu";
2012
        break;
2013
#endif
2014
    case OPC_MADD:
2015
        gen_op_madd();
2016
        opn = "madd";
2017
        break;
2018
    case OPC_MADDU:
2019
        gen_op_maddu();
2020
        opn = "maddu";
2021
        break;
2022
    case OPC_MSUB:
2023
        gen_op_msub();
2024
        opn = "msub";
2025
        break;
2026
    case OPC_MSUBU:
2027
        gen_op_msubu();
2028
        opn = "msubu";
2029
        break;
2030
    default:
2031
        MIPS_INVAL(opn);
2032
        generate_exception(ctx, EXCP_RI);
2033
        return;
2034
    }
2035
    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2036
}
2037

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

    
2043
    gen_load_gpr(cpu_T[0], rs);
2044
    gen_load_gpr(cpu_T[1], rt);
2045

    
2046
    switch (opc) {
2047
    case OPC_VR54XX_MULS:
2048
        gen_op_muls();
2049
        opn = "muls";
2050
        break;
2051
    case OPC_VR54XX_MULSU:
2052
        gen_op_mulsu();
2053
        opn = "mulsu";
2054
        break;
2055
    case OPC_VR54XX_MACC:
2056
        gen_op_macc();
2057
        opn = "macc";
2058
        break;
2059
    case OPC_VR54XX_MACCU:
2060
        gen_op_maccu();
2061
        opn = "maccu";
2062
        break;
2063
    case OPC_VR54XX_MSAC:
2064
        gen_op_msac();
2065
        opn = "msac";
2066
        break;
2067
    case OPC_VR54XX_MSACU:
2068
        gen_op_msacu();
2069
        opn = "msacu";
2070
        break;
2071
    case OPC_VR54XX_MULHI:
2072
        gen_op_mulhi();
2073
        opn = "mulhi";
2074
        break;
2075
    case OPC_VR54XX_MULHIU:
2076
        gen_op_mulhiu();
2077
        opn = "mulhiu";
2078
        break;
2079
    case OPC_VR54XX_MULSHI:
2080
        gen_op_mulshi();
2081
        opn = "mulshi";
2082
        break;
2083
    case OPC_VR54XX_MULSHIU:
2084
        gen_op_mulshiu();
2085
        opn = "mulshiu";
2086
        break;
2087
    case OPC_VR54XX_MACCHI:
2088
        gen_op_macchi();
2089
        opn = "macchi";
2090
        break;
2091
    case OPC_VR54XX_MACCHIU:
2092
        gen_op_macchiu();
2093
        opn = "macchiu";
2094
        break;
2095
    case OPC_VR54XX_MSACHI:
2096
        gen_op_msachi();
2097
        opn = "msachi";
2098
        break;
2099
    case OPC_VR54XX_MSACHIU:
2100
        gen_op_msachiu();
2101
        opn = "msachiu";
2102
        break;
2103
    default:
2104
        MIPS_INVAL("mul vr54xx");
2105
        generate_exception(ctx, EXCP_RI);
2106
        return;
2107
    }
2108
    gen_store_gpr(cpu_T[0], rd);
2109
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2110
}
2111

    
2112
static void gen_cl (DisasContext *ctx, uint32_t opc,
2113
                    int rd, int rs)
2114
{
2115
    const char *opn = "CLx";
2116
    if (rd == 0) {
2117
        /* Treat as NOP. */
2118
        MIPS_DEBUG("NOP");
2119
        return;
2120
    }
2121
    gen_load_gpr(cpu_T[0], rs);
2122
    switch (opc) {
2123
    case OPC_CLO:
2124
        tcg_gen_helper_0_0(do_clo);
2125
        opn = "clo";
2126
        break;
2127
    case OPC_CLZ:
2128
        tcg_gen_helper_0_0(do_clz);
2129
        opn = "clz";
2130
        break;
2131
#if defined(TARGET_MIPS64)
2132
    case OPC_DCLO:
2133
        tcg_gen_helper_0_0(do_dclo);
2134
        opn = "dclo";
2135
        break;
2136
    case OPC_DCLZ:
2137
        tcg_gen_helper_0_0(do_dclz);
2138
        opn = "dclz";
2139
        break;
2140
#endif
2141
    default:
2142
        MIPS_INVAL(opn);
2143
        generate_exception(ctx, EXCP_RI);
2144
        return;
2145
    }
2146
    gen_store_gpr(cpu_T[0], rd);
2147
    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2148
}
2149

    
2150
/* Traps */
2151
static void gen_trap (DisasContext *ctx, uint32_t opc,
2152
                      int rs, int rt, int16_t imm)
2153
{
2154
    int cond;
2155

    
2156
    cond = 0;
2157
    /* Load needed operands */
2158
    switch (opc) {
2159
    case OPC_TEQ:
2160
    case OPC_TGE:
2161
    case OPC_TGEU:
2162
    case OPC_TLT:
2163
    case OPC_TLTU:
2164
    case OPC_TNE:
2165
        /* Compare two registers */
2166
        if (rs != rt) {
2167
            gen_load_gpr(cpu_T[0], rs);
2168
            gen_load_gpr(cpu_T[1], rt);
2169
            cond = 1;
2170
        }
2171
        break;
2172
    case OPC_TEQI:
2173
    case OPC_TGEI:
2174
    case OPC_TGEIU:
2175
    case OPC_TLTI:
2176
    case OPC_TLTIU:
2177
    case OPC_TNEI:
2178
        /* Compare register to immediate */
2179
        if (rs != 0 || imm != 0) {
2180
            gen_load_gpr(cpu_T[0], rs);
2181
            tcg_gen_movi_tl(cpu_T[1], (int32_t)imm);
2182
            cond = 1;
2183
        }
2184
        break;
2185
    }
2186
    if (cond == 0) {
2187
        switch (opc) {
2188
        case OPC_TEQ:   /* rs == rs */
2189
        case OPC_TEQI:  /* r0 == 0  */
2190
        case OPC_TGE:   /* rs >= rs */
2191
        case OPC_TGEI:  /* r0 >= 0  */
2192
        case OPC_TGEU:  /* rs >= rs unsigned */
2193
        case OPC_TGEIU: /* r0 >= 0  unsigned */
2194
            /* Always trap */
2195
            tcg_gen_movi_tl(cpu_T[0], 1);
2196
            break;
2197
        case OPC_TLT:   /* rs < rs           */
2198
        case OPC_TLTI:  /* r0 < 0            */
2199
        case OPC_TLTU:  /* rs < rs unsigned  */
2200
        case OPC_TLTIU: /* r0 < 0  unsigned  */
2201
        case OPC_TNE:   /* rs != rs          */
2202
        case OPC_TNEI:  /* r0 != 0           */
2203
            /* Never trap: treat as NOP. */
2204
            return;
2205
        default:
2206
            MIPS_INVAL("trap");
2207
            generate_exception(ctx, EXCP_RI);
2208
            return;
2209
        }
2210
    } else {
2211
        switch (opc) {
2212
        case OPC_TEQ:
2213
        case OPC_TEQI:
2214
            gen_op_eq();
2215
            break;
2216
        case OPC_TGE:
2217
        case OPC_TGEI:
2218
            gen_op_ge();
2219
            break;
2220
        case OPC_TGEU:
2221
        case OPC_TGEIU:
2222
            gen_op_geu();
2223
            break;
2224
        case OPC_TLT:
2225
        case OPC_TLTI:
2226
            gen_op_lt();
2227
            break;
2228
        case OPC_TLTU:
2229
        case OPC_TLTIU:
2230
            gen_op_ltu();
2231
            break;
2232
        case OPC_TNE:
2233
        case OPC_TNEI:
2234
            gen_op_ne();
2235
            break;
2236
        default:
2237
            MIPS_INVAL("trap");
2238
            generate_exception(ctx, EXCP_RI);
2239
            return;
2240
        }
2241
    }
2242
    save_cpu_state(ctx, 1);
2243
    gen_op_trap();
2244
    ctx->bstate = BS_STOP;
2245
}
2246

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

    
2261
/* Branches (before delay slot) */
2262
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2263
                                int rs, int rt, int32_t offset)
2264
{
2265
    target_ulong btarget = -1;
2266
    int blink = 0;
2267
    int bcond = 0;
2268

    
2269
    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2270
#ifdef MIPS_DEBUG_DISAS
2271
        if (loglevel & CPU_LOG_TB_IN_ASM) {
2272
            fprintf(logfile,
2273
                    "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
2274
                    ctx->pc);
2275
        }
2276
#endif
2277
        generate_exception(ctx, EXCP_RI);
2278
        return;
2279
    }
2280

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

    
2493
    ctx->btarget = btarget;
2494
    if (blink > 0) {
2495
        tcg_gen_movi_tl(cpu_T[0], ctx->pc + 8);
2496
        gen_store_gpr(cpu_T[0], blink);
2497
    }
2498
}
2499

    
2500
/* special3 bitfield operations */
2501
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2502
                       int rs, int lsb, int msb)
2503
{
2504
    gen_load_gpr(cpu_T[1], rs);
2505
    switch (opc) {
2506
    case OPC_EXT:
2507
        if (lsb + msb > 31)
2508
            goto fail;
2509
        gen_op_ext(lsb, msb + 1);
2510
        break;
2511
#if defined(TARGET_MIPS64)
2512
    case OPC_DEXTM:
2513
        if (lsb + msb > 63)
2514
            goto fail;
2515
        gen_op_dext(lsb, msb + 1 + 32);
2516
        break;
2517
    case OPC_DEXTU:
2518
        if (lsb + msb > 63)
2519
            goto fail;
2520
        gen_op_dext(lsb + 32, msb + 1);
2521
        break;
2522
    case OPC_DEXT:
2523
        if (lsb + msb > 63)
2524
            goto fail;
2525
        gen_op_dext(lsb, msb + 1);
2526
        break;
2527
#endif
2528
    case OPC_INS:
2529
        if (lsb > msb)
2530
            goto fail;
2531
        gen_load_gpr(cpu_T[0], rt);
2532
        gen_op_ins(lsb, msb - lsb + 1);
2533
        break;
2534
#if defined(TARGET_MIPS64)
2535
    case OPC_DINSM:
2536
        if (lsb > msb)
2537
            goto fail;
2538
        gen_load_gpr(cpu_T[0], rt);
2539
        gen_op_dins(lsb, msb - lsb + 1 + 32);
2540
        break;
2541
    case OPC_DINSU:
2542
        if (lsb > msb)
2543
            goto fail;
2544
        gen_load_gpr(cpu_T[0], rt);
2545
        gen_op_dins(lsb + 32, msb - lsb + 1);
2546
        break;
2547
    case OPC_DINS:
2548
        if (lsb > msb)
2549
            goto fail;
2550
        gen_load_gpr(cpu_T[0], rt);
2551
        gen_op_dins(lsb, msb - lsb + 1);
2552
        break;
2553
#endif
2554
    default:
2555
fail:
2556
        MIPS_INVAL("bitops");
2557
        generate_exception(ctx, EXCP_RI);
2558
        return;
2559
    }
2560
    gen_store_gpr(cpu_T[0], rt);
2561
}
2562

    
2563
/* CP0 (MMU and control) */
2564
static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
2565
{
2566
    const char *rn = "invalid";
2567
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
2568
    TCGv r_tmp64 = tcg_temp_new(TCG_TYPE_I64);
2569

    
2570
    if (sel != 0)
2571
        check_insn(env, ctx, ISA_MIPS32);
2572

    
2573
    switch (reg) {
2574
    case 0:
2575
        switch (sel) {
2576
        case 0:
2577
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
2578
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2579
            rn = "Index";
2580
            break;
2581
        case 1:
2582
            check_insn(env, ctx, ASE_MT);
2583
            gen_op_mfc0_mvpcontrol();
2584
            rn = "MVPControl";
2585
            break;
2586
        case 2:
2587
            check_insn(env, ctx, ASE_MT);
2588
            gen_op_mfc0_mvpconf0();
2589
            rn = "MVPConf0";
2590
            break;
2591
        case 3:
2592
            check_insn(env, ctx, ASE_MT);
2593
            gen_op_mfc0_mvpconf1();
2594
            rn = "MVPConf1";
2595
            break;
2596
        default:
2597
            goto die;
2598
        }
2599
        break;
2600
    case 1:
2601
        switch (sel) {
2602
        case 0:
2603
            gen_op_mfc0_random();
2604
            rn = "Random";
2605
            break;
2606
        case 1:
2607
            check_insn(env, ctx, ASE_MT);
2608
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
2609
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2610
            rn = "VPEControl";
2611
            break;
2612
        case 2:
2613
            check_insn(env, ctx, ASE_MT);
2614
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
2615
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2616
            rn = "VPEConf0";
2617
            break;
2618
        case 3:
2619
            check_insn(env, ctx, ASE_MT);
2620
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
2621
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2622
            rn = "VPEConf1";
2623
            break;
2624
        case 4:
2625
            check_insn(env, ctx, ASE_MT);
2626
            tcg_gen_ld_i64(r_tmp64, cpu_env, offsetof(CPUState, CP0_YQMask));
2627
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2628
            rn = "YQMask";
2629
            break;
2630
        case 5:
2631
            check_insn(env, ctx, ASE_MT);
2632
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPESchedule));
2633
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2634
            rn = "VPESchedule";
2635
            break;
2636
        case 6:
2637
            check_insn(env, ctx, ASE_MT);
2638
            tcg_gen_ld_tl(r_tmp64, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
2639
            tcg_gen_trunc_i64_tl(cpu_T[0], r_tmp64);
2640
            rn = "VPEScheFBack";
2641
            break;
2642
        case 7:
2643
            check_insn(env, ctx, ASE_MT);
2644
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
2645
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2646
            rn = "VPEOpt";
2647
            break;
2648
        default:
2649
            goto die;
2650
        }
2651
        break;
2652
    case 2:
2653
        switch (sel) {
2654
        case 0:
2655
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
2656
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2657
            rn = "EntryLo0";
2658
            break;
2659
        case 1:
2660
            check_insn(env, ctx, ASE_MT);
2661
            gen_op_mfc0_tcstatus();
2662
            rn = "TCStatus";
2663
            break;
2664
        case 2:
2665
            check_insn(env, ctx, ASE_MT);
2666
            gen_op_mfc0_tcbind();
2667
            rn = "TCBind";
2668
            break;
2669
        case 3:
2670
            check_insn(env, ctx, ASE_MT);
2671
            gen_op_mfc0_tcrestart();
2672
            rn = "TCRestart";
2673
            break;
2674
        case 4:
2675
            check_insn(env, ctx, ASE_MT);
2676
            gen_op_mfc0_tchalt();
2677
            rn = "TCHalt";
2678
            break;
2679
        case 5:
2680
            check_insn(env, ctx, ASE_MT);
2681
            gen_op_mfc0_tccontext();
2682
            rn = "TCContext";
2683
            break;
2684
        case 6:
2685
            check_insn(env, ctx, ASE_MT);
2686
            gen_op_mfc0_tcschedule();
2687
            rn = "TCSchedule";
2688
            break;
2689
        case 7:
2690
            check_insn(env, ctx, ASE_MT);
2691
            gen_op_mfc0_tcschefback();
2692
            rn = "TCScheFBack";
2693
            break;
2694
        default:
2695
            goto die;
2696
        }
2697
        break;
2698
    case 3:
2699
        switch (sel) {
2700
        case 0:
2701
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
2702
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2703
            rn = "EntryLo1";
2704
            break;
2705
        default:
2706
            goto die;
2707
        }
2708
        break;
2709
    case 4:
2710
        switch (sel) {
2711
        case 0:
2712
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
2713
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2714
            rn = "Context";
2715
            break;
2716
        case 1:
2717
//            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
2718
            rn = "ContextConfig";
2719
//            break;
2720
        default:
2721
            goto die;
2722
        }
2723
        break;
2724
    case 5:
2725
        switch (sel) {
2726
        case 0:
2727
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
2728
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2729
            rn = "PageMask";
2730
            break;
2731
        case 1:
2732
            check_insn(env, ctx, ISA_MIPS32R2);
2733
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
2734
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2735
            rn = "PageGrain";
2736
            break;
2737
        default:
2738
            goto die;
2739
        }
2740
        break;
2741
    case 6:
2742
        switch (sel) {
2743
        case 0:
2744
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
2745
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2746
            rn = "Wired";
2747
            break;
2748
        case 1:
2749
            check_insn(env, ctx, ISA_MIPS32R2);
2750
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
2751
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2752
            rn = "SRSConf0";
2753
            break;
2754
        case 2:
2755
            check_insn(env, ctx, ISA_MIPS32R2);
2756
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
2757
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2758
            rn = "SRSConf1";
2759
            break;
2760
        case 3:
2761
            check_insn(env, ctx, ISA_MIPS32R2);
2762
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
2763
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2764
            rn = "SRSConf2";
2765
            break;
2766
        case 4:
2767
            check_insn(env, ctx, ISA_MIPS32R2);
2768
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
2769
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2770
            rn = "SRSConf3";
2771
            break;
2772
        case 5:
2773
            check_insn(env, ctx, ISA_MIPS32R2);
2774
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
2775
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2776
            rn = "SRSConf4";
2777
            break;
2778
        default:
2779
            goto die;
2780
        }
2781
        break;
2782
    case 7:
2783
        switch (sel) {
2784
        case 0:
2785
            check_insn(env, ctx, ISA_MIPS32R2);
2786
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
2787
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2788
            rn = "HWREna";
2789
            break;
2790
        default:
2791
            goto die;
2792
        }
2793
        break;
2794
    case 8:
2795
        switch (sel) {
2796
        case 0:
2797
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
2798
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2799
            rn = "BadVAddr";
2800
            break;
2801
        default:
2802
            goto die;
2803
       }
2804
        break;
2805
    case 9:
2806
        switch (sel) {
2807
        case 0:
2808
            gen_op_mfc0_count();
2809
            rn = "Count";
2810
            break;
2811
        /* 6,7 are implementation dependent */
2812
        default:
2813
            goto die;
2814
        }
2815
        break;
2816
    case 10:
2817
        switch (sel) {
2818
        case 0:
2819
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
2820
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2821
            rn = "EntryHi";
2822
            break;
2823
        default:
2824
            goto die;
2825
        }
2826
        break;
2827
    case 11:
2828
        switch (sel) {
2829
        case 0:
2830
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
2831
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2832
            rn = "Compare";
2833
            break;
2834
        /* 6,7 are implementation dependent */
2835
        default:
2836
            goto die;
2837
        }
2838
        break;
2839
    case 12:
2840
        switch (sel) {
2841
        case 0:
2842
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
2843
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2844
            rn = "Status";
2845
            break;
2846
        case 1:
2847
            check_insn(env, ctx, ISA_MIPS32R2);
2848
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
2849
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2850
            rn = "IntCtl";
2851
            break;
2852
        case 2:
2853
            check_insn(env, ctx, ISA_MIPS32R2);
2854
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
2855
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2856
            rn = "SRSCtl";
2857
            break;
2858
        case 3:
2859
            check_insn(env, ctx, ISA_MIPS32R2);
2860
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
2861
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2862
            rn = "SRSMap";
2863
            break;
2864
        default:
2865
            goto die;
2866
       }
2867
        break;
2868
    case 13:
2869
        switch (sel) {
2870
        case 0:
2871
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
2872
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2873
            rn = "Cause";
2874
            break;
2875
        default:
2876
            goto die;
2877
       }
2878
        break;
2879
    case 14:
2880
        switch (sel) {
2881
        case 0:
2882
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
2883
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2884
            rn = "EPC";
2885
            break;
2886
        default:
2887
            goto die;
2888
        }
2889
        break;
2890
    case 15:
2891
        switch (sel) {
2892
        case 0:
2893
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
2894
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2895
            rn = "PRid";
2896
            break;
2897
        case 1:
2898
            check_insn(env, ctx, ISA_MIPS32R2);
2899
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
2900
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2901
            rn = "EBase";
2902
            break;
2903
        default:
2904
            goto die;
2905
       }
2906
        break;
2907
    case 16:
2908
        switch (sel) {
2909
        case 0:
2910
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
2911
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2912
            rn = "Config";
2913
            break;
2914
        case 1:
2915
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
2916
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2917
            rn = "Config1";
2918
            break;
2919
        case 2:
2920
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
2921
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2922
            rn = "Config2";
2923
            break;
2924
        case 3:
2925
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
2926
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2927
            rn = "Config3";
2928
            break;
2929
        /* 4,5 are reserved */
2930
        /* 6,7 are implementation dependent */
2931
        case 6:
2932
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
2933
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2934
            rn = "Config6";
2935
            break;
2936
        case 7:
2937
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
2938
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2939
            rn = "Config7";
2940
            break;
2941
        default:
2942
            goto die;
2943
        }
2944
        break;
2945
    case 17:
2946
        switch (sel) {
2947
        case 0:
2948
            gen_op_mfc0_lladdr();
2949
            rn = "LLAddr";
2950
            break;
2951
        default:
2952
            goto die;
2953
        }
2954
        break;
2955
    case 18:
2956
        switch (sel) {
2957
        case 0 ... 7:
2958
            gen_op_mfc0_watchlo(sel);
2959
            rn = "WatchLo";
2960
            break;
2961
        default:
2962
            goto die;
2963
        }
2964
        break;
2965
    case 19:
2966
        switch (sel) {
2967
        case 0 ...7:
2968
            gen_op_mfc0_watchhi(sel);
2969
            rn = "WatchHi";
2970
            break;
2971
        default:
2972
            goto die;
2973
        }
2974
        break;
2975
    case 20:
2976
        switch (sel) {
2977
        case 0:
2978
#if defined(TARGET_MIPS64)
2979
            check_insn(env, ctx, ISA_MIPS3);
2980
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
2981
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
2982
            rn = "XContext";
2983
            break;
2984
#endif
2985
        default:
2986
            goto die;
2987
        }
2988
        break;
2989
    case 21:
2990
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
2991
        switch (sel) {
2992
        case 0:
2993
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
2994
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
2995
            rn = "Framemask";
2996
            break;
2997
        default:
2998
            goto die;
2999
        }
3000
        break;
3001
    case 22:
3002
        /* ignored */
3003
        rn = "'Diagnostic"; /* implementation dependent */
3004
        break;
3005
    case 23:
3006
        switch (sel) {
3007
        case 0:
3008
            gen_op_mfc0_debug(); /* EJTAG support */
3009
            rn = "Debug";
3010
            break;
3011
        case 1:
3012
//            gen_op_mfc0_tracecontrol(); /* PDtrace support */
3013
            rn = "TraceControl";
3014
//            break;
3015
        case 2:
3016
//            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
3017
            rn = "TraceControl2";
3018
//            break;
3019
        case 3:
3020
//            gen_op_mfc0_usertracedata(); /* PDtrace support */
3021
            rn = "UserTraceData";
3022
//            break;
3023
        case 4:
3024
//            gen_op_mfc0_debug(); /* PDtrace support */
3025
            rn = "TraceBPC";
3026
//            break;
3027
        default:
3028
            goto die;
3029
        }
3030
        break;
3031
    case 24:
3032
        switch (sel) {
3033
        case 0:
3034
            /* EJTAG support */
3035
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
3036
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3037
            rn = "DEPC";
3038
            break;
3039
        default:
3040
            goto die;
3041
        }
3042
        break;
3043
    case 25:
3044
        switch (sel) {
3045
        case 0:
3046
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
3047
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3048
            rn = "Performance0";
3049
            break;
3050
        case 1:
3051
//            gen_op_mfc0_performance1();
3052
            rn = "Performance1";
3053
//            break;
3054
        case 2:
3055
//            gen_op_mfc0_performance2();
3056
            rn = "Performance2";
3057
//            break;
3058
        case 3:
3059
//            gen_op_mfc0_performance3();
3060
            rn = "Performance3";
3061
//            break;
3062
        case 4:
3063
//            gen_op_mfc0_performance4();
3064
            rn = "Performance4";
3065
//            break;
3066
        case 5:
3067
//            gen_op_mfc0_performance5();
3068
            rn = "Performance5";
3069
//            break;
3070
        case 6:
3071
//            gen_op_mfc0_performance6();
3072
            rn = "Performance6";
3073
//            break;
3074
        case 7:
3075
//            gen_op_mfc0_performance7();
3076
            rn = "Performance7";
3077
//            break;
3078
        default:
3079
            goto die;
3080
        }
3081
        break;
3082
    case 26:
3083
       rn = "ECC";
3084
       break;
3085
    case 27:
3086
        switch (sel) {
3087
        /* ignored */
3088
        case 0 ... 3:
3089
            rn = "CacheErr";
3090
            break;
3091
        default:
3092
            goto die;
3093
        }
3094
        break;
3095
    case 28:
3096
        switch (sel) {
3097
        case 0:
3098
        case 2:
3099
        case 4:
3100
        case 6:
3101
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
3102
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3103
            rn = "TagLo";
3104
            break;
3105
        case 1:
3106
        case 3:
3107
        case 5:
3108
        case 7:
3109
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
3110
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3111
            rn = "DataLo";
3112
            break;
3113
        default:
3114
            goto die;
3115
        }
3116
        break;
3117
    case 29:
3118
        switch (sel) {
3119
        case 0:
3120
        case 2:
3121
        case 4:
3122
        case 6:
3123
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
3124
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3125
            rn = "TagHi";
3126
            break;
3127
        case 1:
3128
        case 3:
3129
        case 5:
3130
        case 7:
3131
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
3132
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3133
            rn = "DataHi";
3134
            break;
3135
        default:
3136
            goto die;
3137
        }
3138
        break;
3139
    case 30:
3140
        switch (sel) {
3141
        case 0:
3142
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3143
            tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
3144
            rn = "ErrorEPC";
3145
            break;
3146
        default:
3147
            goto die;
3148
        }
3149
        break;
3150
    case 31:
3151
        switch (sel) {
3152
        case 0:
3153
            /* EJTAG support */
3154
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
3155
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3156
            rn = "DESAVE";
3157
            break;
3158
        default:
3159
            goto die;
3160
        }
3161
        break;
3162
    default:
3163
       goto die;
3164
    }
3165
#if defined MIPS_DEBUG_DISAS
3166
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3167
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3168
                rn, reg, sel);
3169
    }
3170
#endif
3171
    return;
3172

    
3173
die:
3174
#if defined MIPS_DEBUG_DISAS
3175
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3176
        fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
3177
                rn, reg, sel);
3178
    }
3179
#endif
3180
    generate_exception(ctx, EXCP_RI);
3181
}
3182

    
3183
static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3184
{
3185
    const char *rn = "invalid";
3186

    
3187
    if (sel != 0)
3188
        check_insn(env, ctx, ISA_MIPS32);
3189

    
3190
    switch (reg) {
3191
    case 0:
3192
        switch (sel) {
3193
        case 0:
3194
            gen_op_mtc0_index();
3195
            rn = "Index";
3196
            break;
3197
        case 1:
3198
            check_insn(env, ctx, ASE_MT);
3199
            gen_op_mtc0_mvpcontrol();
3200
            rn = "MVPControl";
3201
            break;
3202
        case 2:
3203
            check_insn(env, ctx, ASE_MT);
3204
            /* ignored */
3205
            rn = "MVPConf0";
3206
            break;
3207
        case 3:
3208
            check_insn(env, ctx, ASE_MT);
3209
            /* ignored */
3210
            rn = "MVPConf1";
3211
            break;
3212
        default:
3213
            goto die;
3214
        }
3215
        break;
3216
    case 1:
3217
        switch (sel) {
3218
        case 0:
3219
            /* ignored */
3220
            rn = "Random";
3221
            break;
3222
        case 1:
3223
            check_insn(env, ctx, ASE_MT);
3224
            gen_op_mtc0_vpecontrol();
3225
            rn = "VPEControl";
3226
            break;
3227
        case 2:
3228
            check_insn(env, ctx, ASE_MT);
3229
            gen_op_mtc0_vpeconf0();
3230
            rn = "VPEConf0";
3231
            break;
3232
        case 3:
3233
            check_insn(env, ctx, ASE_MT);
3234
            gen_op_mtc0_vpeconf1();
3235
            rn = "VPEConf1";
3236
            break;
3237
        case 4:
3238
            check_insn(env, ctx, ASE_MT);
3239
            gen_op_mtc0_yqmask();
3240
            rn = "YQMask";
3241
            break;
3242
        case 5:
3243
            check_insn(env, ctx, ASE_MT);
3244
            gen_op_mtc0_vpeschedule();
3245
            rn = "VPESchedule";
3246
            break;
3247
        case 6:
3248
            check_insn(env, ctx, ASE_MT);
3249
            gen_op_mtc0_vpeschefback();
3250
            rn = "VPEScheFBack";
3251
            break;
3252
        case 7:
3253
            check_insn(env, ctx, ASE_MT);
3254
            gen_op_mtc0_vpeopt();
3255
            rn = "VPEOpt";
3256
            break;
3257
        default:
3258
            goto die;
3259
        }
3260
        break;
3261
    case 2:
3262
        switch (sel) {
3263
        case 0:
3264
            gen_op_mtc0_entrylo0();
3265
            rn = "EntryLo0";
3266
            break;
3267
        case 1:
3268
            check_insn(env, ctx, ASE_MT);
3269
            gen_op_mtc0_tcstatus();
3270
            rn = "TCStatus";
3271
            break;
3272
        case 2:
3273
            check_insn(env, ctx, ASE_MT);
3274
            gen_op_mtc0_tcbind();
3275
            rn = "TCBind";
3276
            break;
3277
        case 3:
3278
            check_insn(env, ctx, ASE_MT);
3279
            gen_op_mtc0_tcrestart();
3280
            rn = "TCRestart";
3281
            break;
3282
        case 4:
3283
            check_insn(env, ctx, ASE_MT);
3284
            gen_op_mtc0_tchalt();
3285
            rn = "TCHalt";
3286
            break;
3287
        case 5:
3288
            check_insn(env, ctx, ASE_MT);
3289
            gen_op_mtc0_tccontext();
3290
            rn = "TCContext";
3291
            break;
3292
        case 6:
3293
            check_insn(env, ctx, ASE_MT);
3294
            gen_op_mtc0_tcschedule();
3295
            rn = "TCSchedule";
3296
            break;
3297
        case 7:
3298
            check_insn(env, ctx, ASE_MT);
3299
            gen_op_mtc0_tcschefback();
3300
            rn = "TCScheFBack";
3301
            break;
3302
        default:
3303
            goto die;
3304
        }
3305
        break;
3306
    case 3:
3307
        switch (sel) {
3308
        case 0:
3309
            gen_op_mtc0_entrylo1();
3310
            rn = "EntryLo1";
3311
            break;
3312
        default:
3313
            goto die;
3314
        }
3315
        break;
3316
    case 4:
3317
        switch (sel) {
3318
        case 0:
3319
            gen_op_mtc0_context();
3320
            rn = "Context";
3321
            break;
3322
        case 1:
3323
//            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3324
            rn = "ContextConfig";
3325
//            break;
3326
        default:
3327
            goto die;
3328
        }
3329
        break;
3330
    case 5:
3331
        switch (sel) {
3332
        case 0:
3333
            gen_op_mtc0_pagemask();
3334
            rn = "PageMask";
3335
            break;
3336
        case 1:
3337
            check_insn(env, ctx, ISA_MIPS32R2);
3338
            gen_op_mtc0_pagegrain();
3339
            rn = "PageGrain";
3340
            break;
3341
        default:
3342
            goto die;
3343
        }
3344
        break;
3345
    case 6:
3346
        switch (sel) {
3347
        case 0:
3348
            gen_op_mtc0_wired();
3349
            rn = "Wired";
3350
            break;
3351
        case 1:
3352
            check_insn(env, ctx, ISA_MIPS32R2);
3353
            gen_op_mtc0_srsconf0();
3354
            rn = "SRSConf0";
3355
            break;
3356
        case 2:
3357
            check_insn(env, ctx, ISA_MIPS32R2);
3358
            gen_op_mtc0_srsconf1();
3359
            rn = "SRSConf1";
3360
            break;
3361
        case 3:
3362
            check_insn(env, ctx, ISA_MIPS32R2);
3363
            gen_op_mtc0_srsconf2();
3364
            rn = "SRSConf2";
3365
            break;
3366
        case 4:
3367
            check_insn(env, ctx, ISA_MIPS32R2);
3368
            gen_op_mtc0_srsconf3();
3369
            rn = "SRSConf3";
3370
            break;
3371
        case 5:
3372
            check_insn(env, ctx, ISA_MIPS32R2);
3373
            gen_op_mtc0_srsconf4();
3374
            rn = "SRSConf4";
3375
            break;
3376
        default:
3377
            goto die;
3378
        }
3379
        break;
3380
    case 7:
3381
        switch (sel) {
3382
        case 0:
3383
            check_insn(env, ctx, ISA_MIPS32R2);
3384
            gen_op_mtc0_hwrena();
3385
            rn = "HWREna";
3386
            break;
3387
        default:
3388
            goto die;
3389
        }
3390
        break;
3391
    case 8:
3392
        /* ignored */
3393
        rn = "BadVAddr";
3394
        break;
3395
    case 9:
3396
        switch (sel) {
3397
        case 0:
3398
            gen_op_mtc0_count();
3399
            rn = "Count";
3400
            break;
3401
        /* 6,7 are implementation dependent */
3402
        default:
3403
            goto die;
3404
        }
3405
        /* Stop translation as we may have switched the execution mode */
3406
        ctx->bstate = BS_STOP;
3407
        break;
3408
    case 10:
3409
        switch (sel) {
3410
        case 0:
3411
            gen_op_mtc0_entryhi();
3412
            rn = "EntryHi";
3413
            break;
3414
        default:
3415
            goto die;
3416
        }
3417
        break;
3418
    case 11:
3419
        switch (sel) {
3420
        case 0:
3421
            gen_op_mtc0_compare();
3422
            rn = "Compare";
3423
            break;
3424
        /* 6,7 are implementation dependent */
3425
        default:
3426
            goto die;
3427
        }
3428
        /* Stop translation as we may have switched the execution mode */
3429
        ctx->bstate = BS_STOP;
3430
        break;
3431
    case 12:
3432
        switch (sel) {
3433
        case 0:
3434
            gen_op_mtc0_status();
3435
            /* BS_STOP isn't good enough here, hflags may have changed. */
3436
            gen_save_pc(ctx->pc + 4);
3437
            ctx->bstate = BS_EXCP;
3438
            rn = "Status";
3439
            break;
3440
        case 1:
3441
            check_insn(env, ctx, ISA_MIPS32R2);
3442
            gen_op_mtc0_intctl();
3443
            /* Stop translation as we may have switched the execution mode */
3444
            ctx->bstate = BS_STOP;
3445
            rn = "IntCtl";
3446
            break;
3447
        case 2:
3448
            check_insn(env, ctx, ISA_MIPS32R2);
3449
            gen_op_mtc0_srsctl();
3450
            /* Stop translation as we may have switched the execution mode */
3451
            ctx->bstate = BS_STOP;
3452
            rn = "SRSCtl";
3453
            break;
3454
        case 3:
3455
            check_insn(env, ctx, ISA_MIPS32R2);
3456
            gen_op_mtc0_srsmap();
3457
            /* Stop translation as we may have switched the execution mode */
3458
            ctx->bstate = BS_STOP;
3459
            rn = "SRSMap";
3460
            break;
3461
        default:
3462
            goto die;
3463
        }
3464
        break;
3465
    case 13:
3466
        switch (sel) {
3467
        case 0:
3468
            gen_op_mtc0_cause();
3469
            rn = "Cause";
3470
            break;
3471
        default:
3472
            goto die;
3473
        }
3474
        /* Stop translation as we may have switched the execution mode */
3475
        ctx->bstate = BS_STOP;
3476
        break;
3477
    case 14:
3478
        switch (sel) {
3479
        case 0:
3480
            gen_op_mtc0_epc();
3481
            rn = "EPC";
3482
            break;
3483
        default:
3484
            goto die;
3485
        }
3486
        break;
3487
    case 15:
3488
        switch (sel) {
3489
        case 0:
3490
            /* ignored */
3491
            rn = "PRid";
3492
            break;
3493
        case 1:
3494
            check_insn(env, ctx, ISA_MIPS32R2);
3495
            gen_op_mtc0_ebase();
3496
            rn = "EBase";
3497
            break;
3498
        default:
3499
            goto die;
3500
        }
3501
        break;
3502
    case 16:
3503
        switch (sel) {
3504
        case 0:
3505
            gen_op_mtc0_config0();
3506
            rn = "Config";
3507
            /* Stop translation as we may have switched the execution mode */
3508
            ctx->bstate = BS_STOP;
3509
            break;
3510
        case 1:
3511
            /* ignored, read only */
3512
            rn = "Config1";
3513
            break;
3514
        case 2:
3515
            gen_op_mtc0_config2();
3516
            rn = "Config2";
3517
            /* Stop translation as we may have switched the execution mode */
3518
            ctx->bstate = BS_STOP;
3519
            break;
3520
        case 3:
3521
            /* ignored, read only */
3522
            rn = "Config3";
3523
            break;
3524
        /* 4,5 are reserved */
3525
        /* 6,7 are implementation dependent */
3526
        case 6:
3527
            /* ignored */
3528
            rn = "Config6";
3529
            break;
3530
        case 7:
3531
            /* ignored */
3532
            rn = "Config7";
3533
            break;
3534
        default:
3535
            rn = "Invalid config selector";
3536
            goto die;
3537
        }
3538
        break;
3539
    case 17:
3540
        switch (sel) {
3541
        case 0:
3542
            /* ignored */
3543
            rn = "LLAddr";
3544
            break;
3545
        default:
3546
            goto die;
3547
        }
3548
        break;
3549
    case 18:
3550
        switch (sel) {
3551
        case 0 ... 7:
3552
            gen_op_mtc0_watchlo(sel);
3553
            rn = "WatchLo";
3554
            break;
3555
        default:
3556
            goto die;
3557
        }
3558
        break;
3559
    case 19:
3560
        switch (sel) {
3561
        case 0 ... 7:
3562
            gen_op_mtc0_watchhi(sel);
3563
            rn = "WatchHi";
3564
            break;
3565
        default:
3566
            goto die;
3567
        }
3568
        break;
3569
    case 20:
3570
        switch (sel) {
3571
        case 0:
3572
#if defined(TARGET_MIPS64)
3573
            check_insn(env, ctx, ISA_MIPS3);
3574
            gen_op_mtc0_xcontext();
3575
            rn = "XContext";
3576
            break;
3577
#endif
3578
        default:
3579
            goto die;
3580
        }
3581
        break;
3582
    case 21:
3583
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3584
        switch (sel) {
3585
        case 0:
3586
            gen_op_mtc0_framemask();
3587
            rn = "Framemask";
3588
            break;
3589
        default:
3590
            goto die;
3591
        }
3592
        break;
3593
    case 22:
3594
        /* ignored */
3595
        rn = "Diagnostic"; /* implementation dependent */
3596
        break;
3597
    case 23:
3598
        switch (sel) {
3599
        case 0:
3600
            gen_op_mtc0_debug(); /* EJTAG support */
3601
            /* BS_STOP isn't good enough here, hflags may have changed. */
3602
            gen_save_pc(ctx->pc + 4);
3603
            ctx->bstate = BS_EXCP;
3604
            rn = "Debug";
3605
            break;
3606
        case 1:
3607
//            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3608
            rn = "TraceControl";
3609
            /* Stop translation as we may have switched the execution mode */
3610
            ctx->bstate = BS_STOP;
3611
//            break;
3612
        case 2:
3613
//            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3614
            rn = "TraceControl2";
3615
            /* Stop translation as we may have switched the execution mode */
3616
            ctx->bstate = BS_STOP;
3617
//            break;
3618
        case 3:
3619
            /* Stop translation as we may have switched the execution mode */
3620
            ctx->bstate = BS_STOP;
3621
//            gen_op_mtc0_usertracedata(); /* PDtrace support */
3622
            rn = "UserTraceData";
3623
            /* Stop translation as we may have switched the execution mode */
3624
            ctx->bstate = BS_STOP;
3625
//            break;
3626
        case 4:
3627
//            gen_op_mtc0_debug(); /* PDtrace support */
3628
            /* Stop translation as we may have switched the execution mode */
3629
            ctx->bstate = BS_STOP;
3630
            rn = "TraceBPC";
3631
//            break;
3632
        default:
3633
            goto die;
3634
        }
3635
        break;
3636
    case 24:
3637
        switch (sel) {
3638
        case 0:
3639
            gen_op_mtc0_depc(); /* EJTAG support */
3640
            rn = "DEPC";
3641
            break;
3642
        default:
3643
            goto die;
3644
        }
3645
        break;
3646
    case 25:
3647
        switch (sel) {
3648
        case 0:
3649
            gen_op_mtc0_performance0();
3650
            rn = "Performance0";
3651
            break;
3652
        case 1:
3653
//            gen_op_mtc0_performance1();
3654
            rn = "Performance1";
3655
//            break;
3656
        case 2:
3657
//            gen_op_mtc0_performance2();
3658
            rn = "Performance2";
3659
//            break;
3660
        case 3:
3661
//            gen_op_mtc0_performance3();
3662
            rn = "Performance3";
3663
//            break;
3664
        case 4:
3665
//            gen_op_mtc0_performance4();
3666
            rn = "Performance4";
3667
//            break;
3668
        case 5:
3669
//            gen_op_mtc0_performance5();
3670
            rn = "Performance5";
3671
//            break;
3672
        case 6:
3673
//            gen_op_mtc0_performance6();
3674
            rn = "Performance6";
3675
//            break;
3676
        case 7:
3677
//            gen_op_mtc0_performance7();
3678
            rn = "Performance7";
3679
//            break;
3680
        default:
3681
            goto die;
3682
        }
3683
       break;
3684
    case 26:
3685
        /* ignored */
3686
        rn = "ECC";
3687
        break;
3688
    case 27:
3689
        switch (sel) {
3690
        case 0 ... 3:
3691
            /* ignored */
3692
            rn = "CacheErr";
3693
            break;
3694
        default:
3695
            goto die;
3696
        }
3697
       break;
3698
    case 28:
3699
        switch (sel) {
3700
        case 0:
3701
        case 2:
3702
        case 4:
3703
        case 6:
3704
            gen_op_mtc0_taglo();
3705
            rn = "TagLo";
3706
            break;
3707
        case 1:
3708
        case 3:
3709
        case 5:
3710
        case 7:
3711
            gen_op_mtc0_datalo();
3712
            rn = "DataLo";
3713
            break;
3714
        default:
3715
            goto die;
3716
        }
3717
        break;
3718
    case 29:
3719
        switch (sel) {
3720
        case 0:
3721
        case 2:
3722
        case 4:
3723
        case 6:
3724
            gen_op_mtc0_taghi();
3725
            rn = "TagHi";
3726
            break;
3727
        case 1:
3728
        case 3:
3729
        case 5:
3730
        case 7:
3731
            gen_op_mtc0_datahi();
3732
            rn = "DataHi";
3733
            break;
3734
        default:
3735
            rn = "invalid sel";
3736
            goto die;
3737
        }
3738
       break;
3739
    case 30:
3740
        switch (sel) {
3741
        case 0:
3742
            gen_op_mtc0_errorepc();
3743
            rn = "ErrorEPC";
3744
            break;
3745
        default:
3746
            goto die;
3747
        }
3748
        break;
3749
    case 31:
3750
        switch (sel) {
3751
        case 0:
3752
            gen_op_mtc0_desave(); /* EJTAG support */
3753
            rn = "DESAVE";
3754
            break;
3755
        default:
3756
            goto die;
3757
        }
3758
        /* Stop translation as we may have switched the execution mode */
3759
        ctx->bstate = BS_STOP;
3760
        break;
3761
    default:
3762
       goto die;
3763
    }
3764
#if defined MIPS_DEBUG_DISAS
3765
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3766
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3767
                rn, reg, sel);
3768
    }
3769
#endif
3770
    return;
3771

    
3772
die:
3773
#if defined MIPS_DEBUG_DISAS
3774
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3775
        fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
3776
                rn, reg, sel);
3777
    }
3778
#endif
3779
    generate_exception(ctx, EXCP_RI);
3780
}
3781

    
3782
#if defined(TARGET_MIPS64)
3783
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
3784
{
3785
    const char *rn = "invalid";
3786
    TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
3787

    
3788
    if (sel != 0)
3789
        check_insn(env, ctx, ISA_MIPS64);
3790

    
3791
    switch (reg) {
3792
    case 0:
3793
        switch (sel) {
3794
        case 0:
3795
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Index));
3796
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3797
            rn = "Index";
3798
            break;
3799
        case 1:
3800
            check_insn(env, ctx, ASE_MT);
3801
            gen_op_mfc0_mvpcontrol();
3802
            rn = "MVPControl";
3803
            break;
3804
        case 2:
3805
            check_insn(env, ctx, ASE_MT);
3806
            gen_op_mfc0_mvpconf0();
3807
            rn = "MVPConf0";
3808
            break;
3809
        case 3:
3810
            check_insn(env, ctx, ASE_MT);
3811
            gen_op_mfc0_mvpconf1();
3812
            rn = "MVPConf1";
3813
            break;
3814
        default:
3815
            goto die;
3816
        }
3817
        break;
3818
    case 1:
3819
        switch (sel) {
3820
        case 0:
3821
            gen_op_mfc0_random();
3822
            rn = "Random";
3823
            break;
3824
        case 1:
3825
            check_insn(env, ctx, ASE_MT);
3826
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEControl));
3827
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3828
            rn = "VPEControl";
3829
            break;
3830
        case 2:
3831
            check_insn(env, ctx, ASE_MT);
3832
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf0));
3833
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3834
            rn = "VPEConf0";
3835
            break;
3836
        case 3:
3837
            check_insn(env, ctx, ASE_MT);
3838
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEConf1));
3839
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3840
            rn = "VPEConf1";
3841
            break;
3842
        case 4:
3843
            check_insn(env, ctx, ASE_MT);
3844
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_YQMask));
3845
            rn = "YQMask";
3846
            break;
3847
        case 5:
3848
            check_insn(env, ctx, ASE_MT);
3849
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPESchedule));
3850
            rn = "VPESchedule";
3851
            break;
3852
        case 6:
3853
            check_insn(env, ctx, ASE_MT);
3854
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3855
            rn = "VPEScheFBack";
3856
            break;
3857
        case 7:
3858
            check_insn(env, ctx, ASE_MT);
3859
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_VPEOpt));
3860
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3861
            rn = "VPEOpt";
3862
            break;
3863
        default:
3864
            goto die;
3865
        }
3866
        break;
3867
    case 2:
3868
        switch (sel) {
3869
        case 0:
3870
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo0));
3871
            rn = "EntryLo0";
3872
            break;
3873
        case 1:
3874
            check_insn(env, ctx, ASE_MT);
3875
            gen_op_mfc0_tcstatus();
3876
            rn = "TCStatus";
3877
            break;
3878
        case 2:
3879
            check_insn(env, ctx, ASE_MT);
3880
            gen_op_mfc0_tcbind();
3881
            rn = "TCBind";
3882
            break;
3883
        case 3:
3884
            check_insn(env, ctx, ASE_MT);
3885
            gen_op_dmfc0_tcrestart();
3886
            rn = "TCRestart";
3887
            break;
3888
        case 4:
3889
            check_insn(env, ctx, ASE_MT);
3890
            gen_op_dmfc0_tchalt();
3891
            rn = "TCHalt";
3892
            break;
3893
        case 5:
3894
            check_insn(env, ctx, ASE_MT);
3895
            gen_op_dmfc0_tccontext();
3896
            rn = "TCContext";
3897
            break;
3898
        case 6:
3899
            check_insn(env, ctx, ASE_MT);
3900
            gen_op_dmfc0_tcschedule();
3901
            rn = "TCSchedule";
3902
            break;
3903
        case 7:
3904
            check_insn(env, ctx, ASE_MT);
3905
            gen_op_dmfc0_tcschefback();
3906
            rn = "TCScheFBack";
3907
            break;
3908
        default:
3909
            goto die;
3910
        }
3911
        break;
3912
    case 3:
3913
        switch (sel) {
3914
        case 0:
3915
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryLo1));
3916
            rn = "EntryLo1";
3917
            break;
3918
        default:
3919
            goto die;
3920
        }
3921
        break;
3922
    case 4:
3923
        switch (sel) {
3924
        case 0:
3925
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_Context));
3926
            rn = "Context";
3927
            break;
3928
        case 1:
3929
//            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3930
            rn = "ContextConfig";
3931
//            break;
3932
        default:
3933
            goto die;
3934
        }
3935
        break;
3936
    case 5:
3937
        switch (sel) {
3938
        case 0:
3939
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageMask));
3940
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3941
            rn = "PageMask";
3942
            break;
3943
        case 1:
3944
            check_insn(env, ctx, ISA_MIPS32R2);
3945
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PageGrain));
3946
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3947
            rn = "PageGrain";
3948
            break;
3949
        default:
3950
            goto die;
3951
        }
3952
        break;
3953
    case 6:
3954
        switch (sel) {
3955
        case 0:
3956
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Wired));
3957
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3958
            rn = "Wired";
3959
            break;
3960
        case 1:
3961
            check_insn(env, ctx, ISA_MIPS32R2);
3962
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf0));
3963
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3964
            rn = "SRSConf0";
3965
            break;
3966
        case 2:
3967
            check_insn(env, ctx, ISA_MIPS32R2);
3968
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf1));
3969
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3970
            rn = "SRSConf1";
3971
            break;
3972
        case 3:
3973
            check_insn(env, ctx, ISA_MIPS32R2);
3974
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf2));
3975
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3976
            rn = "SRSConf2";
3977
            break;
3978
        case 4:
3979
            check_insn(env, ctx, ISA_MIPS32R2);
3980
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf3));
3981
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3982
            rn = "SRSConf3";
3983
            break;
3984
        case 5:
3985
            check_insn(env, ctx, ISA_MIPS32R2);
3986
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSConf4));
3987
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
3988
            rn = "SRSConf4";
3989
            break;
3990
        default:
3991
            goto die;
3992
        }
3993
        break;
3994
    case 7:
3995
        switch (sel) {
3996
        case 0:
3997
            check_insn(env, ctx, ISA_MIPS32R2);
3998
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_HWREna));
3999
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4000
            rn = "HWREna";
4001
            break;
4002
        default:
4003
            goto die;
4004
        }
4005
        break;
4006
    case 8:
4007
        switch (sel) {
4008
        case 0:
4009
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr));
4010
            rn = "BadVAddr";
4011
            break;
4012
        default:
4013
            goto die;
4014
        }
4015
        break;
4016
    case 9:
4017
        switch (sel) {
4018
        case 0:
4019
            gen_op_mfc0_count();
4020
            rn = "Count";
4021
            break;
4022
        /* 6,7 are implementation dependent */
4023
        default:
4024
            goto die;
4025
        }
4026
        break;
4027
    case 10:
4028
        switch (sel) {
4029
        case 0:
4030
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EntryHi));
4031
            rn = "EntryHi";
4032
            break;
4033
        default:
4034
            goto die;
4035
        }
4036
        break;
4037
    case 11:
4038
        switch (sel) {
4039
        case 0:
4040
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Compare));
4041
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4042
            rn = "Compare";
4043
            break;
4044
        /* 6,7 are implementation dependent */
4045
        default:
4046
            goto die;
4047
        }
4048
        break;
4049
    case 12:
4050
        switch (sel) {
4051
        case 0:
4052
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Status));
4053
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4054
            rn = "Status";
4055
            break;
4056
        case 1:
4057
            check_insn(env, ctx, ISA_MIPS32R2);
4058
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_IntCtl));
4059
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4060
            rn = "IntCtl";
4061
            break;
4062
        case 2:
4063
            check_insn(env, ctx, ISA_MIPS32R2);
4064
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
4065
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4066
            rn = "SRSCtl";
4067
            break;
4068
        case 3:
4069
            check_insn(env, ctx, ISA_MIPS32R2);
4070
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSMap));
4071
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4072
            rn = "SRSMap";
4073
            break;
4074
        default:
4075
            goto die;
4076
        }
4077
        break;
4078
    case 13:
4079
        switch (sel) {
4080
        case 0:
4081
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Cause));
4082
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4083
            rn = "Cause";
4084
            break;
4085
        default:
4086
            goto die;
4087
        }
4088
        break;
4089
    case 14:
4090
        switch (sel) {
4091
        case 0:
4092
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_EPC));
4093
            rn = "EPC";
4094
            break;
4095
        default:
4096
            goto die;
4097
        }
4098
        break;
4099
    case 15:
4100
        switch (sel) {
4101
        case 0:
4102
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_PRid));
4103
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4104
            rn = "PRid";
4105
            break;
4106
        case 1:
4107
            check_insn(env, ctx, ISA_MIPS32R2);
4108
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_EBase));
4109
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4110
            rn = "EBase";
4111
            break;
4112
        default:
4113
            goto die;
4114
        }
4115
        break;
4116
    case 16:
4117
        switch (sel) {
4118
        case 0:
4119
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config0));
4120
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4121
            rn = "Config";
4122
            break;
4123
        case 1:
4124
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config1));
4125
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4126
            rn = "Config1";
4127
            break;
4128
        case 2:
4129
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config2));
4130
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4131
            rn = "Config2";
4132
            break;
4133
        case 3:
4134
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config3));
4135
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4136
            rn = "Config3";
4137
            break;
4138
       /* 6,7 are implementation dependent */
4139
        case 6:
4140
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config6));
4141
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4142
            rn = "Config6";
4143
            break;
4144
        case 7:
4145
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Config7));
4146
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4147
            rn = "Config7";
4148
            break;
4149
        default:
4150
            goto die;
4151
        }
4152
        break;
4153
    case 17:
4154
        switch (sel) {
4155
        case 0:
4156
            gen_op_dmfc0_lladdr();
4157
            rn = "LLAddr";
4158
            break;
4159
        default:
4160
            goto die;
4161
        }
4162
        break;
4163
    case 18:
4164
        switch (sel) {
4165
        case 0 ... 7:
4166
            gen_op_dmfc0_watchlo(sel);
4167
            rn = "WatchLo";
4168
            break;
4169
        default:
4170
            goto die;
4171
        }
4172
        break;
4173
    case 19:
4174
        switch (sel) {
4175
        case 0 ... 7:
4176
            gen_op_mfc0_watchhi(sel);
4177
            rn = "WatchHi";
4178
            break;
4179
        default:
4180
            goto die;
4181
        }
4182
        break;
4183
    case 20:
4184
        switch (sel) {
4185
        case 0:
4186
            check_insn(env, ctx, ISA_MIPS3);
4187
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_XContext));
4188
            rn = "XContext";
4189
            break;
4190
        default:
4191
            goto die;
4192
        }
4193
        break;
4194
    case 21:
4195
       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4196
        switch (sel) {
4197
        case 0:
4198
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Framemask));
4199
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4200
            rn = "Framemask";
4201
            break;
4202
        default:
4203
            goto die;
4204
        }
4205
        break;
4206
    case 22:
4207
        /* ignored */
4208
        rn = "'Diagnostic"; /* implementation dependent */
4209
        break;
4210
    case 23:
4211
        switch (sel) {
4212
        case 0:
4213
            gen_op_mfc0_debug(); /* EJTAG support */
4214
            rn = "Debug";
4215
            break;
4216
        case 1:
4217
//            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
4218
            rn = "TraceControl";
4219
//            break;
4220
        case 2:
4221
//            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
4222
            rn = "TraceControl2";
4223
//            break;
4224
        case 3:
4225
//            gen_op_dmfc0_usertracedata(); /* PDtrace support */
4226
            rn = "UserTraceData";
4227
//            break;
4228
        case 4:
4229
//            gen_op_dmfc0_debug(); /* PDtrace support */
4230
            rn = "TraceBPC";
4231
//            break;
4232
        default:
4233
            goto die;
4234
        }
4235
        break;
4236
    case 24:
4237
        switch (sel) {
4238
        case 0:
4239
            /* EJTAG support */
4240
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_DEPC));
4241
            rn = "DEPC";
4242
            break;
4243
        default:
4244
            goto die;
4245
        }
4246
        break;
4247
    case 25:
4248
        switch (sel) {
4249
        case 0:
4250
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_Performance0));
4251
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4252
            rn = "Performance0";
4253
            break;
4254
        case 1:
4255
//            gen_op_dmfc0_performance1();
4256
            rn = "Performance1";
4257
//            break;
4258
        case 2:
4259
//            gen_op_dmfc0_performance2();
4260
            rn = "Performance2";
4261
//            break;
4262
        case 3:
4263
//            gen_op_dmfc0_performance3();
4264
            rn = "Performance3";
4265
//            break;
4266
        case 4:
4267
//            gen_op_dmfc0_performance4();
4268
            rn = "Performance4";
4269
//            break;
4270
        case 5:
4271
//            gen_op_dmfc0_performance5();
4272
            rn = "Performance5";
4273
//            break;
4274
        case 6:
4275
//            gen_op_dmfc0_performance6();
4276
            rn = "Performance6";
4277
//            break;
4278
        case 7:
4279
//            gen_op_dmfc0_performance7();
4280
            rn = "Performance7";
4281
//            break;
4282
        default:
4283
            goto die;
4284
        }
4285
        break;
4286
    case 26:
4287
       rn = "ECC";
4288
       break;
4289
    case 27:
4290
        switch (sel) {
4291
        /* ignored */
4292
        case 0 ... 3:
4293
            rn = "CacheErr";
4294
            break;
4295
        default:
4296
            goto die;
4297
        }
4298
        break;
4299
    case 28:
4300
        switch (sel) {
4301
        case 0:
4302
        case 2:
4303
        case 4:
4304
        case 6:
4305
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagLo));
4306
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4307
            rn = "TagLo";
4308
            break;
4309
        case 1:
4310
        case 3:
4311
        case 5:
4312
        case 7:
4313
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataLo));
4314
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4315
            rn = "DataLo";
4316
            break;
4317
        default:
4318
            goto die;
4319
        }
4320
        break;
4321
    case 29:
4322
        switch (sel) {
4323
        case 0:
4324
        case 2:
4325
        case 4:
4326
        case 6:
4327
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_TagHi));
4328
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4329
            rn = "TagHi";
4330
            break;
4331
        case 1:
4332
        case 3:
4333
        case 5:
4334
        case 7:
4335
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DataHi));
4336
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4337
            rn = "DataHi";
4338
            break;
4339
        default:
4340
            goto die;
4341
        }
4342
        break;
4343
    case 30:
4344
        switch (sel) {
4345
        case 0:
4346
            tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4347
            rn = "ErrorEPC";
4348
            break;
4349
        default:
4350
            goto die;
4351
        }
4352
        break;
4353
    case 31:
4354
        switch (sel) {
4355
        case 0:
4356
            /* EJTAG support */
4357
            tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_DESAVE));
4358
            tcg_gen_ext_i32_tl(cpu_T[0], r_tmp);
4359
            rn = "DESAVE";
4360
            break;
4361
        default:
4362
            goto die;
4363
        }
4364
        break;
4365
    default:
4366
        goto die;
4367
    }
4368
#if defined MIPS_DEBUG_DISAS
4369
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4370
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4371
                rn, reg, sel);
4372
    }
4373
#endif
4374
    return;
4375

    
4376
die:
4377
#if defined MIPS_DEBUG_DISAS
4378
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4379
        fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
4380
                rn, reg, sel);
4381
    }
4382
#endif
4383
    generate_exception(ctx, EXCP_RI);
4384
}
4385

    
4386
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
4387
{
4388
    const char *rn = "invalid";
4389

    
4390
    if (sel != 0)
4391
        check_insn(env, ctx, ISA_MIPS64);
4392

    
4393
    switch (reg) {
4394
    case 0:
4395
        switch (sel) {
4396
        case 0:
4397
            gen_op_mtc0_index();
4398
            rn = "Index";
4399
            break;
4400
        case 1:
4401
            check_insn(env, ctx, ASE_MT);
4402
            gen_op_mtc0_mvpcontrol();
4403
            rn = "MVPControl";
4404
            break;
4405
        case 2:
4406
            check_insn(env, ctx, ASE_MT);
4407
            /* ignored */
4408
            rn = "MVPConf0";
4409
            break;
4410
        case 3:
4411
            check_insn(env, ctx, ASE_MT);
4412
            /* ignored */
4413
            rn = "MVPConf1";
4414
            break;
4415
        default:
4416
            goto die;
4417
        }
4418
        break;
4419
    case 1:
4420
        switch (sel) {
4421
        case 0:
4422
            /* ignored */
4423
            rn = "Random";
4424
            break;
4425
        case 1:
4426
            check_insn(env, ctx, ASE_MT);
4427
            gen_op_mtc0_vpecontrol();
4428
            rn = "VPEControl";
4429
            break;
4430
        case 2:
4431
            check_insn(env, ctx, ASE_MT);
4432
            gen_op_mtc0_vpeconf0();
4433
            rn = "VPEConf0";
4434
            break;
4435
        case 3:
4436
            check_insn(env, ctx, ASE_MT);
4437
            gen_op_mtc0_vpeconf1();
4438
            rn = "VPEConf1";
4439
            break;
4440
        case 4:
4441
            check_insn(env, ctx, ASE_MT);
4442
            gen_op_mtc0_yqmask();
4443
            rn = "YQMask";
4444
            break;
4445
        case 5:
4446
            check_insn(env, ctx, ASE_MT);
4447
            gen_op_mtc0_vpeschedule();
4448
            rn = "VPESchedule";
4449
            break;
4450
        case 6:
4451
            check_insn(env, ctx, ASE_MT);
4452
            gen_op_mtc0_vpeschefback();
4453
            rn = "VPEScheFBack";
4454
            break;
4455
        case 7:
4456
            check_insn(env, ctx, ASE_MT);
4457
            gen_op_mtc0_vpeopt();
4458
            rn = "VPEOpt";
4459
            break;
4460
        default:
4461
            goto die;
4462
        }
4463
        break;
4464
    case 2:
4465
        switch (sel) {
4466
        case 0:
4467
            gen_op_mtc0_entrylo0();
4468
            rn = "EntryLo0";
4469
            break;
4470
        case 1:
4471
            check_insn(env, ctx, ASE_MT);
4472
            gen_op_mtc0_tcstatus();
4473
            rn = "TCStatus";
4474
            break;
4475
        case 2:
4476
            check_insn(env, ctx, ASE_MT);
4477
            gen_op_mtc0_tcbind();
4478
            rn = "TCBind";
4479
            break;
4480
        case 3:
4481
            check_insn(env, ctx, ASE_MT);
4482
            gen_op_mtc0_tcrestart();
4483
            rn = "TCRestart";
4484
            break;
4485
        case 4:
4486
            check_insn(env, ctx, ASE_MT);
4487
            gen_op_mtc0_tchalt();
4488
            rn = "TCHalt";
4489
            break;
4490
        case 5:
4491
            check_insn(env, ctx, ASE_MT);
4492
            gen_op_mtc0_tccontext();
4493
            rn = "TCContext";
4494
            break;
4495
        case 6:
4496
            check_insn(env, ctx, ASE_MT);
4497
            gen_op_mtc0_tcschedule();
4498
            rn = "TCSchedule";
4499
            break;
4500
        case 7:
4501
            check_insn(env, ctx, ASE_MT);
4502
            gen_op_mtc0_tcschefback();
4503
            rn = "TCScheFBack";
4504
            break;
4505
        default:
4506
            goto die;
4507
        }
4508
        break;
4509
    case 3:
4510
        switch (sel) {
4511
        case 0:
4512
            gen_op_mtc0_entrylo1();
4513
            rn = "EntryLo1";
4514
            break;
4515
        default:
4516
            goto die;
4517
        }
4518
        break;
4519
    case 4:
4520
        switch (sel) {
4521
        case 0:
4522
            gen_op_mtc0_context();
4523
            rn = "Context";
4524
            break;
4525
        case 1:
4526
//           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
4527
            rn = "ContextConfig";
4528
//           break;
4529
        default:
4530
            goto die;
4531
        }
4532
        break;
4533
    case 5:
4534
        switch (sel) {
4535
        case 0:
4536
            gen_op_mtc0_pagemask();
4537
            rn = "PageMask";
4538
            break;
4539
        case 1:
4540
            check_insn(env, ctx, ISA_MIPS32R2);
4541
            gen_op_mtc0_pagegrain();
4542
            rn = "PageGrain";
4543
            break;
4544
        default:
4545
            goto die;
4546
        }
4547
        break;
4548
    case 6:
4549
        switch (sel) {
4550
        case 0:
4551
            gen_op_mtc0_wired();
4552
            rn = "Wired";
4553
            break;
4554
        case 1:
4555
            check_insn(env, ctx, ISA_MIPS32R2);
4556
            gen_op_mtc0_srsconf0();
4557
            rn = "SRSConf0";
4558
            break;
4559
        case 2:
4560
            check_insn(env, ctx, ISA_MIPS32R2);
4561
            gen_op_mtc0_srsconf1();
4562
            rn = "SRSConf1";
4563
            break;
4564
        case 3:
4565
            check_insn(env, ctx, ISA_MIPS32R2);
4566
            gen_op_mtc0_srsconf2();
4567
            rn = "SRSConf2";
4568
            break;
4569
        case 4:
4570
            check_insn(env, ctx, ISA_MIPS32R2);
4571
            gen_op_mtc0_srsconf3();
4572
            rn = "SRSConf3";
4573
            break;
4574
        case 5:
4575
            check_insn(env, ctx, ISA_MIPS32R2);
4576
            gen_op_mtc0_srsconf4();
4577
            rn = "SRSConf4";
4578
            break;
4579
        default:
4580
            goto die;
4581
        }
4582
        break;
4583
    case 7:
4584
        switch (sel) {
4585
        case 0:
4586
            check_insn(env, ctx, ISA_MIPS32R2);
4587
            gen_op_mtc0_hwrena();
4588
            rn = "HWREna";
4589
            break;
4590
        default:
4591
            goto die;
4592
        }
4593
        break;
4594
    case 8:
4595
        /* ignored */
4596
        rn = "BadVAddr";
4597
        break;
4598
    case 9:
4599
        switch (sel) {
4600
        case 0:
4601
            gen_op_mtc0_count();
4602
            rn = "Count";
4603
            break;
4604
        /* 6,7 are implementation dependent */
4605
        default:
4606
            goto die;
4607
        }
4608
        /* Stop translation as we may have switched the execution mode */
4609
        ctx->bstate = BS_STOP;
4610
        break;
4611
    case 10:
4612
        switch (sel) {
4613
        case 0:
4614
            gen_op_mtc0_entryhi();
4615
            rn = "EntryHi";
4616
            break;
4617
        default:
4618
            goto die;
4619
        }
4620
        break;
4621
    case 11:
4622
        switch (sel) {
4623
        case 0:
4624
            gen_op_mtc0_compare();
4625
            rn = "Compare";
4626
            break;
4627
        /* 6,7 are implementation dependent */
4628
        default:
4629
            goto die;
4630
        }
4631
        /* Stop translation as we may have switched the execution mode */
4632
        ctx->bstate = BS_STOP;
4633
        break;
4634
    case 12:
4635
        switch (sel) {
4636
        case 0:
4637
            gen_op_mtc0_status();
4638
            /* BS_STOP isn't good enough here, hflags may have changed. */
4639
            gen_save_pc(ctx->pc + 4);
4640
            ctx->bstate = BS_EXCP;
4641
            rn = "Status";
4642
            break;
4643
        case 1:
4644
            check_insn(env, ctx, ISA_MIPS32R2);
4645
            gen_op_mtc0_intctl();
4646
            /* Stop translation as we may have switched the execution mode */
4647
            ctx->bstate = BS_STOP;
4648
            rn = "IntCtl";
4649
            break;
4650
        case 2:
4651
            check_insn(env, ctx, ISA_MIPS32R2);
4652
            gen_op_mtc0_srsctl();
4653
            /* Stop translation as we may have switched the execution mode */
4654
            ctx->bstate = BS_STOP;
4655
            rn = "SRSCtl";
4656
            break;
4657
        case 3: