2
* MIPS32 emulation for qemu: main translation routines.
4
* Copyright (c) 2004-2005 Jocelyn Mayer
5
* Copyright (c) 2006 Marius Groeger (FPU operations)
6
* Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7
* Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
9
* This library is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU Lesser General Public
11
* License as published by the Free Software Foundation; either
12
* version 2 of the License, or (at your option) any later version.
14
* This library is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* Lesser General Public License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
32
#include "qemu-common.h"
38
//#define MIPS_DEBUG_DISAS
39
//#define MIPS_DEBUG_SIGN_EXTENSIONS
41
/* MIPS major opcodes */
42
#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
45
/* indirect opcode tables */
46
OPC_SPECIAL = (0x00 << 26),
47
OPC_REGIMM = (0x01 << 26),
48
OPC_CP0 = (0x10 << 26),
49
OPC_CP1 = (0x11 << 26),
50
OPC_CP2 = (0x12 << 26),
51
OPC_CP3 = (0x13 << 26),
52
OPC_SPECIAL2 = (0x1C << 26),
53
OPC_SPECIAL3 = (0x1F << 26),
54
/* arithmetic with immediate */
55
OPC_ADDI = (0x08 << 26),
56
OPC_ADDIU = (0x09 << 26),
57
OPC_SLTI = (0x0A << 26),
58
OPC_SLTIU = (0x0B << 26),
59
/* logic with immediate */
60
OPC_ANDI = (0x0C << 26),
61
OPC_ORI = (0x0D << 26),
62
OPC_XORI = (0x0E << 26),
63
OPC_LUI = (0x0F << 26),
64
/* arithmetic with immediate */
65
OPC_DADDI = (0x18 << 26),
66
OPC_DADDIU = (0x19 << 26),
67
/* Jump and branches */
69
OPC_JAL = (0x03 << 26),
70
OPC_JALS = OPC_JAL | 0x5,
71
OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
72
OPC_BEQL = (0x14 << 26),
73
OPC_BNE = (0x05 << 26),
74
OPC_BNEL = (0x15 << 26),
75
OPC_BLEZ = (0x06 << 26),
76
OPC_BLEZL = (0x16 << 26),
77
OPC_BGTZ = (0x07 << 26),
78
OPC_BGTZL = (0x17 << 26),
79
OPC_JALX = (0x1D << 26), /* MIPS 16 only */
80
OPC_JALXS = OPC_JALX | 0x5,
82
OPC_LDL = (0x1A << 26),
83
OPC_LDR = (0x1B << 26),
84
OPC_LB = (0x20 << 26),
85
OPC_LH = (0x21 << 26),
86
OPC_LWL = (0x22 << 26),
87
OPC_LW = (0x23 << 26),
88
OPC_LWPC = OPC_LW | 0x5,
89
OPC_LBU = (0x24 << 26),
90
OPC_LHU = (0x25 << 26),
91
OPC_LWR = (0x26 << 26),
92
OPC_LWU = (0x27 << 26),
93
OPC_SB = (0x28 << 26),
94
OPC_SH = (0x29 << 26),
95
OPC_SWL = (0x2A << 26),
96
OPC_SW = (0x2B << 26),
97
OPC_SDL = (0x2C << 26),
98
OPC_SDR = (0x2D << 26),
99
OPC_SWR = (0x2E << 26),
100
OPC_LL = (0x30 << 26),
101
OPC_LLD = (0x34 << 26),
102
OPC_LD = (0x37 << 26),
103
OPC_LDPC = OPC_LD | 0x5,
104
OPC_SC = (0x38 << 26),
105
OPC_SCD = (0x3C << 26),
106
OPC_SD = (0x3F << 26),
107
/* Floating point load/store */
108
OPC_LWC1 = (0x31 << 26),
109
OPC_LWC2 = (0x32 << 26),
110
OPC_LDC1 = (0x35 << 26),
111
OPC_LDC2 = (0x36 << 26),
112
OPC_SWC1 = (0x39 << 26),
113
OPC_SWC2 = (0x3A << 26),
114
OPC_SDC1 = (0x3D << 26),
115
OPC_SDC2 = (0x3E << 26),
116
/* MDMX ASE specific */
117
OPC_MDMX = (0x1E << 26),
118
/* Cache and prefetch */
119
OPC_CACHE = (0x2F << 26),
120
OPC_PREF = (0x33 << 26),
121
/* Reserved major opcode */
122
OPC_MAJOR3B_RESERVED = (0x3B << 26),
125
/* MIPS special opcodes */
126
#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
130
OPC_SLL = 0x00 | OPC_SPECIAL,
131
/* NOP is SLL r0, r0, 0 */
132
/* SSNOP is SLL r0, r0, 1 */
133
/* EHB is SLL r0, r0, 3 */
134
OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
135
OPC_ROTR = OPC_SRL | (1 << 21),
136
OPC_SRA = 0x03 | OPC_SPECIAL,
137
OPC_SLLV = 0x04 | OPC_SPECIAL,
138
OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
139
OPC_ROTRV = OPC_SRLV | (1 << 6),
140
OPC_SRAV = 0x07 | OPC_SPECIAL,
141
OPC_DSLLV = 0x14 | OPC_SPECIAL,
142
OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
143
OPC_DROTRV = OPC_DSRLV | (1 << 6),
144
OPC_DSRAV = 0x17 | OPC_SPECIAL,
145
OPC_DSLL = 0x38 | OPC_SPECIAL,
146
OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
147
OPC_DROTR = OPC_DSRL | (1 << 21),
148
OPC_DSRA = 0x3B | OPC_SPECIAL,
149
OPC_DSLL32 = 0x3C | OPC_SPECIAL,
150
OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
151
OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
152
OPC_DSRA32 = 0x3F | OPC_SPECIAL,
153
/* Multiplication / division */
154
OPC_MULT = 0x18 | OPC_SPECIAL,
155
OPC_MULTU = 0x19 | OPC_SPECIAL,
156
OPC_DIV = 0x1A | OPC_SPECIAL,
157
OPC_DIVU = 0x1B | OPC_SPECIAL,
158
OPC_DMULT = 0x1C | OPC_SPECIAL,
159
OPC_DMULTU = 0x1D | OPC_SPECIAL,
160
OPC_DDIV = 0x1E | OPC_SPECIAL,
161
OPC_DDIVU = 0x1F | OPC_SPECIAL,
162
/* 2 registers arithmetic / logic */
163
OPC_ADD = 0x20 | OPC_SPECIAL,
164
OPC_ADDU = 0x21 | OPC_SPECIAL,
165
OPC_SUB = 0x22 | OPC_SPECIAL,
166
OPC_SUBU = 0x23 | OPC_SPECIAL,
167
OPC_AND = 0x24 | OPC_SPECIAL,
168
OPC_OR = 0x25 | OPC_SPECIAL,
169
OPC_XOR = 0x26 | OPC_SPECIAL,
170
OPC_NOR = 0x27 | OPC_SPECIAL,
171
OPC_SLT = 0x2A | OPC_SPECIAL,
172
OPC_SLTU = 0x2B | OPC_SPECIAL,
173
OPC_DADD = 0x2C | OPC_SPECIAL,
174
OPC_DADDU = 0x2D | OPC_SPECIAL,
175
OPC_DSUB = 0x2E | OPC_SPECIAL,
176
OPC_DSUBU = 0x2F | OPC_SPECIAL,
178
OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
179
OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
180
OPC_JALRC = OPC_JALR | (0x5 << 6),
181
OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
183
OPC_TGE = 0x30 | OPC_SPECIAL,
184
OPC_TGEU = 0x31 | OPC_SPECIAL,
185
OPC_TLT = 0x32 | OPC_SPECIAL,
186
OPC_TLTU = 0x33 | OPC_SPECIAL,
187
OPC_TEQ = 0x34 | OPC_SPECIAL,
188
OPC_TNE = 0x36 | OPC_SPECIAL,
189
/* HI / LO registers load & stores */
190
OPC_MFHI = 0x10 | OPC_SPECIAL,
191
OPC_MTHI = 0x11 | OPC_SPECIAL,
192
OPC_MFLO = 0x12 | OPC_SPECIAL,
193
OPC_MTLO = 0x13 | OPC_SPECIAL,
194
/* Conditional moves */
195
OPC_MOVZ = 0x0A | OPC_SPECIAL,
196
OPC_MOVN = 0x0B | OPC_SPECIAL,
198
OPC_MOVCI = 0x01 | OPC_SPECIAL,
201
OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
202
OPC_SYSCALL = 0x0C | OPC_SPECIAL,
203
OPC_BREAK = 0x0D | OPC_SPECIAL,
204
OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
205
OPC_SYNC = 0x0F | OPC_SPECIAL,
207
OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
208
OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
209
OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
210
OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
211
OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
212
OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
213
OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
216
/* Multiplication variants of the vr54xx. */
217
#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
220
OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
221
OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
222
OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
223
OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
224
OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
225
OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
226
OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
227
OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
228
OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
229
OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
230
OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
231
OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
232
OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
233
OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
236
/* REGIMM (rt field) opcodes */
237
#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
240
OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
241
OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
242
OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
243
OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
244
OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
245
OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
246
OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
247
OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
248
OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
249
OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
250
OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
251
OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
252
OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
253
OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
254
OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
255
OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
256
OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
259
/* Special2 opcodes */
260
#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
263
/* Multiply & xxx operations */
264
OPC_MADD = 0x00 | OPC_SPECIAL2,
265
OPC_MADDU = 0x01 | OPC_SPECIAL2,
266
OPC_MUL = 0x02 | OPC_SPECIAL2,
267
OPC_MSUB = 0x04 | OPC_SPECIAL2,
268
OPC_MSUBU = 0x05 | OPC_SPECIAL2,
270
OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
271
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
272
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
273
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
274
OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
275
OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
276
OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
277
OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
278
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
279
OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
280
OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
281
OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
283
OPC_CLZ = 0x20 | OPC_SPECIAL2,
284
OPC_CLO = 0x21 | OPC_SPECIAL2,
285
OPC_DCLZ = 0x24 | OPC_SPECIAL2,
286
OPC_DCLO = 0x25 | OPC_SPECIAL2,
288
OPC_SDBBP = 0x3F | OPC_SPECIAL2,
291
/* Special3 opcodes */
292
#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
295
OPC_EXT = 0x00 | OPC_SPECIAL3,
296
OPC_DEXTM = 0x01 | OPC_SPECIAL3,
297
OPC_DEXTU = 0x02 | OPC_SPECIAL3,
298
OPC_DEXT = 0x03 | OPC_SPECIAL3,
299
OPC_INS = 0x04 | OPC_SPECIAL3,
300
OPC_DINSM = 0x05 | OPC_SPECIAL3,
301
OPC_DINSU = 0x06 | OPC_SPECIAL3,
302
OPC_DINS = 0x07 | OPC_SPECIAL3,
303
OPC_FORK = 0x08 | OPC_SPECIAL3,
304
OPC_YIELD = 0x09 | OPC_SPECIAL3,
305
OPC_BSHFL = 0x20 | OPC_SPECIAL3,
306
OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
307
OPC_RDHWR = 0x3B | OPC_SPECIAL3,
310
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
311
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
312
OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
313
OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
314
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
315
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
316
OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
317
OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
318
OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
319
OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
320
OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
321
OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
325
#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
328
OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
329
OPC_SEB = (0x10 << 6) | OPC_BSHFL,
330
OPC_SEH = (0x18 << 6) | OPC_BSHFL,
334
#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
337
OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
338
OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
341
/* Coprocessor 0 (rs field) */
342
#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
345
OPC_MFC0 = (0x00 << 21) | OPC_CP0,
346
OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
347
OPC_MTC0 = (0x04 << 21) | OPC_CP0,
348
OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
349
OPC_MFTR = (0x08 << 21) | OPC_CP0,
350
OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
351
OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
352
OPC_MTTR = (0x0C << 21) | OPC_CP0,
353
OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
354
OPC_C0 = (0x10 << 21) | OPC_CP0,
355
OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
356
OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
360
#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
363
OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
364
OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
365
OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
366
OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
367
OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
368
OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
371
/* Coprocessor 0 (with rs == C0) */
372
#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
375
OPC_TLBR = 0x01 | OPC_C0,
376
OPC_TLBWI = 0x02 | OPC_C0,
377
OPC_TLBWR = 0x06 | OPC_C0,
378
OPC_TLBP = 0x08 | OPC_C0,
379
OPC_RFE = 0x10 | OPC_C0,
380
OPC_ERET = 0x18 | OPC_C0,
381
OPC_DERET = 0x1F | OPC_C0,
382
OPC_WAIT = 0x20 | OPC_C0,
385
/* Coprocessor 1 (rs field) */
386
#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
388
/* Values for the fmt field in FP instructions */
390
/* 0 - 15 are reserved */
391
FMT_S = 16, /* single fp */
392
FMT_D = 17, /* double fp */
393
FMT_E = 18, /* extended fp */
394
FMT_Q = 19, /* quad fp */
395
FMT_W = 20, /* 32-bit fixed */
396
FMT_L = 21, /* 64-bit fixed */
397
FMT_PS = 22, /* paired single fp */
398
/* 23 - 31 are reserved */
402
OPC_MFC1 = (0x00 << 21) | OPC_CP1,
403
OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
404
OPC_CFC1 = (0x02 << 21) | OPC_CP1,
405
OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
406
OPC_MTC1 = (0x04 << 21) | OPC_CP1,
407
OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
408
OPC_CTC1 = (0x06 << 21) | OPC_CP1,
409
OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
410
OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
411
OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
412
OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
413
OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
414
OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
415
OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
416
OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
417
OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
418
OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
419
OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
422
#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
423
#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
426
OPC_BC1F = (0x00 << 16) | OPC_BC1,
427
OPC_BC1T = (0x01 << 16) | OPC_BC1,
428
OPC_BC1FL = (0x02 << 16) | OPC_BC1,
429
OPC_BC1TL = (0x03 << 16) | OPC_BC1,
433
OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
434
OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
438
OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
439
OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
442
#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
445
OPC_MFC2 = (0x00 << 21) | OPC_CP2,
446
OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
447
OPC_CFC2 = (0x02 << 21) | OPC_CP2,
448
OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
449
OPC_MTC2 = (0x04 << 21) | OPC_CP2,
450
OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
451
OPC_CTC2 = (0x06 << 21) | OPC_CP2,
452
OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
453
OPC_BC2 = (0x08 << 21) | OPC_CP2,
456
#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
459
OPC_LWXC1 = 0x00 | OPC_CP3,
460
OPC_LDXC1 = 0x01 | OPC_CP3,
461
OPC_LUXC1 = 0x05 | OPC_CP3,
462
OPC_SWXC1 = 0x08 | OPC_CP3,
463
OPC_SDXC1 = 0x09 | OPC_CP3,
464
OPC_SUXC1 = 0x0D | OPC_CP3,
465
OPC_PREFX = 0x0F | OPC_CP3,
466
OPC_ALNV_PS = 0x1E | OPC_CP3,
467
OPC_MADD_S = 0x20 | OPC_CP3,
468
OPC_MADD_D = 0x21 | OPC_CP3,
469
OPC_MADD_PS = 0x26 | OPC_CP3,
470
OPC_MSUB_S = 0x28 | OPC_CP3,
471
OPC_MSUB_D = 0x29 | OPC_CP3,
472
OPC_MSUB_PS = 0x2E | OPC_CP3,
473
OPC_NMADD_S = 0x30 | OPC_CP3,
474
OPC_NMADD_D = 0x31 | OPC_CP3,
475
OPC_NMADD_PS= 0x36 | OPC_CP3,
476
OPC_NMSUB_S = 0x38 | OPC_CP3,
477
OPC_NMSUB_D = 0x39 | OPC_CP3,
478
OPC_NMSUB_PS= 0x3E | OPC_CP3,
481
/* global register indices */
482
static TCGv_ptr cpu_env;
483
static TCGv cpu_gpr[32], cpu_PC;
484
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
485
static TCGv cpu_dspctrl, btarget, bcond;
486
static TCGv_i32 hflags;
487
static TCGv_i32 fpu_fcr0, fpu_fcr31;
489
static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
491
#include "gen-icount.h"
493
#define gen_helper_0i(name, arg) do { \
494
TCGv_i32 helper_tmp = tcg_const_i32(arg); \
495
gen_helper_##name(helper_tmp); \
496
tcg_temp_free_i32(helper_tmp); \
499
#define gen_helper_1i(name, arg1, arg2) do { \
500
TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
501
gen_helper_##name(arg1, helper_tmp); \
502
tcg_temp_free_i32(helper_tmp); \
505
#define gen_helper_2i(name, arg1, arg2, arg3) do { \
506
TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
507
gen_helper_##name(arg1, arg2, helper_tmp); \
508
tcg_temp_free_i32(helper_tmp); \
511
#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
512
TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
513
gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
514
tcg_temp_free_i32(helper_tmp); \
517
typedef struct DisasContext {
518
struct TranslationBlock *tb;
519
target_ulong pc, saved_pc;
521
int singlestep_enabled;
522
/* Routine used to access memory */
524
uint32_t hflags, saved_hflags;
526
target_ulong btarget;
530
BS_NONE = 0, /* We go out of the TB without reaching a branch or an
531
* exception condition */
532
BS_STOP = 1, /* We want to stop translation for any reason */
533
BS_BRANCH = 2, /* We reached a branch condition */
534
BS_EXCP = 3, /* We reached an exception condition */
537
static const char *regnames[] =
538
{ "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
539
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
540
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
541
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
543
static const char *regnames_HI[] =
544
{ "HI0", "HI1", "HI2", "HI3", };
546
static const char *regnames_LO[] =
547
{ "LO0", "LO1", "LO2", "LO3", };
549
static const char *regnames_ACX[] =
550
{ "ACX0", "ACX1", "ACX2", "ACX3", };
552
static const char *fregnames[] =
553
{ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
554
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
555
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
556
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
558
#ifdef MIPS_DEBUG_DISAS
559
#define MIPS_DEBUG(fmt, ...) \
560
qemu_log_mask(CPU_LOG_TB_IN_ASM, \
561
TARGET_FMT_lx ": %08x " fmt "\n", \
562
ctx->pc, ctx->opcode , ## __VA_ARGS__)
563
#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
565
#define MIPS_DEBUG(fmt, ...) do { } while(0)
566
#define LOG_DISAS(...) do { } while (0)
569
#define MIPS_INVAL(op) \
571
MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
572
ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
575
/* General purpose registers moves. */
576
static inline void gen_load_gpr (TCGv t, int reg)
579
tcg_gen_movi_tl(t, 0);
581
tcg_gen_mov_tl(t, cpu_gpr[reg]);
584
static inline void gen_store_gpr (TCGv t, int reg)
587
tcg_gen_mov_tl(cpu_gpr[reg], t);
590
/* Moves to/from ACX register. */
591
static inline void gen_load_ACX (TCGv t, int reg)
593
tcg_gen_mov_tl(t, cpu_ACX[reg]);
596
static inline void gen_store_ACX (TCGv t, int reg)
598
tcg_gen_mov_tl(cpu_ACX[reg], t);
601
/* Moves to/from shadow registers. */
602
static inline void gen_load_srsgpr (int from, int to)
604
TCGv t0 = tcg_temp_new();
607
tcg_gen_movi_tl(t0, 0);
609
TCGv_i32 t2 = tcg_temp_new_i32();
610
TCGv_ptr addr = tcg_temp_new_ptr();
612
tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
613
tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
614
tcg_gen_andi_i32(t2, t2, 0xf);
615
tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
616
tcg_gen_ext_i32_ptr(addr, t2);
617
tcg_gen_add_ptr(addr, cpu_env, addr);
619
tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
620
tcg_temp_free_ptr(addr);
621
tcg_temp_free_i32(t2);
623
gen_store_gpr(t0, to);
627
static inline void gen_store_srsgpr (int from, int to)
630
TCGv t0 = tcg_temp_new();
631
TCGv_i32 t2 = tcg_temp_new_i32();
632
TCGv_ptr addr = tcg_temp_new_ptr();
634
gen_load_gpr(t0, from);
635
tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
636
tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
637
tcg_gen_andi_i32(t2, t2, 0xf);
638
tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
639
tcg_gen_ext_i32_ptr(addr, t2);
640
tcg_gen_add_ptr(addr, cpu_env, addr);
642
tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
643
tcg_temp_free_ptr(addr);
644
tcg_temp_free_i32(t2);
649
/* Floating point register moves. */
650
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
652
tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
655
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
657
tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
660
static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
662
tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
665
static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
667
tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
670
static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
672
if (ctx->hflags & MIPS_HFLAG_F64) {
673
tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
675
TCGv_i32 t0 = tcg_temp_new_i32();
676
TCGv_i32 t1 = tcg_temp_new_i32();
677
gen_load_fpr32(t0, reg & ~1);
678
gen_load_fpr32(t1, reg | 1);
679
tcg_gen_concat_i32_i64(t, t0, t1);
680
tcg_temp_free_i32(t0);
681
tcg_temp_free_i32(t1);
685
static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
687
if (ctx->hflags & MIPS_HFLAG_F64) {
688
tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
690
TCGv_i64 t0 = tcg_temp_new_i64();
691
TCGv_i32 t1 = tcg_temp_new_i32();
692
tcg_gen_trunc_i64_i32(t1, t);
693
gen_store_fpr32(t1, reg & ~1);
694
tcg_gen_shri_i64(t0, t, 32);
695
tcg_gen_trunc_i64_i32(t1, t0);
696
gen_store_fpr32(t1, reg | 1);
697
tcg_temp_free_i32(t1);
698
tcg_temp_free_i64(t0);
702
static inline int get_fp_bit (int cc)
711
static inline void gen_save_pc(target_ulong pc)
713
tcg_gen_movi_tl(cpu_PC, pc);
716
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
718
LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
719
if (do_save_pc && ctx->pc != ctx->saved_pc) {
720
gen_save_pc(ctx->pc);
721
ctx->saved_pc = ctx->pc;
723
if (ctx->hflags != ctx->saved_hflags) {
724
tcg_gen_movi_i32(hflags, ctx->hflags);
725
ctx->saved_hflags = ctx->hflags;
726
switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
732
tcg_gen_movi_tl(btarget, ctx->btarget);
738
static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
740
ctx->saved_hflags = ctx->hflags;
741
switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
747
ctx->btarget = env->btarget;
753
generate_exception_err (DisasContext *ctx, int excp, int err)
755
TCGv_i32 texcp = tcg_const_i32(excp);
756
TCGv_i32 terr = tcg_const_i32(err);
757
save_cpu_state(ctx, 1);
758
gen_helper_raise_exception_err(texcp, terr);
759
tcg_temp_free_i32(terr);
760
tcg_temp_free_i32(texcp);
764
generate_exception (DisasContext *ctx, int excp)
766
save_cpu_state(ctx, 1);
767
gen_helper_0i(raise_exception, excp);
770
/* Addresses computation */
771
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
773
tcg_gen_add_tl(ret, arg0, arg1);
775
#if defined(TARGET_MIPS64)
776
/* For compatibility with 32-bit code, data reference in user mode
777
with Status_UX = 0 should be casted to 32-bit and sign extended.
778
See the MIPS64 PRA manual, section 4.10. */
779
if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
780
!(ctx->hflags & MIPS_HFLAG_UX)) {
781
tcg_gen_ext32s_i64(ret, ret);
786
static inline void check_cp0_enabled(DisasContext *ctx)
788
if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
789
generate_exception_err(ctx, EXCP_CpU, 0);
792
static inline void check_cp1_enabled(DisasContext *ctx)
794
if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
795
generate_exception_err(ctx, EXCP_CpU, 1);
798
/* Verify that the processor is running with COP1X instructions enabled.
799
This is associated with the nabla symbol in the MIPS32 and MIPS64
802
static inline void check_cop1x(DisasContext *ctx)
804
if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
805
generate_exception(ctx, EXCP_RI);
808
/* Verify that the processor is running with 64-bit floating-point
809
operations enabled. */
811
static inline void check_cp1_64bitmode(DisasContext *ctx)
813
if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
814
generate_exception(ctx, EXCP_RI);
818
* Verify if floating point register is valid; an operation is not defined
819
* if bit 0 of any register specification is set and the FR bit in the
820
* Status register equals zero, since the register numbers specify an
821
* even-odd pair of adjacent coprocessor general registers. When the FR bit
822
* in the Status register equals one, both even and odd register numbers
823
* are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
825
* Multiple 64 bit wide registers can be checked by calling
826
* gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
828
static inline void check_cp1_registers(DisasContext *ctx, int regs)
830
if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
831
generate_exception(ctx, EXCP_RI);
834
/* This code generates a "reserved instruction" exception if the
835
CPU does not support the instruction set corresponding to flags. */
836
static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
838
if (unlikely(!(env->insn_flags & flags)))
839
generate_exception(ctx, EXCP_RI);
842
/* This code generates a "reserved instruction" exception if 64-bit
843
instructions are not enabled. */
844
static inline void check_mips_64(DisasContext *ctx)
846
if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
847
generate_exception(ctx, EXCP_RI);
850
/* Define small wrappers for gen_load_fpr* so that we have a uniform
851
calling interface for 32 and 64-bit FPRs. No sense in changing
852
all callers for gen_load_fpr32 when we need the CTX parameter for
854
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
855
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
856
#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
857
static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
858
int ft, int fs, int cc) \
860
TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
861
TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
864
check_cp1_64bitmode(ctx); \
870
check_cp1_registers(ctx, fs | ft); \
878
gen_ldcmp_fpr##bits (ctx, fp0, fs); \
879
gen_ldcmp_fpr##bits (ctx, fp1, ft); \
881
case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
882
case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
883
case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
884
case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
885
case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
886
case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
887
case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
888
case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
889
case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
890
case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
891
case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
892
case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
893
case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
894
case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
895
case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
896
case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
899
tcg_temp_free_i##bits (fp0); \
900
tcg_temp_free_i##bits (fp1); \
903
FOP_CONDS(, 0, d, FMT_D, 64)
904
FOP_CONDS(abs, 1, d, FMT_D, 64)
905
FOP_CONDS(, 0, s, FMT_S, 32)
906
FOP_CONDS(abs, 1, s, FMT_S, 32)
907
FOP_CONDS(, 0, ps, FMT_PS, 64)
908
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
910
#undef gen_ldcmp_fpr32
911
#undef gen_ldcmp_fpr64
913
/* load/store instructions. */
914
#define OP_LD(insn,fname) \
915
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
917
tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
924
#if defined(TARGET_MIPS64)
930
#define OP_ST(insn,fname) \
931
static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
933
tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
938
#if defined(TARGET_MIPS64)
943
#ifdef CONFIG_USER_ONLY
944
#define OP_LD_ATOMIC(insn,fname) \
945
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
947
TCGv t0 = tcg_temp_new(); \
948
tcg_gen_mov_tl(t0, arg1); \
949
tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
950
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
951
tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval)); \
955
#define OP_LD_ATOMIC(insn,fname) \
956
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
958
gen_helper_2i(insn, ret, arg1, ctx->mem_idx); \
961
OP_LD_ATOMIC(ll,ld32s);
962
#if defined(TARGET_MIPS64)
963
OP_LD_ATOMIC(lld,ld64);
967
#ifdef CONFIG_USER_ONLY
968
#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
969
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
971
TCGv t0 = tcg_temp_new(); \
972
int l1 = gen_new_label(); \
973
int l2 = gen_new_label(); \
975
tcg_gen_andi_tl(t0, arg2, almask); \
976
tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
977
tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
978
generate_exception(ctx, EXCP_AdES); \
980
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
981
tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
982
tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
983
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg)); \
984
tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval)); \
985
gen_helper_0i(raise_exception, EXCP_SC); \
987
tcg_gen_movi_tl(t0, 0); \
988
gen_store_gpr(t0, rt); \
992
#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
993
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
995
TCGv t0 = tcg_temp_new(); \
996
gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx); \
997
gen_store_gpr(t0, rt); \
1001
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1002
#if defined(TARGET_MIPS64)
1003
OP_ST_ATOMIC(scd,st64,ld64,0x7);
1007
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1008
int base, int16_t offset)
1011
tcg_gen_movi_tl(addr, offset);
1012
} else if (offset == 0) {
1013
gen_load_gpr(addr, base);
1015
tcg_gen_movi_tl(addr, offset);
1016
gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1020
static target_ulong pc_relative_pc (DisasContext *ctx)
1022
target_ulong pc = ctx->pc;
1024
if (ctx->hflags & MIPS_HFLAG_BMASK) {
1025
int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1030
pc &= ~(target_ulong)3;
1035
static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
1036
int rt, int base, int16_t offset)
1038
const char *opn = "ld";
1041
if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1042
/* Loongson CPU uses a load to zero register for prefetch.
1043
We emulate it as a NOP. On other CPU we must perform the
1044
actual memory access. */
1049
t0 = tcg_temp_new();
1050
t1 = tcg_temp_new();
1051
gen_base_offset_addr(ctx, t0, base, offset);
1054
#if defined(TARGET_MIPS64)
1056
save_cpu_state(ctx, 0);
1057
op_ld_lwu(t0, t0, ctx);
1058
gen_store_gpr(t0, rt);
1062
save_cpu_state(ctx, 0);
1063
op_ld_ld(t0, t0, ctx);
1064
gen_store_gpr(t0, rt);
1068
save_cpu_state(ctx, 1);
1069
op_ld_lld(t0, t0, ctx);
1070
gen_store_gpr(t0, rt);
1074
save_cpu_state(ctx, 1);
1075
gen_load_gpr(t1, rt);
1076
gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1077
gen_store_gpr(t1, rt);
1081
save_cpu_state(ctx, 1);
1082
gen_load_gpr(t1, rt);
1083
gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1084
gen_store_gpr(t1, rt);
1088
save_cpu_state(ctx, 0);
1089
tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1090
gen_op_addr_add(ctx, t0, t0, t1);
1091
op_ld_ld(t0, t0, ctx);
1092
gen_store_gpr(t0, rt);
1097
save_cpu_state(ctx, 0);
1098
tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1099
gen_op_addr_add(ctx, t0, t0, t1);
1100
op_ld_lw(t0, t0, ctx);
1101
gen_store_gpr(t0, rt);
1105
save_cpu_state(ctx, 0);
1106
op_ld_lw(t0, t0, ctx);
1107
gen_store_gpr(t0, rt);
1111
save_cpu_state(ctx, 0);
1112
op_ld_lh(t0, t0, ctx);
1113
gen_store_gpr(t0, rt);
1117
save_cpu_state(ctx, 0);
1118
op_ld_lhu(t0, t0, ctx);
1119
gen_store_gpr(t0, rt);
1123
save_cpu_state(ctx, 0);
1124
op_ld_lb(t0, t0, ctx);
1125
gen_store_gpr(t0, rt);
1129
save_cpu_state(ctx, 0);
1130
op_ld_lbu(t0, t0, ctx);
1131
gen_store_gpr(t0, rt);
1135
save_cpu_state(ctx, 1);
1136
gen_load_gpr(t1, rt);
1137
gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1138
gen_store_gpr(t1, rt);
1142
save_cpu_state(ctx, 1);
1143
gen_load_gpr(t1, rt);
1144
gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1145
gen_store_gpr(t1, rt);
1149
save_cpu_state(ctx, 1);
1150
op_ld_ll(t0, t0, ctx);
1151
gen_store_gpr(t0, rt);
1155
(void)opn; /* avoid a compiler warning */
1156
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1162
static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1163
int base, int16_t offset)
1165
const char *opn = "st";
1166
TCGv t0 = tcg_temp_new();
1167
TCGv t1 = tcg_temp_new();
1169
gen_base_offset_addr(ctx, t0, base, offset);
1170
gen_load_gpr(t1, rt);
1172
#if defined(TARGET_MIPS64)
1174
save_cpu_state(ctx, 0);
1175
op_st_sd(t1, t0, ctx);
1179
save_cpu_state(ctx, 1);
1180
gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1184
save_cpu_state(ctx, 1);
1185
gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1190
save_cpu_state(ctx, 0);
1191
op_st_sw(t1, t0, ctx);
1195
save_cpu_state(ctx, 0);
1196
op_st_sh(t1, t0, ctx);
1200
save_cpu_state(ctx, 0);
1201
op_st_sb(t1, t0, ctx);
1205
save_cpu_state(ctx, 1);
1206
gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1210
save_cpu_state(ctx, 1);
1211
gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1215
(void)opn; /* avoid a compiler warning */
1216
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1222
/* Store conditional */
1223
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1224
int base, int16_t offset)
1226
const char *opn = "st_cond";
1229
t0 = tcg_temp_local_new();
1231
gen_base_offset_addr(ctx, t0, base, offset);
1232
/* Don't do NOP if destination is zero: we must perform the actual
1235
t1 = tcg_temp_local_new();
1236
gen_load_gpr(t1, rt);
1238
#if defined(TARGET_MIPS64)
1240
save_cpu_state(ctx, 1);
1241
op_st_scd(t1, t0, rt, ctx);
1246
save_cpu_state(ctx, 1);
1247
op_st_sc(t1, t0, rt, ctx);
1251
(void)opn; /* avoid a compiler warning */
1252
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1257
/* Load and store */
1258
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1259
int base, int16_t offset)
1261
const char *opn = "flt_ldst";
1262
TCGv t0 = tcg_temp_new();
1264
gen_base_offset_addr(ctx, t0, base, offset);
1265
/* Don't do NOP if destination is zero: we must perform the actual
1270
TCGv_i32 fp0 = tcg_temp_new_i32();
1272
tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1273
tcg_gen_trunc_tl_i32(fp0, t0);
1274
gen_store_fpr32(fp0, ft);
1275
tcg_temp_free_i32(fp0);
1281
TCGv_i32 fp0 = tcg_temp_new_i32();
1282
TCGv t1 = tcg_temp_new();
1284
gen_load_fpr32(fp0, ft);
1285
tcg_gen_extu_i32_tl(t1, fp0);
1286
tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1288
tcg_temp_free_i32(fp0);
1294
TCGv_i64 fp0 = tcg_temp_new_i64();
1296
tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1297
gen_store_fpr64(ctx, fp0, ft);
1298
tcg_temp_free_i64(fp0);
1304
TCGv_i64 fp0 = tcg_temp_new_i64();
1306
gen_load_fpr64(ctx, fp0, ft);
1307
tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1308
tcg_temp_free_i64(fp0);
1314
generate_exception(ctx, EXCP_RI);
1317
(void)opn; /* avoid a compiler warning */
1318
MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1323
static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
1324
uint32_t op, int rt, int rs, int16_t imm)
1326
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1327
check_cp1_enabled(ctx);
1328
gen_flt_ldst(ctx, op, rt, rs, imm);
1330
generate_exception_err(ctx, EXCP_CpU, 1);
1334
/* Arithmetic with immediate operand */
1335
static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1336
int rt, int rs, int16_t imm)
1338
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1339
const char *opn = "imm arith";
1341
if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1342
/* If no destination, treat it as a NOP.
1343
For addi, we must generate the overflow exception when needed. */
1350
TCGv t0 = tcg_temp_local_new();
1351
TCGv t1 = tcg_temp_new();
1352
TCGv t2 = tcg_temp_new();
1353
int l1 = gen_new_label();
1355
gen_load_gpr(t1, rs);
1356
tcg_gen_addi_tl(t0, t1, uimm);
1357
tcg_gen_ext32s_tl(t0, t0);
1359
tcg_gen_xori_tl(t1, t1, ~uimm);
1360
tcg_gen_xori_tl(t2, t0, uimm);
1361
tcg_gen_and_tl(t1, t1, t2);
1363
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1365
/* operands of same sign, result different sign */
1366
generate_exception(ctx, EXCP_OVERFLOW);
1368
tcg_gen_ext32s_tl(t0, t0);
1369
gen_store_gpr(t0, rt);
1376
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1377
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1379
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1383
#if defined(TARGET_MIPS64)
1386
TCGv t0 = tcg_temp_local_new();
1387
TCGv t1 = tcg_temp_new();
1388
TCGv t2 = tcg_temp_new();
1389
int l1 = gen_new_label();
1391
gen_load_gpr(t1, rs);
1392
tcg_gen_addi_tl(t0, t1, uimm);
1394
tcg_gen_xori_tl(t1, t1, ~uimm);
1395
tcg_gen_xori_tl(t2, t0, uimm);
1396
tcg_gen_and_tl(t1, t1, t2);
1398
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1400
/* operands of same sign, result different sign */
1401
generate_exception(ctx, EXCP_OVERFLOW);
1403
gen_store_gpr(t0, rt);
1410
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1412
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1418
(void)opn; /* avoid a compiler warning */
1419
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1422
/* Logic with immediate operand */
1423
static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1426
const char *opn = "imm logic";
1429
/* If no destination, treat it as a NOP. */
1433
uimm = (uint16_t)imm;
1436
if (likely(rs != 0))
1437
tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1439
tcg_gen_movi_tl(cpu_gpr[rt], 0);
1444
tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1446
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1450
if (likely(rs != 0))
1451
tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1453
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1457
tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1461
(void)opn; /* avoid a compiler warning */
1462
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1465
/* Set on less than with immediate operand */
1466
static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1468
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1469
const char *opn = "imm arith";
1473
/* If no destination, treat it as a NOP. */
1477
t0 = tcg_temp_new();
1478
gen_load_gpr(t0, rs);
1481
tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1485
tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1489
(void)opn; /* avoid a compiler warning */
1490
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1494
/* Shifts with immediate operand */
1495
static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1496
int rt, int rs, int16_t imm)
1498
target_ulong uimm = ((uint16_t)imm) & 0x1f;
1499
const char *opn = "imm shift";
1503
/* If no destination, treat it as a NOP. */
1508
t0 = tcg_temp_new();
1509
gen_load_gpr(t0, rs);
1512
tcg_gen_shli_tl(t0, t0, uimm);
1513
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1517
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1522
tcg_gen_ext32u_tl(t0, t0);
1523
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1525
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1531
TCGv_i32 t1 = tcg_temp_new_i32();
1533
tcg_gen_trunc_tl_i32(t1, t0);
1534
tcg_gen_rotri_i32(t1, t1, uimm);
1535
tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1536
tcg_temp_free_i32(t1);
1538
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1542
#if defined(TARGET_MIPS64)
1544
tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1548
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1552
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1557
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1559
tcg_gen_mov_tl(cpu_gpr[rt], t0);
1564
tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1568
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1572
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1576
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1581
(void)opn; /* avoid a compiler warning */
1582
MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1587
static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1588
int rd, int rs, int rt)
1590
const char *opn = "arith";
1592
if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1593
&& opc != OPC_DADD && opc != OPC_DSUB) {
1594
/* If no destination, treat it as a NOP.
1595
For add & sub, we must generate the overflow exception when needed. */
1603
TCGv t0 = tcg_temp_local_new();
1604
TCGv t1 = tcg_temp_new();
1605
TCGv t2 = tcg_temp_new();
1606
int l1 = gen_new_label();
1608
gen_load_gpr(t1, rs);
1609
gen_load_gpr(t2, rt);
1610
tcg_gen_add_tl(t0, t1, t2);
1611
tcg_gen_ext32s_tl(t0, t0);
1612
tcg_gen_xor_tl(t1, t1, t2);
1613
tcg_gen_xor_tl(t2, t0, t2);
1614
tcg_gen_andc_tl(t1, t2, t1);
1616
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1618
/* operands of same sign, result different sign */
1619
generate_exception(ctx, EXCP_OVERFLOW);
1621
gen_store_gpr(t0, rd);
1627
if (rs != 0 && rt != 0) {
1628
tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1629
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1630
} else if (rs == 0 && rt != 0) {
1631
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1632
} else if (rs != 0 && rt == 0) {
1633
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1635
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1641
TCGv t0 = tcg_temp_local_new();
1642
TCGv t1 = tcg_temp_new();
1643
TCGv t2 = tcg_temp_new();
1644
int l1 = gen_new_label();
1646
gen_load_gpr(t1, rs);
1647
gen_load_gpr(t2, rt);
1648
tcg_gen_sub_tl(t0, t1, t2);
1649
tcg_gen_ext32s_tl(t0, t0);
1650
tcg_gen_xor_tl(t2, t1, t2);
1651
tcg_gen_xor_tl(t1, t0, t1);
1652
tcg_gen_and_tl(t1, t1, t2);
1654
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1656
/* operands of different sign, first operand and result different sign */
1657
generate_exception(ctx, EXCP_OVERFLOW);
1659
gen_store_gpr(t0, rd);
1665
if (rs != 0 && rt != 0) {
1666
tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1667
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1668
} else if (rs == 0 && rt != 0) {
1669
tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1670
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1671
} else if (rs != 0 && rt == 0) {
1672
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1674
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1678
#if defined(TARGET_MIPS64)
1681
TCGv t0 = tcg_temp_local_new();
1682
TCGv t1 = tcg_temp_new();
1683
TCGv t2 = tcg_temp_new();
1684
int l1 = gen_new_label();
1686
gen_load_gpr(t1, rs);
1687
gen_load_gpr(t2, rt);
1688
tcg_gen_add_tl(t0, t1, t2);
1689
tcg_gen_xor_tl(t1, t1, t2);
1690
tcg_gen_xor_tl(t2, t0, t2);
1691
tcg_gen_andc_tl(t1, t2, t1);
1693
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1695
/* operands of same sign, result different sign */
1696
generate_exception(ctx, EXCP_OVERFLOW);
1698
gen_store_gpr(t0, rd);
1704
if (rs != 0 && rt != 0) {
1705
tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1706
} else if (rs == 0 && rt != 0) {
1707
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1708
} else if (rs != 0 && rt == 0) {
1709
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1711
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1717
TCGv t0 = tcg_temp_local_new();
1718
TCGv t1 = tcg_temp_new();
1719
TCGv t2 = tcg_temp_new();
1720
int l1 = gen_new_label();
1722
gen_load_gpr(t1, rs);
1723
gen_load_gpr(t2, rt);
1724
tcg_gen_sub_tl(t0, t1, t2);
1725
tcg_gen_xor_tl(t2, t1, t2);
1726
tcg_gen_xor_tl(t1, t0, t1);
1727
tcg_gen_and_tl(t1, t1, t2);
1729
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1731
/* operands of different sign, first operand and result different sign */
1732
generate_exception(ctx, EXCP_OVERFLOW);
1734
gen_store_gpr(t0, rd);
1740
if (rs != 0 && rt != 0) {
1741
tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1742
} else if (rs == 0 && rt != 0) {
1743
tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1744
} else if (rs != 0 && rt == 0) {
1745
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1747
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1753
if (likely(rs != 0 && rt != 0)) {
1754
tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1755
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1757
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1762
(void)opn; /* avoid a compiler warning */
1763
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1766
/* Conditional move */
1767
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1769
const char *opn = "cond move";
1773
/* If no destination, treat it as a NOP.
1774
For add & sub, we must generate the overflow exception when needed. */
1779
l1 = gen_new_label();
1782
if (likely(rt != 0))
1783
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1789
if (likely(rt != 0))
1790
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1795
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1797
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1800
(void)opn; /* avoid a compiler warning */
1801
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1805
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1807
const char *opn = "logic";
1810
/* If no destination, treat it as a NOP. */
1817
if (likely(rs != 0 && rt != 0)) {
1818
tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1820
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1825
if (rs != 0 && rt != 0) {
1826
tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1827
} else if (rs == 0 && rt != 0) {
1828
tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1829
} else if (rs != 0 && rt == 0) {
1830
tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1832
tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1837
if (likely(rs != 0 && rt != 0)) {
1838
tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1839
} else if (rs == 0 && rt != 0) {
1840
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1841
} else if (rs != 0 && rt == 0) {
1842
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1844
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1849
if (likely(rs != 0 && rt != 0)) {
1850
tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1851
} else if (rs == 0 && rt != 0) {
1852
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1853
} else if (rs != 0 && rt == 0) {
1854
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1856
tcg_gen_movi_tl(cpu_gpr[rd], 0);
1861
(void)opn; /* avoid a compiler warning */
1862
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1865
/* Set on lower than */
1866
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1868
const char *opn = "slt";
1872
/* If no destination, treat it as a NOP. */
1877
t0 = tcg_temp_new();
1878
t1 = tcg_temp_new();
1879
gen_load_gpr(t0, rs);
1880
gen_load_gpr(t1, rt);
1883
tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1887
tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1891
(void)opn; /* avoid a compiler warning */
1892
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1898
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1899
int rd, int rs, int rt)
1901
const char *opn = "shifts";
1905
/* If no destination, treat it as a NOP.
1906
For add & sub, we must generate the overflow exception when needed. */
1911
t0 = tcg_temp_new();
1912
t1 = tcg_temp_new();
1913
gen_load_gpr(t0, rs);
1914
gen_load_gpr(t1, rt);
1917
tcg_gen_andi_tl(t0, t0, 0x1f);
1918
tcg_gen_shl_tl(t0, t1, t0);
1919
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1923
tcg_gen_andi_tl(t0, t0, 0x1f);
1924
tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1928
tcg_gen_ext32u_tl(t1, t1);
1929
tcg_gen_andi_tl(t0, t0, 0x1f);
1930
tcg_gen_shr_tl(t0, t1, t0);
1931
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1936
TCGv_i32 t2 = tcg_temp_new_i32();
1937
TCGv_i32 t3 = tcg_temp_new_i32();
1939
tcg_gen_trunc_tl_i32(t2, t0);
1940
tcg_gen_trunc_tl_i32(t3, t1);
1941
tcg_gen_andi_i32(t2, t2, 0x1f);
1942
tcg_gen_rotr_i32(t2, t3, t2);
1943
tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1944
tcg_temp_free_i32(t2);
1945
tcg_temp_free_i32(t3);
1949
#if defined(TARGET_MIPS64)
1951
tcg_gen_andi_tl(t0, t0, 0x3f);
1952
tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1956
tcg_gen_andi_tl(t0, t0, 0x3f);
1957
tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1961
tcg_gen_andi_tl(t0, t0, 0x3f);
1962
tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1966
tcg_gen_andi_tl(t0, t0, 0x3f);
1967
tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1972
(void)opn; /* avoid a compiler warning */
1973
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1978
/* Arithmetic on HI/LO registers */
1979
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1981
const char *opn = "hilo";
1983
if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1990
tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1994
tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1999
tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
2001
tcg_gen_movi_tl(cpu_HI[0], 0);
2006
tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2008
tcg_gen_movi_tl(cpu_LO[0], 0);
2012
(void)opn; /* avoid a compiler warning */
2013
MIPS_DEBUG("%s %s", opn, regnames[reg]);
2016
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2019
const char *opn = "mul/div";
2025
#if defined(TARGET_MIPS64)
2029
t0 = tcg_temp_local_new();
2030
t1 = tcg_temp_local_new();
2033
t0 = tcg_temp_new();
2034
t1 = tcg_temp_new();
2038
gen_load_gpr(t0, rs);
2039
gen_load_gpr(t1, rt);
2043
int l1 = gen_new_label();
2044
int l2 = gen_new_label();
2046
tcg_gen_ext32s_tl(t0, t0);
2047
tcg_gen_ext32s_tl(t1, t1);
2048
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2049
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2050
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2052
tcg_gen_mov_tl(cpu_LO[0], t0);
2053
tcg_gen_movi_tl(cpu_HI[0], 0);
2056
tcg_gen_div_tl(cpu_LO[0], t0, t1);
2057
tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2058
tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2059
tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2066
int l1 = gen_new_label();
2068
tcg_gen_ext32u_tl(t0, t0);
2069
tcg_gen_ext32u_tl(t1, t1);
2070
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2071
tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2072
tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2073
tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2074
tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2081
TCGv_i64 t2 = tcg_temp_new_i64();
2082
TCGv_i64 t3 = tcg_temp_new_i64();
2084
tcg_gen_ext_tl_i64(t2, t0);
2085
tcg_gen_ext_tl_i64(t3, t1);
2086
tcg_gen_mul_i64(t2, t2, t3);
2087
tcg_temp_free_i64(t3);
2088
tcg_gen_trunc_i64_tl(t0, t2);
2089
tcg_gen_shri_i64(t2, t2, 32);
2090
tcg_gen_trunc_i64_tl(t1, t2);
2091
tcg_temp_free_i64(t2);
2092
tcg_gen_ext32s_tl(cpu_LO[0], t0);
2093
tcg_gen_ext32s_tl(cpu_HI[0], t1);
2099
TCGv_i64 t2 = tcg_temp_new_i64();
2100
TCGv_i64 t3 = tcg_temp_new_i64();
2102
tcg_gen_ext32u_tl(t0, t0);
2103
tcg_gen_ext32u_tl(t1, t1);
2104
tcg_gen_extu_tl_i64(t2, t0);
2105
tcg_gen_extu_tl_i64(t3, t1);
2106
tcg_gen_mul_i64(t2, t2, t3);
2107
tcg_temp_free_i64(t3);
2108
tcg_gen_trunc_i64_tl(t0, t2);
2109
tcg_gen_shri_i64(t2, t2, 32);
2110
tcg_gen_trunc_i64_tl(t1, t2);
2111
tcg_temp_free_i64(t2);
2112
tcg_gen_ext32s_tl(cpu_LO[0], t0);
2113
tcg_gen_ext32s_tl(cpu_HI[0], t1);
2117
#if defined(TARGET_MIPS64)
2120
int l1 = gen_new_label();
2121
int l2 = gen_new_label();
2123
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2124
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2125
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2126
tcg_gen_mov_tl(cpu_LO[0], t0);
2127
tcg_gen_movi_tl(cpu_HI[0], 0);
2130
tcg_gen_div_i64(cpu_LO[0], t0, t1);
2131
tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2138
int l1 = gen_new_label();
2140
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2141
tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2142
tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2148
gen_helper_dmult(t0, t1);
2152
gen_helper_dmultu(t0, t1);
2158
TCGv_i64 t2 = tcg_temp_new_i64();
2159
TCGv_i64 t3 = tcg_temp_new_i64();
2161
tcg_gen_ext_tl_i64(t2, t0);
2162
tcg_gen_ext_tl_i64(t3, t1);
2163
tcg_gen_mul_i64(t2, t2, t3);
2164
tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2165
tcg_gen_add_i64(t2, t2, t3);
2166
tcg_temp_free_i64(t3);
2167
tcg_gen_trunc_i64_tl(t0, t2);
2168
tcg_gen_shri_i64(t2, t2, 32);
2169
tcg_gen_trunc_i64_tl(t1, t2);
2170
tcg_temp_free_i64(t2);
2171
tcg_gen_ext32s_tl(cpu_LO[0], t0);
2172
tcg_gen_ext32s_tl(cpu_HI[0], t1);
2178
TCGv_i64 t2 = tcg_temp_new_i64();
2179
TCGv_i64 t3 = tcg_temp_new_i64();
2181
tcg_gen_ext32u_tl(t0, t0);
2182
tcg_gen_ext32u_tl(t1, t1);
2183
tcg_gen_extu_tl_i64(t2, t0);
2184
tcg_gen_extu_tl_i64(t3, t1);
2185
tcg_gen_mul_i64(t2, t2, t3);
2186
tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2187
tcg_gen_add_i64(t2, t2, t3);
2188
tcg_temp_free_i64(t3);
2189
tcg_gen_trunc_i64_tl(t0, t2);
2190
tcg_gen_shri_i64(t2, t2, 32);
2191
tcg_gen_trunc_i64_tl(t1, t2);
2192
tcg_temp_free_i64(t2);
2193
tcg_gen_ext32s_tl(cpu_LO[0], t0);
2194
tcg_gen_ext32s_tl(cpu_HI[0], t1);
2200
TCGv_i64 t2 = tcg_temp_new_i64();
2201
TCGv_i64 t3 = tcg_temp_new_i64();
2203
tcg_gen_ext_tl_i64(t2, t0);
2204
tcg_gen_ext_tl_i64(t3, t1);
2205
tcg_gen_mul_i64(t2, t2, t3);
2206
tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2207
tcg_gen_sub_i64(t2, t3, t2);
2208
tcg_temp_free_i64(t3);
2209
tcg_gen_trunc_i64_tl(t0, t2);
2210
tcg_gen_shri_i64(t2, t2, 32);
2211
tcg_gen_trunc_i64_tl(t1, t2);
2212
tcg_temp_free_i64(t2);
2213
tcg_gen_ext32s_tl(cpu_LO[0], t0);
2214
tcg_gen_ext32s_tl(cpu_HI[0], t1);
2220
TCGv_i64 t2 = tcg_temp_new_i64();
2221
TCGv_i64 t3 = tcg_temp_new_i64();
2223
tcg_gen_ext32u_tl(t0, t0);
2224
tcg_gen_ext32u_tl(t1, t1);
2225
tcg_gen_extu_tl_i64(t2, t0);
2226
tcg_gen_extu_tl_i64(t3, t1);
2227
tcg_gen_mul_i64(t2, t2, t3);
2228
tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2229
tcg_gen_sub_i64(t2, t3, t2);
2230
tcg_temp_free_i64(t3);
2231
tcg_gen_trunc_i64_tl(t0, t2);
2232
tcg_gen_shri_i64(t2, t2, 32);
2233
tcg_gen_trunc_i64_tl(t1, t2);
2234
tcg_temp_free_i64(t2);
2235
tcg_gen_ext32s_tl(cpu_LO[0], t0);
2236
tcg_gen_ext32s_tl(cpu_HI[0], t1);
2242
generate_exception(ctx, EXCP_RI);
2245
(void)opn; /* avoid a compiler warning */
2246
MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2252
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2253
int rd, int rs, int rt)
2255
const char *opn = "mul vr54xx";
2256
TCGv t0 = tcg_temp_new();
2257
TCGv t1 = tcg_temp_new();
2259
gen_load_gpr(t0, rs);
2260
gen_load_gpr(t1, rt);
2263
case OPC_VR54XX_MULS:
2264
gen_helper_muls(t0, t0, t1);
2267
case OPC_VR54XX_MULSU:
2268
gen_helper_mulsu(t0, t0, t1);
2271
case OPC_VR54XX_MACC:
2272
gen_helper_macc(t0, t0, t1);
2275
case OPC_VR54XX_MACCU:
2276
gen_helper_maccu(t0, t0, t1);
2279
case OPC_VR54XX_MSAC:
2280
gen_helper_msac(t0, t0, t1);
2283
case OPC_VR54XX_MSACU:
2284
gen_helper_msacu(t0, t0, t1);
2287
case OPC_VR54XX_MULHI:
2288
gen_helper_mulhi(t0, t0, t1);
2291
case OPC_VR54XX_MULHIU:
2292
gen_helper_mulhiu(t0, t0, t1);
2295
case OPC_VR54XX_MULSHI:
2296
gen_helper_mulshi(t0, t0, t1);
2299
case OPC_VR54XX_MULSHIU:
2300
gen_helper_mulshiu(t0, t0, t1);
2303
case OPC_VR54XX_MACCHI:
2304
gen_helper_macchi(t0, t0, t1);
2307
case OPC_VR54XX_MACCHIU:
2308
gen_helper_macchiu(t0, t0, t1);
2311
case OPC_VR54XX_MSACHI:
2312
gen_helper_msachi(t0, t0, t1);
2315
case OPC_VR54XX_MSACHIU:
2316
gen_helper_msachiu(t0, t0, t1);
2320
MIPS_INVAL("mul vr54xx");
2321
generate_exception(ctx, EXCP_RI);
2324
gen_store_gpr(t0, rd);
2325
(void)opn; /* avoid a compiler warning */
2326
MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2333
static void gen_cl (DisasContext *ctx, uint32_t opc,
2336
const char *opn = "CLx";
2344
t0 = tcg_temp_new();
2345
gen_load_gpr(t0, rs);
2348
gen_helper_clo(cpu_gpr[rd], t0);
2352
gen_helper_clz(cpu_gpr[rd], t0);
2355
#if defined(TARGET_MIPS64)
2357
gen_helper_dclo(cpu_gpr[rd], t0);
2361
gen_helper_dclz(cpu_gpr[rd], t0);
2366
(void)opn; /* avoid a compiler warning */
2367
MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2371
/* Godson integer instructions */
2372
static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
2373
int rd, int rs, int rt)
2375
const char *opn = "loongson";
2387
case OPC_MULTU_G_2E:
2388
case OPC_MULTU_G_2F:
2389
#if defined(TARGET_MIPS64)
2390
case OPC_DMULT_G_2E:
2391
case OPC_DMULT_G_2F:
2392
case OPC_DMULTU_G_2E:
2393
case OPC_DMULTU_G_2F:
2395
t0 = tcg_temp_new();
2396
t1 = tcg_temp_new();
2399
t0 = tcg_temp_local_new();
2400
t1 = tcg_temp_local_new();
2404
gen_load_gpr(t0, rs);
2405
gen_load_gpr(t1, rt);
2410
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2411
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2414
case OPC_MULTU_G_2E:
2415
case OPC_MULTU_G_2F:
2416
tcg_gen_ext32u_tl(t0, t0);
2417
tcg_gen_ext32u_tl(t1, t1);
2418
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2419
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2425
int l1 = gen_new_label();
2426
int l2 = gen_new_label();
2427
int l3 = gen_new_label();
2428
tcg_gen_ext32s_tl(t0, t0);
2429
tcg_gen_ext32s_tl(t1, t1);
2430
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2431
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2434
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2435
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2436
tcg_gen_mov_tl(cpu_gpr[rd], t0);
2439
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2440
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2448
int l1 = gen_new_label();
2449
int l2 = gen_new_label();
2450
tcg_gen_ext32u_tl(t0, t0);
2451
tcg_gen_ext32u_tl(t1, t1);
2452
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2453
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2456
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2457
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2465
int l1 = gen_new_label();
2466
int l2 = gen_new_label();
2467
int l3 = gen_new_label();
2468
tcg_gen_ext32u_tl(t0, t0);
2469
tcg_gen_ext32u_tl(t1, t1);
2470
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2471
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2472
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2474
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2477
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2478
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2486
int l1 = gen_new_label();
2487
int l2 = gen_new_label();
2488
tcg_gen_ext32u_tl(t0, t0);
2489
tcg_gen_ext32u_tl(t1, t1);
2490
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2491
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2494
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2495
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2500
#if defined(TARGET_MIPS64)
2501
case OPC_DMULT_G_2E:
2502
case OPC_DMULT_G_2F:
2503
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2506
case OPC_DMULTU_G_2E:
2507
case OPC_DMULTU_G_2F:
2508
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2514
int l1 = gen_new_label();
2515
int l2 = gen_new_label();
2516
int l3 = gen_new_label();
2517
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2518
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2521
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2522
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2523
tcg_gen_mov_tl(cpu_gpr[rd], t0);
2526
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2531
case OPC_DDIVU_G_2E:
2532
case OPC_DDIVU_G_2F:
2534
int l1 = gen_new_label();
2535
int l2 = gen_new_label();
2536
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2537
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2540
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2548
int l1 = gen_new_label();
2549
int l2 = gen_new_label();
2550
int l3 = gen_new_label();
2551
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2552
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2553
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2555
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2558
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2563
case OPC_DMODU_G_2E:
2564
case OPC_DMODU_G_2F:
2566
int l1 = gen_new_label();
2567
int l2 = gen_new_label();
2568
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2569
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2572
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2580
(void)opn; /* avoid a compiler warning */
2581
MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2587
static void gen_trap (DisasContext *ctx, uint32_t opc,
2588
int rs, int rt, int16_t imm)
2591
TCGv t0 = tcg_temp_new();
2592
TCGv t1 = tcg_temp_new();
2595
/* Load needed operands */
2603
/* Compare two registers */
2605
gen_load_gpr(t0, rs);
2606
gen_load_gpr(t1, rt);
2616
/* Compare register to immediate */
2617
if (rs != 0 || imm != 0) {
2618
gen_load_gpr(t0, rs);
2619
tcg_gen_movi_tl(t1, (int32_t)imm);
2626
case OPC_TEQ: /* rs == rs */
2627
case OPC_TEQI: /* r0 == 0 */
2628
case OPC_TGE: /* rs >= rs */
2629
case OPC_TGEI: /* r0 >= 0 */
2630
case OPC_TGEU: /* rs >= rs unsigned */
2631
case OPC_TGEIU: /* r0 >= 0 unsigned */
2633
generate_exception(ctx, EXCP_TRAP);
2635
case OPC_TLT: /* rs < rs */
2636
case OPC_TLTI: /* r0 < 0 */
2637
case OPC_TLTU: /* rs < rs unsigned */
2638
case OPC_TLTIU: /* r0 < 0 unsigned */
2639
case OPC_TNE: /* rs != rs */
2640
case OPC_TNEI: /* r0 != 0 */
2641
/* Never trap: treat as NOP. */
2645
int l1 = gen_new_label();
2650
tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2654
tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2658
tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2662
tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2666
tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2670
tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2673
generate_exception(ctx, EXCP_TRAP);
2680
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2682
TranslationBlock *tb;
2684
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2685
likely(!ctx->singlestep_enabled)) {
2688
tcg_gen_exit_tb((tcg_target_long)tb + n);
2691
if (ctx->singlestep_enabled) {
2692
save_cpu_state(ctx, 0);
2693
gen_helper_0i(raise_exception, EXCP_DEBUG);
2699
/* Branches (before delay slot) */
2700
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2702
int rs, int rt, int32_t offset)
2704
target_ulong btgt = -1;
2706
int bcond_compute = 0;
2707
TCGv t0 = tcg_temp_new();
2708
TCGv t1 = tcg_temp_new();
2710
if (ctx->hflags & MIPS_HFLAG_BMASK) {
2711
#ifdef MIPS_DEBUG_DISAS
2712
LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2714
generate_exception(ctx, EXCP_RI);
2718
/* Load needed operands */
2724
/* Compare two registers */
2726
gen_load_gpr(t0, rs);
2727
gen_load_gpr(t1, rt);
2730
btgt = ctx->pc + insn_bytes + offset;
2746
/* Compare to zero */
2748
gen_load_gpr(t0, rs);
2751
btgt = ctx->pc + insn_bytes + offset;
2758
/* Jump to immediate */
2759
btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
2765
/* Jump to register */
2766
if (offset != 0 && offset != 16) {
2767
/* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2768
others are reserved. */
2769
MIPS_INVAL("jump hint");
2770
generate_exception(ctx, EXCP_RI);
2773
gen_load_gpr(btarget, rs);
2776
MIPS_INVAL("branch/jump");
2777
generate_exception(ctx, EXCP_RI);
2780
if (bcond_compute == 0) {
2781
/* No condition to be computed */
2783
case OPC_BEQ: /* rx == rx */
2784
case OPC_BEQL: /* rx == rx likely */
2785
case OPC_BGEZ: /* 0 >= 0 */
2786
case OPC_BGEZL: /* 0 >= 0 likely */
2787
case OPC_BLEZ: /* 0 <= 0 */
2788
case OPC_BLEZL: /* 0 <= 0 likely */
2790
ctx->hflags |= MIPS_HFLAG_B;
2791
MIPS_DEBUG("balways");
2794
case OPC_BGEZAL: /* 0 >= 0 */
2795
case OPC_BGEZALL: /* 0 >= 0 likely */
2796
ctx->hflags |= (opc == OPC_BGEZALS
2798
: MIPS_HFLAG_BDS32);
2799
/* Always take and link */
2801
ctx->hflags |= MIPS_HFLAG_B;
2802
MIPS_DEBUG("balways and link");
2804
case OPC_BNE: /* rx != rx */
2805
case OPC_BGTZ: /* 0 > 0 */
2806
case OPC_BLTZ: /* 0 < 0 */
2808
MIPS_DEBUG("bnever (NOP)");
2811
case OPC_BLTZAL: /* 0 < 0 */
2812
ctx->hflags |= (opc == OPC_BLTZALS
2814
: MIPS_HFLAG_BDS32);
2815
/* Handle as an unconditional branch to get correct delay
2818
btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
2819
ctx->hflags |= MIPS_HFLAG_B;
2820
MIPS_DEBUG("bnever and link");
2822
case OPC_BLTZALL: /* 0 < 0 likely */
2823
tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2824
/* Skip the instruction in the delay slot */
2825
MIPS_DEBUG("bnever, link and skip");
2828
case OPC_BNEL: /* rx != rx likely */
2829
case OPC_BGTZL: /* 0 > 0 likely */
2830
case OPC_BLTZL: /* 0 < 0 likely */
2831
/* Skip the instruction in the delay slot */
2832
MIPS_DEBUG("bnever and skip");
2836
ctx->hflags |= MIPS_HFLAG_B;
2837
MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2841
ctx->hflags |= MIPS_HFLAG_BX;
2846
ctx->hflags |= MIPS_HFLAG_B;
2847
ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
2849
: MIPS_HFLAG_BDS32);
2850
MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2853
ctx->hflags |= MIPS_HFLAG_BR;
2854
if (insn_bytes == 4)
2855
ctx->hflags |= MIPS_HFLAG_BDS32;
2856
MIPS_DEBUG("jr %s", regnames[rs]);
2862
ctx->hflags |= MIPS_HFLAG_BR;
2863
ctx->hflags |= (opc == OPC_JALRS
2865
: MIPS_HFLAG_BDS32);
2866
MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2869
MIPS_INVAL("branch/jump");
2870
generate_exception(ctx, EXCP_RI);
2876
tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2877
MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2878
regnames[rs], regnames[rt], btgt);
2881
tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
2882
MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2883
regnames[rs], regnames[rt], btgt);
2886
tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2887
MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2888
regnames[rs], regnames[rt], btgt);
2891
tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
2892
MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2893
regnames[rs], regnames[rt], btgt);
2896
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2897
MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2900
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2901
MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2905
ctx->hflags |= (opc == OPC_BGEZALS
2907
: MIPS_HFLAG_BDS32);
2908
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2909
MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2913
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
2915
MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2918
tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2919
MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2922
tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
2923
MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2926
tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2927
MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2930
tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
2931
MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2934
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2935
MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2938
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2939
MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2943
ctx->hflags |= (opc == OPC_BLTZALS
2945
: MIPS_HFLAG_BDS32);
2946
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2948
MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2950
ctx->hflags |= MIPS_HFLAG_BC;
2953
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
2955
MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2957
ctx->hflags |= MIPS_HFLAG_BL;
2960
MIPS_INVAL("conditional branch/jump");
2961
generate_exception(ctx, EXCP_RI);
2965
MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2966
blink, ctx->hflags, btgt);
2968
ctx->btarget = btgt;
2970
int post_delay = insn_bytes;
2971
int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
2973
if (opc != OPC_JALRC)
2974
post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
2976
tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
2980
if (insn_bytes == 2)
2981
ctx->hflags |= MIPS_HFLAG_B16;
2986
/* special3 bitfield operations */
2987
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2988
int rs, int lsb, int msb)
2990
TCGv t0 = tcg_temp_new();
2991
TCGv t1 = tcg_temp_new();
2994
gen_load_gpr(t1, rs);
2999
tcg_gen_shri_tl(t0, t1, lsb);
3001
tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3003
tcg_gen_ext32s_tl(t0, t0);
3006
#if defined(TARGET_MIPS64)
3008
tcg_gen_shri_tl(t0, t1, lsb);
3010
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3014
tcg_gen_shri_tl(t0, t1, lsb + 32);
3015
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3018
tcg_gen_shri_tl(t0, t1, lsb);
3019
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3025
mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3026
gen_load_gpr(t0, rt);
3027
tcg_gen_andi_tl(t0, t0, ~mask);
3028
tcg_gen_shli_tl(t1, t1, lsb);
3029
tcg_gen_andi_tl(t1, t1, mask);
3030
tcg_gen_or_tl(t0, t0, t1);
3031
tcg_gen_ext32s_tl(t0, t0);
3033
#if defined(TARGET_MIPS64)
3037
mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3038
gen_load_gpr(t0, rt);
3039
tcg_gen_andi_tl(t0, t0, ~mask);
3040
tcg_gen_shli_tl(t1, t1, lsb);
3041
tcg_gen_andi_tl(t1, t1, mask);
3042
tcg_gen_or_tl(t0, t0, t1);
3047
mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3048
gen_load_gpr(t0, rt);
3049
tcg_gen_andi_tl(t0, t0, ~mask);
3050
tcg_gen_shli_tl(t1, t1, lsb + 32);
3051
tcg_gen_andi_tl(t1, t1, mask);
3052
tcg_gen_or_tl(t0, t0, t1);
3057
gen_load_gpr(t0, rt);
3058
mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3059
gen_load_gpr(t0, rt);
3060
tcg_gen_andi_tl(t0, t0, ~mask);
3061
tcg_gen_shli_tl(t1, t1, lsb);
3062
tcg_gen_andi_tl(t1, t1, mask);
3063
tcg_gen_or_tl(t0, t0, t1);
3068
MIPS_INVAL("bitops");
3069
generate_exception(ctx, EXCP_RI);
3074
gen_store_gpr(t0, rt);
3079
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3084
/* If no destination, treat it as a NOP. */
3089
t0 = tcg_temp_new();
3090
gen_load_gpr(t0, rt);
3094
TCGv t1 = tcg_temp_new();
3096
tcg_gen_shri_tl(t1, t0, 8);
3097
tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3098
tcg_gen_shli_tl(t0, t0, 8);
3099
tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3100
tcg_gen_or_tl(t0, t0, t1);
3102
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3106
tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3109
tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3111
#if defined(TARGET_MIPS64)
3114
TCGv t1 = tcg_temp_new();
3116
tcg_gen_shri_tl(t1, t0, 8);
3117
tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3118
tcg_gen_shli_tl(t0, t0, 8);
3119
tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3120
tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3126
TCGv t1 = tcg_temp_new();
3128
tcg_gen_shri_tl(t1, t0, 16);
3129
tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3130
tcg_gen_shli_tl(t0, t0, 16);
3131
tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3132
tcg_gen_or_tl(t0, t0, t1);
3133
tcg_gen_shri_tl(t1, t0, 32);
3134
tcg_gen_shli_tl(t0, t0, 32);
3135
tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3141
MIPS_INVAL("bsfhl");
3142
generate_exception(ctx, EXCP_RI);
3149
#ifndef CONFIG_USER_ONLY
3150
/* CP0 (MMU and control) */
3151
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3153
TCGv_i32 t0 = tcg_temp_new_i32();
3155
tcg_gen_ld_i32(t0, cpu_env, off);
3156
tcg_gen_ext_i32_tl(arg, t0);
3157
tcg_temp_free_i32(t0);
3160
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3162
tcg_gen_ld_tl(arg, cpu_env, off);
3163
tcg_gen_ext32s_tl(arg, arg);
3166
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3168
TCGv_i32 t0 = tcg_temp_new_i32();
3170
tcg_gen_trunc_tl_i32(t0, arg);
3171
tcg_gen_st_i32(t0, cpu_env, off);
3172
tcg_temp_free_i32(t0);
3175
static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3177
tcg_gen_ext32s_tl(arg, arg);
3178
tcg_gen_st_tl(arg, cpu_env, off);
3181
static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3183
const char *rn = "invalid";
3186
check_insn(env, ctx, ISA_MIPS32);
3192
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
3196
check_insn(env, ctx, ASE_MT);
3197
gen_helper_mfc0_mvpcontrol(arg);
3201
check_insn(env, ctx, ASE_MT);
3202
gen_helper_mfc0_mvpconf0(arg);
3206
check_insn(env, ctx, ASE_MT);
3207
gen_helper_mfc0_mvpconf1(arg);
3217
gen_helper_mfc0_random(arg);
3221
check_insn(env, ctx, ASE_MT);
3222
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
3226
check_insn(env, ctx, ASE_MT);
3227
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
3231
check_insn(env, ctx, ASE_MT);
3232
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
3236
check_insn(env, ctx, ASE_MT);
3237
gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
3241
check_insn(env, ctx, ASE_MT);
3242
gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
3246
check_insn(env, ctx, ASE_MT);
3247
gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3248
rn = "VPEScheFBack";
3251
check_insn(env, ctx, ASE_MT);
3252
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
3262
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3263
tcg_gen_ext32s_tl(arg, arg);
3267
check_insn(env, ctx, ASE_MT);
3268
gen_helper_mfc0_tcstatus(arg);
3272
check_insn(env, ctx, ASE_MT);
3273
gen_helper_mfc0_tcbind(arg);
3277
check_insn(env, ctx, ASE_MT);
3278
gen_helper_mfc0_tcrestart(arg);
3282
check_insn(env, ctx, ASE_MT);
3283
gen_helper_mfc0_tchalt(arg);
3287
check_insn(env, ctx, ASE_MT);
3288
gen_helper_mfc0_tccontext(arg);
3292
check_insn(env, ctx, ASE_MT);
3293
gen_helper_mfc0_tcschedule(arg);
3297
check_insn(env, ctx, ASE_MT);
3298
gen_helper_mfc0_tcschefback(arg);
3308
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3309
tcg_gen_ext32s_tl(arg, arg);
3319
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3320
tcg_gen_ext32s_tl(arg, arg);
3324
// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3325
rn = "ContextConfig";
3334
gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3338
check_insn(env, ctx, ISA_MIPS32R2);
3339
gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3349
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3353
check_insn(env, ctx, ISA_MIPS32R2);
3354
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3358
check_insn(env, ctx, ISA_MIPS32R2);
3359
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3363
check_insn(env, ctx, ISA_MIPS32R2);
3364
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3368
check_insn(env, ctx, ISA_MIPS32R2);
3369
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3373
check_insn(env, ctx, ISA_MIPS32R2);
3374
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3384
check_insn(env, ctx, ISA_MIPS32R2);
3385
gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3395
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3396
tcg_gen_ext32s_tl(arg, arg);
3406
/* Mark as an IO operation because we read the time. */
3409
gen_helper_mfc0_count(arg);
3413
/* Break the TB to be able to take timer interrupts immediately
3414
after reading count. */
3415
ctx->bstate = BS_STOP;
3418
/* 6,7 are implementation dependent */
3426
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3427
tcg_gen_ext32s_tl(arg, arg);
3437
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3440
/* 6,7 are implementation dependent */
3448
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3452
check_insn(env, ctx, ISA_MIPS32R2);
3453
gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3457
check_insn(env, ctx, ISA_MIPS32R2);
3458
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3462
check_insn(env, ctx, ISA_MIPS32R2);
3463
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3473
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3483
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3484
tcg_gen_ext32s_tl(arg, arg);
3494
gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3498
check_insn(env, ctx, ISA_MIPS32R2);
3499
gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3509
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3513
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3517
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3521
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3524
/* 4,5 are reserved */
3525
/* 6,7 are implementation dependent */
3527
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3531
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3541
gen_helper_mfc0_lladdr(arg);
3551
gen_helper_1i(mfc0_watchlo, arg, sel);
3561
gen_helper_1i(mfc0_watchhi, arg, sel);
3571
#if defined(TARGET_MIPS64)
3572
check_insn(env, ctx, ISA_MIPS3);
3573
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3574
tcg_gen_ext32s_tl(arg, arg);
3583
/* Officially reserved, but sel 0 is used for R1x000 framemask */
3586
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3594
tcg_gen_movi_tl(arg, 0); /* unimplemented */
3595
rn = "'Diagnostic"; /* implementation dependent */
3600
gen_helper_mfc0_debug(arg); /* EJTAG support */
3604
// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3605
rn = "TraceControl";
3608
// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3609
rn = "TraceControl2";
3612
// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3613
rn = "UserTraceData";
3616
// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3627
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3628
tcg_gen_ext32s_tl(arg, arg);
3638
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3639
rn = "Performance0";
3642
// gen_helper_mfc0_performance1(arg);
3643
rn = "Performance1";
3646
// gen_helper_mfc0_performance2(arg);
3647
rn = "Performance2";
3650
// gen_helper_mfc0_performance3(arg);
3651
rn = "Performance3";
3654
// gen_helper_mfc0_performance4(arg);
3655
rn = "Performance4";
3658
// gen_helper_mfc0_performance5(arg);
3659
rn = "Performance5";
3662
// gen_helper_mfc0_performance6(arg);
3663
rn = "Performance6";
3666
// gen_helper_mfc0_performance7(arg);
3667
rn = "Performance7";
3674
tcg_gen_movi_tl(arg, 0); /* unimplemented */
3680
tcg_gen_movi_tl(arg, 0); /* unimplemented */
3693
gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3700
gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3713
gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3720
gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3730
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3731
tcg_gen_ext32s_tl(arg, arg);
3742
gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3752
(void)rn; /* avoid a compiler warning */
3753
LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3757
LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3758
generate_exception(ctx, EXCP_RI);
3761
static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3763
const char *rn = "invalid";
3766
check_insn(env, ctx, ISA_MIPS32);
3775
gen_helper_mtc0_index(arg);
3779
check_insn(env, ctx, ASE_MT);
3780
gen_helper_mtc0_mvpcontrol(arg);
3784
check_insn(env, ctx, ASE_MT);
3789
check_insn(env, ctx, ASE_MT);
3804
check_insn(env, ctx, ASE_MT);
3805
gen_helper_mtc0_vpecontrol(arg);
3809
check_insn(env, ctx, ASE_MT);
3810
gen_helper_mtc0_vpeconf0(arg);
3814
check_insn(env, ctx, ASE_MT);
3815
gen_helper_mtc0_vpeconf1(arg);
3819
check_insn(env, ctx, ASE_MT);
3820
gen_helper_mtc0_yqmask(arg);
3824
check_insn(env, ctx, ASE_MT);
3825
gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3829
check_insn(env, ctx, ASE_MT);
3830
gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3831
rn = "VPEScheFBack";
3834
check_insn(env, ctx, ASE_MT);
3835
gen_helper_mtc0_vpeopt(arg);
3845
gen_helper_mtc0_entrylo0(arg);
3849
check_insn(env, ctx, ASE_MT);
3850
gen_helper_mtc0_tcstatus(arg);
3854
check_insn(env, ctx, ASE_MT);
3855
gen_helper_mtc0_tcbind(arg);
3859
check_insn(env, ctx, ASE_MT);
3860
gen_helper_mtc0_tcrestart(arg);
3864
check_insn(env, ctx, ASE_MT);
3865
gen_helper_mtc0_tchalt(arg);
3869
check_insn(env, ctx, ASE_MT);
3870
gen_helper_mtc0_tccontext(arg);
3874
check_insn(env, ctx, ASE_MT);
3875
gen_helper_mtc0_tcschedule(arg);
3879
check_insn(env, ctx, ASE_MT);
3880
gen_helper_mtc0_tcschefback(arg);
3890
gen_helper_mtc0_entrylo1(arg);
3900
gen_helper_mtc0_context(arg);
3904
// gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3905
rn = "ContextConfig";
3914
gen_helper_mtc0_pagemask(arg);
3918
check_insn(env, ctx, ISA_MIPS32R2);
3919
gen_helper_mtc0_pagegrain(arg);
3929
gen_helper_mtc0_wired(arg);
3933
check_insn(env, ctx, ISA_MIPS32R2);
3934
gen_helper_mtc0_srsconf0(arg);
3938
check_insn(env, ctx, ISA_MIPS32R2);
3939
gen_helper_mtc0_srsconf1(arg);
3943
check_insn(env, ctx, ISA_MIPS32R2);
3944
gen_helper_mtc0_srsconf2(arg);
3948
check_insn(env, ctx, ISA_MIPS32R2);
3949
gen_helper_mtc0_srsconf3(arg);
3953
check_insn(env, ctx, ISA_MIPS32R2);
3954
gen_helper_mtc0_srsconf4(arg);
3964
check_insn(env, ctx, ISA_MIPS32R2);
3965
gen_helper_mtc0_hwrena(arg);
3979
gen_helper_mtc0_count(arg);
3982
/* 6,7 are implementation dependent */
3990
gen_helper_mtc0_entryhi(arg);
4000
gen_helper_mtc0_compare(arg);
4003
/* 6,7 are implementation dependent */
4011
save_cpu_state(ctx, 1);
4012
gen_helper_mtc0_status(arg);
4013
/* BS_STOP isn't good enough here, hflags may have changed. */
4014
gen_save_pc(ctx->pc + 4);
4015
ctx->bstate = BS_EXCP;
4019
check_insn(env, ctx, ISA_MIPS32R2);
4020
gen_helper_mtc0_intctl(arg);
4021
/* Stop translation as we may have switched the execution mode */
4022
ctx->bstate = BS_STOP;
4026
check_insn(env, ctx, ISA_MIPS32R2);
4027
gen_helper_mtc0_srsctl(arg);
4028
/* Stop translation as we may have switched the execution mode */
4029
ctx->bstate = BS_STOP;
4033
check_insn(env, ctx, ISA_MIPS32R2);
4034
gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4035
/* Stop translation as we may have switched the execution mode */
4036
ctx->bstate = BS_STOP;
4046
save_cpu_state(ctx, 1);
4047
gen_helper_mtc0_cause(arg);
4057
gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
4071
check_insn(env, ctx, ISA_MIPS32R2);
4072
gen_helper_mtc0_ebase(arg);
4082
gen_helper_mtc0_config0(arg);
4084
/* Stop translation as we may have switched the execution mode */
4085
ctx->bstate = BS_STOP;
4088
/* ignored, read only */
4092
gen_helper_mtc0_config2(arg);
4094
/* Stop translation as we may have switched the execution mode */
4095
ctx->bstate = BS_STOP;
4098
/* ignored, read only */
4101
/* 4,5 are reserved */
4102
/* 6,7 are implementation dependent */
4112
rn = "Invalid config selector";
4119
gen_helper_mtc0_lladdr(arg);
4129
gen_helper_1i(mtc0_watchlo, arg, sel);
4139
gen_helper_1i(mtc0_watchhi, arg, sel);
4149
#if defined(TARGET_MIPS64)
4150
check_insn(env, ctx, ISA_MIPS3);
4151
gen_helper_mtc0_xcontext(arg);
4160
/* Officially reserved, but sel 0 is used for R1x000 framemask */
4163
gen_helper_mtc0_framemask(arg);
4172
rn = "Diagnostic"; /* implementation dependent */
4177
gen_helper_mtc0_debug(arg); /* EJTAG support */
4178
/* BS_STOP isn't good enough here, hflags may have changed. */
4179
gen_save_pc(ctx->pc + 4);
4180
ctx->bstate = BS_EXCP;
4184
// gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
4185
rn = "TraceControl";
4186
/* Stop translation as we may have switched the execution mode */
4187
ctx->bstate = BS_STOP;
4190
// gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
4191
rn = "TraceControl2";
4192
/* Stop translation as we may have switched the execution mode */
4193
ctx->bstate = BS_STOP;
4196
/* Stop translation as we may have switched the execution mode */
4197
ctx->bstate = BS_STOP;
4198
// gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
4199
rn = "UserTraceData";
4200
/* Stop translation as we may have switched the execution mode */
4201
ctx->bstate = BS_STOP;
4204
// gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
4205
/* Stop translation as we may have switched the execution mode */
4206
ctx->bstate = BS_STOP;
4217
gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
4227
gen_helper_mtc0_performance0(arg);
4228
rn = "Performance0";
4231
// gen_helper_mtc0_performance1(arg);
4232
rn = "Performance1";
4235
// gen_helper_mtc0_performance2(arg);
4236
rn = "Performance2";
4239
// gen_helper_mtc0_performance3(arg);
4240
rn = "Performance3";
4243
// gen_helper_mtc0_performance4(arg);
4244
rn = "Performance4";
4247
// gen_helper_mtc0_performance5(arg);
4248
rn = "Performance5";
4251
// gen_helper_mtc0_performance6(arg);
4252
rn = "Performance6";
4255
// gen_helper_mtc0_performance7(arg);
4256
rn = "Performance7";
4282
gen_helper_mtc0_taglo(arg);
4289
gen_helper_mtc0_datalo(arg);
4302
gen_helper_mtc0_taghi(arg);
4309
gen_helper_mtc0_datahi(arg);
4320
gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4331
gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4337
/* Stop translation as we may have switched the execution mode */
4338
ctx->bstate = BS_STOP;
4343
(void)rn; /* avoid a compiler warning */
4344
LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4345
/* For simplicity assume that all writes can cause interrupts. */
4348
ctx->bstate = BS_STOP;
4353
LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4354
generate_exception(ctx, EXCP_RI);
4357
#if defined(TARGET_MIPS64)
4358
static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4360
const char *rn = "invalid";
4363
check_insn(env, ctx, ISA_MIPS64);
4369
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4373
check_insn(env, ctx, ASE_MT);
4374
gen_helper_mfc0_mvpcontrol(arg);
4378
check_insn(env, ctx, ASE_MT);
4379
gen_helper_mfc0_mvpconf0(arg);
4383
check_insn(env, ctx, ASE_MT);
4384
gen_helper_mfc0_mvpconf1(arg);
4394
gen_helper_mfc0_random(arg);
4398
check_insn(env, ctx, ASE_MT);
4399
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4403
check_insn(env, ctx, ASE_MT);
4404
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4408
check_insn(env, ctx, ASE_MT);
4409
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4413
check_insn(env, ctx, ASE_MT);
4414
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4418
check_insn(env, ctx, ASE_MT);
4419
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4423
check_insn(env, ctx, ASE_MT);
4424
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4425
rn = "VPEScheFBack";
4428
check_insn(env, ctx, ASE_MT);
4429
gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4439
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4443
check_insn(env, ctx, ASE_MT);
4444
gen_helper_mfc0_tcstatus(arg);
4448
check_insn(env, ctx, ASE_MT);
4449
gen_helper_mfc0_tcbind(arg);
4453
check_insn(env, ctx, ASE_MT);
4454
gen_helper_dmfc0_tcrestart(arg);
4458
check_insn(env, ctx, ASE_MT);
4459
gen_helper_dmfc0_tchalt(arg);
4463
check_insn(env, ctx, ASE_MT);
4464
gen_helper_dmfc0_tccontext(arg);
4468
check_insn(env, ctx, ASE_MT);
4469
gen_helper_dmfc0_tcschedule(arg);
4473
check_insn(env, ctx, ASE_MT);
4474
gen_helper_dmfc0_tcschefback(arg);
4484
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4494
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4498
// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4499
rn = "ContextConfig";
4508
gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4512
check_insn(env, ctx, ISA_MIPS32R2);
4513
gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4523
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4527
check_insn(env, ctx, ISA_MIPS32R2);
4528
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4532
check_insn(env, ctx, ISA_MIPS32R2);
4533
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4537
check_insn(env, ctx, ISA_MIPS32R2);
4538
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4542
check_insn(env, ctx, ISA_MIPS32R2);
4543
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4547
check_insn(env, ctx, ISA_MIPS32R2);
4548
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4558
check_insn(env, ctx, ISA_MIPS32R2);
4559
gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4569
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4579
/* Mark as an IO operation because we read the time. */
4582
gen_helper_mfc0_count(arg);
4586
/* Break the TB to be able to take timer interrupts immediately
4587
after reading count. */
4588
ctx->bstate = BS_STOP;
4591
/* 6,7 are implementation dependent */
4599
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4609
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4612
/* 6,7 are implementation dependent */
4620
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4624
check_insn(env, ctx, ISA_MIPS32R2);
4625
gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4629
check_insn(env, ctx, ISA_MIPS32R2);
4630
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4634
check_insn(env, ctx, ISA_MIPS32R2);
4635
gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4645
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4655
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4665
gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4669
check_insn(env, ctx, ISA_MIPS32R2);
4670
gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4680
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4684
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4688
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4692
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4695
/* 6,7 are implementation dependent */
4697
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4701
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4711
gen_helper_dmfc0_lladdr(arg);
4721
gen_helper_1i(dmfc0_watchlo, arg, sel);
4731
gen_helper_1i(mfc0_watchhi, arg, sel);
4741
check_insn(env, ctx, ISA_MIPS3);
4742
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4750
/* Officially reserved, but sel 0 is used for R1x000 framemask */
4753
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4761
tcg_gen_movi_tl(arg, 0); /* unimplemented */
4762
rn = "'Diagnostic"; /* implementation dependent */
4767
gen_helper_mfc0_debug(arg); /* EJTAG support */
4771
// gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4772
rn = "TraceControl";
4775
// gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4776
rn = "TraceControl2";
4779
// gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4780
rn = "UserTraceData";
4783
// gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4794
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4804
gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4805
rn = "Performance0";
4808
// gen_helper_dmfc0_performance1(arg);
4809
rn = "Performance1";
4812
// gen_helper_dmfc0_performance2(arg);
4813
rn = "Performance2";
4816
// gen_helper_dmfc0_performance3(arg);
4817
rn = "Performance3";
4820
// gen_helper_dmfc0_performance4(arg);
4821
rn = "Performance4";
4824
// gen_helper_dmfc0_performance5(arg);
4825
rn = "Performance5";
4828
// gen_helper_dmfc0_performance6(arg);
4829
rn = "Performance6";
4832
// gen_helper_dmfc0_performance7(arg);
4833
rn = "Performance7";
4840
tcg_gen_movi_tl(arg, 0); /* unimplemented */
4847
tcg_gen_movi_tl(arg, 0); /* unimplemented */
4860
gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4867
gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4880
gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4887
gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4897
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4908
gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4918
(void)rn; /* avoid a compiler warning */
4919
LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4923
LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4924
generate_exception(ctx, EXCP_RI);
4927
static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4929
const char *rn = "invalid";
4932
check_insn(env, ctx, ISA_MIPS64);
4941
gen_helper_mtc0_index(arg);
4945
check_insn(env, ctx, ASE_MT);
4946
gen_helper_mtc0_mvpcontrol(arg);
4950
check_insn(env, ctx, ASE_MT);
4955
check_insn(env, ctx, ASE_MT);
4970
check_insn(env, ctx, ASE_MT);
4971
gen_helper_mtc0_vpecontrol(arg);
4975
check_insn(env, ctx, ASE_MT);
4976
gen_helper_mtc0_vpeconf0(arg);
4980
check_insn(env, ctx, ASE_MT);
4981
gen_helper_mtc0_vpeconf1(arg);
4985
check_insn(env, ctx, ASE_MT);
4986
gen_helper_mtc0_yqmask(arg);
4990
check_insn(env, ctx, ASE_MT);
4991
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4995
check_insn(env, ctx, ASE_MT);
4996
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4997
rn = "VPEScheFBack";
5000
check_insn(env, ctx, ASE_MT);
5001
gen_helper_mtc0_vpeopt(arg);
5011
gen_helper_mtc0_entrylo0(arg);
5015
check_insn(env, ctx, ASE_MT);
5016
gen_helper_mtc0_tcstatus(arg);
5020
check_insn(env, ctx, ASE_MT);
5021
gen_helper_mtc0_tcbind(arg);
5025
check_insn(env, ctx, ASE_MT);
5026
gen_helper_mtc0_tcrestart(arg);
5030
check_insn(env, ctx, ASE_MT);
5031
gen_helper_mtc0_tchalt(arg);
5035
check_insn(env, ctx, ASE_MT);
5036
gen_helper_mtc0_tccontext(arg);
5040
check_insn(env, ctx, ASE_MT);
5041
gen_helper_mtc0_tcschedule(arg);
5045
check_insn(env, ctx, ASE_MT);
5046
gen_helper_mtc0_tcschefback(arg);
5056
gen_helper_mtc0_entrylo1(arg);
5066
gen_helper_mtc0_context(arg);
5070
// gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
5071
rn = "ContextConfig";
5080
gen_helper_mtc0_pagemask(arg);
5084
check_insn(env, ctx, ISA_MIPS32R2);
5085
gen_helper_mtc0_pagegrain(arg);
5095
gen_helper_mtc0_wired(arg);
5099
check_insn(env, ctx, ISA_MIPS32R2);
5100
gen_helper_mtc0_srsconf0(arg);
5104
check_insn(env, ctx, ISA_MIPS32R2);
5105
gen_helper_mtc0_srsconf1(arg);
5109
check_insn(env, ctx, ISA_MIPS32R2);
5110
gen_helper_mtc0_srsconf2(arg);
5114
check_insn(env, ctx, ISA_MIPS32R2);
5115
gen_helper_mtc0_srsconf3(arg);
5119
check_insn(env, ctx, ISA_MIPS32R2);
5120
gen_helper_mtc0_srsconf4(arg);
5130
check_insn(env, ctx, ISA_MIPS32R2);
5131
gen_helper_mtc0_hwrena(arg);
5145
gen_helper_mtc0_count(arg);
5148
/* 6,7 are implementation dependent */
5152
/* Stop translation as we may have switched the execution mode */
5153
ctx->bstate = BS_STOP;
5158
gen_helper_mtc0_entryhi(arg);
5168
gen_helper_mtc0_compare(arg);
5171
/* 6,7 are implementation dependent */
5175
/* Stop translation as we may have switched the execution mode */
5176
ctx->bstate = BS_STOP;
5181
save_cpu_state(ctx, 1);
5182
gen_helper_mtc0_status(arg);
5183
/* BS_STOP isn't good enough here, hflags may have changed. */
5184
gen_save_pc(ctx->pc + 4);
5185
ctx->bstate = BS_EXCP;
5189
check_insn(env, ctx, ISA_MIPS32R2);
5190
gen_helper_mtc0_intctl(arg);
5191
/* Stop translation as we may have switched the execution mode */
5192
ctx->bstate = BS_STOP;
5196
check_insn(env, ctx, ISA_MIPS32R2);
5197
gen_helper_mtc0_srsctl(arg);
5198
/* Stop translation as we may have switched the execution mode */
5199
ctx->bstate = BS_STOP;
5203
check_insn(env, ctx, ISA_MIPS32R2);
5204
gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
5205
/* Stop translation as we may have switched the execution mode */
5206
ctx->bstate = BS_STOP;
5216
save_cpu_state(ctx, 1);
5217
/* Mark as an IO operation because we may trigger a software
5222
gen_helper_mtc0_cause(arg);
5226
/* Stop translation as we may have triggered an intetrupt */
5227
ctx->bstate = BS_STOP;
5237
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
5251
check_insn(env, ctx, ISA_MIPS32R2);
5252
gen_helper_mtc0_ebase(arg);
5262
gen_helper_mtc0_config0(arg);
5264
/* Stop translation as we may have switched the execution mode */
5265
ctx->bstate = BS_STOP;
5268
/* ignored, read only */
5272
gen_helper_mtc0_config2(arg);
5274
/* Stop translation as we may have switched the execution mode */
5275
ctx->bstate = BS_STOP;
5281
/* 6,7 are implementation dependent */
5283
rn = "Invalid config selector";
5290
gen_helper_mtc0_lladdr(arg);
5300
gen_helper_1i(mtc0_watchlo, arg, sel);
5310
gen_helper_1i(mtc0_watchhi, arg, sel);
5320
check_insn(env, ctx, ISA_MIPS3);
5321
gen_helper_mtc0_xcontext(arg);
5329
/* Officially reserved, but sel 0 is used for R1x000 framemask */
5332
gen_helper_mtc0_framemask(arg);
5341
rn = "Diagnostic"; /* implementation dependent */
5346
gen_helper_mtc0_debug(arg); /* EJTAG support */
5347
/* BS_STOP isn't good enough here, hflags may have changed. */
5348
gen_save_pc(ctx->pc + 4);
5349
ctx->bstate = BS_EXCP;
5353
// gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5354
/* Stop translation as we may have switched the execution mode */
5355
ctx->bstate = BS_STOP;
5356
rn = "TraceControl";
5359
// gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5360
/* Stop translation as we may have switched the execution mode */
5361
ctx->bstate = BS_STOP;
5362
rn = "TraceControl2";
5365
// gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5366
/* Stop translation as we may have switched the execution mode */
5367
ctx->bstate = BS_STOP;
5368
rn = "UserTraceData";
5371
// gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5372
/* Stop translation as we may have switched the execution mode */
5373
ctx->bstate = BS_STOP;
5384
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5394
gen_helper_mtc0_performance0(arg);
5395
rn = "Performance0";
5398
// gen_helper_mtc0_performance1(arg);
5399
rn = "Performance1";
5402
// gen_helper_mtc0_performance2(arg);
5403
rn = "Performance2";
5406
// gen_helper_mtc0_performance3(arg);
5407
rn = "Performance3";
5410
// gen_helper_mtc0_performance4(arg);
5411
rn = "Performance4";
5414
// gen_helper_mtc0_performance5(arg);
5415
rn = "Performance5";
5418
// gen_helper_mtc0_performance6(arg);
5419
rn = "Performance6";
5422
// gen_helper_mtc0_performance7(arg);
5423
rn = "Performance7";
5449
gen_helper_mtc0_taglo(arg);
5456
gen_helper_mtc0_datalo(arg);
5469
gen_helper_mtc0_taghi(arg);
5476
gen_helper_mtc0_datahi(arg);
5487
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5498
gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5504
/* Stop translation as we may have switched the execution mode */
5505
ctx->bstate = BS_STOP;
5510
(void)rn; /* avoid a compiler warning */
5511
LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5512
/* For simplicity assume that all writes can cause interrupts. */
5515
ctx->bstate = BS_STOP;
5520
LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5521
generate_exception(ctx, EXCP_RI);
5523
#endif /* TARGET_MIPS64 */
5525
static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5526
int u, int sel, int h)
5528
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5529
TCGv t0 = tcg_temp_local_new();
5531
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5532
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5533
(env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5534
tcg_gen_movi_tl(t0, -1);
5535
else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5536
(env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5537
tcg_gen_movi_tl(t0, -1);
5543
gen_helper_mftc0_tcstatus(t0);
5546
gen_helper_mftc0_tcbind(t0);
5549
gen_helper_mftc0_tcrestart(t0);
5552
gen_helper_mftc0_tchalt(t0);
5555
gen_helper_mftc0_tccontext(t0);
5558
gen_helper_mftc0_tcschedule(t0);
5561
gen_helper_mftc0_tcschefback(t0);
5564
gen_mfc0(env, ctx, t0, rt, sel);
5571
gen_helper_mftc0_entryhi(t0);
5574
gen_mfc0(env, ctx, t0, rt, sel);
5580
gen_helper_mftc0_status(t0);
5583
gen_mfc0(env, ctx, t0, rt, sel);
5589
gen_helper_mftc0_debug(t0);
5592
gen_mfc0(env, ctx, t0, rt, sel);
5597
gen_mfc0(env, ctx, t0, rt, sel);
5599
} else switch (sel) {
5600
/* GPR registers. */
5602
gen_helper_1i(mftgpr, t0, rt);
5604
/* Auxiliary CPU registers */
5608
gen_helper_1i(mftlo, t0, 0);
5611
gen_helper_1i(mfthi, t0, 0);
5614
gen_helper_1i(mftacx, t0, 0);
5617
gen_helper_1i(mftlo, t0, 1);
5620
gen_helper_1i(mfthi, t0, 1);
5623
gen_helper_1i(mftacx, t0, 1);
5626
gen_helper_1i(mftlo, t0, 2);
5629
gen_helper_1i(mfthi, t0, 2);
5632
gen_helper_1i(mftacx, t0, 2);
5635
gen_helper_1i(mftlo, t0, 3);
5638
gen_helper_1i(mfthi, t0, 3);
5641
gen_helper_1i(mftacx, t0, 3);
5644
gen_helper_mftdsp(t0);
5650
/* Floating point (COP1). */
5652
/* XXX: For now we support only a single FPU context. */
5654
TCGv_i32 fp0 = tcg_temp_new_i32();
5656
gen_load_fpr32(fp0, rt);
5657
tcg_gen_ext_i32_tl(t0, fp0);
5658
tcg_temp_free_i32(fp0);
5660
TCGv_i32 fp0 = tcg_temp_new_i32();
5662
gen_load_fpr32h(fp0, rt);
5663
tcg_gen_ext_i32_tl(t0, fp0);
5664
tcg_temp_free_i32(fp0);
5668
/* XXX: For now we support only a single FPU context. */
5669
gen_helper_1i(cfc1, t0, rt);
5671
/* COP2: Not implemented. */
5678
LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5679
gen_store_gpr(t0, rd);
5685
LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5686
generate_exception(ctx, EXCP_RI);
5689
static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5690
int u, int sel, int h)
5692
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5693
TCGv t0 = tcg_temp_local_new();
5695
gen_load_gpr(t0, rt);
5696
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5697
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5698
(env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5700
else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5701
(env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5708
gen_helper_mttc0_tcstatus(t0);
5711
gen_helper_mttc0_tcbind(t0);
5714
gen_helper_mttc0_tcrestart(t0);
5717
gen_helper_mttc0_tchalt(t0);
5720
gen_helper_mttc0_tccontext(t0);
5723
gen_helper_mttc0_tcschedule(t0);
5726
gen_helper_mttc0_tcschefback(t0);
5729
gen_mtc0(env, ctx, t0, rd, sel);
5736
gen_helper_mttc0_entryhi(t0);
5739
gen_mtc0(env, ctx, t0, rd, sel);
5745
gen_helper_mttc0_status(t0);
5748
gen_mtc0(env, ctx, t0, rd, sel);
5754
gen_helper_mttc0_debug(t0);
5757
gen_mtc0(env, ctx, t0, rd, sel);
5762
gen_mtc0(env, ctx, t0, rd, sel);
5764
} else switch (sel) {
5765
/* GPR registers. */
5767
gen_helper_1i(mttgpr, t0, rd);
5769
/* Auxiliary CPU registers */
5773
gen_helper_1i(mttlo, t0, 0);
5776
gen_helper_1i(mtthi, t0, 0);
5779
gen_helper_1i(mttacx, t0, 0);
5782
gen_helper_1i(mttlo, t0, 1);
5785
gen_helper_1i(mtthi, t0, 1);
5788
gen_helper_1i(mttacx, t0, 1);
5791
gen_helper_1i(mttlo, t0, 2);
5794
gen_helper_1i(mtthi, t0, 2);
5797
gen_helper_1i(mttacx, t0, 2);
5800
gen_helper_1i(mttlo, t0, 3);
5803
gen_helper_1i(mtthi, t0, 3);
5806
gen_helper_1i(mttacx, t0, 3);
5809
gen_helper_mttdsp(t0);
5815
/* Floating point (COP1). */
5817
/* XXX: For now we support only a single FPU context. */
5819
TCGv_i32 fp0 = tcg_temp_new_i32();
5821
tcg_gen_trunc_tl_i32(fp0, t0);
5822
gen_store_fpr32(fp0, rd);
5823
tcg_temp_free_i32(fp0);
5825
TCGv_i32 fp0 = tcg_temp_new_i32();
5827
tcg_gen_trunc_tl_i32(fp0, t0);
5828
gen_store_fpr32h(fp0, rd);
5829
tcg_temp_free_i32(fp0);
5833
/* XXX: For now we support only a single FPU context. */
5834
gen_helper_1i(ctc1, t0, rd);
5836
/* COP2: Not implemented. */
5843
LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5849
LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5850
generate_exception(ctx, EXCP_RI);
5853
static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5855
const char *opn = "ldst";
5863
gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5868
TCGv t0 = tcg_temp_new();
5870
gen_load_gpr(t0, rt);
5871
gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5876
#if defined(TARGET_MIPS64)
5878
check_insn(env, ctx, ISA_MIPS3);
5883
gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5887
check_insn(env, ctx, ISA_MIPS3);
5889
TCGv t0 = tcg_temp_new();
5891
gen_load_gpr(t0, rt);
5892
gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5899
check_insn(env, ctx, ASE_MT);
5904
gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5905
ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5909
check_insn(env, ctx, ASE_MT);
5910
gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5911
ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5916
if (!env->tlb->helper_tlbwi)
5922
if (!env->tlb->helper_tlbwr)
5928
if (!env->tlb->helper_tlbp)
5934
if (!env->tlb->helper_tlbr)
5940
check_insn(env, ctx, ISA_MIPS2);
5942
ctx->bstate = BS_EXCP;
5946
check_insn(env, ctx, ISA_MIPS32);
5947
if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5949
generate_exception(ctx, EXCP_RI);
5952
ctx->bstate = BS_EXCP;
5957
check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5958
/* If we get an exception, we want to restart at next instruction */
5960
save_cpu_state(ctx, 1);
5963
ctx->bstate = BS_EXCP;
5968
generate_exception(ctx, EXCP_RI);
5971
(void)opn; /* avoid a compiler warning */
5972
MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5974
#endif /* !CONFIG_USER_ONLY */
5976
/* CP1 Branches (before delay slot) */
5977
static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5978
int32_t cc, int32_t offset)
5980
target_ulong btarget;
5981
const char *opn = "cp1 cond branch";
5982
TCGv_i32 t0 = tcg_temp_new_i32();
5985
check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5987
btarget = ctx->pc + 4 + offset;
5991
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5992
tcg_gen_not_i32(t0, t0);
5993
tcg_gen_andi_i32(t0, t0, 1);
5994
tcg_gen_extu_i32_tl(bcond, t0);
5998
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5999
tcg_gen_not_i32(t0, t0);
6000
tcg_gen_andi_i32(t0, t0, 1);
6001
tcg_gen_extu_i32_tl(bcond, t0);
6005
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6006
tcg_gen_andi_i32(t0, t0, 1);
6007
tcg_gen_extu_i32_tl(bcond, t0);
6011
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6012
tcg_gen_andi_i32(t0, t0, 1);
6013
tcg_gen_extu_i32_tl(bcond, t0);
6016
ctx->hflags |= MIPS_HFLAG_BL;
6020
TCGv_i32 t1 = tcg_temp_new_i32();
6021
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6022
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6023
tcg_gen_nor_i32(t0, t0, t1);
6024
tcg_temp_free_i32(t1);
6025
tcg_gen_andi_i32(t0, t0, 1);
6026
tcg_gen_extu_i32_tl(bcond, t0);
6032
TCGv_i32 t1 = tcg_temp_new_i32();
6033
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6034
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6035
tcg_gen_or_i32(t0, t0, t1);
6036
tcg_temp_free_i32(t1);
6037
tcg_gen_andi_i32(t0, t0, 1);
6038
tcg_gen_extu_i32_tl(bcond, t0);
6044
TCGv_i32 t1 = tcg_temp_new_i32();
6045
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6046
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6047
tcg_gen_or_i32(t0, t0, t1);
6048
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6049
tcg_gen_or_i32(t0, t0, t1);
6050
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6051
tcg_gen_nor_i32(t0, t0, t1);
6052
tcg_temp_free_i32(t1);
6053
tcg_gen_andi_i32(t0, t0, 1);
6054
tcg_gen_extu_i32_tl(bcond, t0);
6060
TCGv_i32 t1 = tcg_temp_new_i32();
6061
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6062
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6063
tcg_gen_or_i32(t0, t0, t1);
6064
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6065
tcg_gen_or_i32(t0, t0, t1);
6066
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6067
tcg_gen_or_i32(t0, t0, t1);
6068
tcg_temp_free_i32(t1);
6069
tcg_gen_andi_i32(t0, t0, 1);
6070
tcg_gen_extu_i32_tl(bcond, t0);
6074
ctx->hflags |= MIPS_HFLAG_BC;
6078
generate_exception (ctx, EXCP_RI);
6081
(void)opn; /* avoid a compiler warning */
6082
MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6083
ctx->hflags, btarget);
6084
ctx->btarget = btarget;
6087
tcg_temp_free_i32(t0);
6090
/* Coprocessor 1 (FPU) */
6092
#define FOP(func, fmt) (((fmt) << 21) | (func))
6095
OPC_ADD_S = FOP(0, FMT_S),
6096
OPC_SUB_S = FOP(1, FMT_S),
6097
OPC_MUL_S = FOP(2, FMT_S),
6098
OPC_DIV_S = FOP(3, FMT_S),
6099
OPC_SQRT_S = FOP(4, FMT_S),
6100
OPC_ABS_S = FOP(5, FMT_S),
6101
OPC_MOV_S = FOP(6, FMT_S),
6102
OPC_NEG_S = FOP(7, FMT_S),
6103
OPC_ROUND_L_S = FOP(8, FMT_S),
6104
OPC_TRUNC_L_S = FOP(9, FMT_S),
6105
OPC_CEIL_L_S = FOP(10, FMT_S),
6106
OPC_FLOOR_L_S = FOP(11, FMT_S),
6107
OPC_ROUND_W_S = FOP(12, FMT_S),
6108
OPC_TRUNC_W_S = FOP(13, FMT_S),
6109
OPC_CEIL_W_S = FOP(14, FMT_S),
6110
OPC_FLOOR_W_S = FOP(15, FMT_S),
6111
OPC_MOVCF_S = FOP(17, FMT_S),
6112
OPC_MOVZ_S = FOP(18, FMT_S),
6113
OPC_MOVN_S = FOP(19, FMT_S),
6114
OPC_RECIP_S = FOP(21, FMT_S),
6115
OPC_RSQRT_S = FOP(22, FMT_S),
6116
OPC_RECIP2_S = FOP(28, FMT_S),
6117
OPC_RECIP1_S = FOP(29, FMT_S),
6118
OPC_RSQRT1_S = FOP(30, FMT_S),
6119
OPC_RSQRT2_S = FOP(31, FMT_S),
6120
OPC_CVT_D_S = FOP(33, FMT_S),
6121
OPC_CVT_W_S = FOP(36, FMT_S),
6122
OPC_CVT_L_S = FOP(37, FMT_S),
6123
OPC_CVT_PS_S = FOP(38, FMT_S),
6124
OPC_CMP_F_S = FOP (48, FMT_S),
6125
OPC_CMP_UN_S = FOP (49, FMT_S),
6126
OPC_CMP_EQ_S = FOP (50, FMT_S),
6127
OPC_CMP_UEQ_S = FOP (51, FMT_S),
6128
OPC_CMP_OLT_S = FOP (52, FMT_S),
6129
OPC_CMP_ULT_S = FOP (53, FMT_S),
6130
OPC_CMP_OLE_S = FOP (54, FMT_S),
6131
OPC_CMP_ULE_S = FOP (55, FMT_S),
6132
OPC_CMP_SF_S = FOP (56, FMT_S),
6133
OPC_CMP_NGLE_S = FOP (57, FMT_S),
6134
OPC_CMP_SEQ_S = FOP (58, FMT_S),
6135
OPC_CMP_NGL_S = FOP (59, FMT_S),
6136
OPC_CMP_LT_S = FOP (60, FMT_S),
6137
OPC_CMP_NGE_S = FOP (61, FMT_S),
6138
OPC_CMP_LE_S = FOP (62, FMT_S),
6139
OPC_CMP_NGT_S = FOP (63, FMT_S),
6141
OPC_ADD_D = FOP(0, FMT_D),
6142
OPC_SUB_D = FOP(1, FMT_D),
6143
OPC_MUL_D = FOP(2, FMT_D),
6144
OPC_DIV_D = FOP(3, FMT_D),
6145
OPC_SQRT_D = FOP(4, FMT_D),
6146
OPC_ABS_D = FOP(5, FMT_D),
6147
OPC_MOV_D = FOP(6, FMT_D),
6148
OPC_NEG_D = FOP(7, FMT_D),
6149
OPC_ROUND_L_D = FOP(8, FMT_D),
6150
OPC_TRUNC_L_D = FOP(9, FMT_D),
6151
OPC_CEIL_L_D = FOP(10, FMT_D),
6152
OPC_FLOOR_L_D = FOP(11, FMT_D),
6153
OPC_ROUND_W_D = FOP(12, FMT_D),
6154
OPC_TRUNC_W_D = FOP(13, FMT_D),
6155
OPC_CEIL_W_D = FOP(14, FMT_D),
6156
OPC_FLOOR_W_D = FOP(15, FMT_D),
6157
OPC_MOVCF_D = FOP(17, FMT_D),
6158
OPC_MOVZ_D = FOP(18, FMT_D),
6159
OPC_MOVN_D = FOP(19, FMT_D),
6160
OPC_RECIP_D = FOP(21, FMT_D),
6161
OPC_RSQRT_D = FOP(22, FMT_D),
6162
OPC_RECIP2_D = FOP(28, FMT_D),
6163
OPC_RECIP1_D = FOP(29, FMT_D),
6164
OPC_RSQRT1_D = FOP(30, FMT_D),
6165
OPC_RSQRT2_D = FOP(31, FMT_D),
6166
OPC_CVT_S_D = FOP(32, FMT_D),
6167
OPC_CVT_W_D = FOP(36, FMT_D),
6168
OPC_CVT_L_D = FOP(37, FMT_D),
6169
OPC_CMP_F_D = FOP (48, FMT_D),
6170
OPC_CMP_UN_D = FOP (49, FMT_D),
6171
OPC_CMP_EQ_D = FOP (50, FMT_D),
6172
OPC_CMP_UEQ_D = FOP (51, FMT_D),
6173
OPC_CMP_OLT_D = FOP (52, FMT_D),
6174
OPC_CMP_ULT_D = FOP (53, FMT_D),
6175
OPC_CMP_OLE_D = FOP (54, FMT_D),
6176
OPC_CMP_ULE_D = FOP (55, FMT_D),
6177
OPC_CMP_SF_D = FOP (56, FMT_D),
6178
OPC_CMP_NGLE_D = FOP (57, FMT_D),
6179
OPC_CMP_SEQ_D = FOP (58, FMT_D),
6180
OPC_CMP_NGL_D = FOP (59, FMT_D),
6181
OPC_CMP_LT_D = FOP (60, FMT_D),
6182
OPC_CMP_NGE_D = FOP (61, FMT_D),
6183
OPC_CMP_LE_D = FOP (62, FMT_D),
6184
OPC_CMP_NGT_D = FOP (63, FMT_D),
6186
OPC_CVT_S_W = FOP(32, FMT_W),
6187
OPC_CVT_D_W = FOP(33, FMT_W),
6188
OPC_CVT_S_L = FOP(32, FMT_L),
6189
OPC_CVT_D_L = FOP(33, FMT_L),
6190
OPC_CVT_PS_PW = FOP(38, FMT_W),
6192
OPC_ADD_PS = FOP(0, FMT_PS),
6193
OPC_SUB_PS = FOP(1, FMT_PS),
6194
OPC_MUL_PS = FOP(2, FMT_PS),
6195
OPC_DIV_PS = FOP(3, FMT_PS),
6196
OPC_ABS_PS = FOP(5, FMT_PS),
6197
OPC_MOV_PS = FOP(6, FMT_PS),
6198
OPC_NEG_PS = FOP(7, FMT_PS),
6199
OPC_MOVCF_PS = FOP(17, FMT_PS),
6200
OPC_MOVZ_PS = FOP(18, FMT_PS),
6201
OPC_MOVN_PS = FOP(19, FMT_PS),
6202
OPC_ADDR_PS = FOP(24, FMT_PS),
6203
OPC_MULR_PS = FOP(26, FMT_PS),
6204
OPC_RECIP2_PS = FOP(28, FMT_PS),
6205
OPC_RECIP1_PS = FOP(29, FMT_PS),
6206
OPC_RSQRT1_PS = FOP(30, FMT_PS),
6207
OPC_RSQRT2_PS = FOP(31, FMT_PS),
6209
OPC_CVT_S_PU = FOP(32, FMT_PS),
6210
OPC_CVT_PW_PS = FOP(36, FMT_PS),
6211
OPC_CVT_S_PL = FOP(40, FMT_PS),
6212
OPC_PLL_PS = FOP(44, FMT_PS),
6213
OPC_PLU_PS = FOP(45, FMT_PS),
6214
OPC_PUL_PS = FOP(46, FMT_PS),
6215
OPC_PUU_PS = FOP(47, FMT_PS),
6216
OPC_CMP_F_PS = FOP (48, FMT_PS),
6217
OPC_CMP_UN_PS = FOP (49, FMT_PS),
6218
OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6219
OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6220
OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6221
OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6222
OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6223
OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6224
OPC_CMP_SF_PS = FOP (56, FMT_PS),
6225
OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6226
OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6227
OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6228
OPC_CMP_LT_PS = FOP (60, FMT_PS),
6229
OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6230
OPC_CMP_LE_PS = FOP (62, FMT_PS),
6231
OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6234
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6236
const char *opn = "cp1 move";
6237
TCGv t0 = tcg_temp_new();
6242
TCGv_i32 fp0 = tcg_temp_new_i32();
6244
gen_load_fpr32(fp0, fs);
6245
tcg_gen_ext_i32_tl(t0, fp0);
6246
tcg_temp_free_i32(fp0);
6248
gen_store_gpr(t0, rt);
6252
gen_load_gpr(t0, rt);
6254
TCGv_i32 fp0 = tcg_temp_new_i32();
6256
tcg_gen_trunc_tl_i32(fp0, t0);
6257
gen_store_fpr32(fp0, fs);
6258
tcg_temp_free_i32(fp0);
6263
gen_helper_1i(cfc1, t0, fs);
6264
gen_store_gpr(t0, rt);
6268
gen_load_gpr(t0, rt);
6269
gen_helper_1i(ctc1, t0, fs);
6272
#if defined(TARGET_MIPS64)
6274
gen_load_fpr64(ctx, t0, fs);
6275
gen_store_gpr(t0, rt);
6279
gen_load_gpr(t0, rt);
6280
gen_store_fpr64(ctx, t0, fs);
6286
TCGv_i32 fp0 = tcg_temp_new_i32();
6288
gen_load_fpr32h(fp0, fs);
6289
tcg_gen_ext_i32_tl(t0, fp0);
6290
tcg_temp_free_i32(fp0);
6292
gen_store_gpr(t0, rt);
6296
gen_load_gpr(t0, rt);
6298
TCGv_i32 fp0 = tcg_temp_new_i32();
6300
tcg_gen_trunc_tl_i32(fp0, t0);
6301
gen_store_fpr32h(fp0, fs);
6302
tcg_temp_free_i32(fp0);
6308
generate_exception (ctx, EXCP_RI);
6311
(void)opn; /* avoid a compiler warning */
6312
MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6318
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6334
l1 = gen_new_label();
6335
t0 = tcg_temp_new_i32();
6336
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6337
tcg_gen_brcondi_i32(cond, t0, 0, l1);
6338
tcg_temp_free_i32(t0);
6340
tcg_gen_movi_tl(cpu_gpr[rd], 0);
6342
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6347
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6350
TCGv_i32 t0 = tcg_temp_new_i32();
6351
int l1 = gen_new_label();
6358
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6359
tcg_gen_brcondi_i32(cond, t0, 0, l1);
6360
gen_load_fpr32(t0, fs);
6361
gen_store_fpr32(t0, fd);
6363
tcg_temp_free_i32(t0);
6366
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6369
TCGv_i32 t0 = tcg_temp_new_i32();
6371
int l1 = gen_new_label();
6378
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6379
tcg_gen_brcondi_i32(cond, t0, 0, l1);
6380
tcg_temp_free_i32(t0);
6381
fp0 = tcg_temp_new_i64();
6382
gen_load_fpr64(ctx, fp0, fs);
6383
gen_store_fpr64(ctx, fp0, fd);
6384
tcg_temp_free_i64(fp0);
6388
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6391
TCGv_i32 t0 = tcg_temp_new_i32();
6392
int l1 = gen_new_label();
6393
int l2 = gen_new_label();
6400
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6401
tcg_gen_brcondi_i32(cond, t0, 0, l1);
6402
gen_load_fpr32(t0, fs);
6403
gen_store_fpr32(t0, fd);
6406
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6407
tcg_gen_brcondi_i32(cond, t0, 0, l2);
6408
gen_load_fpr32h(t0, fs);
6409
gen_store_fpr32h(t0, fd);
6410
tcg_temp_free_i32(t0);
6415
static void gen_farith (DisasContext *ctx, enum fopcode op1,
6416
int ft, int fs, int fd, int cc)
6418
const char *opn = "farith";
6419
const char *condnames[] = {
6437
const char *condnames_abs[] = {
6455
enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6456
uint32_t func = ctx->opcode & 0x3f;
6461
TCGv_i32 fp0 = tcg_temp_new_i32();
6462
TCGv_i32 fp1 = tcg_temp_new_i32();
6464
gen_load_fpr32(fp0, fs);
6465
gen_load_fpr32(fp1, ft);
6466
gen_helper_float_add_s(fp0, fp0, fp1);
6467
tcg_temp_free_i32(fp1);
6468
gen_store_fpr32(fp0, fd);
6469
tcg_temp_free_i32(fp0);
6476
TCGv_i32 fp0 = tcg_temp_new_i32();
6477
TCGv_i32 fp1 = tcg_temp_new_i32();
6479
gen_load_fpr32(fp0, fs);
6480
gen_load_fpr32(fp1, ft);
6481
gen_helper_float_sub_s(fp0, fp0, fp1);
6482
tcg_temp_free_i32(fp1);
6483
gen_store_fpr32(fp0, fd);
6484
tcg_temp_free_i32(fp0);
6491
TCGv_i32 fp0 = tcg_temp_new_i32();
6492
TCGv_i32 fp1 = tcg_temp_new_i32();
6494
gen_load_fpr32(fp0, fs);
6495
gen_load_fpr32(fp1, ft);
6496
gen_helper_float_mul_s(fp0, fp0, fp1);
6497
tcg_temp_free_i32(fp1);
6498
gen_store_fpr32(fp0, fd);
6499
tcg_temp_free_i32(fp0);
6506
TCGv_i32 fp0 = tcg_temp_new_i32();
6507
TCGv_i32 fp1 = tcg_temp_new_i32();
6509
gen_load_fpr32(fp0, fs);
6510
gen_load_fpr32(fp1, ft);
6511
gen_helper_float_div_s(fp0, fp0, fp1);
6512
tcg_temp_free_i32(fp1);
6513
gen_store_fpr32(fp0, fd);
6514
tcg_temp_free_i32(fp0);
6521
TCGv_i32 fp0 = tcg_temp_new_i32();
6523
gen_load_fpr32(fp0, fs);
6524
gen_helper_float_sqrt_s(fp0, fp0);
6525
gen_store_fpr32(fp0, fd);
6526
tcg_temp_free_i32(fp0);
6532
TCGv_i32 fp0 = tcg_temp_new_i32();
6534
gen_load_fpr32(fp0, fs);
6535
gen_helper_float_abs_s(fp0, fp0);
6536
gen_store_fpr32(fp0, fd);
6537
tcg_temp_free_i32(fp0);
6543
TCGv_i32 fp0 = tcg_temp_new_i32();
6545
gen_load_fpr32(fp0, fs);
6546
gen_store_fpr32(fp0, fd);
6547
tcg_temp_free_i32(fp0);
6553
TCGv_i32 fp0 = tcg_temp_new_i32();
6555
gen_load_fpr32(fp0, fs);
6556
gen_helper_float_chs_s(fp0, fp0);
6557
gen_store_fpr32(fp0, fd);
6558
tcg_temp_free_i32(fp0);
6563
check_cp1_64bitmode(ctx);
6565
TCGv_i32 fp32 = tcg_temp_new_i32();
6566
TCGv_i64 fp64 = tcg_temp_new_i64();
6568
gen_load_fpr32(fp32, fs);
6569
gen_helper_float_roundl_s(fp64, fp32);
6570
tcg_temp_free_i32(fp32);
6571
gen_store_fpr64(ctx, fp64, fd);
6572
tcg_temp_free_i64(fp64);
6577
check_cp1_64bitmode(ctx);
6579
TCGv_i32 fp32 = tcg_temp_new_i32();
6580
TCGv_i64 fp64 = tcg_temp_new_i64();
6582
gen_load_fpr32(fp32, fs);
6583
gen_helper_float_truncl_s(fp64, fp32);
6584
tcg_temp_free_i32(fp32);
6585
gen_store_fpr64(ctx, fp64, fd);
6586
tcg_temp_free_i64(fp64);
6591
check_cp1_64bitmode(ctx);
6593
TCGv_i32 fp32 = tcg_temp_new_i32();
6594
TCGv_i64 fp64 = tcg_temp_new_i64();
6596
gen_load_fpr32(fp32, fs);
6597
gen_helper_float_ceill_s(fp64, fp32);
6598
tcg_temp_free_i32(fp32);
6599
gen_store_fpr64(ctx, fp64, fd);
6600
tcg_temp_free_i64(fp64);
6605
check_cp1_64bitmode(ctx);
6607
TCGv_i32 fp32 = tcg_temp_new_i32();
6608
TCGv_i64 fp64 = tcg_temp_new_i64();
6610
gen_load_fpr32(fp32, fs);
6611
gen_helper_float_floorl_s(fp64, fp32);
6612
tcg_temp_free_i32(fp32);
6613
gen_store_fpr64(ctx, fp64, fd);
6614
tcg_temp_free_i64(fp64);
6620
TCGv_i32 fp0 = tcg_temp_new_i32();
6622
gen_load_fpr32(fp0, fs);
6623
gen_helper_float_roundw_s(fp0, fp0);
6624
gen_store_fpr32(fp0, fd);
6625
tcg_temp_free_i32(fp0);
6631
TCGv_i32 fp0 = tcg_temp_new_i32();
6633
gen_load_fpr32(fp0, fs);
6634
gen_helper_float_truncw_s(fp0, fp0);
6635
gen_store_fpr32(fp0, fd);
6636
tcg_temp_free_i32(fp0);
6642
TCGv_i32 fp0 = tcg_temp_new_i32();
6644
gen_load_fpr32(fp0, fs);
6645
gen_helper_float_ceilw_s(fp0, fp0);
6646
gen_store_fpr32(fp0, fd);
6647
tcg_temp_free_i32(fp0);
6653
TCGv_i32 fp0 = tcg_temp_new_i32();
6655
gen_load_fpr32(fp0, fs);
6656
gen_helper_float_floorw_s(fp0, fp0);
6657
gen_store_fpr32(fp0, fd);
6658
tcg_temp_free_i32(fp0);
6663
gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6668
int l1 = gen_new_label();
6672
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6674
fp0 = tcg_temp_new_i32();
6675
gen_load_fpr32(fp0, fs);
6676
gen_store_fpr32(fp0, fd);
6677
tcg_temp_free_i32(fp0);
6684
int l1 = gen_new_label();
6688
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6689
fp0 = tcg_temp_new_i32();
6690
gen_load_fpr32(fp0, fs);
6691
gen_store_fpr32(fp0, fd);
6692
tcg_temp_free_i32(fp0);
6701
TCGv_i32 fp0 = tcg_temp_new_i32();
6703
gen_load_fpr32(fp0, fs);
6704
gen_helper_float_recip_s(fp0, fp0);
6705
gen_store_fpr32(fp0, fd);
6706
tcg_temp_free_i32(fp0);
6713
TCGv_i32 fp0 = tcg_temp_new_i32();
6715
gen_load_fpr32(fp0, fs);
6716
gen_helper_float_rsqrt_s(fp0, fp0);
6717
gen_store_fpr32(fp0, fd);
6718
tcg_temp_free_i32(fp0);
6723
check_cp1_64bitmode(ctx);
6725
TCGv_i32 fp0 = tcg_temp_new_i32();
6726
TCGv_i32 fp1 = tcg_temp_new_i32();
6728
gen_load_fpr32(fp0, fs);
6729
gen_load_fpr32(fp1, fd);
6730
gen_helper_float_recip2_s(fp0, fp0, fp1);
6731
tcg_temp_free_i32(fp1);
6732
gen_store_fpr32(fp0, fd);
6733
tcg_temp_free_i32(fp0);
6738
check_cp1_64bitmode(ctx);
6740
TCGv_i32 fp0 = tcg_temp_new_i32();
6742
gen_load_fpr32(fp0, fs);
6743
gen_helper_float_recip1_s(fp0, fp0);
6744
gen_store_fpr32(fp0, fd);
6745
tcg_temp_free_i32(fp0);
6750
check_cp1_64bitmode(ctx);
6752
TCGv_i32 fp0 = tcg_temp_new_i32();
6754
gen_load_fpr32(fp0, fs);
6755
gen_helper_float_rsqrt1_s(fp0, fp0);
6756
gen_store_fpr32(fp0, fd);
6757
tcg_temp_free_i32(fp0);
6762
check_cp1_64bitmode(ctx);
6764
TCGv_i32 fp0 = tcg_temp_new_i32();
6765
TCGv_i32 fp1 = tcg_temp_new_i32();
6767
gen_load_fpr32(fp0, fs);
6768
gen_load_fpr32(fp1, ft);
6769
gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6770
tcg_temp_free_i32(fp1);
6771
gen_store_fpr32(fp0, fd);
6772
tcg_temp_free_i32(fp0);
6777
check_cp1_registers(ctx, fd);
6779
TCGv_i32 fp32 = tcg_temp_new_i32();
6780
TCGv_i64 fp64 = tcg_temp_new_i64();
6782
gen_load_fpr32(fp32, fs);
6783
gen_helper_float_cvtd_s(fp64, fp32);
6784
tcg_temp_free_i32(fp32);
6785
gen_store_fpr64(ctx, fp64, fd);
6786
tcg_temp_free_i64(fp64);
6792
TCGv_i32 fp0 = tcg_temp_new_i32();
6794
gen_load_fpr32(fp0, fs);
6795
gen_helper_float_cvtw_s(fp0, fp0);
6796
gen_store_fpr32(fp0, fd);
6797
tcg_temp_free_i32(fp0);
6802
check_cp1_64bitmode(ctx);
6804
TCGv_i32 fp32 = tcg_temp_new_i32();
6805
TCGv_i64 fp64 = tcg_temp_new_i64();
6807
gen_load_fpr32(fp32, fs);
6808
gen_helper_float_cvtl_s(fp64, fp32);
6809
tcg_temp_free_i32(fp32);
6810
gen_store_fpr64(ctx, fp64, fd);
6811
tcg_temp_free_i64(fp64);
6816
check_cp1_64bitmode(ctx);
6818
TCGv_i64 fp64 = tcg_temp_new_i64();
6819
TCGv_i32 fp32_0 = tcg_temp_new_i32();
6820
TCGv_i32 fp32_1 = tcg_temp_new_i32();
6822
gen_load_fpr32(fp32_0, fs);
6823
gen_load_fpr32(fp32_1, ft);
6824
tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6825
tcg_temp_free_i32(fp32_1);
6826
tcg_temp_free_i32(fp32_0);
6827
gen_store_fpr64(ctx, fp64, fd);
6828
tcg_temp_free_i64(fp64);
6841
case OPC_CMP_NGLE_S:
6848
if (ctx->opcode & (1 << 6)) {
6849
gen_cmpabs_s(ctx, func-48, ft, fs, cc);
6850
opn = condnames_abs[func-48];
6852
gen_cmp_s(ctx, func-48, ft, fs, cc);
6853
opn = condnames[func-48];
6857
check_cp1_registers(ctx, fs | ft | fd);
6859
TCGv_i64 fp0 = tcg_temp_new_i64();
6860
TCGv_i64 fp1 = tcg_temp_new_i64();
6862
gen_load_fpr64(ctx, fp0, fs);
6863
gen_load_fpr64(ctx, fp1, ft);
6864
gen_helper_float_add_d(fp0, fp0, fp1);
6865
tcg_temp_free_i64(fp1);
6866
gen_store_fpr64(ctx, fp0, fd);
6867
tcg_temp_free_i64(fp0);
6873
check_cp1_registers(ctx, fs | ft | fd);
6875
TCGv_i64 fp0 = tcg_temp_new_i64();
6876
TCGv_i64 fp1 = tcg_temp_new_i64();
6878
gen_load_fpr64(ctx, fp0, fs);
6879
gen_load_fpr64(ctx, fp1, ft);
6880
gen_helper_float_sub_d(fp0, fp0, fp1);
6881
tcg_temp_free_i64(fp1);
6882
gen_store_fpr64(ctx, fp0, fd);
6883
tcg_temp_free_i64(fp0);
6889
check_cp1_registers(ctx, fs | ft | fd);
6891
TCGv_i64 fp0 = tcg_temp_new_i64();
6892
TCGv_i64 fp1 = tcg_temp_new_i64();
6894
gen_load_fpr64(ctx, fp0, fs);
6895
gen_load_fpr64(ctx, fp1, ft);
6896
gen_helper_float_mul_d(fp0, fp0, fp1);
6897
tcg_temp_free_i64(fp1);
6898
gen_store_fpr64(ctx, fp0, fd);
6899
tcg_temp_free_i64(fp0);
6905
check_cp1_registers(ctx, fs | ft | fd);
6907
TCGv_i64 fp0 = tcg_temp_new_i64();
6908
TCGv_i64 fp1 = tcg_temp_new_i64();
6910
gen_load_fpr64(ctx, fp0, fs);
6911
gen_load_fpr64(ctx, fp1, ft);
6912
gen_helper_float_div_d(fp0, fp0, fp1);
6913
tcg_temp_free_i64(fp1);
6914
gen_store_fpr64(ctx, fp0, fd);
6915
tcg_temp_free_i64(fp0);
6921
check_cp1_registers(ctx, fs | fd);
6923
TCGv_i64 fp0 = tcg_temp_new_i64();
6925
gen_load_fpr64(ctx, fp0, fs);
6926
gen_helper_float_sqrt_d(fp0, fp0);
6927
gen_store_fpr64(ctx, fp0, fd);
6928
tcg_temp_free_i64(fp0);
6933
check_cp1_registers(ctx, fs | fd);
6935
TCGv_i64 fp0 = tcg_temp_new_i64();
6937
gen_load_fpr64(ctx, fp0, fs);
6938
gen_helper_float_abs_d(fp0, fp0);
6939
gen_store_fpr64(ctx, fp0, fd);
6940
tcg_temp_free_i64(fp0);
6945
check_cp1_registers(ctx, fs | fd);
6947
TCGv_i64 fp0 = tcg_temp_new_i64();
6949
gen_load_fpr64(ctx, fp0, fs);
6950
gen_store_fpr64(ctx, fp0, fd);
6951
tcg_temp_free_i64(fp0);
6956
check_cp1_registers(ctx, fs | fd);
6958
TCGv_i64 fp0 = tcg_temp_new_i64();
6960
gen_load_fpr64(ctx, fp0, fs);
6961
gen_helper_float_chs_d(fp0, fp0);
6962
gen_store_fpr64(ctx, fp0, fd);
6963
tcg_temp_free_i64(fp0);
6968
check_cp1_64bitmode(ctx);
6970
TCGv_i64 fp0 = tcg_temp_new_i64();
6972
gen_load_fpr64(ctx, fp0, fs);
6973
gen_helper_float_roundl_d(fp0, fp0);
6974
gen_store_fpr64(ctx, fp0, fd);
6975
tcg_temp_free_i64(fp0);
6980
check_cp1_64bitmode(ctx);
6982
TCGv_i64 fp0 = tcg_temp_new_i64();
6984
gen_load_fpr64(ctx, fp0, fs);
6985
gen_helper_float_truncl_d(fp0, fp0);
6986
gen_store_fpr64(ctx, fp0, fd);
6987
tcg_temp_free_i64(fp0);
6992
check_cp1_64bitmode(ctx);
6994
TCGv_i64 fp0 = tcg_temp_new_i64();
6996
gen_load_fpr64(ctx, fp0, fs);
6997
gen_helper_float_ceill_d(fp0, fp0);
6998
gen_store_fpr64(ctx, fp0, fd);
6999
tcg_temp_free_i64(fp0);
7004
check_cp1_64bitmode(ctx);
7006
TCGv_i64 fp0 = tcg_temp_new_i64();
7008
gen_load_fpr64(ctx, fp0, fs);
7009
gen_helper_float_floorl_d(fp0, fp0);
7010
gen_store_fpr64(ctx, fp0, fd);
7011
tcg_temp_free_i64(fp0);
7016
check_cp1_registers(ctx, fs);
7018
TCGv_i32 fp32 = tcg_temp_new_i32();
7019
TCGv_i64 fp64 = tcg_temp_new_i64();
7021
gen_load_fpr64(ctx, fp64, fs);
7022
gen_helper_float_roundw_d(fp32, fp64);
7023
tcg_temp_free_i64(fp64);
7024
gen_store_fpr32(fp32, fd);
7025
tcg_temp_free_i32(fp32);
7030
check_cp1_registers(ctx, fs);
7032
TCGv_i32 fp32 = tcg_temp_new_i32();
7033
TCGv_i64 fp64 = tcg_temp_new_i64();
7035
gen_load_fpr64(ctx, fp64, fs);
7036
gen_helper_float_truncw_d(fp32, fp64);
7037
tcg_temp_free_i64(fp64);
7038
gen_store_fpr32(fp32, fd);
7039
tcg_temp_free_i32(fp32);
7044
check_cp1_registers(ctx, fs);
7046
TCGv_i32 fp32 = tcg_temp_new_i32();
7047
TCGv_i64 fp64 = tcg_temp_new_i64();
7049
gen_load_fpr64(ctx, fp64, fs);
7050
gen_helper_float_ceilw_d(fp32, fp64);
7051
tcg_temp_free_i64(fp64);
7052
gen_store_fpr32(fp32, fd);
7053
tcg_temp_free_i32(fp32);
7058
check_cp1_registers(ctx, fs);
7060
TCGv_i32 fp32 = tcg_temp_new_i32();
7061
TCGv_i64 fp64 = tcg_temp_new_i64();
7063
gen_load_fpr64(ctx, fp64, fs);
7064
gen_helper_float_floorw_d(fp32, fp64);
7065
tcg_temp_free_i64(fp64);
7066
gen_store_fpr32(fp32, fd);
7067
tcg_temp_free_i32(fp32);
7072
gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7077
int l1 = gen_new_label();
7081
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7083
fp0 = tcg_temp_new_i64();
7084
gen_load_fpr64(ctx, fp0, fs);
7085
gen_store_fpr64(ctx, fp0, fd);
7086
tcg_temp_free_i64(fp0);
7093
int l1 = gen_new_label();
7097
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7098
fp0 = tcg_temp_new_i64();
7099
gen_load_fpr64(ctx, fp0, fs);
7100
gen_store_fpr64(ctx, fp0, fd);
7101
tcg_temp_free_i64(fp0);
7108
check_cp1_64bitmode(ctx);
7110
TCGv_i64 fp0 = tcg_temp_new_i64();
7112
gen_load_fpr64(ctx, fp0, fs);
7113
gen_helper_float_recip_d(fp0, fp0);
7114
gen_store_fpr64(ctx, fp0, fd);
7115
tcg_temp_free_i64(fp0);
7120
check_cp1_64bitmode(ctx);
7122
TCGv_i64 fp0 = tcg_temp_new_i64();
7124
gen_load_fpr64(ctx, fp0, fs);
7125
gen_helper_float_rsqrt_d(fp0, fp0);
7126
gen_store_fpr64(ctx, fp0, fd);
7127
tcg_temp_free_i64(fp0);
7132
check_cp1_64bitmode(ctx);
7134
TCGv_i64 fp0 = tcg_temp_new_i64();
7135
TCGv_i64 fp1 = tcg_temp_new_i64();
7137
gen_load_fpr64(ctx, fp0, fs);
7138
gen_load_fpr64(ctx, fp1, ft);
7139
gen_helper_float_recip2_d(fp0, fp0, fp1);
7140
tcg_temp_free_i64(fp1);
7141
gen_store_fpr64(ctx, fp0, fd);
7142
tcg_temp_free_i64(fp0);
7147
check_cp1_64bitmode(ctx);
7149
TCGv_i64 fp0 = tcg_temp_new_i64();
7151
gen_load_fpr64(ctx, fp0, fs);
7152
gen_helper_float_recip1_d(fp0, fp0);
7153
gen_store_fpr64(ctx, fp0, fd);
7154
tcg_temp_free_i64(fp0);
7159
check_cp1_64bitmode(ctx);
7161
TCGv_i64 fp0 = tcg_temp_new_i64();
7163
gen_load_fpr64(ctx, fp0, fs);
7164
gen_helper_float_rsqrt1_d(fp0, fp0);
7165
gen_store_fpr64(ctx, fp0, fd);
7166
tcg_temp_free_i64(fp0);
7171
check_cp1_64bitmode(ctx);
7173
TCGv_i64 fp0 = tcg_temp_new_i64();
7174
TCGv_i64 fp1 = tcg_temp_new_i64();
7176
gen_load_fpr64(ctx, fp0, fs);
7177
gen_load_fpr64(ctx, fp1, ft);
7178
gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
7179
tcg_temp_free_i64(fp1);
7180
gen_store_fpr64(ctx, fp0, fd);
7181
tcg_temp_free_i64(fp0);
7194
case OPC_CMP_NGLE_D:
7201
if (ctx->opcode & (1 << 6)) {
7202
gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7203
opn = condnames_abs[func-48];
7205
gen_cmp_d(ctx, func-48, ft, fs, cc);
7206
opn = condnames[func-48];
7210
check_cp1_registers(ctx, fs);
7212
TCGv_i32 fp32 = tcg_temp_new_i32();
7213
TCGv_i64 fp64 = tcg_temp_new_i64();
7215
gen_load_fpr64(ctx, fp64, fs);
7216
gen_helper_float_cvts_d(fp32, fp64);
7217
tcg_temp_free_i64(fp64);
7218
gen_store_fpr32(fp32, fd);
7219
tcg_temp_free_i32(fp32);
7224
check_cp1_registers(ctx, fs);
7226
TCGv_i32 fp32 = tcg_temp_new_i32();
7227
TCGv_i64 fp64 = tcg_temp_new_i64();
7229
gen_load_fpr64(ctx, fp64, fs);
7230
gen_helper_float_cvtw_d(fp32, fp64);
7231
tcg_temp_free_i64(fp64);
7232
gen_store_fpr32(fp32, fd);
7233
tcg_temp_free_i32(fp32);
7238
check_cp1_64bitmode(ctx);
7240
TCGv_i64 fp0 = tcg_temp_new_i64();
7242
gen_load_fpr64(ctx, fp0, fs);
7243
gen_helper_float_cvtl_d(fp0, fp0);
7244
gen_store_fpr64(ctx, fp0, fd);
7245
tcg_temp_free_i64(fp0);
7251
TCGv_i32 fp0 = tcg_temp_new_i32();
7253
gen_load_fpr32(fp0, fs);
7254
gen_helper_float_cvts_w(fp0, fp0);
7255
gen_store_fpr32(fp0, fd);
7256
tcg_temp_free_i32(fp0);
7261
check_cp1_registers(ctx, fd);
7263
TCGv_i32 fp32 = tcg_temp_new_i32();
7264
TCGv_i64 fp64 = tcg_temp_new_i64();
7266
gen_load_fpr32(fp32, fs);
7267
gen_helper_float_cvtd_w(fp64, fp32);
7268
tcg_temp_free_i32(fp32);
7269
gen_store_fpr64(ctx, fp64, fd);
7270
tcg_temp_free_i64(fp64);
7275
check_cp1_64bitmode(ctx);
7277
TCGv_i32 fp32 = tcg_temp_new_i32();
7278
TCGv_i64 fp64 = tcg_temp_new_i64();
7280
gen_load_fpr64(ctx, fp64, fs);
7281
gen_helper_float_cvts_l(fp32, fp64);
7282
tcg_temp_free_i64(fp64);
7283
gen_store_fpr32(fp32, fd);
7284
tcg_temp_free_i32(fp32);
7289
check_cp1_64bitmode(ctx);
7291
TCGv_i64 fp0 = tcg_temp_new_i64();
7293
gen_load_fpr64(ctx, fp0, fs);
7294
gen_helper_float_cvtd_l(fp0, fp0);
7295
gen_store_fpr64(ctx, fp0, fd);
7296
tcg_temp_free_i64(fp0);
7301
check_cp1_64bitmode(ctx);
7303
TCGv_i64 fp0 = tcg_temp_new_i64();
7305
gen_load_fpr64(ctx, fp0, fs);
7306
gen_helper_float_cvtps_pw(fp0, fp0);
7307
gen_store_fpr64(ctx, fp0, fd);
7308
tcg_temp_free_i64(fp0);
7313
check_cp1_64bitmode(ctx);
7315
TCGv_i64 fp0 = tcg_temp_new_i64();
7316
TCGv_i64 fp1 = tcg_temp_new_i64();
7318
gen_load_fpr64(ctx, fp0, fs);
7319
gen_load_fpr64(ctx, fp1, ft);
7320
gen_helper_float_add_ps(fp0, fp0, fp1);
7321
tcg_temp_free_i64(fp1);
7322
gen_store_fpr64(ctx, fp0, fd);
7323
tcg_temp_free_i64(fp0);
7328
check_cp1_64bitmode(ctx);
7330
TCGv_i64 fp0 = tcg_temp_new_i64();
7331
TCGv_i64 fp1 = tcg_temp_new_i64();
7333
gen_load_fpr64(ctx, fp0, fs);
7334
gen_load_fpr64(ctx, fp1, ft);
7335
gen_helper_float_sub_ps(fp0, fp0, fp1);
7336
tcg_temp_free_i64(fp1);
7337
gen_store_fpr64(ctx, fp0, fd);
7338
tcg_temp_free_i64(fp0);
7343
check_cp1_64bitmode(ctx);
7345
TCGv_i64 fp0 = tcg_temp_new_i64();
7346
TCGv_i64 fp1 = tcg_temp_new_i64();
7348
gen_load_fpr64(ctx, fp0, fs);
7349
gen_load_fpr64(ctx, fp1, ft);
7350
gen_helper_float_mul_ps(fp0, fp0, fp1);
7351
tcg_temp_free_i64(fp1);
7352
gen_store_fpr64(ctx, fp0, fd);
7353
tcg_temp_free_i64(fp0);
7358
check_cp1_64bitmode(ctx);
7360
TCGv_i64 fp0 = tcg_temp_new_i64();
7362
gen_load_fpr64(ctx, fp0, fs);
7363
gen_helper_float_abs_ps(fp0, fp0);
7364
gen_store_fpr64(ctx, fp0, fd);
7365
tcg_temp_free_i64(fp0);
7370
check_cp1_64bitmode(ctx);
7372
TCGv_i64 fp0 = tcg_temp_new_i64();
7374
gen_load_fpr64(ctx, fp0, fs);
7375
gen_store_fpr64(ctx, fp0, fd);
7376
tcg_temp_free_i64(fp0);
7381
check_cp1_64bitmode(ctx);
7383
TCGv_i64 fp0 = tcg_temp_new_i64();
7385
gen_load_fpr64(ctx, fp0, fs);
7386
gen_helper_float_chs_ps(fp0, fp0);
7387
gen_store_fpr64(ctx, fp0, fd);
7388
tcg_temp_free_i64(fp0);
7393
check_cp1_64bitmode(ctx);
7394
gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7398
check_cp1_64bitmode(ctx);
7400
int l1 = gen_new_label();
7404
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7405
fp0 = tcg_temp_new_i64();
7406
gen_load_fpr64(ctx, fp0, fs);
7407
gen_store_fpr64(ctx, fp0, fd);
7408
tcg_temp_free_i64(fp0);
7414
check_cp1_64bitmode(ctx);
7416
int l1 = gen_new_label();
7420
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7421
fp0 = tcg_temp_new_i64();
7422
gen_load_fpr64(ctx, fp0, fs);
7423
gen_store_fpr64(ctx, fp0, fd);
7424
tcg_temp_free_i64(fp0);
7431
check_cp1_64bitmode(ctx);
7433
TCGv_i64 fp0 = tcg_temp_new_i64();
7434
TCGv_i64 fp1 = tcg_temp_new_i64();
7436
gen_load_fpr64(ctx, fp0, ft);
7437
gen_load_fpr64(ctx, fp1, fs);
7438
gen_helper_float_addr_ps(fp0, fp0, fp1);
7439
tcg_temp_free_i64(fp1);
7440
gen_store_fpr64(ctx, fp0, fd);
7441
tcg_temp_free_i64(fp0);
7446
check_cp1_64bitmode(ctx);
7448
TCGv_i64 fp0 = tcg_temp_new_i64();
7449
TCGv_i64 fp1 = tcg_temp_new_i64();
7451
gen_load_fpr64(ctx, fp0, ft);
7452
gen_load_fpr64(ctx, fp1, fs);
7453
gen_helper_float_mulr_ps(fp0, fp0, fp1);
7454
tcg_temp_free_i64(fp1);
7455
gen_store_fpr64(ctx, fp0, fd);
7456
tcg_temp_free_i64(fp0);
7461
check_cp1_64bitmode(ctx);
7463
TCGv_i64 fp0 = tcg_temp_new_i64();
7464
TCGv_i64 fp1 = tcg_temp_new_i64();
7466
gen_load_fpr64(ctx, fp0, fs);
7467
gen_load_fpr64(ctx, fp1, fd);
7468
gen_helper_float_recip2_ps(fp0, fp0, fp1);
7469
tcg_temp_free_i64(fp1);
7470
gen_store_fpr64(ctx, fp0, fd);
7471
tcg_temp_free_i64(fp0);
7476
check_cp1_64bitmode(ctx);
7478
TCGv_i64 fp0 = tcg_temp_new_i64();
7480
gen_load_fpr64(ctx, fp0, fs);
7481
gen_helper_float_recip1_ps(fp0, fp0);
7482
gen_store_fpr64(ctx, fp0, fd);
7483
tcg_temp_free_i64(fp0);
7488
check_cp1_64bitmode(ctx);
7490
TCGv_i64 fp0 = tcg_temp_new_i64();
7492
gen_load_fpr64(ctx, fp0, fs);
7493
gen_helper_float_rsqrt1_ps(fp0, fp0);
7494
gen_store_fpr64(ctx, fp0, fd);
7495
tcg_temp_free_i64(fp0);
7500
check_cp1_64bitmode(ctx);
7502
TCGv_i64 fp0 = tcg_temp_new_i64();
7503
TCGv_i64 fp1 = tcg_temp_new_i64();
7505
gen_load_fpr64(ctx, fp0, fs);
7506
gen_load_fpr64(ctx, fp1, ft);
7507
gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7508
tcg_temp_free_i64(fp1);
7509
gen_store_fpr64(ctx, fp0, fd);
7510
tcg_temp_free_i64(fp0);
7515
check_cp1_64bitmode(ctx);
7517
TCGv_i32 fp0 = tcg_temp_new_i32();
7519
gen_load_fpr32h(fp0, fs);
7520
gen_helper_float_cvts_pu(fp0, fp0);
7521
gen_store_fpr32(fp0, fd);
7522
tcg_temp_free_i32(fp0);
7527
check_cp1_64bitmode(ctx);
7529
TCGv_i64 fp0 = tcg_temp_new_i64();
7531
gen_load_fpr64(ctx, fp0, fs);
7532
gen_helper_float_cvtpw_ps(fp0, fp0);
7533
gen_store_fpr64(ctx, fp0, fd);
7534
tcg_temp_free_i64(fp0);
7539
check_cp1_64bitmode(ctx);
7541
TCGv_i32 fp0 = tcg_temp_new_i32();
7543
gen_load_fpr32(fp0, fs);
7544
gen_helper_float_cvts_pl(fp0, fp0);
7545
gen_store_fpr32(fp0, fd);
7546
tcg_temp_free_i32(fp0);
7551
check_cp1_64bitmode(ctx);
7553
TCGv_i32 fp0 = tcg_temp_new_i32();
7554
TCGv_i32 fp1 = tcg_temp_new_i32();
7556
gen_load_fpr32(fp0, fs);
7557
gen_load_fpr32(fp1, ft);
7558
gen_store_fpr32h(fp0, fd);
7559
gen_store_fpr32(fp1, fd);
7560
tcg_temp_free_i32(fp0);
7561
tcg_temp_free_i32(fp1);
7566
check_cp1_64bitmode(ctx);
7568
TCGv_i32 fp0 = tcg_temp_new_i32();
7569
TCGv_i32 fp1 = tcg_temp_new_i32();
7571
gen_load_fpr32(fp0, fs);
7572
gen_load_fpr32h(fp1, ft);
7573
gen_store_fpr32(fp1, fd);
7574
gen_store_fpr32h(fp0, fd);
7575
tcg_temp_free_i32(fp0);
7576
tcg_temp_free_i32(fp1);
7581
check_cp1_64bitmode(ctx);
7583
TCGv_i32 fp0 = tcg_temp_new_i32();
7584
TCGv_i32 fp1 = tcg_temp_new_i32();
7586
gen_load_fpr32h(fp0, fs);
7587
gen_load_fpr32(fp1, ft);
7588
gen_store_fpr32(fp1, fd);
7589
gen_store_fpr32h(fp0, fd);
7590
tcg_temp_free_i32(fp0);
7591
tcg_temp_free_i32(fp1);
7596
check_cp1_64bitmode(ctx);
7598
TCGv_i32 fp0 = tcg_temp_new_i32();
7599
TCGv_i32 fp1 = tcg_temp_new_i32();
7601
gen_load_fpr32h(fp0, fs);
7602
gen_load_fpr32h(fp1, ft);
7603
gen_store_fpr32(fp1, fd);
7604
gen_store_fpr32h(fp0, fd);
7605
tcg_temp_free_i32(fp0);
7606
tcg_temp_free_i32(fp1);
7613
case OPC_CMP_UEQ_PS:
7614
case OPC_CMP_OLT_PS:
7615
case OPC_CMP_ULT_PS:
7616
case OPC_CMP_OLE_PS:
7617
case OPC_CMP_ULE_PS:
7619
case OPC_CMP_NGLE_PS:
7620
case OPC_CMP_SEQ_PS:
7621
case OPC_CMP_NGL_PS:
7623
case OPC_CMP_NGE_PS:
7625
case OPC_CMP_NGT_PS:
7626
if (ctx->opcode & (1 << 6)) {
7627
gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
7628
opn = condnames_abs[func-48];
7630
gen_cmp_ps(ctx, func-48, ft, fs, cc);
7631
opn = condnames[func-48];
7636
generate_exception (ctx, EXCP_RI);
7639
(void)opn; /* avoid a compiler warning */
7642
MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7645
MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7648
MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7653
/* Coprocessor 3 (FPU) */
7654
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7655
int fd, int fs, int base, int index)
7657
const char *opn = "extended float load/store";
7659
TCGv t0 = tcg_temp_new();
7662
gen_load_gpr(t0, index);
7663
} else if (index == 0) {
7664
gen_load_gpr(t0, base);
7666
gen_load_gpr(t0, index);
7667
gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7669
/* Don't do NOP if destination is zero: we must perform the actual
7671
save_cpu_state(ctx, 0);
7676
TCGv_i32 fp0 = tcg_temp_new_i32();
7678
tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7679
tcg_gen_trunc_tl_i32(fp0, t0);
7680
gen_store_fpr32(fp0, fd);
7681
tcg_temp_free_i32(fp0);
7687
check_cp1_registers(ctx, fd);
7689
TCGv_i64 fp0 = tcg_temp_new_i64();
7691
tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7692
gen_store_fpr64(ctx, fp0, fd);
7693
tcg_temp_free_i64(fp0);
7698
check_cp1_64bitmode(ctx);
7699
tcg_gen_andi_tl(t0, t0, ~0x7);
7701
TCGv_i64 fp0 = tcg_temp_new_i64();
7703
tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7704
gen_store_fpr64(ctx, fp0, fd);
7705
tcg_temp_free_i64(fp0);
7712
TCGv_i32 fp0 = tcg_temp_new_i32();
7713
TCGv t1 = tcg_temp_new();
7715
gen_load_fpr32(fp0, fs);
7716
tcg_gen_extu_i32_tl(t1, fp0);
7717
tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7718
tcg_temp_free_i32(fp0);
7726
check_cp1_registers(ctx, fs);
7728
TCGv_i64 fp0 = tcg_temp_new_i64();
7730
gen_load_fpr64(ctx, fp0, fs);
7731
tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7732
tcg_temp_free_i64(fp0);
7738
check_cp1_64bitmode(ctx);
7739
tcg_gen_andi_tl(t0, t0, ~0x7);
7741
TCGv_i64 fp0 = tcg_temp_new_i64();
7743
gen_load_fpr64(ctx, fp0, fs);
7744
tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7745
tcg_temp_free_i64(fp0);
7752
(void)opn; (void)store; /* avoid compiler warnings */
7753
MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7754
regnames[index], regnames[base]);
7757
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7758
int fd, int fr, int fs, int ft)
7760
const char *opn = "flt3_arith";
7764
check_cp1_64bitmode(ctx);
7766
TCGv t0 = tcg_temp_local_new();
7767
TCGv_i32 fp = tcg_temp_new_i32();
7768
TCGv_i32 fph = tcg_temp_new_i32();
7769
int l1 = gen_new_label();
7770
int l2 = gen_new_label();
7772
gen_load_gpr(t0, fr);
7773
tcg_gen_andi_tl(t0, t0, 0x7);
7775
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7776
gen_load_fpr32(fp, fs);
7777
gen_load_fpr32h(fph, fs);
7778
gen_store_fpr32(fp, fd);
7779
gen_store_fpr32h(fph, fd);
7782
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7784
#ifdef TARGET_WORDS_BIGENDIAN
7785
gen_load_fpr32(fp, fs);
7786
gen_load_fpr32h(fph, ft);
7787
gen_store_fpr32h(fp, fd);
7788
gen_store_fpr32(fph, fd);
7790
gen_load_fpr32h(fph, fs);
7791
gen_load_fpr32(fp, ft);
7792
gen_store_fpr32(fph, fd);
7793
gen_store_fpr32h(fp, fd);
7796
tcg_temp_free_i32(fp);
7797
tcg_temp_free_i32(fph);
7804
TCGv_i32 fp0 = tcg_temp_new_i32();
7805
TCGv_i32 fp1 = tcg_temp_new_i32();
7806
TCGv_i32 fp2 = tcg_temp_new_i32();
7808
gen_load_fpr32(fp0, fs);
7809
gen_load_fpr32(fp1, ft);
7810
gen_load_fpr32(fp2, fr);
7811
gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7812
tcg_temp_free_i32(fp0);
7813
tcg_temp_free_i32(fp1);
7814
gen_store_fpr32(fp2, fd);
7815
tcg_temp_free_i32(fp2);
7821
check_cp1_registers(ctx, fd | fs | ft | fr);
7823
TCGv_i64 fp0 = tcg_temp_new_i64();
7824
TCGv_i64 fp1 = tcg_temp_new_i64();
7825
TCGv_i64 fp2 = tcg_temp_new_i64();
7827
gen_load_fpr64(ctx, fp0, fs);
7828
gen_load_fpr64(ctx, fp1, ft);
7829
gen_load_fpr64(ctx, fp2, fr);
7830
gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7831
tcg_temp_free_i64(fp0);
7832
tcg_temp_free_i64(fp1);
7833
gen_store_fpr64(ctx, fp2, fd);
7834
tcg_temp_free_i64(fp2);
7839
check_cp1_64bitmode(ctx);
7841
TCGv_i64 fp0 = tcg_temp_new_i64();
7842
TCGv_i64 fp1 = tcg_temp_new_i64();
7843
TCGv_i64 fp2 = tcg_temp_new_i64();
7845
gen_load_fpr64(ctx, fp0, fs);
7846
gen_load_fpr64(ctx, fp1, ft);
7847
gen_load_fpr64(ctx, fp2, fr);
7848
gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7849
tcg_temp_free_i64(fp0);
7850
tcg_temp_free_i64(fp1);
7851
gen_store_fpr64(ctx, fp2, fd);
7852
tcg_temp_free_i64(fp2);
7859
TCGv_i32 fp0 = tcg_temp_new_i32();
7860
TCGv_i32 fp1 = tcg_temp_new_i32();
7861
TCGv_i32 fp2 = tcg_temp_new_i32();
7863
gen_load_fpr32(fp0, fs);
7864
gen_load_fpr32(fp1, ft);
7865
gen_load_fpr32(fp2, fr);
7866
gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7867
tcg_temp_free_i32(fp0);
7868
tcg_temp_free_i32(fp1);
7869
gen_store_fpr32(fp2, fd);
7870
tcg_temp_free_i32(fp2);
7876
check_cp1_registers(ctx, fd | fs | ft | fr);
7878
TCGv_i64 fp0 = tcg_temp_new_i64();
7879
TCGv_i64 fp1 = tcg_temp_new_i64();
7880
TCGv_i64 fp2 = tcg_temp_new_i64();
7882
gen_load_fpr64(ctx, fp0, fs);
7883
gen_load_fpr64(ctx, fp1, ft);
7884
gen_load_fpr64(ctx, fp2, fr);
7885
gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7886
tcg_temp_free_i64(fp0);
7887
tcg_temp_free_i64(fp1);
7888
gen_store_fpr64(ctx, fp2, fd);
7889
tcg_temp_free_i64(fp2);
7894
check_cp1_64bitmode(ctx);
7896
TCGv_i64 fp0 = tcg_temp_new_i64();
7897
TCGv_i64 fp1 = tcg_temp_new_i64();
7898
TCGv_i64 fp2 = tcg_temp_new_i64();
7900
gen_load_fpr64(ctx, fp0, fs);
7901
gen_load_fpr64(ctx, fp1, ft);
7902
gen_load_fpr64(ctx, fp2, fr);
7903
gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7904
tcg_temp_free_i64(fp0);
7905
tcg_temp_free_i64(fp1);
7906
gen_store_fpr64(ctx, fp2, fd);
7907
tcg_temp_free_i64(fp2);
7914
TCGv_i32 fp0 = tcg_temp_new_i32();
7915
TCGv_i32 fp1 = tcg_temp_new_i32();
7916
TCGv_i32 fp2 = tcg_temp_new_i32();
7918
gen_load_fpr32(fp0, fs);
7919
gen_load_fpr32(fp1, ft);
7920
gen_load_fpr32(fp2, fr);
7921
gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7922
tcg_temp_free_i32(fp0);
7923
tcg_temp_free_i32(fp1);
7924
gen_store_fpr32(fp2, fd);
7925
tcg_temp_free_i32(fp2);
7931
check_cp1_registers(ctx, fd | fs | ft | fr);
7933
TCGv_i64 fp0 = tcg_temp_new_i64();
7934
TCGv_i64 fp1 = tcg_temp_new_i64();
7935
TCGv_i64 fp2 = tcg_temp_new_i64();
7937
gen_load_fpr64(ctx, fp0, fs);
7938
gen_load_fpr64(ctx, fp1, ft);
7939
gen_load_fpr64(ctx, fp2, fr);
7940
gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7941
tcg_temp_free_i64(fp0);
7942
tcg_temp_free_i64(fp1);
7943
gen_store_fpr64(ctx, fp2, fd);
7944
tcg_temp_free_i64(fp2);
7949
check_cp1_64bitmode(ctx);
7951
TCGv_i64 fp0 = tcg_temp_new_i64();
7952
TCGv_i64 fp1 = tcg_temp_new_i64();
7953
TCGv_i64 fp2 = tcg_temp_new_i64();
7955
gen_load_fpr64(ctx, fp0, fs);
7956
gen_load_fpr64(ctx, fp1, ft);
7957
gen_load_fpr64(ctx, fp2, fr);
7958
gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7959
tcg_temp_free_i64(fp0);
7960
tcg_temp_free_i64(fp1);
7961
gen_store_fpr64(ctx, fp2, fd);
7962
tcg_temp_free_i64(fp2);
7969
TCGv_i32 fp0 = tcg_temp_new_i32();
7970
TCGv_i32 fp1 = tcg_temp_new_i32();
7971
TCGv_i32 fp2 = tcg_temp_new_i32();
7973
gen_load_fpr32(fp0, fs);
7974
gen_load_fpr32(fp1, ft);
7975
gen_load_fpr32(fp2, fr);
7976
gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7977
tcg_temp_free_i32(fp0);
7978
tcg_temp_free_i32(fp1);
7979
gen_store_fpr32(fp2, fd);
7980
tcg_temp_free_i32(fp2);
7986
check_cp1_registers(ctx, fd | fs | ft | fr);
7988
TCGv_i64 fp0 = tcg_temp_new_i64();
7989
TCGv_i64 fp1 = tcg_temp_new_i64();
7990
TCGv_i64 fp2 = tcg_temp_new_i64();
7992
gen_load_fpr64(ctx, fp0, fs);
7993
gen_load_fpr64(ctx, fp1, ft);
7994
gen_load_fpr64(ctx, fp2, fr);
7995
gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7996
tcg_temp_free_i64(fp0);
7997
tcg_temp_free_i64(fp1);
7998
gen_store_fpr64(ctx, fp2, fd);
7999
tcg_temp_free_i64(fp2);
8004
check_cp1_64bitmode(ctx);
8006
TCGv_i64 fp0 = tcg_temp_new_i64();
8007
TCGv_i64 fp1 = tcg_temp_new_i64();
8008
TCGv_i64 fp2 = tcg_temp_new_i64();
8010
gen_load_fpr64(ctx, fp0, fs);
8011
gen_load_fpr64(ctx, fp1, ft);
8012
gen_load_fpr64(ctx, fp2, fr);
8013
gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
8014
tcg_temp_free_i64(fp0);
8015
tcg_temp_free_i64(fp1);
8016
gen_store_fpr64(ctx, fp2, fd);
8017
tcg_temp_free_i64(fp2);
8023
generate_exception (ctx, EXCP_RI);
8026
(void)opn; /* avoid a compiler warning */
8027
MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8028
fregnames[fs], fregnames[ft]);
8032
gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
8036
check_insn(env, ctx, ISA_MIPS32R2);
8037
t0 = tcg_temp_new();
8041
save_cpu_state(ctx, 1);
8042
gen_helper_rdhwr_cpunum(t0);
8043
gen_store_gpr(t0, rt);
8046
save_cpu_state(ctx, 1);
8047
gen_helper_rdhwr_synci_step(t0);
8048
gen_store_gpr(t0, rt);
8051
save_cpu_state(ctx, 1);
8052
gen_helper_rdhwr_cc(t0);
8053
gen_store_gpr(t0, rt);
8056
save_cpu_state(ctx, 1);
8057
gen_helper_rdhwr_ccres(t0);
8058
gen_store_gpr(t0, rt);
8061
#if defined(CONFIG_USER_ONLY)
8062
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
8063
gen_store_gpr(t0, rt);
8066
/* XXX: Some CPUs implement this in hardware.
8067
Not supported yet. */
8069
default: /* Invalid */
8070
MIPS_INVAL("rdhwr");
8071
generate_exception(ctx, EXCP_RI);
8077
static void handle_delay_slot (CPUState *env, DisasContext *ctx,
8080
if (ctx->hflags & MIPS_HFLAG_BMASK) {
8081
int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8082
/* Branches completion */
8083
ctx->hflags &= ~MIPS_HFLAG_BMASK;
8084
ctx->bstate = BS_BRANCH;
8085
save_cpu_state(ctx, 0);
8086
/* FIXME: Need to clear can_do_io. */
8087
switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8089
/* unconditional branch */
8090
MIPS_DEBUG("unconditional branch");
8091
if (proc_hflags & MIPS_HFLAG_BX) {
8092
tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8094
gen_goto_tb(ctx, 0, ctx->btarget);
8097
/* blikely taken case */
8098
MIPS_DEBUG("blikely branch taken");
8099
gen_goto_tb(ctx, 0, ctx->btarget);
8102
/* Conditional branch */
8103
MIPS_DEBUG("conditional branch");
8105
int l1 = gen_new_label();
8107
tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8108
gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8110
gen_goto_tb(ctx, 0, ctx->btarget);
8114
/* unconditional branch to register */
8115
MIPS_DEBUG("branch to register");
8116
if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8117
TCGv t0 = tcg_temp_new();
8118
TCGv_i32 t1 = tcg_temp_new_i32();
8120
tcg_gen_andi_tl(t0, btarget, 0x1);
8121
tcg_gen_trunc_tl_i32(t1, t0);
8123
tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8124
tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8125
tcg_gen_or_i32(hflags, hflags, t1);
8126
tcg_temp_free_i32(t1);
8128
tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8130
tcg_gen_mov_tl(cpu_PC, btarget);
8132
if (ctx->singlestep_enabled) {
8133
save_cpu_state(ctx, 0);
8134
gen_helper_0i(raise_exception, EXCP_DEBUG);
8139
MIPS_DEBUG("unknown branch");
8145
/* ISA extensions (ASEs) */
8146
/* MIPS16 extension to MIPS32 */
8148
/* MIPS16 major opcodes */
8150
M16_OPC_ADDIUSP = 0x00,
8151
M16_OPC_ADDIUPC = 0x01,
8154
M16_OPC_BEQZ = 0x04,
8155
M16_OPC_BNEQZ = 0x05,
8156
M16_OPC_SHIFT = 0x06,
8158
M16_OPC_RRIA = 0x08,
8159
M16_OPC_ADDIU8 = 0x09,
8160
M16_OPC_SLTI = 0x0a,
8161
M16_OPC_SLTIU = 0x0b,
8164
M16_OPC_CMPI = 0x0e,
8168
M16_OPC_LWSP = 0x12,
8172
M16_OPC_LWPC = 0x16,
8176
M16_OPC_SWSP = 0x1a,
8180
M16_OPC_EXTEND = 0x1e,
8184
/* I8 funct field */
8203
/* RR funct field */
8237
/* I64 funct field */
8249
/* RR ry field for CNVT */
8251
RR_RY_CNVT_ZEB = 0x0,
8252
RR_RY_CNVT_ZEH = 0x1,
8253
RR_RY_CNVT_ZEW = 0x2,
8254
RR_RY_CNVT_SEB = 0x4,
8255
RR_RY_CNVT_SEH = 0x5,
8256
RR_RY_CNVT_SEW = 0x6,
8259
static int xlat (int r)
8261
static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8266
static void gen_mips16_save (DisasContext *ctx,
8267
int xsregs, int aregs,
8268
int do_ra, int do_s0, int do_s1,
8271
TCGv t0 = tcg_temp_new();
8272
TCGv t1 = tcg_temp_new();
8302
generate_exception(ctx, EXCP_RI);
8308
gen_base_offset_addr(ctx, t0, 29, 12);
8309
gen_load_gpr(t1, 7);
8310
op_st_sw(t1, t0, ctx);
8313
gen_base_offset_addr(ctx, t0, 29, 8);
8314
gen_load_gpr(t1, 6);
8315
op_st_sw(t1, t0, ctx);
8318
gen_base_offset_addr(ctx, t0, 29, 4);
8319
gen_load_gpr(t1, 5);
8320
op_st_sw(t1, t0, ctx);
8323
gen_base_offset_addr(ctx, t0, 29, 0);
8324
gen_load_gpr(t1, 4);
8325
op_st_sw(t1, t0, ctx);
8328
gen_load_gpr(t0, 29);
8330
#define DECR_AND_STORE(reg) do { \
8331
tcg_gen_subi_tl(t0, t0, 4); \
8332
gen_load_gpr(t1, reg); \
8333
op_st_sw(t1, t0, ctx); \
8397
generate_exception(ctx, EXCP_RI);
8413
#undef DECR_AND_STORE
8415
tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8420
static void gen_mips16_restore (DisasContext *ctx,
8421
int xsregs, int aregs,
8422
int do_ra, int do_s0, int do_s1,
8426
TCGv t0 = tcg_temp_new();
8427
TCGv t1 = tcg_temp_new();
8429
tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8431
#define DECR_AND_LOAD(reg) do { \
8432
tcg_gen_subi_tl(t0, t0, 4); \
8433
op_ld_lw(t1, t0, ctx); \
8434
gen_store_gpr(t1, reg); \
8498
generate_exception(ctx, EXCP_RI);
8514
#undef DECR_AND_LOAD
8516
tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8521
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
8522
int is_64_bit, int extended)
8526
if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8527
generate_exception(ctx, EXCP_RI);
8531
t0 = tcg_temp_new();
8533
tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
8534
tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
8536
tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
8542
#if defined(TARGET_MIPS64)
8543
static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
8544
int ry, int funct, int16_t offset,
8550
offset = extended ? offset : offset << 3;
8551
gen_ld(env, ctx, OPC_LD, ry, 29, offset);
8555
offset = extended ? offset : offset << 3;
8556
gen_st(ctx, OPC_SD, ry, 29, offset);
8560
offset = extended ? offset : (ctx->opcode & 0xff) << 3;
8561
gen_st(ctx, OPC_SD, 31, 29, offset);
8565
offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
8566
gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
8569
if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8570
generate_exception(ctx, EXCP_RI);
8572
offset = extended ? offset : offset << 3;
8573
gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
8578
offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
8579
gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
8583
offset = extended ? offset : offset << 2;
8584
gen_addiupc(ctx, ry, offset, 1, extended);
8588
offset = extended ? offset : offset << 2;
8589
gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
8595
static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
8598
int extend = lduw_code(ctx->pc + 2);
8599
int op, rx, ry, funct, sa;
8600
int16_t imm, offset;
8602
ctx->opcode = (ctx->opcode << 16) | extend;
8603
op = (ctx->opcode >> 11) & 0x1f;
8604
sa = (ctx->opcode >> 22) & 0x1f;
8605
funct = (ctx->opcode >> 8) & 0x7;
8606
rx = xlat((ctx->opcode >> 8) & 0x7);
8607
ry = xlat((ctx->opcode >> 5) & 0x7);
8608
offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
8609
| ((ctx->opcode >> 21) & 0x3f) << 5
8610
| (ctx->opcode & 0x1f));
8612
/* The extended opcodes cleverly reuse the opcodes from their 16-bit
8615
case M16_OPC_ADDIUSP:
8616
gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8618
case M16_OPC_ADDIUPC:
8619
gen_addiupc(ctx, rx, imm, 0, 1);
8622
gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
8623
/* No delay slot, so just process as a normal instruction */
8626
gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
8627
/* No delay slot, so just process as a normal instruction */
8630
gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
8631
/* No delay slot, so just process as a normal instruction */
8634
switch (ctx->opcode & 0x3) {
8636
gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8639
#if defined(TARGET_MIPS64)
8641
gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8643
generate_exception(ctx, EXCP_RI);
8647
gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8650
gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8654
#if defined(TARGET_MIPS64)
8657
gen_ld(env, ctx, OPC_LD, ry, rx, offset);
8661
imm = ctx->opcode & 0xf;
8662
imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
8663
imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
8664
imm = (int16_t) (imm << 1) >> 1;
8665
if ((ctx->opcode >> 4) & 0x1) {
8666
#if defined(TARGET_MIPS64)
8668
gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8670
generate_exception(ctx, EXCP_RI);
8673
gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8676
case M16_OPC_ADDIU8:
8677
gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8680
gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8683
gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8688
gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
8691
gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
8694
gen_st(ctx, OPC_SW, 31, 29, imm);
8697
gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
8701
int xsregs = (ctx->opcode >> 24) & 0x7;
8702
int aregs = (ctx->opcode >> 16) & 0xf;
8703
int do_ra = (ctx->opcode >> 6) & 0x1;
8704
int do_s0 = (ctx->opcode >> 5) & 0x1;
8705
int do_s1 = (ctx->opcode >> 4) & 0x1;
8706
int framesize = (((ctx->opcode >> 20) & 0xf) << 4
8707
| (ctx->opcode & 0xf)) << 3;
8709
if (ctx->opcode & (1 << 7)) {
8710
gen_mips16_save(ctx, xsregs, aregs,
8711
do_ra, do_s0, do_s1,
8714
gen_mips16_restore(ctx, xsregs, aregs,
8715
do_ra, do_s0, do_s1,
8721
generate_exception(ctx, EXCP_RI);
8726
tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
8729
tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
8731
#if defined(TARGET_MIPS64)
8733
gen_st(ctx, OPC_SD, ry, rx, offset);
8737
gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8740
gen_ld(env, ctx, OPC_LH, ry, rx, offset);
8743
gen_ld(env, ctx, OPC_LW, rx, 29, offset);
8746
gen_ld(env, ctx, OPC_LW, ry, rx, offset);
8749
gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
8752
gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
8755
gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
8757
#if defined(TARGET_MIPS64)
8759
gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
8763
gen_st(ctx, OPC_SB, ry, rx, offset);
8766
gen_st(ctx, OPC_SH, ry, rx, offset);
8769
gen_st(ctx, OPC_SW, rx, 29, offset);
8772
gen_st(ctx, OPC_SW, ry, rx, offset);
8774
#if defined(TARGET_MIPS64)
8776
decode_i64_mips16(env, ctx, ry, funct, offset, 1);
8780
generate_exception(ctx, EXCP_RI);
8787
static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
8792
int op, cnvt_op, op1, offset;
8796
op = (ctx->opcode >> 11) & 0x1f;
8797
sa = (ctx->opcode >> 2) & 0x7;
8798
sa = sa == 0 ? 8 : sa;
8799
rx = xlat((ctx->opcode >> 8) & 0x7);
8800
cnvt_op = (ctx->opcode >> 5) & 0x7;
8801
ry = xlat((ctx->opcode >> 5) & 0x7);
8802
op1 = offset = ctx->opcode & 0x1f;
8807
case M16_OPC_ADDIUSP:
8809
int16_t imm = ((uint8_t) ctx->opcode) << 2;
8811
gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
8814
case M16_OPC_ADDIUPC:
8815
gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
8818
offset = (ctx->opcode & 0x7ff) << 1;
8819
offset = (int16_t)(offset << 4) >> 4;
8820
gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
8821
/* No delay slot, so just process as a normal instruction */
8824
offset = lduw_code(ctx->pc + 2);
8825
offset = (((ctx->opcode & 0x1f) << 21)
8826
| ((ctx->opcode >> 5) & 0x1f) << 16
8828
op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
8829
gen_compute_branch(ctx, op, 4, rx, ry, offset);
8834
gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8835
/* No delay slot, so just process as a normal instruction */
8838
gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
8839
/* No delay slot, so just process as a normal instruction */
8842
switch (ctx->opcode & 0x3) {
8844
gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
8847
#if defined(TARGET_MIPS64)
8849
gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
8851
generate_exception(ctx, EXCP_RI);
8855
gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
8858
gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
8862
#if defined(TARGET_MIPS64)
8865
gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
8870
int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
8872
if ((ctx->opcode >> 4) & 1) {
8873
#if defined(TARGET_MIPS64)
8875
gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
8877
generate_exception(ctx, EXCP_RI);
8880
gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
8884
case M16_OPC_ADDIU8:
8886
int16_t imm = (int8_t) ctx->opcode;
8888
gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
8893
int16_t imm = (uint8_t) ctx->opcode;
8895
gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
8900
int16_t imm = (uint8_t) ctx->opcode;
8902
gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
8909
funct = (ctx->opcode >> 8) & 0x7;
8912
gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
8913
((int8_t)ctx->opcode) << 1);
8916
gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
8917
((int8_t)ctx->opcode) << 1);
8920
gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
8923
gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
8924
((int8_t)ctx->opcode) << 3);
8928
int do_ra = ctx->opcode & (1 << 6);
8929
int do_s0 = ctx->opcode & (1 << 5);
8930
int do_s1 = ctx->opcode & (1 << 4);
8931
int framesize = ctx->opcode & 0xf;
8933
if (framesize == 0) {
8936
framesize = framesize << 3;
8939
if (ctx->opcode & (1 << 7)) {
8940
gen_mips16_save(ctx, 0, 0,
8941
do_ra, do_s0, do_s1, framesize);
8943
gen_mips16_restore(ctx, 0, 0,
8944
do_ra, do_s0, do_s1, framesize);
8950
int rz = xlat(ctx->opcode & 0x7);
8952
reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
8953
((ctx->opcode >> 5) & 0x7);
8954
gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
8958
reg32 = ctx->opcode & 0x1f;
8959
gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
8962
generate_exception(ctx, EXCP_RI);
8969
int16_t imm = (uint8_t) ctx->opcode;
8971
gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
8976
int16_t imm = (uint8_t) ctx->opcode;
8978
gen_logic_imm(env, OPC_XORI, 24, rx, imm);
8981
#if defined(TARGET_MIPS64)
8984
gen_st(ctx, OPC_SD, ry, rx, offset << 3);
8988
gen_ld(env, ctx, OPC_LB, ry, rx, offset);
8991
gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
8994
gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
8997
gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9000
gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9003
gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9006
gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9008
#if defined (TARGET_MIPS64)
9011
gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9015
gen_st(ctx, OPC_SB, ry, rx, offset);
9018
gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9021
gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9024
gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9028
int rz = xlat((ctx->opcode >> 2) & 0x7);
9031
switch (ctx->opcode & 0x3) {
9033
mips32_op = OPC_ADDU;
9036
mips32_op = OPC_SUBU;
9038
#if defined(TARGET_MIPS64)
9040
mips32_op = OPC_DADDU;
9044
mips32_op = OPC_DSUBU;
9049
generate_exception(ctx, EXCP_RI);
9053
gen_arith(env, ctx, mips32_op, rz, rx, ry);
9062
int nd = (ctx->opcode >> 7) & 0x1;
9063
int link = (ctx->opcode >> 6) & 0x1;
9064
int ra = (ctx->opcode >> 5) & 0x1;
9067
op = nd ? OPC_JALRC : OPC_JALRS;
9072
gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9079
/* XXX: not clear which exception should be raised
9080
* when in debug mode...
9082
check_insn(env, ctx, ISA_MIPS32);
9083
if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9084
generate_exception(ctx, EXCP_DBp);
9086
generate_exception(ctx, EXCP_DBp);
9090
gen_slt(env, OPC_SLT, 24, rx, ry);
9093
gen_slt(env, OPC_SLTU, 24, rx, ry);
9096
generate_exception(ctx, EXCP_BREAK);
9099
gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9102
gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9105
gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9107
#if defined (TARGET_MIPS64)
9110
gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9114
gen_logic(env, OPC_XOR, 24, rx, ry);
9117
gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9120
gen_logic(env, OPC_AND, rx, rx, ry);
9123
gen_logic(env, OPC_OR, rx, rx, ry);
9126
gen_logic(env, OPC_XOR, rx, rx, ry);
9129
gen_logic(env, OPC_NOR, rx, ry, 0);
9132
gen_HILO(ctx, OPC_MFHI, rx);
9136
case RR_RY_CNVT_ZEB:
9137
tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9139
case RR_RY_CNVT_ZEH:
9140
tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9142
case RR_RY_CNVT_SEB:
9143
tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9145
case RR_RY_CNVT_SEH:
9146
tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9148
#if defined (TARGET_MIPS64)
9149
case RR_RY_CNVT_ZEW:
9151
tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9153
case RR_RY_CNVT_SEW:
9155
tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9159
generate_exception(ctx, EXCP_RI);
9164
gen_HILO(ctx, OPC_MFLO, rx);
9166
#if defined (TARGET_MIPS64)
9169
gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9173
gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9177
gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9181
gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9185
gen_muldiv(ctx, OPC_MULT, rx, ry);
9188
gen_muldiv(ctx, OPC_MULTU, rx, ry);
9191
gen_muldiv(ctx, OPC_DIV, rx, ry);
9194
gen_muldiv(ctx, OPC_DIVU, rx, ry);
9196
#if defined (TARGET_MIPS64)
9199
gen_muldiv(ctx, OPC_DMULT, rx, ry);
9203
gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9207
gen_muldiv(ctx, OPC_DDIV, rx, ry);
9211
gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9215
generate_exception(ctx, EXCP_RI);
9219
case M16_OPC_EXTEND:
9220
decode_extended_mips16_opc(env, ctx, is_branch);
9223
#if defined(TARGET_MIPS64)
9225
funct = (ctx->opcode >> 8) & 0x7;
9226
decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9230
generate_exception(ctx, EXCP_RI);
9237
/* microMIPS extension to MIPS32 */
9239
/* microMIPS32 major opcodes */
9278
/* 0x20 is reserved */
9288
/* 0x28 and 0x29 are reserved */
9298
/* 0x30 and 0x31 are reserved */
9308
/* 0x38 and 0x39 are reserved */
9319
/* POOL32A encoding of minor opcode field */
9322
/* These opcodes are distinguished only by bits 9..6; those bits are
9323
* what are recorded below. */
9349
/* The following can be distinguished by their lower 6 bits. */
9355
/* POOL32AXF encoding of minor opcode field extension */
9369
/* bits 13..12 for 0x01 */
9375
/* bits 13..12 for 0x2a */
9381
/* bits 13..12 for 0x32 */
9385
/* bits 15..12 for 0x2c */
9401
/* bits 15..12 for 0x34 */
9409
/* bits 15..12 for 0x3c */
9411
JR = 0x0, /* alias */
9416
/* bits 15..12 for 0x05 */
9420
/* bits 15..12 for 0x0d */
9430
/* bits 15..12 for 0x15 */
9436
/* bits 15..12 for 0x1d */
9440
/* bits 15..12 for 0x2d */
9445
/* bits 15..12 for 0x35 */
9452
/* POOL32B encoding of minor opcode field (bits 15..12) */
9468
/* POOL32C encoding of minor opcode field (bits 15..12) */
9476
/* 0xa is reserved */
9483
/* 0x6 is reserved */
9489
/* POOL32F encoding of minor opcode field (bits 5..0) */
9492
/* These are the bit 7..6 values */
9503
/* These are the bit 8..6 values */
9547
CABS_COND_FMT = 0x1c, /* MIPS3D */
9551
/* POOL32Fxf encoding of minor opcode extension field */
9589
/* POOL32I encoding of minor opcode field (bits 25..21) */
9614
/* These overlap and are distinguished by bit16 of the instruction */
9623
/* POOL16A encoding of minor opcode field */
9630
/* POOL16B encoding of minor opcode field */
9637
/* POOL16C encoding of minor opcode field */
9657
/* POOL16D encoding of minor opcode field */
9664
/* POOL16E encoding of minor opcode field */
9671
static int mmreg (int r)
9673
static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9678
/* Used for 16-bit store instructions. */
9679
static int mmreg2 (int r)
9681
static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
9686
#define uMIPS_RD(op) ((op >> 7) & 0x7)
9687
#define uMIPS_RS(op) ((op >> 4) & 0x7)
9688
#define uMIPS_RS2(op) uMIPS_RS(op)
9689
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
9690
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
9691
#define uMIPS_RS5(op) (op & 0x1f)
9693
/* Signed immediate */
9694
#define SIMM(op, start, width) \
9695
((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
9698
/* Zero-extended immediate */
9699
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
9701
static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
9703
int rd = mmreg(uMIPS_RD(ctx->opcode));
9705
gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
9708
static void gen_addiur2 (CPUState *env, DisasContext *ctx)
9710
static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
9711
int rd = mmreg(uMIPS_RD(ctx->opcode));
9712
int rs = mmreg(uMIPS_RS(ctx->opcode));
9714
gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
9717
static void gen_addiusp (CPUState *env, DisasContext *ctx)
9719
int encoded = ZIMM(ctx->opcode, 1, 9);
9723
decoded = 256 + encoded;
9724
} else if (encoded <= 255) {
9726
} else if (encoded <= 509) {
9727
decoded = encoded - 512;
9729
decoded = encoded - 768;
9732
gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
9735
static void gen_addius5 (CPUState *env, DisasContext *ctx)
9737
int imm = SIMM(ctx->opcode, 1, 4);
9738
int rd = (ctx->opcode >> 5) & 0x1f;
9740
gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
9743
static void gen_andi16 (CPUState *env, DisasContext *ctx)
9745
static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
9746
31, 32, 63, 64, 255, 32768, 65535 };
9747
int rd = mmreg(uMIPS_RD(ctx->opcode));
9748
int rs = mmreg(uMIPS_RS(ctx->opcode));
9749
int encoded = ZIMM(ctx->opcode, 0, 4);
9751
gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
9754
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
9755
int base, int16_t offset)
9760
if (ctx->hflags & MIPS_HFLAG_BMASK) {
9761
generate_exception(ctx, EXCP_RI);
9765
t0 = tcg_temp_new();
9767
gen_base_offset_addr(ctx, t0, base, offset);
9769
t1 = tcg_const_tl(reglist);
9770
t2 = tcg_const_i32(ctx->mem_idx);
9772
save_cpu_state(ctx, 1);
9775
gen_helper_lwm(t0, t1, t2);
9778
gen_helper_swm(t0, t1, t2);
9780
#ifdef TARGET_MIPS64
9782
gen_helper_ldm(t0, t1, t2);
9785
gen_helper_sdm(t0, t1, t2);
9789
MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
9792
tcg_temp_free_i32(t2);
9796
static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
9798
int rd = mmreg((ctx->opcode >> 3) & 0x7);
9799
int rs = mmreg(ctx->opcode & 0x7);
9802
switch (((ctx->opcode) >> 4) & 0x3f) {
9807
gen_logic(env, OPC_NOR, rd, rs, 0);
9813
gen_logic(env, OPC_XOR, rd, rd, rs);
9819
gen_logic(env, OPC_AND, rd, rd, rs);
9825
gen_logic(env, OPC_OR, rd, rd, rs);
9832
static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9833
int offset = ZIMM(ctx->opcode, 0, 4);
9835
gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
9844
static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
9845
int offset = ZIMM(ctx->opcode, 0, 4);
9847
gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
9854
int reg = ctx->opcode & 0x1f;
9856
gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9863
int reg = ctx->opcode & 0x1f;
9865
gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
9866
/* Let normal delay slot handling in our caller take us
9867
to the branch target. */
9879
int reg = ctx->opcode & 0x1f;
9881
gen_compute_branch(ctx, opc, 2, reg, 31, 0);
9887
gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
9891
gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
9894
generate_exception(ctx, EXCP_BREAK);
9897
/* XXX: not clear which exception should be raised
9898
* when in debug mode...
9900
check_insn(env, ctx, ISA_MIPS32);
9901
if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9902
generate_exception(ctx, EXCP_DBp);
9904
generate_exception(ctx, EXCP_DBp);
9910
int imm = ZIMM(ctx->opcode, 0, 5);
9912
gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
9913
gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
9914
/* Let normal delay slot handling in our caller take us
9915
to the branch target. */
9919
generate_exception(ctx, EXCP_RI);
9924
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
9926
TCGv t0 = tcg_temp_new();
9927
TCGv t1 = tcg_temp_new();
9929
gen_load_gpr(t0, base);
9932
gen_load_gpr(t1, index);
9933
tcg_gen_shli_tl(t1, t1, 2);
9934
gen_op_addr_add(ctx, t0, t1, t0);
9937
save_cpu_state(ctx, 0);
9938
op_ld_lw(t1, t0, ctx);
9939
gen_store_gpr(t1, rd);
9945
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
9946
int base, int16_t offset)
9948
const char *opn = "ldst_pair";
9951
if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
9952
generate_exception(ctx, EXCP_RI);
9956
t0 = tcg_temp_new();
9957
t1 = tcg_temp_new();
9959
gen_base_offset_addr(ctx, t0, base, offset);
9963
save_cpu_state(ctx, 0);
9964
op_ld_lw(t1, t0, ctx);
9965
gen_store_gpr(t1, rd);
9966
tcg_gen_movi_tl(t1, 4);
9967
gen_op_addr_add(ctx, t0, t0, t1);
9968
op_ld_lw(t1, t0, ctx);
9969
gen_store_gpr(t1, rd+1);
9973
save_cpu_state(ctx, 0);
9974
gen_load_gpr(t1, rd);
9975
op_st_sw(t1, t0, ctx);
9976
tcg_gen_movi_tl(t1, 4);
9977
gen_op_addr_add(ctx, t0, t0, t1);
9978
gen_load_gpr(t1, rd+1);
9979
op_st_sw(t1, t0, ctx);
9982
#ifdef TARGET_MIPS64
9984
save_cpu_state(ctx, 0);
9985
op_ld_ld(t1, t0, ctx);
9986
gen_store_gpr(t1, rd);
9987
tcg_gen_movi_tl(t1, 8);
9988
gen_op_addr_add(ctx, t0, t0, t1);
9989
op_ld_ld(t1, t0, ctx);
9990
gen_store_gpr(t1, rd+1);
9994
save_cpu_state(ctx, 0);
9995
gen_load_gpr(t1, rd);
9996
op_st_sd(t1, t0, ctx);
9997
tcg_gen_movi_tl(t1, 8);
9998
gen_op_addr_add(ctx, t0, t0, t1);
9999
gen_load_gpr(t1, rd+1);
10000
op_st_sd(t1, t0, ctx);
10005
(void)opn; /* avoid a compiler warning */
10006
MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10011
static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
10014
int extension = (ctx->opcode >> 6) & 0x3f;
10015
int minor = (ctx->opcode >> 12) & 0xf;
10016
uint32_t mips32_op;
10018
switch (extension) {
10020
mips32_op = OPC_TEQ;
10023
mips32_op = OPC_TGE;
10026
mips32_op = OPC_TGEU;
10029
mips32_op = OPC_TLT;
10032
mips32_op = OPC_TLTU;
10035
mips32_op = OPC_TNE;
10037
gen_trap(ctx, mips32_op, rs, rt, -1);
10039
#ifndef CONFIG_USER_ONLY
10043
/* Treat as NOP. */
10046
gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10051
TCGv t0 = tcg_temp_new();
10053
gen_load_gpr(t0, rt);
10054
gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10062
gen_bshfl(ctx, OPC_SEB, rs, rt);
10065
gen_bshfl(ctx, OPC_SEH, rs, rt);
10068
mips32_op = OPC_CLO;
10071
mips32_op = OPC_CLZ;
10073
check_insn(env, ctx, ISA_MIPS32);
10074
gen_cl(ctx, mips32_op, rt, rs);
10077
gen_rdhwr(env, ctx, rt, rs);
10080
gen_bshfl(ctx, OPC_WSBH, rs, rt);
10083
mips32_op = OPC_MULT;
10086
mips32_op = OPC_MULTU;
10089
mips32_op = OPC_DIV;
10092
mips32_op = OPC_DIVU;
10095
mips32_op = OPC_MADD;
10098
mips32_op = OPC_MADDU;
10101
mips32_op = OPC_MSUB;
10104
mips32_op = OPC_MSUBU;
10106
check_insn(env, ctx, ISA_MIPS32);
10107
gen_muldiv(ctx, mips32_op, rs, rt);
10110
goto pool32axf_invalid;
10121
generate_exception_err(ctx, EXCP_CpU, 2);
10124
goto pool32axf_invalid;
10131
gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10136
gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10140
goto pool32axf_invalid;
10146
check_insn(env, ctx, ISA_MIPS32R2);
10147
gen_load_srsgpr(rt, rs);
10150
check_insn(env, ctx, ISA_MIPS32R2);
10151
gen_store_srsgpr(rt, rs);
10154
goto pool32axf_invalid;
10157
#ifndef CONFIG_USER_ONLY
10161
mips32_op = OPC_TLBP;
10164
mips32_op = OPC_TLBR;
10167
mips32_op = OPC_TLBWI;
10170
mips32_op = OPC_TLBWR;
10173
mips32_op = OPC_WAIT;
10176
mips32_op = OPC_DERET;
10179
mips32_op = OPC_ERET;
10181
gen_cp0(env, ctx, mips32_op, rt, rs);
10184
goto pool32axf_invalid;
10191
TCGv t0 = tcg_temp_new();
10193
save_cpu_state(ctx, 1);
10195
gen_store_gpr(t0, rs);
10196
/* Stop translation as we may have switched the execution mode */
10197
ctx->bstate = BS_STOP;
10203
TCGv t0 = tcg_temp_new();
10205
save_cpu_state(ctx, 1);
10207
gen_store_gpr(t0, rs);
10208
/* Stop translation as we may have switched the execution mode */
10209
ctx->bstate = BS_STOP;
10214
goto pool32axf_invalid;
10224
generate_exception(ctx, EXCP_SYSCALL);
10225
ctx->bstate = BS_STOP;
10228
check_insn(env, ctx, ISA_MIPS32);
10229
if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10230
generate_exception(ctx, EXCP_DBp);
10232
generate_exception(ctx, EXCP_DBp);
10236
goto pool32axf_invalid;
10242
gen_HILO(ctx, OPC_MFHI, rs);
10245
gen_HILO(ctx, OPC_MFLO, rs);
10248
gen_HILO(ctx, OPC_MTHI, rs);
10251
gen_HILO(ctx, OPC_MTLO, rs);
10254
goto pool32axf_invalid;
10259
MIPS_INVAL("pool32axf");
10260
generate_exception(ctx, EXCP_RI);
10265
/* Values for microMIPS fmt field. Variable-width, depending on which
10266
formats the instruction supports. */
10285
static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
10287
int extension = (ctx->opcode >> 6) & 0x3ff;
10288
uint32_t mips32_op;
10290
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10291
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10292
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10294
switch (extension) {
10295
case FLOAT_1BIT_FMT(CFC1, 0):
10296
mips32_op = OPC_CFC1;
10298
case FLOAT_1BIT_FMT(CTC1, 0):
10299
mips32_op = OPC_CTC1;
10301
case FLOAT_1BIT_FMT(MFC1, 0):
10302
mips32_op = OPC_MFC1;
10304
case FLOAT_1BIT_FMT(MTC1, 0):
10305
mips32_op = OPC_MTC1;
10307
case FLOAT_1BIT_FMT(MFHC1, 0):
10308
mips32_op = OPC_MFHC1;
10310
case FLOAT_1BIT_FMT(MTHC1, 0):
10311
mips32_op = OPC_MTHC1;
10313
gen_cp1(ctx, mips32_op, rt, rs);
10316
/* Reciprocal square root */
10317
case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10318
mips32_op = OPC_RSQRT_S;
10320
case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10321
mips32_op = OPC_RSQRT_D;
10325
case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10326
mips32_op = OPC_SQRT_S;
10328
case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10329
mips32_op = OPC_SQRT_D;
10333
case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10334
mips32_op = OPC_RECIP_S;
10336
case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10337
mips32_op = OPC_RECIP_D;
10341
case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10342
mips32_op = OPC_FLOOR_L_S;
10344
case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10345
mips32_op = OPC_FLOOR_L_D;
10347
case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10348
mips32_op = OPC_FLOOR_W_S;
10350
case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10351
mips32_op = OPC_FLOOR_W_D;
10355
case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10356
mips32_op = OPC_CEIL_L_S;
10358
case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10359
mips32_op = OPC_CEIL_L_D;
10361
case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10362
mips32_op = OPC_CEIL_W_S;
10364
case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10365
mips32_op = OPC_CEIL_W_D;
10369
case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10370
mips32_op = OPC_TRUNC_L_S;
10372
case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10373
mips32_op = OPC_TRUNC_L_D;
10375
case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10376
mips32_op = OPC_TRUNC_W_S;
10378
case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10379
mips32_op = OPC_TRUNC_W_D;
10383
case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10384
mips32_op = OPC_ROUND_L_S;
10386
case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10387
mips32_op = OPC_ROUND_L_D;
10389
case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10390
mips32_op = OPC_ROUND_W_S;
10392
case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10393
mips32_op = OPC_ROUND_W_D;
10396
/* Integer to floating-point conversion */
10397
case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10398
mips32_op = OPC_CVT_L_S;
10400
case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10401
mips32_op = OPC_CVT_L_D;
10403
case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10404
mips32_op = OPC_CVT_W_S;
10406
case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10407
mips32_op = OPC_CVT_W_D;
10410
/* Paired-foo conversions */
10411
case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10412
mips32_op = OPC_CVT_S_PL;
10414
case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10415
mips32_op = OPC_CVT_S_PU;
10417
case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10418
mips32_op = OPC_CVT_PW_PS;
10420
case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10421
mips32_op = OPC_CVT_PS_PW;
10424
/* Floating-point moves */
10425
case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10426
mips32_op = OPC_MOV_S;
10428
case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10429
mips32_op = OPC_MOV_D;
10431
case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10432
mips32_op = OPC_MOV_PS;
10435
/* Absolute value */
10436
case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10437
mips32_op = OPC_ABS_S;
10439
case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10440
mips32_op = OPC_ABS_D;
10442
case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10443
mips32_op = OPC_ABS_PS;
10447
case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10448
mips32_op = OPC_NEG_S;
10450
case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10451
mips32_op = OPC_NEG_D;
10453
case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10454
mips32_op = OPC_NEG_PS;
10457
/* Reciprocal square root step */
10458
case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10459
mips32_op = OPC_RSQRT1_S;
10461
case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10462
mips32_op = OPC_RSQRT1_D;
10464
case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10465
mips32_op = OPC_RSQRT1_PS;
10468
/* Reciprocal step */
10469
case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10470
mips32_op = OPC_RECIP1_S;
10472
case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10473
mips32_op = OPC_RECIP1_S;
10475
case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10476
mips32_op = OPC_RECIP1_PS;
10479
/* Conversions from double */
10480
case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10481
mips32_op = OPC_CVT_D_S;
10483
case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10484
mips32_op = OPC_CVT_D_W;
10486
case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10487
mips32_op = OPC_CVT_D_L;
10490
/* Conversions from single */
10491
case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10492
mips32_op = OPC_CVT_S_D;
10494
case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10495
mips32_op = OPC_CVT_S_W;
10497
case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10498
mips32_op = OPC_CVT_S_L;
10500
gen_farith(ctx, mips32_op, -1, rs, rt, 0);
10503
/* Conditional moves on floating-point codes */
10504
case COND_FLOAT_MOV(MOVT, 0):
10505
case COND_FLOAT_MOV(MOVT, 1):
10506
case COND_FLOAT_MOV(MOVT, 2):
10507
case COND_FLOAT_MOV(MOVT, 3):
10508
case COND_FLOAT_MOV(MOVT, 4):
10509
case COND_FLOAT_MOV(MOVT, 5):
10510
case COND_FLOAT_MOV(MOVT, 6):
10511
case COND_FLOAT_MOV(MOVT, 7):
10512
gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
10514
case COND_FLOAT_MOV(MOVF, 0):
10515
case COND_FLOAT_MOV(MOVF, 1):
10516
case COND_FLOAT_MOV(MOVF, 2):
10517
case COND_FLOAT_MOV(MOVF, 3):
10518
case COND_FLOAT_MOV(MOVF, 4):
10519
case COND_FLOAT_MOV(MOVF, 5):
10520
case COND_FLOAT_MOV(MOVF, 6):
10521
case COND_FLOAT_MOV(MOVF, 7):
10522
gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
10525
MIPS_INVAL("pool32fxf");
10526
generate_exception(ctx, EXCP_RI);
10531
static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
10532
uint16_t insn_hw1, int *is_branch)
10536
int rt, rs, rd, rr;
10538
uint32_t op, minor, mips32_op;
10539
uint32_t cond, fmt, cc;
10541
insn = lduw_code(ctx->pc + 2);
10542
ctx->opcode = (ctx->opcode << 16) | insn;
10544
rt = (ctx->opcode >> 21) & 0x1f;
10545
rs = (ctx->opcode >> 16) & 0x1f;
10546
rd = (ctx->opcode >> 11) & 0x1f;
10547
rr = (ctx->opcode >> 6) & 0x1f;
10548
imm = (int16_t) ctx->opcode;
10550
op = (ctx->opcode >> 26) & 0x3f;
10553
minor = ctx->opcode & 0x3f;
10556
minor = (ctx->opcode >> 6) & 0xf;
10559
mips32_op = OPC_SLL;
10562
mips32_op = OPC_SRA;
10565
mips32_op = OPC_SRL;
10568
mips32_op = OPC_ROTR;
10570
gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
10573
goto pool32a_invalid;
10577
minor = (ctx->opcode >> 6) & 0xf;
10581
mips32_op = OPC_ADD;
10584
mips32_op = OPC_ADDU;
10587
mips32_op = OPC_SUB;
10590
mips32_op = OPC_SUBU;
10593
mips32_op = OPC_MUL;
10595
gen_arith(env, ctx, mips32_op, rd, rs, rt);
10599
mips32_op = OPC_SLLV;
10602
mips32_op = OPC_SRLV;
10605
mips32_op = OPC_SRAV;
10608
mips32_op = OPC_ROTRV;
10610
gen_shift(env, ctx, mips32_op, rd, rs, rt);
10612
/* Logical operations */
10614
mips32_op = OPC_AND;
10617
mips32_op = OPC_OR;
10620
mips32_op = OPC_NOR;
10623
mips32_op = OPC_XOR;
10625
gen_logic(env, mips32_op, rd, rs, rt);
10627
/* Set less than */
10629
mips32_op = OPC_SLT;
10632
mips32_op = OPC_SLTU;
10634
gen_slt(env, mips32_op, rd, rs, rt);
10637
goto pool32a_invalid;
10641
minor = (ctx->opcode >> 6) & 0xf;
10643
/* Conditional moves */
10645
mips32_op = OPC_MOVN;
10648
mips32_op = OPC_MOVZ;
10650
gen_cond_move(env, mips32_op, rd, rs, rt);
10653
gen_ldxs(ctx, rs, rt, rd);
10656
goto pool32a_invalid;
10660
gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
10663
gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
10666
gen_pool32axf(env, ctx, rt, rs, is_branch);
10669
generate_exception(ctx, EXCP_BREAK);
10673
MIPS_INVAL("pool32a");
10674
generate_exception(ctx, EXCP_RI);
10679
minor = (ctx->opcode >> 12) & 0xf;
10682
/* Treat as no-op. */
10686
/* COP2: Not implemented. */
10687
generate_exception_err(ctx, EXCP_CpU, 2);
10691
#ifdef TARGET_MIPS64
10695
gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10699
#ifdef TARGET_MIPS64
10703
gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
10706
MIPS_INVAL("pool32b");
10707
generate_exception(ctx, EXCP_RI);
10712
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
10713
minor = ctx->opcode & 0x3f;
10714
check_cp1_enabled(ctx);
10717
mips32_op = OPC_ALNV_PS;
10720
mips32_op = OPC_MADD_S;
10723
mips32_op = OPC_MADD_D;
10726
mips32_op = OPC_MADD_PS;
10729
mips32_op = OPC_MSUB_S;
10732
mips32_op = OPC_MSUB_D;
10735
mips32_op = OPC_MSUB_PS;
10738
mips32_op = OPC_NMADD_S;
10741
mips32_op = OPC_NMADD_D;
10744
mips32_op = OPC_NMADD_PS;
10747
mips32_op = OPC_NMSUB_S;
10750
mips32_op = OPC_NMSUB_D;
10753
mips32_op = OPC_NMSUB_PS;
10755
gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
10757
case CABS_COND_FMT:
10758
cond = (ctx->opcode >> 6) & 0xf;
10759
cc = (ctx->opcode >> 13) & 0x7;
10760
fmt = (ctx->opcode >> 10) & 0x3;
10763
gen_cmpabs_s(ctx, cond, rt, rs, cc);
10766
gen_cmpabs_d(ctx, cond, rt, rs, cc);
10769
gen_cmpabs_ps(ctx, cond, rt, rs, cc);
10772
goto pool32f_invalid;
10776
cond = (ctx->opcode >> 6) & 0xf;
10777
cc = (ctx->opcode >> 13) & 0x7;
10778
fmt = (ctx->opcode >> 10) & 0x3;
10781
gen_cmp_s(ctx, cond, rt, rs, cc);
10784
gen_cmp_d(ctx, cond, rt, rs, cc);
10787
gen_cmp_ps(ctx, cond, rt, rs, cc);
10790
goto pool32f_invalid;
10794
gen_pool32fxf(env, ctx, rt, rs);
10798
switch ((ctx->opcode >> 6) & 0x7) {
10800
mips32_op = OPC_PLL_PS;
10803
mips32_op = OPC_PLU_PS;
10806
mips32_op = OPC_PUL_PS;
10809
mips32_op = OPC_PUU_PS;
10812
mips32_op = OPC_CVT_PS_S;
10814
gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10817
goto pool32f_invalid;
10822
switch ((ctx->opcode >> 6) & 0x7) {
10824
mips32_op = OPC_LWXC1;
10827
mips32_op = OPC_SWXC1;
10830
mips32_op = OPC_LDXC1;
10833
mips32_op = OPC_SDXC1;
10836
mips32_op = OPC_LUXC1;
10839
mips32_op = OPC_SUXC1;
10841
gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
10844
goto pool32f_invalid;
10849
fmt = (ctx->opcode >> 9) & 0x3;
10850
switch ((ctx->opcode >> 6) & 0x7) {
10854
mips32_op = OPC_RSQRT2_S;
10857
mips32_op = OPC_RSQRT2_D;
10860
mips32_op = OPC_RSQRT2_PS;
10863
goto pool32f_invalid;
10869
mips32_op = OPC_RECIP2_S;
10872
mips32_op = OPC_RECIP2_D;
10875
mips32_op = OPC_RECIP2_PS;
10878
goto pool32f_invalid;
10882
mips32_op = OPC_ADDR_PS;
10885
mips32_op = OPC_MULR_PS;
10887
gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10890
goto pool32f_invalid;
10894
/* MOV[FT].fmt and PREFX */
10895
cc = (ctx->opcode >> 13) & 0x7;
10896
fmt = (ctx->opcode >> 9) & 0x3;
10897
switch ((ctx->opcode >> 6) & 0x7) {
10901
gen_movcf_s(rs, rt, cc, 0);
10904
gen_movcf_d(ctx, rs, rt, cc, 0);
10907
gen_movcf_ps(rs, rt, cc, 0);
10910
goto pool32f_invalid;
10916
gen_movcf_s(rs, rt, cc, 1);
10919
gen_movcf_d(ctx, rs, rt, cc, 1);
10922
gen_movcf_ps(rs, rt, cc, 1);
10925
goto pool32f_invalid;
10931
goto pool32f_invalid;
10934
#define FINSN_3ARG_SDPS(prfx) \
10935
switch ((ctx->opcode >> 8) & 0x3) { \
10937
mips32_op = OPC_##prfx##_S; \
10940
mips32_op = OPC_##prfx##_D; \
10942
case FMT_SDPS_PS: \
10943
mips32_op = OPC_##prfx##_PS; \
10946
goto pool32f_invalid; \
10949
/* regular FP ops */
10950
switch ((ctx->opcode >> 6) & 0x3) {
10952
FINSN_3ARG_SDPS(ADD);
10955
FINSN_3ARG_SDPS(SUB);
10958
FINSN_3ARG_SDPS(MUL);
10961
fmt = (ctx->opcode >> 8) & 0x3;
10963
mips32_op = OPC_DIV_D;
10964
} else if (fmt == 0) {
10965
mips32_op = OPC_DIV_S;
10967
goto pool32f_invalid;
10971
goto pool32f_invalid;
10976
switch ((ctx->opcode >> 6) & 0x3) {
10978
FINSN_3ARG_SDPS(MOVN);
10981
FINSN_3ARG_SDPS(MOVZ);
10984
goto pool32f_invalid;
10988
gen_farith(ctx, mips32_op, rt, rs, rd, 0);
10992
MIPS_INVAL("pool32f");
10993
generate_exception(ctx, EXCP_RI);
10997
generate_exception_err(ctx, EXCP_CpU, 1);
11001
minor = (ctx->opcode >> 21) & 0x1f;
11004
mips32_op = OPC_BLTZ;
11007
mips32_op = OPC_BLTZAL;
11010
mips32_op = OPC_BLTZALS;
11013
mips32_op = OPC_BGEZ;
11016
mips32_op = OPC_BGEZAL;
11019
mips32_op = OPC_BGEZALS;
11022
mips32_op = OPC_BLEZ;
11025
mips32_op = OPC_BGTZ;
11027
gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11033
mips32_op = OPC_TLTI;
11036
mips32_op = OPC_TGEI;
11039
mips32_op = OPC_TLTIU;
11042
mips32_op = OPC_TGEIU;
11045
mips32_op = OPC_TNEI;
11048
mips32_op = OPC_TEQI;
11050
gen_trap(ctx, mips32_op, rs, -1, imm);
11055
gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11056
4, rs, 0, imm << 1);
11057
/* Compact branches don't have a delay slot, so just let
11058
the normal delay slot handling take us to the branch
11062
gen_logic_imm(env, OPC_LUI, rs, -1, imm);
11068
/* COP2: Not implemented. */
11069
generate_exception_err(ctx, EXCP_CpU, 2);
11072
mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11075
mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11078
mips32_op = OPC_BC1FANY4;
11081
mips32_op = OPC_BC1TANY4;
11084
check_insn(env, ctx, ASE_MIPS3D);
11087
gen_compute_branch1(env, ctx, mips32_op,
11088
(ctx->opcode >> 18) & 0x7, imm << 1);
11093
/* MIPS DSP: not implemented */
11096
MIPS_INVAL("pool32i");
11097
generate_exception(ctx, EXCP_RI);
11102
minor = (ctx->opcode >> 12) & 0xf;
11105
mips32_op = OPC_LWL;
11108
mips32_op = OPC_SWL;
11111
mips32_op = OPC_LWR;
11114
mips32_op = OPC_SWR;
11116
#if defined(TARGET_MIPS64)
11118
mips32_op = OPC_LDL;
11121
mips32_op = OPC_SDL;
11124
mips32_op = OPC_LDR;
11127
mips32_op = OPC_SDR;
11130
mips32_op = OPC_LWU;
11133
mips32_op = OPC_LLD;
11137
mips32_op = OPC_LL;
11140
gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11143
gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11146
gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11148
#if defined(TARGET_MIPS64)
11150
gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11154
/* Treat as no-op */
11157
MIPS_INVAL("pool32c");
11158
generate_exception(ctx, EXCP_RI);
11163
mips32_op = OPC_ADDI;
11166
mips32_op = OPC_ADDIU;
11168
gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11171
/* Logical operations */
11173
mips32_op = OPC_ORI;
11176
mips32_op = OPC_XORI;
11179
mips32_op = OPC_ANDI;
11181
gen_logic_imm(env, mips32_op, rt, rs, imm);
11184
/* Set less than immediate */
11186
mips32_op = OPC_SLTI;
11189
mips32_op = OPC_SLTIU;
11191
gen_slt_imm(env, mips32_op, rt, rs, imm);
11194
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11195
gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11199
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11200
gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11204
gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11208
gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11212
gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11213
(int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11217
gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11218
(int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11221
/* Floating point (COP1) */
11223
mips32_op = OPC_LWC1;
11226
mips32_op = OPC_LDC1;
11229
mips32_op = OPC_SWC1;
11232
mips32_op = OPC_SDC1;
11234
gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11238
int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11239
int offset = SIMM(ctx->opcode, 0, 23) << 2;
11241
gen_addiupc(ctx, reg, offset, 0, 0);
11244
/* Loads and stores */
11246
mips32_op = OPC_LB;
11249
mips32_op = OPC_LBU;
11252
mips32_op = OPC_LH;
11255
mips32_op = OPC_LHU;
11258
mips32_op = OPC_LW;
11260
#ifdef TARGET_MIPS64
11262
mips32_op = OPC_LD;
11265
mips32_op = OPC_SD;
11269
mips32_op = OPC_SB;
11272
mips32_op = OPC_SH;
11275
mips32_op = OPC_SW;
11278
gen_ld(env, ctx, mips32_op, rt, rs, imm);
11281
gen_st(ctx, mips32_op, rt, rs, imm);
11284
generate_exception(ctx, EXCP_RI);
11289
static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11293
/* make sure instructions are on a halfword boundary */
11294
if (ctx->pc & 0x1) {
11295
env->CP0_BadVAddr = ctx->pc;
11296
generate_exception(ctx, EXCP_AdEL);
11297
ctx->bstate = BS_STOP;
11301
op = (ctx->opcode >> 10) & 0x3f;
11302
/* Enforce properly-sized instructions in a delay slot */
11303
if (ctx->hflags & MIPS_HFLAG_BMASK) {
11304
int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11338
case POOL48A: /* ??? */
11343
if (bits & MIPS_HFLAG_BDS16) {
11344
generate_exception(ctx, EXCP_RI);
11345
/* Just stop translation; the user is confused. */
11346
ctx->bstate = BS_STOP;
11371
if (bits & MIPS_HFLAG_BDS32) {
11372
generate_exception(ctx, EXCP_RI);
11373
/* Just stop translation; the user is confused. */
11374
ctx->bstate = BS_STOP;
11385
int rd = mmreg(uMIPS_RD(ctx->opcode));
11386
int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11387
int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11390
switch (ctx->opcode & 0x1) {
11399
gen_arith(env, ctx, opc, rd, rs1, rs2);
11404
int rd = mmreg(uMIPS_RD(ctx->opcode));
11405
int rs = mmreg(uMIPS_RS(ctx->opcode));
11406
int amount = (ctx->opcode >> 1) & 0x7;
11408
amount = amount == 0 ? 8 : amount;
11410
switch (ctx->opcode & 0x1) {
11419
gen_shift_imm(env, ctx, opc, rd, rs, amount);
11423
gen_pool16c_insn(env, ctx, is_branch);
11427
int rd = mmreg(uMIPS_RD(ctx->opcode));
11428
int rb = 28; /* GP */
11429
int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11431
gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11435
if (ctx->opcode & 1) {
11436
generate_exception(ctx, EXCP_RI);
11439
int enc_dest = uMIPS_RD(ctx->opcode);
11440
int enc_rt = uMIPS_RS2(ctx->opcode);
11441
int enc_rs = uMIPS_RS1(ctx->opcode);
11442
int rd, rs, re, rt;
11443
static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11444
static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11445
static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11447
rd = rd_enc[enc_dest];
11448
re = re_enc[enc_dest];
11449
rs = rs_rt_enc[enc_rs];
11450
rt = rs_rt_enc[enc_rt];
11452
gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11453
gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11458
int rd = mmreg(uMIPS_RD(ctx->opcode));
11459
int rb = mmreg(uMIPS_RS(ctx->opcode));
11460
int16_t offset = ZIMM(ctx->opcode, 0, 4);
11461
offset = (offset == 0xf ? -1 : offset);
11463
gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11468
int rd = mmreg(uMIPS_RD(ctx->opcode));
11469
int rb = mmreg(uMIPS_RS(ctx->opcode));
11470
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11472
gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11477
int rd = (ctx->opcode >> 5) & 0x1f;
11478
int rb = 29; /* SP */
11479
int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11481
gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11486
int rd = mmreg(uMIPS_RD(ctx->opcode));
11487
int rb = mmreg(uMIPS_RS(ctx->opcode));
11488
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11490
gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11495
int rd = mmreg2(uMIPS_RD(ctx->opcode));
11496
int rb = mmreg(uMIPS_RS(ctx->opcode));
11497
int16_t offset = ZIMM(ctx->opcode, 0, 4);
11499
gen_st(ctx, OPC_SB, rd, rb, offset);
11504
int rd = mmreg2(uMIPS_RD(ctx->opcode));
11505
int rb = mmreg(uMIPS_RS(ctx->opcode));
11506
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11508
gen_st(ctx, OPC_SH, rd, rb, offset);
11513
int rd = (ctx->opcode >> 5) & 0x1f;
11514
int rb = 29; /* SP */
11515
int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11517
gen_st(ctx, OPC_SW, rd, rb, offset);
11522
int rd = mmreg2(uMIPS_RD(ctx->opcode));
11523
int rb = mmreg(uMIPS_RS(ctx->opcode));
11524
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11526
gen_st(ctx, OPC_SW, rd, rb, offset);
11531
int rd = uMIPS_RD5(ctx->opcode);
11532
int rs = uMIPS_RS5(ctx->opcode);
11534
gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11538
gen_andi16(env, ctx);
11541
switch (ctx->opcode & 0x1) {
11543
gen_addius5(env, ctx);
11546
gen_addiusp(env, ctx);
11551
switch (ctx->opcode & 0x1) {
11553
gen_addiur2(env, ctx);
11556
gen_addiur1sp(env, ctx);
11561
gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
11562
SIMM(ctx->opcode, 0, 10) << 1);
11567
gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
11568
mmreg(uMIPS_RD(ctx->opcode)),
11569
0, SIMM(ctx->opcode, 0, 7) << 1);
11574
int reg = mmreg(uMIPS_RD(ctx->opcode));
11575
int imm = ZIMM(ctx->opcode, 0, 7);
11577
imm = (imm == 0x7f ? -1 : imm);
11578
tcg_gen_movi_tl(cpu_gpr[reg], imm);
11588
generate_exception(ctx, EXCP_RI);
11591
decode_micromips32_opc (env, ctx, op, is_branch);
11598
/* SmartMIPS extension to MIPS32 */
11600
#if defined(TARGET_MIPS64)
11602
/* MDMX extension to MIPS64 */
11606
static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
11609
int rs, rt, rd, sa;
11610
uint32_t op, op1, op2;
11613
/* make sure instructions are on a word boundary */
11614
if (ctx->pc & 0x3) {
11615
env->CP0_BadVAddr = ctx->pc;
11616
generate_exception(ctx, EXCP_AdEL);
11620
/* Handle blikely not taken case */
11621
if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
11622
int l1 = gen_new_label();
11624
MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
11625
tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11626
tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
11627
gen_goto_tb(ctx, 1, ctx->pc + 4);
11631
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
11632
tcg_gen_debug_insn_start(ctx->pc);
11634
op = MASK_OP_MAJOR(ctx->opcode);
11635
rs = (ctx->opcode >> 21) & 0x1f;
11636
rt = (ctx->opcode >> 16) & 0x1f;
11637
rd = (ctx->opcode >> 11) & 0x1f;
11638
sa = (ctx->opcode >> 6) & 0x1f;
11639
imm = (int16_t)ctx->opcode;
11642
op1 = MASK_SPECIAL(ctx->opcode);
11644
case OPC_SLL: /* Shift with immediate */
11646
gen_shift_imm(env, ctx, op1, rd, rt, sa);
11649
switch ((ctx->opcode >> 21) & 0x1f) {
11651
/* rotr is decoded as srl on non-R2 CPUs */
11652
if (env->insn_flags & ISA_MIPS32R2) {
11657
gen_shift_imm(env, ctx, op1, rd, rt, sa);
11660
generate_exception(ctx, EXCP_RI);
11664
case OPC_MOVN: /* Conditional move */
11666
check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
11667
INSN_LOONGSON2E | INSN_LOONGSON2F);
11668
gen_cond_move(env, op1, rd, rs, rt);
11670
case OPC_ADD ... OPC_SUBU:
11671
gen_arith(env, ctx, op1, rd, rs, rt);
11673
case OPC_SLLV: /* Shifts */
11675
gen_shift(env, ctx, op1, rd, rs, rt);
11678
switch ((ctx->opcode >> 6) & 0x1f) {
11680
/* rotrv is decoded as srlv on non-R2 CPUs */
11681
if (env->insn_flags & ISA_MIPS32R2) {
11686
gen_shift(env, ctx, op1, rd, rs, rt);
11689
generate_exception(ctx, EXCP_RI);
11693
case OPC_SLT: /* Set on less than */
11695
gen_slt(env, op1, rd, rs, rt);
11697
case OPC_AND: /* Logic*/
11701
gen_logic(env, op1, rd, rs, rt);
11703
case OPC_MULT ... OPC_DIVU:
11705
check_insn(env, ctx, INSN_VR54XX);
11706
op1 = MASK_MUL_VR54XX(ctx->opcode);
11707
gen_mul_vr54xx(ctx, op1, rd, rs, rt);
11709
gen_muldiv(ctx, op1, rs, rt);
11711
case OPC_JR ... OPC_JALR:
11712
gen_compute_branch(ctx, op1, 4, rs, rd, sa);
11715
case OPC_TGE ... OPC_TEQ: /* Traps */
11717
gen_trap(ctx, op1, rs, rt, -1);
11719
case OPC_MFHI: /* Move from HI/LO */
11721
gen_HILO(ctx, op1, rd);
11724
case OPC_MTLO: /* Move to HI/LO */
11725
gen_HILO(ctx, op1, rs);
11727
case OPC_PMON: /* Pmon entry point, also R4010 selsl */
11728
#ifdef MIPS_STRICT_STANDARD
11729
MIPS_INVAL("PMON / selsl");
11730
generate_exception(ctx, EXCP_RI);
11732
gen_helper_0i(pmon, sa);
11736
generate_exception(ctx, EXCP_SYSCALL);
11737
ctx->bstate = BS_STOP;
11740
generate_exception(ctx, EXCP_BREAK);
11743
#ifdef MIPS_STRICT_STANDARD
11744
MIPS_INVAL("SPIM");
11745
generate_exception(ctx, EXCP_RI);
11747
/* Implemented as RI exception for now. */
11748
MIPS_INVAL("spim (unofficial)");
11749
generate_exception(ctx, EXCP_RI);
11753
/* Treat as NOP. */
11757
check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
11758
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11759
check_cp1_enabled(ctx);
11760
gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
11761
(ctx->opcode >> 16) & 1);
11763
generate_exception_err(ctx, EXCP_CpU, 1);
11767
#if defined(TARGET_MIPS64)
11768
/* MIPS64 specific opcodes */
11773
check_insn(env, ctx, ISA_MIPS3);
11774
check_mips_64(ctx);
11775
gen_shift_imm(env, ctx, op1, rd, rt, sa);
11778
switch ((ctx->opcode >> 21) & 0x1f) {
11780
/* drotr is decoded as dsrl on non-R2 CPUs */
11781
if (env->insn_flags & ISA_MIPS32R2) {
11786
check_insn(env, ctx, ISA_MIPS3);
11787
check_mips_64(ctx);
11788
gen_shift_imm(env, ctx, op1, rd, rt, sa);
11791
generate_exception(ctx, EXCP_RI);
11796
switch ((ctx->opcode >> 21) & 0x1f) {
11798
/* drotr32 is decoded as dsrl32 on non-R2 CPUs */
11799
if (env->insn_flags & ISA_MIPS32R2) {
11804
check_insn(env, ctx, ISA_MIPS3);
11805
check_mips_64(ctx);
11806
gen_shift_imm(env, ctx, op1, rd, rt, sa);
11809
generate_exception(ctx, EXCP_RI);
11813
case OPC_DADD ... OPC_DSUBU:
11814
check_insn(env, ctx, ISA_MIPS3);
11815
check_mips_64(ctx);
11816
gen_arith(env, ctx, op1, rd, rs, rt);
11820
check_insn(env, ctx, ISA_MIPS3);
11821
check_mips_64(ctx);
11822
gen_shift(env, ctx, op1, rd, rs, rt);
11825
switch ((ctx->opcode >> 6) & 0x1f) {
11827
/* drotrv is decoded as dsrlv on non-R2 CPUs */
11828
if (env->insn_flags & ISA_MIPS32R2) {
11833
check_insn(env, ctx, ISA_MIPS3);
11834
check_mips_64(ctx);
11835
gen_shift(env, ctx, op1, rd, rs, rt);
11838
generate_exception(ctx, EXCP_RI);
11842
case OPC_DMULT ... OPC_DDIVU:
11843
check_insn(env, ctx, ISA_MIPS3);
11844
check_mips_64(ctx);
11845
gen_muldiv(ctx, op1, rs, rt);
11848
default: /* Invalid */
11849
MIPS_INVAL("special");
11850
generate_exception(ctx, EXCP_RI);
11855
op1 = MASK_SPECIAL2(ctx->opcode);
11857
case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
11858
case OPC_MSUB ... OPC_MSUBU:
11859
check_insn(env, ctx, ISA_MIPS32);
11860
gen_muldiv(ctx, op1, rs, rt);
11863
gen_arith(env, ctx, op1, rd, rs, rt);
11867
check_insn(env, ctx, ISA_MIPS32);
11868
gen_cl(ctx, op1, rd, rs);
11871
/* XXX: not clear which exception should be raised
11872
* when in debug mode...
11874
check_insn(env, ctx, ISA_MIPS32);
11875
if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11876
generate_exception(ctx, EXCP_DBp);
11878
generate_exception(ctx, EXCP_DBp);
11880
/* Treat as NOP. */
11883
case OPC_DIVU_G_2F:
11884
case OPC_MULT_G_2F:
11885
case OPC_MULTU_G_2F:
11887
case OPC_MODU_G_2F:
11888
check_insn(env, ctx, INSN_LOONGSON2F);
11889
gen_loongson_integer(ctx, op1, rd, rs, rt);
11891
#if defined(TARGET_MIPS64)
11894
check_insn(env, ctx, ISA_MIPS64);
11895
check_mips_64(ctx);
11896
gen_cl(ctx, op1, rd, rs);
11898
case OPC_DMULT_G_2F:
11899
case OPC_DMULTU_G_2F:
11900
case OPC_DDIV_G_2F:
11901
case OPC_DDIVU_G_2F:
11902
case OPC_DMOD_G_2F:
11903
case OPC_DMODU_G_2F:
11904
check_insn(env, ctx, INSN_LOONGSON2F);
11905
gen_loongson_integer(ctx, op1, rd, rs, rt);
11908
default: /* Invalid */
11909
MIPS_INVAL("special2");
11910
generate_exception(ctx, EXCP_RI);
11915
op1 = MASK_SPECIAL3(ctx->opcode);
11919
check_insn(env, ctx, ISA_MIPS32R2);
11920
gen_bitops(ctx, op1, rt, rs, sa, rd);
11923
check_insn(env, ctx, ISA_MIPS32R2);
11924
op2 = MASK_BSHFL(ctx->opcode);
11925
gen_bshfl(ctx, op2, rt, rd);
11928
gen_rdhwr(env, ctx, rt, rd);
11931
check_insn(env, ctx, ASE_MT);
11933
TCGv t0 = tcg_temp_new();
11934
TCGv t1 = tcg_temp_new();
11936
gen_load_gpr(t0, rt);
11937
gen_load_gpr(t1, rs);
11938
gen_helper_fork(t0, t1);
11944
check_insn(env, ctx, ASE_MT);
11946
TCGv t0 = tcg_temp_new();
11948
save_cpu_state(ctx, 1);
11949
gen_load_gpr(t0, rs);
11950
gen_helper_yield(t0, t0);
11951
gen_store_gpr(t0, rd);
11955
case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
11956
case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
11957
case OPC_MOD_G_2E ... OPC_MODU_G_2E:
11958
check_insn(env, ctx, INSN_LOONGSON2E);
11959
gen_loongson_integer(ctx, op1, rd, rs, rt);
11961
#if defined(TARGET_MIPS64)
11962
case OPC_DEXTM ... OPC_DEXT:
11963
case OPC_DINSM ... OPC_DINS:
11964
check_insn(env, ctx, ISA_MIPS64R2);
11965
check_mips_64(ctx);
11966
gen_bitops(ctx, op1, rt, rs, sa, rd);
11969
check_insn(env, ctx, ISA_MIPS64R2);
11970
check_mips_64(ctx);
11971
op2 = MASK_DBSHFL(ctx->opcode);
11972
gen_bshfl(ctx, op2, rt, rd);
11974
case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
11975
case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
11976
case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
11977
check_insn(env, ctx, INSN_LOONGSON2E);
11978
gen_loongson_integer(ctx, op1, rd, rs, rt);
11981
default: /* Invalid */
11982
MIPS_INVAL("special3");
11983
generate_exception(ctx, EXCP_RI);
11988
op1 = MASK_REGIMM(ctx->opcode);
11990
case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
11991
case OPC_BLTZAL ... OPC_BGEZALL:
11992
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
11995
case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
11997
gen_trap(ctx, op1, rs, -1, imm);
12000
check_insn(env, ctx, ISA_MIPS32R2);
12001
/* Treat as NOP. */
12003
default: /* Invalid */
12004
MIPS_INVAL("regimm");
12005
generate_exception(ctx, EXCP_RI);
12010
check_cp0_enabled(ctx);
12011
op1 = MASK_CP0(ctx->opcode);
12017
#if defined(TARGET_MIPS64)
12021
#ifndef CONFIG_USER_ONLY
12022
gen_cp0(env, ctx, op1, rt, rd);
12023
#endif /* !CONFIG_USER_ONLY */
12025
case OPC_C0_FIRST ... OPC_C0_LAST:
12026
#ifndef CONFIG_USER_ONLY
12027
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12028
#endif /* !CONFIG_USER_ONLY */
12031
#ifndef CONFIG_USER_ONLY
12033
TCGv t0 = tcg_temp_new();
12035
op2 = MASK_MFMC0(ctx->opcode);
12038
check_insn(env, ctx, ASE_MT);
12039
gen_helper_dmt(t0);
12040
gen_store_gpr(t0, rt);
12043
check_insn(env, ctx, ASE_MT);
12044
gen_helper_emt(t0);
12045
gen_store_gpr(t0, rt);
12048
check_insn(env, ctx, ASE_MT);
12049
gen_helper_dvpe(t0);
12050
gen_store_gpr(t0, rt);
12053
check_insn(env, ctx, ASE_MT);
12054
gen_helper_evpe(t0);
12055
gen_store_gpr(t0, rt);
12058
check_insn(env, ctx, ISA_MIPS32R2);
12059
save_cpu_state(ctx, 1);
12061
gen_store_gpr(t0, rt);
12062
/* Stop translation as we may have switched the execution mode */
12063
ctx->bstate = BS_STOP;
12066
check_insn(env, ctx, ISA_MIPS32R2);
12067
save_cpu_state(ctx, 1);
12069
gen_store_gpr(t0, rt);
12070
/* Stop translation as we may have switched the execution mode */
12071
ctx->bstate = BS_STOP;
12073
default: /* Invalid */
12074
MIPS_INVAL("mfmc0");
12075
generate_exception(ctx, EXCP_RI);
12080
#endif /* !CONFIG_USER_ONLY */
12083
check_insn(env, ctx, ISA_MIPS32R2);
12084
gen_load_srsgpr(rt, rd);
12087
check_insn(env, ctx, ISA_MIPS32R2);
12088
gen_store_srsgpr(rt, rd);
12092
generate_exception(ctx, EXCP_RI);
12096
case OPC_ADDI: /* Arithmetic with immediate opcode */
12098
gen_arith_imm(env, ctx, op, rt, rs, imm);
12100
case OPC_SLTI: /* Set on less than with immediate opcode */
12102
gen_slt_imm(env, op, rt, rs, imm);
12104
case OPC_ANDI: /* Arithmetic with immediate opcode */
12108
gen_logic_imm(env, op, rt, rs, imm);
12110
case OPC_J ... OPC_JAL: /* Jump */
12111
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12112
gen_compute_branch(ctx, op, 4, rs, rt, offset);
12115
case OPC_BEQ ... OPC_BGTZ: /* Branch */
12116
case OPC_BEQL ... OPC_BGTZL:
12117
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12120
case OPC_LB ... OPC_LWR: /* Load and stores */
12122
gen_ld(env, ctx, op, rt, rs, imm);
12124
case OPC_SB ... OPC_SW:
12126
gen_st(ctx, op, rt, rs, imm);
12129
gen_st_cond(ctx, op, rt, rs, imm);
12132
check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12133
/* Treat as NOP. */
12136
check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12137
/* Treat as NOP. */
12140
/* Floating point (COP1). */
12145
gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12149
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12150
check_cp1_enabled(ctx);
12151
op1 = MASK_CP1(ctx->opcode);
12155
check_insn(env, ctx, ISA_MIPS32R2);
12160
gen_cp1(ctx, op1, rt, rd);
12162
#if defined(TARGET_MIPS64)
12165
check_insn(env, ctx, ISA_MIPS3);
12166
gen_cp1(ctx, op1, rt, rd);
12172
check_insn(env, ctx, ASE_MIPS3D);
12175
gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12176
(rt >> 2) & 0x7, imm << 2);
12184
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12189
generate_exception (ctx, EXCP_RI);
12193
generate_exception_err(ctx, EXCP_CpU, 1);
12203
/* COP2: Not implemented. */
12204
generate_exception_err(ctx, EXCP_CpU, 2);
12208
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12209
check_cp1_enabled(ctx);
12210
op1 = MASK_CP3(ctx->opcode);
12218
gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12221
/* Treat as NOP. */
12236
gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12240
generate_exception (ctx, EXCP_RI);
12244
generate_exception_err(ctx, EXCP_CpU, 1);
12248
#if defined(TARGET_MIPS64)
12249
/* MIPS64 opcodes */
12251
case OPC_LDL ... OPC_LDR:
12254
check_insn(env, ctx, ISA_MIPS3);
12255
check_mips_64(ctx);
12256
gen_ld(env, ctx, op, rt, rs, imm);
12258
case OPC_SDL ... OPC_SDR:
12260
check_insn(env, ctx, ISA_MIPS3);
12261
check_mips_64(ctx);
12262
gen_st(ctx, op, rt, rs, imm);
12265
check_insn(env, ctx, ISA_MIPS3);
12266
check_mips_64(ctx);
12267
gen_st_cond(ctx, op, rt, rs, imm);
12271
check_insn(env, ctx, ISA_MIPS3);
12272
check_mips_64(ctx);
12273
gen_arith_imm(env, ctx, op, rt, rs, imm);
12277
check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12278
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12279
gen_compute_branch(ctx, op, 4, rs, rt, offset);
12283
check_insn(env, ctx, ASE_MDMX);
12284
/* MDMX: Not implemented. */
12285
default: /* Invalid */
12286
MIPS_INVAL("major opcode");
12287
generate_exception(ctx, EXCP_RI);
12293
gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
12297
target_ulong pc_start;
12298
uint16_t *gen_opc_end;
12307
qemu_log("search pc %d\n", search_pc);
12310
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12313
ctx.singlestep_enabled = env->singlestep_enabled;
12315
ctx.bstate = BS_NONE;
12316
/* Restore delay slot state from the tb context. */
12317
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12318
restore_cpu_state(env, &ctx);
12319
#ifdef CONFIG_USER_ONLY
12320
ctx.mem_idx = MIPS_HFLAG_UM;
12322
ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12325
max_insns = tb->cflags & CF_COUNT_MASK;
12326
if (max_insns == 0)
12327
max_insns = CF_COUNT_MASK;
12328
LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12329
gen_icount_start();
12330
while (ctx.bstate == BS_NONE) {
12331
if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12332
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12333
if (bp->pc == ctx.pc) {
12334
save_cpu_state(&ctx, 1);
12335
ctx.bstate = BS_BRANCH;
12336
gen_helper_0i(raise_exception, EXCP_DEBUG);
12337
/* Include the breakpoint location or the tb won't
12338
* be flushed when it must be. */
12340
goto done_generating;
12346
j = gen_opc_ptr - gen_opc_buf;
12350
gen_opc_instr_start[lj++] = 0;
12352
gen_opc_pc[lj] = ctx.pc;
12353
gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12354
gen_opc_instr_start[lj] = 1;
12355
gen_opc_icount[lj] = num_insns;
12357
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12361
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12362
ctx.opcode = ldl_code(ctx.pc);
12364
decode_opc(env, &ctx, &is_branch);
12365
} else if (env->insn_flags & ASE_MICROMIPS) {
12366
ctx.opcode = lduw_code(ctx.pc);
12367
insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12368
} else if (env->insn_flags & ASE_MIPS16) {
12369
ctx.opcode = lduw_code(ctx.pc);
12370
insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12372
generate_exception(&ctx, EXCP_RI);
12373
ctx.bstate = BS_STOP;
12377
handle_delay_slot(env, &ctx, insn_bytes);
12379
ctx.pc += insn_bytes;
12383
/* Execute a branch and its delay slot as a single instruction.
12384
This is what GDB expects and is consistent with what the
12385
hardware does (e.g. if a delay slot instruction faults, the
12386
reported PC is the PC of the branch). */
12387
if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12390
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12393
if (gen_opc_ptr >= gen_opc_end)
12396
if (num_insns >= max_insns)
12402
if (tb->cflags & CF_LAST_IO)
12404
if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12405
save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12406
gen_helper_0i(raise_exception, EXCP_DEBUG);
12408
switch (ctx.bstate) {
12410
gen_goto_tb(&ctx, 0, ctx.pc);
12413
save_cpu_state(&ctx, 0);
12414
gen_goto_tb(&ctx, 0, ctx.pc);
12417
tcg_gen_exit_tb(0);
12425
gen_icount_end(tb, num_insns);
12426
*gen_opc_ptr = INDEX_op_end;
12428
j = gen_opc_ptr - gen_opc_buf;
12431
gen_opc_instr_start[lj++] = 0;
12433
tb->size = ctx.pc - pc_start;
12434
tb->icount = num_insns;
12438
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12439
qemu_log("IN: %s\n", lookup_symbol(pc_start));
12440
log_target_disas(pc_start, ctx.pc - pc_start, 0);
12446
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
12448
gen_intermediate_code_internal(env, tb, 0);
12451
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
12453
gen_intermediate_code_internal(env, tb, 1);
12456
static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
12460
int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12462
#define printfpr(fp) \
12465
fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12466
" fd:%13g fs:%13g psu: %13g\n", \
12467
(fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12468
(double)(fp)->fd, \
12469
(double)(fp)->fs[FP_ENDIAN_IDX], \
12470
(double)(fp)->fs[!FP_ENDIAN_IDX]); \
12473
tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12474
tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12475
fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12476
" fd:%13g fs:%13g psu:%13g\n", \
12477
tmp.w[FP_ENDIAN_IDX], tmp.d, \
12479
(double)tmp.fs[FP_ENDIAN_IDX], \
12480
(double)tmp.fs[!FP_ENDIAN_IDX]); \
12485
fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
12486
env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12487
get_float_exception_flags(&env->active_fpu.fp_status));
12488
for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12489
fpu_fprintf(f, "%3s: ", fregnames[i]);
12490
printfpr(&env->active_fpu.fpr[i]);
12496
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12497
/* Debug help: The architecture requires 32bit code to maintain proper
12498
sign-extended values on 64bit machines. */
12500
#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
12503
cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
12504
fprintf_function cpu_fprintf,
12509
if (!SIGN_EXT_P(env->active_tc.PC))
12510
cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
12511
if (!SIGN_EXT_P(env->active_tc.HI[0]))
12512
cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
12513
if (!SIGN_EXT_P(env->active_tc.LO[0]))
12514
cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
12515
if (!SIGN_EXT_P(env->btarget))
12516
cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
12518
for (i = 0; i < 32; i++) {
12519
if (!SIGN_EXT_P(env->active_tc.gpr[i]))
12520
cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
12523
if (!SIGN_EXT_P(env->CP0_EPC))
12524
cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
12525
if (!SIGN_EXT_P(env->lladdr))
12526
cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
12530
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
12535
cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
12536
" LO=0x" TARGET_FMT_lx " ds %04x "
12537
TARGET_FMT_lx " " TARGET_FMT_ld "\n",
12538
env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
12539
env->hflags, env->btarget, env->bcond);
12540
for (i = 0; i < 32; i++) {
12542
cpu_fprintf(f, "GPR%02d:", i);
12543
cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
12545
cpu_fprintf(f, "\n");
12548
cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
12549
env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
12550
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
12551
env->CP0_Config0, env->CP0_Config1, env->lladdr);
12552
if (env->hflags & MIPS_HFLAG_FPU)
12553
fpu_dump_state(env, f, cpu_fprintf, flags);
12554
#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
12555
cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
12559
static void mips_tcg_init(void)
12564
/* Initialize various static tables. */
12568
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
12569
TCGV_UNUSED(cpu_gpr[0]);
12570
for (i = 1; i < 32; i++)
12571
cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
12572
offsetof(CPUState, active_tc.gpr[i]),
12574
cpu_PC = tcg_global_mem_new(TCG_AREG0,
12575
offsetof(CPUState, active_tc.PC), "PC");
12576
for (i = 0; i < MIPS_DSP_ACC; i++) {
12577
cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
12578
offsetof(CPUState, active_tc.HI[i]),
12580
cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
12581
offsetof(CPUState, active_tc.LO[i]),
12583
cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
12584
offsetof(CPUState, active_tc.ACX[i]),
12587
cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
12588
offsetof(CPUState, active_tc.DSPControl),
12590
bcond = tcg_global_mem_new(TCG_AREG0,
12591
offsetof(CPUState, bcond), "bcond");
12592
btarget = tcg_global_mem_new(TCG_AREG0,
12593
offsetof(CPUState, btarget), "btarget");
12594
hflags = tcg_global_mem_new_i32(TCG_AREG0,
12595
offsetof(CPUState, hflags), "hflags");
12597
fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
12598
offsetof(CPUState, active_fpu.fcr0),
12600
fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
12601
offsetof(CPUState, active_fpu.fcr31),
12604
/* register helpers */
12605
#define GEN_HELPER 2
12606
#include "helper.h"
12611
#include "translate_init.c"
12613
CPUMIPSState *cpu_mips_init (const char *cpu_model)
12616
const mips_def_t *def;
12618
def = cpu_mips_find_by_name(cpu_model);
12621
env = qemu_mallocz(sizeof(CPUMIPSState));
12622
env->cpu_model = def;
12623
env->cpu_model_str = cpu_model;
12625
cpu_exec_init(env);
12626
#ifndef CONFIG_USER_ONLY
12627
mmu_init(env, def);
12629
fpu_init(env, def);
12630
mvp_init(env, def);
12633
qemu_init_vcpu(env);
12637
void cpu_reset (CPUMIPSState *env)
12639
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
12640
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
12641
log_cpu_state(env, 0);
12644
memset(env, 0, offsetof(CPUMIPSState, breakpoints));
12647
/* Reset registers to their default values */
12648
env->CP0_PRid = env->cpu_model->CP0_PRid;
12649
env->CP0_Config0 = env->cpu_model->CP0_Config0;
12650
#ifdef TARGET_WORDS_BIGENDIAN
12651
env->CP0_Config0 |= (1 << CP0C0_BE);
12653
env->CP0_Config1 = env->cpu_model->CP0_Config1;
12654
env->CP0_Config2 = env->cpu_model->CP0_Config2;
12655
env->CP0_Config3 = env->cpu_model->CP0_Config3;
12656
env->CP0_Config6 = env->cpu_model->CP0_Config6;
12657
env->CP0_Config7 = env->cpu_model->CP0_Config7;
12658
env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
12659
<< env->cpu_model->CP0_LLAddr_shift;
12660
env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
12661
env->SYNCI_Step = env->cpu_model->SYNCI_Step;
12662
env->CCRes = env->cpu_model->CCRes;
12663
env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
12664
env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
12665
env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
12666
env->current_tc = 0;
12667
env->SEGBITS = env->cpu_model->SEGBITS;
12668
env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
12669
#if defined(TARGET_MIPS64)
12670
if (env->cpu_model->insn_flags & ISA_MIPS3) {
12671
env->SEGMask |= 3ULL << 62;
12674
env->PABITS = env->cpu_model->PABITS;
12675
env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
12676
env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
12677
env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
12678
env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
12679
env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
12680
env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
12681
env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
12682
env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
12683
env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
12684
env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
12685
env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
12686
env->insn_flags = env->cpu_model->insn_flags;
12688
#if defined(CONFIG_USER_ONLY)
12689
env->hflags = MIPS_HFLAG_UM;
12690
/* Enable access to the SYNCI_Step register. */
12691
env->CP0_HWREna |= (1 << 1);
12692
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12693
env->hflags |= MIPS_HFLAG_FPU;
12695
#ifdef TARGET_MIPS64
12696
if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
12697
env->hflags |= MIPS_HFLAG_F64;
12701
if (env->hflags & MIPS_HFLAG_BMASK) {
12702
/* If the exception was raised from a delay slot,
12703
come back to the jump. */
12704
env->CP0_ErrorEPC = env->active_tc.PC - 4;
12706
env->CP0_ErrorEPC = env->active_tc.PC;
12708
env->active_tc.PC = (int32_t)0xBFC00000;
12709
env->CP0_Random = env->tlb->nb_tlb - 1;
12710
env->tlb->tlb_in_use = env->tlb->nb_tlb;
12711
env->CP0_Wired = 0;
12712
env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
12713
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
12714
/* vectored interrupts not implemented, timer on int 7,
12715
no performance counters. */
12716
env->CP0_IntCtl = 0xe0000000;
12720
for (i = 0; i < 7; i++) {
12721
env->CP0_WatchLo[i] = 0;
12722
env->CP0_WatchHi[i] = 0x80000000;
12724
env->CP0_WatchLo[7] = 0;
12725
env->CP0_WatchHi[7] = 0;
12727
/* Count register increments in debug mode, EJTAG version 1 */
12728
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
12729
env->hflags = MIPS_HFLAG_CP0;
12731
#if defined(TARGET_MIPS64)
12732
if (env->cpu_model->insn_flags & ISA_MIPS3) {
12733
env->hflags |= MIPS_HFLAG_64;
12736
env->exception_index = EXCP_NONE;
12739
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
12741
env->active_tc.PC = gen_opc_pc[pc_pos];
12742
env->hflags &= ~MIPS_HFLAG_BMASK;
12743
env->hflags |= gen_opc_hflags[pc_pos];