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)
8
* Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10
* This library is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2 of the License, or (at your option) any later version.
15
* This library is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
* Lesser General Public License for more details.
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
24
#include "qemu/osdep.h"
26
#include "disas/disas.h"
27
#include "exec/exec-all.h"
29
#include "exec/cpu_ldst.h"
31
#include "exec/helper-proto.h"
32
#include "exec/helper-gen.h"
33
#include "sysemu/kvm.h"
34
#include "exec/semihost.h"
36
#include "trace-tcg.h"
39
#define MIPS_DEBUG_DISAS 0
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_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
71
OPC_BEQL = (0x14 << 26),
72
OPC_BNE = (0x05 << 26),
73
OPC_BNEL = (0x15 << 26),
74
OPC_BLEZ = (0x06 << 26),
75
OPC_BLEZL = (0x16 << 26),
76
OPC_BGTZ = (0x07 << 26),
77
OPC_BGTZL = (0x17 << 26),
78
OPC_JALX = (0x1D << 26),
79
OPC_DAUI = (0x1D << 26),
81
OPC_LDL = (0x1A << 26),
82
OPC_LDR = (0x1B << 26),
83
OPC_LB = (0x20 << 26),
84
OPC_LH = (0x21 << 26),
85
OPC_LWL = (0x22 << 26),
86
OPC_LW = (0x23 << 26),
87
OPC_LWPC = OPC_LW | 0x5,
88
OPC_LBU = (0x24 << 26),
89
OPC_LHU = (0x25 << 26),
90
OPC_LWR = (0x26 << 26),
91
OPC_LWU = (0x27 << 26),
92
OPC_SB = (0x28 << 26),
93
OPC_SH = (0x29 << 26),
94
OPC_SWL = (0x2A << 26),
95
OPC_SW = (0x2B << 26),
96
OPC_SDL = (0x2C << 26),
97
OPC_SDR = (0x2D << 26),
98
OPC_SWR = (0x2E << 26),
99
OPC_LL = (0x30 << 26),
100
OPC_LLD = (0x34 << 26),
101
OPC_LD = (0x37 << 26),
102
OPC_LDPC = OPC_LD | 0x5,
103
OPC_SC = (0x38 << 26),
104
OPC_SCD = (0x3C << 26),
105
OPC_SD = (0x3F << 26),
106
/* Floating point load/store */
107
OPC_LWC1 = (0x31 << 26),
108
OPC_LWC2 = (0x32 << 26),
109
OPC_LDC1 = (0x35 << 26),
110
OPC_LDC2 = (0x36 << 26),
111
OPC_SWC1 = (0x39 << 26),
112
OPC_SWC2 = (0x3A << 26),
113
OPC_SDC1 = (0x3D << 26),
114
OPC_SDC2 = (0x3E << 26),
115
/* Compact Branches */
116
OPC_BLEZALC = (0x06 << 26),
117
OPC_BGEZALC = (0x06 << 26),
118
OPC_BGEUC = (0x06 << 26),
119
OPC_BGTZALC = (0x07 << 26),
120
OPC_BLTZALC = (0x07 << 26),
121
OPC_BLTUC = (0x07 << 26),
122
OPC_BOVC = (0x08 << 26),
123
OPC_BEQZALC = (0x08 << 26),
124
OPC_BEQC = (0x08 << 26),
125
OPC_BLEZC = (0x16 << 26),
126
OPC_BGEZC = (0x16 << 26),
127
OPC_BGEC = (0x16 << 26),
128
OPC_BGTZC = (0x17 << 26),
129
OPC_BLTZC = (0x17 << 26),
130
OPC_BLTC = (0x17 << 26),
131
OPC_BNVC = (0x18 << 26),
132
OPC_BNEZALC = (0x18 << 26),
133
OPC_BNEC = (0x18 << 26),
134
OPC_BC = (0x32 << 26),
135
OPC_BEQZC = (0x36 << 26),
136
OPC_JIC = (0x36 << 26),
137
OPC_BALC = (0x3A << 26),
138
OPC_BNEZC = (0x3E << 26),
139
OPC_JIALC = (0x3E << 26),
140
/* MDMX ASE specific */
141
OPC_MDMX = (0x1E << 26),
142
/* MSA ASE, same as MDMX */
144
/* Cache and prefetch */
145
OPC_CACHE = (0x2F << 26),
146
OPC_PREF = (0x33 << 26),
147
/* PC-relative address computation / loads */
148
OPC_PCREL = (0x3B << 26),
151
/* PC-relative address computation / loads */
152
#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
153
#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
155
/* Instructions determined by bits 19 and 20 */
156
OPC_ADDIUPC = OPC_PCREL | (0 << 19),
157
R6_OPC_LWPC = OPC_PCREL | (1 << 19),
158
OPC_LWUPC = OPC_PCREL | (2 << 19),
160
/* Instructions determined by bits 16 ... 20 */
161
OPC_AUIPC = OPC_PCREL | (0x1e << 16),
162
OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
165
R6_OPC_LDPC = OPC_PCREL | (6 << 18),
168
/* MIPS special opcodes */
169
#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
173
OPC_SLL = 0x00 | OPC_SPECIAL,
174
/* NOP is SLL r0, r0, 0 */
175
/* SSNOP is SLL r0, r0, 1 */
176
/* EHB is SLL r0, r0, 3 */
177
OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
178
OPC_ROTR = OPC_SRL | (1 << 21),
179
OPC_SRA = 0x03 | OPC_SPECIAL,
180
OPC_SLLV = 0x04 | OPC_SPECIAL,
181
OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
182
OPC_ROTRV = OPC_SRLV | (1 << 6),
183
OPC_SRAV = 0x07 | OPC_SPECIAL,
184
OPC_DSLLV = 0x14 | OPC_SPECIAL,
185
OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
186
OPC_DROTRV = OPC_DSRLV | (1 << 6),
187
OPC_DSRAV = 0x17 | OPC_SPECIAL,
188
OPC_DSLL = 0x38 | OPC_SPECIAL,
189
OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
190
OPC_DROTR = OPC_DSRL | (1 << 21),
191
OPC_DSRA = 0x3B | OPC_SPECIAL,
192
OPC_DSLL32 = 0x3C | OPC_SPECIAL,
193
OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
194
OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
195
OPC_DSRA32 = 0x3F | OPC_SPECIAL,
196
/* Multiplication / division */
197
OPC_MULT = 0x18 | OPC_SPECIAL,
198
OPC_MULTU = 0x19 | OPC_SPECIAL,
199
OPC_DIV = 0x1A | OPC_SPECIAL,
200
OPC_DIVU = 0x1B | OPC_SPECIAL,
201
OPC_DMULT = 0x1C | OPC_SPECIAL,
202
OPC_DMULTU = 0x1D | OPC_SPECIAL,
203
OPC_DDIV = 0x1E | OPC_SPECIAL,
204
OPC_DDIVU = 0x1F | OPC_SPECIAL,
206
/* 2 registers arithmetic / logic */
207
OPC_ADD = 0x20 | OPC_SPECIAL,
208
OPC_ADDU = 0x21 | OPC_SPECIAL,
209
OPC_SUB = 0x22 | OPC_SPECIAL,
210
OPC_SUBU = 0x23 | OPC_SPECIAL,
211
OPC_AND = 0x24 | OPC_SPECIAL,
212
OPC_OR = 0x25 | OPC_SPECIAL,
213
OPC_XOR = 0x26 | OPC_SPECIAL,
214
OPC_NOR = 0x27 | OPC_SPECIAL,
215
OPC_SLT = 0x2A | OPC_SPECIAL,
216
OPC_SLTU = 0x2B | OPC_SPECIAL,
217
OPC_DADD = 0x2C | OPC_SPECIAL,
218
OPC_DADDU = 0x2D | OPC_SPECIAL,
219
OPC_DSUB = 0x2E | OPC_SPECIAL,
220
OPC_DSUBU = 0x2F | OPC_SPECIAL,
222
OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
223
OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
225
OPC_TGE = 0x30 | OPC_SPECIAL,
226
OPC_TGEU = 0x31 | OPC_SPECIAL,
227
OPC_TLT = 0x32 | OPC_SPECIAL,
228
OPC_TLTU = 0x33 | OPC_SPECIAL,
229
OPC_TEQ = 0x34 | OPC_SPECIAL,
230
OPC_TNE = 0x36 | OPC_SPECIAL,
231
/* HI / LO registers load & stores */
232
OPC_MFHI = 0x10 | OPC_SPECIAL,
233
OPC_MTHI = 0x11 | OPC_SPECIAL,
234
OPC_MFLO = 0x12 | OPC_SPECIAL,
235
OPC_MTLO = 0x13 | OPC_SPECIAL,
236
/* Conditional moves */
237
OPC_MOVZ = 0x0A | OPC_SPECIAL,
238
OPC_MOVN = 0x0B | OPC_SPECIAL,
240
OPC_SELEQZ = 0x35 | OPC_SPECIAL,
241
OPC_SELNEZ = 0x37 | OPC_SPECIAL,
243
OPC_MOVCI = 0x01 | OPC_SPECIAL,
246
OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
247
OPC_SYSCALL = 0x0C | OPC_SPECIAL,
248
OPC_BREAK = 0x0D | OPC_SPECIAL,
249
OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
250
OPC_SYNC = 0x0F | OPC_SPECIAL,
252
OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
253
OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
254
OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
255
OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
258
/* R6 Multiply and Divide instructions have the same Opcode
259
and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260
#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
263
R6_OPC_MUL = OPC_MULT | (2 << 6),
264
R6_OPC_MUH = OPC_MULT | (3 << 6),
265
R6_OPC_MULU = OPC_MULTU | (2 << 6),
266
R6_OPC_MUHU = OPC_MULTU | (3 << 6),
267
R6_OPC_DIV = OPC_DIV | (2 << 6),
268
R6_OPC_MOD = OPC_DIV | (3 << 6),
269
R6_OPC_DIVU = OPC_DIVU | (2 << 6),
270
R6_OPC_MODU = OPC_DIVU | (3 << 6),
272
R6_OPC_DMUL = OPC_DMULT | (2 << 6),
273
R6_OPC_DMUH = OPC_DMULT | (3 << 6),
274
R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
275
R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
276
R6_OPC_DDIV = OPC_DDIV | (2 << 6),
277
R6_OPC_DMOD = OPC_DDIV | (3 << 6),
278
R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
279
R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
281
R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
282
R6_OPC_CLO = 0x11 | OPC_SPECIAL,
283
R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
284
R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
285
R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
287
OPC_LSA = 0x05 | OPC_SPECIAL,
288
OPC_DLSA = 0x15 | OPC_SPECIAL,
291
/* Multiplication variants of the vr54xx. */
292
#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
295
OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
296
OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
297
OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
298
OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
299
OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
300
OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
301
OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
302
OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
303
OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
304
OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
305
OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
306
OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
307
OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
308
OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
311
/* REGIMM (rt field) opcodes */
312
#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
315
OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
316
OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
317
OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
318
OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
319
OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
320
OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
321
OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
322
OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
323
OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
324
OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
325
OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
326
OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
327
OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
328
OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
329
OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
330
OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
332
OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
333
OPC_DATI = (0x1e << 16) | OPC_REGIMM,
336
/* Special2 opcodes */
337
#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
340
/* Multiply & xxx operations */
341
OPC_MADD = 0x00 | OPC_SPECIAL2,
342
OPC_MADDU = 0x01 | OPC_SPECIAL2,
343
OPC_MUL = 0x02 | OPC_SPECIAL2,
344
OPC_MSUB = 0x04 | OPC_SPECIAL2,
345
OPC_MSUBU = 0x05 | OPC_SPECIAL2,
347
OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
348
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
349
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
350
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
351
OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
352
OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
353
OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
354
OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
355
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
356
OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
357
OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
358
OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
360
OPC_CLZ = 0x20 | OPC_SPECIAL2,
361
OPC_CLO = 0x21 | OPC_SPECIAL2,
362
OPC_DCLZ = 0x24 | OPC_SPECIAL2,
363
OPC_DCLO = 0x25 | OPC_SPECIAL2,
365
OPC_SDBBP = 0x3F | OPC_SPECIAL2,
368
/* Special3 opcodes */
369
#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
372
OPC_EXT = 0x00 | OPC_SPECIAL3,
373
OPC_DEXTM = 0x01 | OPC_SPECIAL3,
374
OPC_DEXTU = 0x02 | OPC_SPECIAL3,
375
OPC_DEXT = 0x03 | OPC_SPECIAL3,
376
OPC_INS = 0x04 | OPC_SPECIAL3,
377
OPC_DINSM = 0x05 | OPC_SPECIAL3,
378
OPC_DINSU = 0x06 | OPC_SPECIAL3,
379
OPC_DINS = 0x07 | OPC_SPECIAL3,
380
OPC_FORK = 0x08 | OPC_SPECIAL3,
381
OPC_YIELD = 0x09 | OPC_SPECIAL3,
382
OPC_BSHFL = 0x20 | OPC_SPECIAL3,
383
OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
384
OPC_RDHWR = 0x3B | OPC_SPECIAL3,
387
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
388
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
389
OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
390
OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
391
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
392
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
393
OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
394
OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
395
OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
396
OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
397
OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
398
OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
401
OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
402
/* MIPS DSP Arithmetic */
403
OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
404
OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
405
OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
406
OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
407
/* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
408
/* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
409
OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
410
OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
411
/* MIPS DSP GPR-Based Shift Sub-class */
412
OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
413
OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
414
/* MIPS DSP Multiply Sub-class insns */
415
/* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
416
/* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
417
OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
418
OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
419
/* DSP Bit/Manipulation Sub-class */
420
OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
421
OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
422
/* MIPS DSP Append Sub-class */
423
OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
424
OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
425
/* MIPS DSP Accumulator and DSPControl Access Sub-class */
426
OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
427
OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
430
R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
431
R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
432
R6_OPC_LL = 0x36 | OPC_SPECIAL3,
433
R6_OPC_SC = 0x26 | OPC_SPECIAL3,
434
R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
435
R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
439
#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
442
OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
443
OPC_SEB = (0x10 << 6) | OPC_BSHFL,
444
OPC_SEH = (0x18 << 6) | OPC_BSHFL,
445
OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
446
OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
447
OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
451
#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
454
OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
455
OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
456
OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
457
OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
458
OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
461
/* MIPS DSP REGIMM opcodes */
463
OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
464
OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
467
#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
470
OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
471
OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
472
OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
473
OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
476
#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
478
/* MIPS DSP Arithmetic Sub-class */
479
OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
480
OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
481
OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
482
OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
483
OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
484
OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
485
OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
486
OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
487
OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
488
OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
489
OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
490
OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
491
OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
492
OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
493
OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
494
OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
495
OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
496
OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
497
/* MIPS DSP Multiply Sub-class insns */
498
OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
499
OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
500
OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
501
OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
502
OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
503
OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
506
#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
507
#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509
/* MIPS DSP Arithmetic Sub-class */
510
OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
511
OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
512
OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
513
OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
514
OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
515
OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
516
OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
517
OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
518
OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
519
OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
520
OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
521
OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
522
/* MIPS DSP Multiply Sub-class insns */
523
OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
524
OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
525
OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
526
OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
529
#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531
/* MIPS DSP Arithmetic Sub-class */
532
OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
533
OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
534
OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
535
OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
536
OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
537
OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
538
OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
539
OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
540
OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
541
OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
542
OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
543
OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
544
OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
545
/* DSP Bit/Manipulation Sub-class */
546
OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
547
OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
548
OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
549
OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
550
OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
553
#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555
/* MIPS DSP Arithmetic Sub-class */
556
OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
557
OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
558
OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
559
OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
560
OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
561
OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
562
OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
563
/* DSP Compare-Pick Sub-class */
564
OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
565
OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
566
OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
567
OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
568
OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
569
OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
570
OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
571
OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
572
OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
573
OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
574
OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
575
OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
576
OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
577
OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
578
OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
581
#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583
/* MIPS DSP GPR-Based Shift Sub-class */
584
OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
585
OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
586
OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
587
OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
588
OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
589
OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
590
OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
591
OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
592
OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
593
OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
594
OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
595
OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
596
OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
597
OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
598
OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
599
OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
600
OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
601
OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
602
OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
603
OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
604
OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
605
OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
608
#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
610
/* MIPS DSP Multiply Sub-class insns */
611
OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
612
OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
613
OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
614
OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
615
OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
616
OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
617
OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
618
OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
619
OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
620
OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
621
OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
622
OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
623
OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
624
OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
625
OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
626
OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
627
OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
628
OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
629
OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
630
OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
631
OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
632
OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
635
#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637
/* DSP Bit/Manipulation Sub-class */
638
OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
641
#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
643
/* MIPS DSP Append Sub-class */
644
OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
645
OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
646
OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
649
#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
651
/* MIPS DSP Accumulator and DSPControl Access Sub-class */
652
OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
653
OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
654
OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
655
OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
656
OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
657
OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
658
OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
659
OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
660
OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
661
OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
662
OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
663
OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
664
OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
665
OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
666
OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
667
OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
668
OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
671
#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673
/* MIPS DSP Arithmetic Sub-class */
674
OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
675
OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
676
OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
677
OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
678
OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
679
OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
680
OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
681
OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
682
OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
683
OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
684
OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
685
OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
686
OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
687
OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
688
OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
689
OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
690
OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
691
/* DSP Bit/Manipulation Sub-class */
692
OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
693
OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
694
OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
695
OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
696
OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
697
OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
700
#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702
/* MIPS DSP Multiply Sub-class insns */
703
OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
704
OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
705
OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
706
OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
707
OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
708
/* MIPS DSP Arithmetic Sub-class */
709
OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
710
OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
711
OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
712
OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
713
OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
714
OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
715
OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
716
OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
717
OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
718
OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
719
OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
720
OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
721
OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
722
OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
723
OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
724
OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
725
OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
726
OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
727
OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
728
OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
729
OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
732
#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
734
/* DSP Compare-Pick Sub-class */
735
OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
736
OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
737
OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
738
OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
739
OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
740
OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
741
OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
742
OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
743
OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
744
OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
745
OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
746
OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
747
OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
748
OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
749
OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
750
OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
751
OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
752
OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
753
OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
754
/* MIPS DSP Arithmetic Sub-class */
755
OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
756
OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
757
OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
758
OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
759
OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
760
OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
761
OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
762
OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
765
#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
767
/* DSP Append Sub-class */
768
OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
769
OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
770
OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
771
OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
774
#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776
/* MIPS DSP Accumulator and DSPControl Access Sub-class */
777
OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
778
OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
779
OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
780
OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
781
OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
782
OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
783
OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
784
OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
785
OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
786
OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
787
OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
788
OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
789
OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
790
OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
791
OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
792
OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
793
OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
794
OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
795
OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
796
OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
797
OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
800
#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802
/* DSP Bit/Manipulation Sub-class */
803
OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
806
#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808
/* MIPS DSP Multiply Sub-class insns */
809
OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
810
OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
811
OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
812
OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
813
OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
814
OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
815
OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
816
OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
817
OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
818
OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
819
OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
820
OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
821
OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
822
OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
823
OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
824
OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
825
OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
826
OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
827
OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
828
OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
829
OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
830
OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
831
OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
832
OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
833
OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
834
OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
837
#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839
/* MIPS DSP GPR-Based Shift Sub-class */
840
OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
841
OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
842
OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
843
OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
844
OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
845
OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
846
OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
847
OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
848
OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
849
OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
850
OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
851
OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
852
OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
853
OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
854
OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
855
OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
856
OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
857
OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
858
OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
859
OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
860
OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
861
OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
862
OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
863
OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
864
OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
865
OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
868
/* Coprocessor 0 (rs field) */
869
#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
872
OPC_MFC0 = (0x00 << 21) | OPC_CP0,
873
OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
874
OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
875
OPC_MTC0 = (0x04 << 21) | OPC_CP0,
876
OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
877
OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
878
OPC_MFTR = (0x08 << 21) | OPC_CP0,
879
OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
880
OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
881
OPC_MTTR = (0x0C << 21) | OPC_CP0,
882
OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
883
OPC_C0 = (0x10 << 21) | OPC_CP0,
884
OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
885
OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
889
#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
892
OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893
OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
894
OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
895
OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
896
OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
897
OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
898
OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
899
OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
902
/* Coprocessor 0 (with rs == C0) */
903
#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
906
OPC_TLBR = 0x01 | OPC_C0,
907
OPC_TLBWI = 0x02 | OPC_C0,
908
OPC_TLBINV = 0x03 | OPC_C0,
909
OPC_TLBINVF = 0x04 | OPC_C0,
910
OPC_TLBWR = 0x06 | OPC_C0,
911
OPC_TLBP = 0x08 | OPC_C0,
912
OPC_RFE = 0x10 | OPC_C0,
913
OPC_ERET = 0x18 | OPC_C0,
914
OPC_DERET = 0x1F | OPC_C0,
915
OPC_WAIT = 0x20 | OPC_C0,
918
/* Coprocessor 1 (rs field) */
919
#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
921
/* Values for the fmt field in FP instructions */
923
/* 0 - 15 are reserved */
924
FMT_S = 16, /* single fp */
925
FMT_D = 17, /* double fp */
926
FMT_E = 18, /* extended fp */
927
FMT_Q = 19, /* quad fp */
928
FMT_W = 20, /* 32-bit fixed */
929
FMT_L = 21, /* 64-bit fixed */
930
FMT_PS = 22, /* paired single fp */
931
/* 23 - 31 are reserved */
935
OPC_MFC1 = (0x00 << 21) | OPC_CP1,
936
OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
937
OPC_CFC1 = (0x02 << 21) | OPC_CP1,
938
OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
939
OPC_MTC1 = (0x04 << 21) | OPC_CP1,
940
OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
941
OPC_CTC1 = (0x06 << 21) | OPC_CP1,
942
OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
943
OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
944
OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
945
OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
946
OPC_BZ_V = (0x0B << 21) | OPC_CP1,
947
OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
948
OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
949
OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
950
OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
951
OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
952
OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
953
OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
954
OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
955
OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
956
OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
957
OPC_BZ_B = (0x18 << 21) | OPC_CP1,
958
OPC_BZ_H = (0x19 << 21) | OPC_CP1,
959
OPC_BZ_W = (0x1A << 21) | OPC_CP1,
960
OPC_BZ_D = (0x1B << 21) | OPC_CP1,
961
OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
962
OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
963
OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
964
OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
967
#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
968
#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
971
OPC_BC1F = (0x00 << 16) | OPC_BC1,
972
OPC_BC1T = (0x01 << 16) | OPC_BC1,
973
OPC_BC1FL = (0x02 << 16) | OPC_BC1,
974
OPC_BC1TL = (0x03 << 16) | OPC_BC1,
978
OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
979
OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
983
OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
984
OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
987
#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
990
OPC_MFC2 = (0x00 << 21) | OPC_CP2,
991
OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
992
OPC_CFC2 = (0x02 << 21) | OPC_CP2,
993
OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
994
OPC_MTC2 = (0x04 << 21) | OPC_CP2,
995
OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
996
OPC_CTC2 = (0x06 << 21) | OPC_CP2,
997
OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
998
OPC_BC2 = (0x08 << 21) | OPC_CP2,
999
OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1000
OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1003
#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1006
OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1007
OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1008
OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1009
OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1010
OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1011
OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1012
OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1013
OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1015
OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1016
OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1017
OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1018
OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1019
OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1020
OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1021
OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1022
OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1024
OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1025
OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1026
OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1027
OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1028
OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1029
OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1030
OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1031
OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1033
OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1034
OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1035
OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1036
OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1037
OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1038
OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1039
OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1040
OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1042
OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1043
OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1044
OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1045
OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1046
OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1047
OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1049
OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1050
OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1051
OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1052
OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1053
OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1054
OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1056
OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1057
OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1058
OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1059
OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1060
OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1061
OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1063
OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1064
OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1065
OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1066
OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1067
OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1068
OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1070
OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1071
OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1072
OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1073
OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1074
OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1075
OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1077
OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1078
OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1079
OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1080
OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1081
OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1082
OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1084
OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1085
OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1086
OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1087
OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1088
OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1089
OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1091
OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1092
OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1093
OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1094
OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1095
OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1096
OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1100
#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1103
OPC_LWXC1 = 0x00 | OPC_CP3,
1104
OPC_LDXC1 = 0x01 | OPC_CP3,
1105
OPC_LUXC1 = 0x05 | OPC_CP3,
1106
OPC_SWXC1 = 0x08 | OPC_CP3,
1107
OPC_SDXC1 = 0x09 | OPC_CP3,
1108
OPC_SUXC1 = 0x0D | OPC_CP3,
1109
OPC_PREFX = 0x0F | OPC_CP3,
1110
OPC_ALNV_PS = 0x1E | OPC_CP3,
1111
OPC_MADD_S = 0x20 | OPC_CP3,
1112
OPC_MADD_D = 0x21 | OPC_CP3,
1113
OPC_MADD_PS = 0x26 | OPC_CP3,
1114
OPC_MSUB_S = 0x28 | OPC_CP3,
1115
OPC_MSUB_D = 0x29 | OPC_CP3,
1116
OPC_MSUB_PS = 0x2E | OPC_CP3,
1117
OPC_NMADD_S = 0x30 | OPC_CP3,
1118
OPC_NMADD_D = 0x31 | OPC_CP3,
1119
OPC_NMADD_PS= 0x36 | OPC_CP3,
1120
OPC_NMSUB_S = 0x38 | OPC_CP3,
1121
OPC_NMSUB_D = 0x39 | OPC_CP3,
1122
OPC_NMSUB_PS= 0x3E | OPC_CP3,
1126
#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1128
OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1129
OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1130
OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1131
OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1132
OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1133
OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1134
OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1135
OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1136
OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1137
OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1138
OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1139
OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1140
OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1141
OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1142
OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1143
OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1144
OPC_MSA_ELM = 0x19 | OPC_MSA,
1145
OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1146
OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1147
OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1148
OPC_MSA_VEC = 0x1E | OPC_MSA,
1150
/* MI10 instruction */
1151
OPC_LD_B = (0x20) | OPC_MSA,
1152
OPC_LD_H = (0x21) | OPC_MSA,
1153
OPC_LD_W = (0x22) | OPC_MSA,
1154
OPC_LD_D = (0x23) | OPC_MSA,
1155
OPC_ST_B = (0x24) | OPC_MSA,
1156
OPC_ST_H = (0x25) | OPC_MSA,
1157
OPC_ST_W = (0x26) | OPC_MSA,
1158
OPC_ST_D = (0x27) | OPC_MSA,
1162
/* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1163
OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1164
OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1165
OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1166
OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1167
OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1168
OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1169
OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1170
OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1171
OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1172
OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1173
OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1174
OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1176
/* I8 instruction */
1177
OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1178
OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1179
OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1180
OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1181
OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1182
OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1183
OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1184
OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1185
OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1186
OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1188
/* VEC/2R/2RF instruction */
1189
OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1190
OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1191
OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1192
OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1193
OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1194
OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1195
OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1197
OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1198
OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1200
/* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1201
OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1202
OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1203
OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1204
OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1206
/* 2RF instruction df(bit 16) = _w, _d */
1207
OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1208
OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1209
OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1210
OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1211
OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1212
OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1213
OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1214
OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1215
OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1216
OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1217
OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1218
OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1219
OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1220
OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1221
OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1222
OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1224
/* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1225
OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1226
OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1227
OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1228
OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1229
OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1230
OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1231
OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1232
OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1233
OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1234
OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1235
OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1236
OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1237
OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1238
OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1239
OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1240
OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1241
OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1242
OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1243
OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1244
OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1245
OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1246
OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1247
OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1248
OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1249
OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1250
OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1251
OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1252
OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1253
OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1254
OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1255
OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1256
OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1257
OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1258
OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1259
OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1260
OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1261
OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1262
OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1263
OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1264
OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1265
OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1266
OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1267
OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1268
OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1269
OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1270
OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1271
OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1272
OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1273
OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1274
OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1275
OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1276
OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1277
OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1278
OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1279
OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1280
OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1281
OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1282
OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1283
OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1284
OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1285
OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1286
OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1287
OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1289
/* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1290
OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291
OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1292
OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293
OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1294
OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1295
OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1296
OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297
OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298
OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1300
/* 3RF instruction _df(bit 21) = _w, _d */
1301
OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1302
OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1303
OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1304
OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1305
OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1306
OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1307
OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1308
OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1309
OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1310
OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1311
OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1312
OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1313
OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1314
OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1315
OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1316
OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1317
OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1318
OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1319
OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1320
OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1321
OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1322
OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1323
OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1324
OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1325
OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1326
OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1327
OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1328
OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1329
OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1330
OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1331
OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1332
OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1333
OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1334
OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1335
OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1336
OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1337
OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1338
OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1339
OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1340
OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1341
OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1343
/* BIT instruction df(bits 22..16) = _B _H _W _D */
1344
OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1345
OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1346
OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1347
OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1348
OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1349
OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1350
OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1351
OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1352
OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1353
OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1354
OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1355
OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1358
/* global register indices */
1359
static TCGv_env cpu_env;
1360
static TCGv cpu_gpr[32], cpu_PC;
1361
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1362
static TCGv cpu_dspctrl, btarget, bcond;
1363
static TCGv_i32 hflags;
1364
static TCGv_i32 fpu_fcr0, fpu_fcr31;
1365
static TCGv_i64 fpu_f64[32];
1366
static TCGv_i64 msa_wr_d[64];
1368
#include "exec/gen-icount.h"
1370
#define gen_helper_0e0i(name, arg) do { \
1371
TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1372
gen_helper_##name(cpu_env, helper_tmp); \
1373
tcg_temp_free_i32(helper_tmp); \
1376
#define gen_helper_0e1i(name, arg1, arg2) do { \
1377
TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1378
gen_helper_##name(cpu_env, arg1, helper_tmp); \
1379
tcg_temp_free_i32(helper_tmp); \
1382
#define gen_helper_1e0i(name, ret, arg1) do { \
1383
TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1384
gen_helper_##name(ret, cpu_env, helper_tmp); \
1385
tcg_temp_free_i32(helper_tmp); \
1388
#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1389
TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1390
gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1391
tcg_temp_free_i32(helper_tmp); \
1394
#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1395
TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1396
gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1397
tcg_temp_free_i32(helper_tmp); \
1400
#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1401
TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1402
gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1403
tcg_temp_free_i32(helper_tmp); \
1406
#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1407
TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1408
gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1409
tcg_temp_free_i32(helper_tmp); \
1412
typedef struct DisasContext {
1413
struct TranslationBlock *tb;
1414
target_ulong pc, saved_pc;
1416
int singlestep_enabled;
1418
int32_t CP0_Config1;
1419
/* Routine used to access memory */
1421
TCGMemOp default_tcg_memop_mask;
1422
uint32_t hflags, saved_hflags;
1424
target_ulong btarget;
1433
int CP0_LLAddr_shift;
1443
BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1444
* exception condition */
1445
BS_STOP = 1, /* We want to stop translation for any reason */
1446
BS_BRANCH = 2, /* We reached a branch condition */
1447
BS_EXCP = 3, /* We reached an exception condition */
1450
static const char * const regnames[] = {
1451
"r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1452
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1453
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1454
"t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1457
static const char * const regnames_HI[] = {
1458
"HI0", "HI1", "HI2", "HI3",
1461
static const char * const regnames_LO[] = {
1462
"LO0", "LO1", "LO2", "LO3",
1465
static const char * const fregnames[] = {
1466
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1467
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1468
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1469
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1472
static const char * const msaregnames[] = {
1473
"w0.d0", "w0.d1", "w1.d0", "w1.d1",
1474
"w2.d0", "w2.d1", "w3.d0", "w3.d1",
1475
"w4.d0", "w4.d1", "w5.d0", "w5.d1",
1476
"w6.d0", "w6.d1", "w7.d0", "w7.d1",
1477
"w8.d0", "w8.d1", "w9.d0", "w9.d1",
1478
"w10.d0", "w10.d1", "w11.d0", "w11.d1",
1479
"w12.d0", "w12.d1", "w13.d0", "w13.d1",
1480
"w14.d0", "w14.d1", "w15.d0", "w15.d1",
1481
"w16.d0", "w16.d1", "w17.d0", "w17.d1",
1482
"w18.d0", "w18.d1", "w19.d0", "w19.d1",
1483
"w20.d0", "w20.d1", "w21.d0", "w21.d1",
1484
"w22.d0", "w22.d1", "w23.d0", "w23.d1",
1485
"w24.d0", "w24.d1", "w25.d0", "w25.d1",
1486
"w26.d0", "w26.d1", "w27.d0", "w27.d1",
1487
"w28.d0", "w28.d1", "w29.d0", "w29.d1",
1488
"w30.d0", "w30.d1", "w31.d0", "w31.d1",
1491
#define LOG_DISAS(...) \
1493
if (MIPS_DEBUG_DISAS) { \
1494
qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1498
#define MIPS_INVAL(op) \
1500
if (MIPS_DEBUG_DISAS) { \
1501
qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1502
TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1503
ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1504
ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1508
/* General purpose registers moves. */
1509
static inline void gen_load_gpr (TCGv t, int reg)
1512
tcg_gen_movi_tl(t, 0);
1514
tcg_gen_mov_tl(t, cpu_gpr[reg]);
1517
static inline void gen_store_gpr (TCGv t, int reg)
1520
tcg_gen_mov_tl(cpu_gpr[reg], t);
1523
/* Moves to/from shadow registers. */
1524
static inline void gen_load_srsgpr (int from, int to)
1526
TCGv t0 = tcg_temp_new();
1529
tcg_gen_movi_tl(t0, 0);
1531
TCGv_i32 t2 = tcg_temp_new_i32();
1532
TCGv_ptr addr = tcg_temp_new_ptr();
1534
tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1535
tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1536
tcg_gen_andi_i32(t2, t2, 0xf);
1537
tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1538
tcg_gen_ext_i32_ptr(addr, t2);
1539
tcg_gen_add_ptr(addr, cpu_env, addr);
1541
tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1542
tcg_temp_free_ptr(addr);
1543
tcg_temp_free_i32(t2);
1545
gen_store_gpr(t0, to);
1549
static inline void gen_store_srsgpr (int from, int to)
1552
TCGv t0 = tcg_temp_new();
1553
TCGv_i32 t2 = tcg_temp_new_i32();
1554
TCGv_ptr addr = tcg_temp_new_ptr();
1556
gen_load_gpr(t0, from);
1557
tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1558
tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1559
tcg_gen_andi_i32(t2, t2, 0xf);
1560
tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1561
tcg_gen_ext_i32_ptr(addr, t2);
1562
tcg_gen_add_ptr(addr, cpu_env, addr);
1564
tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1565
tcg_temp_free_ptr(addr);
1566
tcg_temp_free_i32(t2);
1572
static inline void gen_save_pc(target_ulong pc)
1574
tcg_gen_movi_tl(cpu_PC, pc);
1577
static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1579
LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1580
if (do_save_pc && ctx->pc != ctx->saved_pc) {
1581
gen_save_pc(ctx->pc);
1582
ctx->saved_pc = ctx->pc;
1584
if (ctx->hflags != ctx->saved_hflags) {
1585
tcg_gen_movi_i32(hflags, ctx->hflags);
1586
ctx->saved_hflags = ctx->hflags;
1587
switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1593
tcg_gen_movi_tl(btarget, ctx->btarget);
1599
static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1601
ctx->saved_hflags = ctx->hflags;
1602
switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1608
ctx->btarget = env->btarget;
1613
static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1615
TCGv_i32 texcp = tcg_const_i32(excp);
1616
TCGv_i32 terr = tcg_const_i32(err);
1617
save_cpu_state(ctx, 1);
1618
gen_helper_raise_exception_err(cpu_env, texcp, terr);
1619
tcg_temp_free_i32(terr);
1620
tcg_temp_free_i32(texcp);
1621
ctx->bstate = BS_EXCP;
1624
static inline void generate_exception(DisasContext *ctx, int excp)
1626
gen_helper_0e0i(raise_exception, excp);
1629
static inline void generate_exception_end(DisasContext *ctx, int excp)
1631
generate_exception_err(ctx, excp, 0);
1634
/* Floating point register moves. */
1635
static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1637
if (ctx->hflags & MIPS_HFLAG_FRE) {
1638
generate_exception(ctx, EXCP_RI);
1640
tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1643
static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1646
if (ctx->hflags & MIPS_HFLAG_FRE) {
1647
generate_exception(ctx, EXCP_RI);
1649
t64 = tcg_temp_new_i64();
1650
tcg_gen_extu_i32_i64(t64, t);
1651
tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1652
tcg_temp_free_i64(t64);
1655
static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1657
if (ctx->hflags & MIPS_HFLAG_F64) {
1658
tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1660
gen_load_fpr32(ctx, t, reg | 1);
1664
static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1666
if (ctx->hflags & MIPS_HFLAG_F64) {
1667
TCGv_i64 t64 = tcg_temp_new_i64();
1668
tcg_gen_extu_i32_i64(t64, t);
1669
tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1670
tcg_temp_free_i64(t64);
1672
gen_store_fpr32(ctx, t, reg | 1);
1676
static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1678
if (ctx->hflags & MIPS_HFLAG_F64) {
1679
tcg_gen_mov_i64(t, fpu_f64[reg]);
1681
tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1685
static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1687
if (ctx->hflags & MIPS_HFLAG_F64) {
1688
tcg_gen_mov_i64(fpu_f64[reg], t);
1691
tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1692
t0 = tcg_temp_new_i64();
1693
tcg_gen_shri_i64(t0, t, 32);
1694
tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1695
tcg_temp_free_i64(t0);
1699
static inline int get_fp_bit (int cc)
1707
/* Addresses computation */
1708
static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1710
tcg_gen_add_tl(ret, arg0, arg1);
1712
#if defined(TARGET_MIPS64)
1713
if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1714
tcg_gen_ext32s_i64(ret, ret);
1719
/* Addresses computation (translation time) */
1720
static target_long addr_add(DisasContext *ctx, target_long base,
1723
target_long sum = base + offset;
1725
#if defined(TARGET_MIPS64)
1726
if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1733
/* Sign-extract the low 32-bits to a target_long. */
1734
static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1736
#if defined(TARGET_MIPS64)
1737
tcg_gen_ext32s_i64(ret, arg);
1739
tcg_gen_extrl_i64_i32(ret, arg);
1743
/* Sign-extract the high 32-bits to a target_long. */
1744
static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1746
#if defined(TARGET_MIPS64)
1747
tcg_gen_sari_i64(ret, arg, 32);
1749
tcg_gen_extrh_i64_i32(ret, arg);
1753
static inline void check_cp0_enabled(DisasContext *ctx)
1755
if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1756
generate_exception_err(ctx, EXCP_CpU, 0);
1759
static inline void check_cp1_enabled(DisasContext *ctx)
1761
if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1762
generate_exception_err(ctx, EXCP_CpU, 1);
1765
/* Verify that the processor is running with COP1X instructions enabled.
1766
This is associated with the nabla symbol in the MIPS32 and MIPS64
1769
static inline void check_cop1x(DisasContext *ctx)
1771
if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1772
generate_exception_end(ctx, EXCP_RI);
1775
/* Verify that the processor is running with 64-bit floating-point
1776
operations enabled. */
1778
static inline void check_cp1_64bitmode(DisasContext *ctx)
1780
if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1781
generate_exception_end(ctx, EXCP_RI);
1785
* Verify if floating point register is valid; an operation is not defined
1786
* if bit 0 of any register specification is set and the FR bit in the
1787
* Status register equals zero, since the register numbers specify an
1788
* even-odd pair of adjacent coprocessor general registers. When the FR bit
1789
* in the Status register equals one, both even and odd register numbers
1790
* are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1792
* Multiple 64 bit wide registers can be checked by calling
1793
* gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1795
static inline void check_cp1_registers(DisasContext *ctx, int regs)
1797
if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1798
generate_exception_end(ctx, EXCP_RI);
1801
/* Verify that the processor is running with DSP instructions enabled.
1802
This is enabled by CP0 Status register MX(24) bit.
1805
static inline void check_dsp(DisasContext *ctx)
1807
if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1808
if (ctx->insn_flags & ASE_DSP) {
1809
generate_exception_end(ctx, EXCP_DSPDIS);
1811
generate_exception_end(ctx, EXCP_RI);
1816
static inline void check_dspr2(DisasContext *ctx)
1818
if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1819
if (ctx->insn_flags & ASE_DSP) {
1820
generate_exception_end(ctx, EXCP_DSPDIS);
1822
generate_exception_end(ctx, EXCP_RI);
1827
/* This code generates a "reserved instruction" exception if the
1828
CPU does not support the instruction set corresponding to flags. */
1829
static inline void check_insn(DisasContext *ctx, int flags)
1831
if (unlikely(!(ctx->insn_flags & flags))) {
1832
generate_exception_end(ctx, EXCP_RI);
1836
/* This code generates a "reserved instruction" exception if the
1837
CPU has corresponding flag set which indicates that the instruction
1838
has been removed. */
1839
static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1841
if (unlikely(ctx->insn_flags & flags)) {
1842
generate_exception_end(ctx, EXCP_RI);
1846
/* This code generates a "reserved instruction" exception if the
1847
CPU does not support 64-bit paired-single (PS) floating point data type */
1848
static inline void check_ps(DisasContext *ctx)
1850
if (unlikely(!ctx->ps)) {
1851
generate_exception(ctx, EXCP_RI);
1853
check_cp1_64bitmode(ctx);
1856
#ifdef TARGET_MIPS64
1857
/* This code generates a "reserved instruction" exception if 64-bit
1858
instructions are not enabled. */
1859
static inline void check_mips_64(DisasContext *ctx)
1861
if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1862
generate_exception_end(ctx, EXCP_RI);
1866
#ifndef CONFIG_USER_ONLY
1867
static inline void check_mvh(DisasContext *ctx)
1869
if (unlikely(!ctx->mvh)) {
1870
generate_exception(ctx, EXCP_RI);
1875
/* Define small wrappers for gen_load_fpr* so that we have a uniform
1876
calling interface for 32 and 64-bit FPRs. No sense in changing
1877
all callers for gen_load_fpr32 when we need the CTX parameter for
1879
#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1880
#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1881
#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1882
static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1883
int ft, int fs, int cc) \
1885
TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1886
TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1895
check_cp1_registers(ctx, fs | ft); \
1903
gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1904
gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1906
case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1907
case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1908
case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1909
case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1910
case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1911
case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1912
case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1913
case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1914
case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1915
case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1916
case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1917
case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1918
case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1919
case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1920
case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1921
case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1924
tcg_temp_free_i##bits (fp0); \
1925
tcg_temp_free_i##bits (fp1); \
1928
FOP_CONDS(, 0, d, FMT_D, 64)
1929
FOP_CONDS(abs, 1, d, FMT_D, 64)
1930
FOP_CONDS(, 0, s, FMT_S, 32)
1931
FOP_CONDS(abs, 1, s, FMT_S, 32)
1932
FOP_CONDS(, 0, ps, FMT_PS, 64)
1933
FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1936
#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1937
static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1938
int ft, int fs, int fd) \
1940
TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1941
TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1942
if (ifmt == FMT_D) { \
1943
check_cp1_registers(ctx, fs | ft | fd); \
1945
gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1946
gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1949
gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1952
gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1955
gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1958
gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1961
gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1964
gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1967
gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1970
gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1973
gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1976
gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1979
gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1982
gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1985
gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1988
gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1991
gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1994
gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1997
gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2000
gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2003
gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2006
gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2009
gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2012
gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2018
tcg_temp_free_i ## bits (fp0); \
2019
tcg_temp_free_i ## bits (fp1); \
2022
FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2023
FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2025
#undef gen_ldcmp_fpr32
2026
#undef gen_ldcmp_fpr64
2028
/* load/store instructions. */
2029
#ifdef CONFIG_USER_ONLY
2030
#define OP_LD_ATOMIC(insn,fname) \
2031
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2033
TCGv t0 = tcg_temp_new(); \
2034
tcg_gen_mov_tl(t0, arg1); \
2035
tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2036
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2037
tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2038
tcg_temp_free(t0); \
2041
#define OP_LD_ATOMIC(insn,fname) \
2042
static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2044
gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2047
OP_LD_ATOMIC(ll,ld32s);
2048
#if defined(TARGET_MIPS64)
2049
OP_LD_ATOMIC(lld,ld64);
2053
#ifdef CONFIG_USER_ONLY
2054
#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2055
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2057
TCGv t0 = tcg_temp_new(); \
2058
TCGLabel *l1 = gen_new_label(); \
2059
TCGLabel *l2 = gen_new_label(); \
2061
tcg_gen_andi_tl(t0, arg2, almask); \
2062
tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2063
tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2064
generate_exception(ctx, EXCP_AdES); \
2065
gen_set_label(l1); \
2066
tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2067
tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2068
tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2069
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2070
tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2071
generate_exception_end(ctx, EXCP_SC); \
2072
gen_set_label(l2); \
2073
tcg_gen_movi_tl(t0, 0); \
2074
gen_store_gpr(t0, rt); \
2075
tcg_temp_free(t0); \
2078
#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2079
static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2081
TCGv t0 = tcg_temp_new(); \
2082
gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2083
gen_store_gpr(t0, rt); \
2084
tcg_temp_free(t0); \
2087
OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2088
#if defined(TARGET_MIPS64)
2089
OP_ST_ATOMIC(scd,st64,ld64,0x7);
2093
static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2094
int base, int16_t offset)
2097
tcg_gen_movi_tl(addr, offset);
2098
} else if (offset == 0) {
2099
gen_load_gpr(addr, base);
2101
tcg_gen_movi_tl(addr, offset);
2102
gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2106
static target_ulong pc_relative_pc (DisasContext *ctx)
2108
target_ulong pc = ctx->pc;
2110
if (ctx->hflags & MIPS_HFLAG_BMASK) {
2111
int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2116
pc &= ~(target_ulong)3;
2121
static void gen_ld(DisasContext *ctx, uint32_t opc,
2122
int rt, int base, int16_t offset)
2126
if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2127
/* Loongson CPU uses a load to zero register for prefetch.
2128
We emulate it as a NOP. On other CPU we must perform the
2129
actual memory access. */
2133
t0 = tcg_temp_new();
2134
gen_base_offset_addr(ctx, t0, base, offset);
2137
#if defined(TARGET_MIPS64)
2139
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2140
ctx->default_tcg_memop_mask);
2141
gen_store_gpr(t0, rt);
2144
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2145
ctx->default_tcg_memop_mask);
2146
gen_store_gpr(t0, rt);
2150
op_ld_lld(t0, t0, ctx);
2151
gen_store_gpr(t0, rt);
2154
t1 = tcg_temp_new();
2155
/* Do a byte access to possibly trigger a page
2156
fault with the unaligned address. */
2157
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2158
tcg_gen_andi_tl(t1, t0, 7);
2159
#ifndef TARGET_WORDS_BIGENDIAN
2160
tcg_gen_xori_tl(t1, t1, 7);
2162
tcg_gen_shli_tl(t1, t1, 3);
2163
tcg_gen_andi_tl(t0, t0, ~7);
2164
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2165
tcg_gen_shl_tl(t0, t0, t1);
2166
t2 = tcg_const_tl(-1);
2167
tcg_gen_shl_tl(t2, t2, t1);
2168
gen_load_gpr(t1, rt);
2169
tcg_gen_andc_tl(t1, t1, t2);
2171
tcg_gen_or_tl(t0, t0, t1);
2173
gen_store_gpr(t0, rt);
2176
t1 = tcg_temp_new();
2177
/* Do a byte access to possibly trigger a page
2178
fault with the unaligned address. */
2179
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2180
tcg_gen_andi_tl(t1, t0, 7);
2181
#ifdef TARGET_WORDS_BIGENDIAN
2182
tcg_gen_xori_tl(t1, t1, 7);
2184
tcg_gen_shli_tl(t1, t1, 3);
2185
tcg_gen_andi_tl(t0, t0, ~7);
2186
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2187
tcg_gen_shr_tl(t0, t0, t1);
2188
tcg_gen_xori_tl(t1, t1, 63);
2189
t2 = tcg_const_tl(0xfffffffffffffffeull);
2190
tcg_gen_shl_tl(t2, t2, t1);
2191
gen_load_gpr(t1, rt);
2192
tcg_gen_and_tl(t1, t1, t2);
2194
tcg_gen_or_tl(t0, t0, t1);
2196
gen_store_gpr(t0, rt);
2199
t1 = tcg_const_tl(pc_relative_pc(ctx));
2200
gen_op_addr_add(ctx, t0, t0, t1);
2202
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2203
gen_store_gpr(t0, rt);
2207
t1 = tcg_const_tl(pc_relative_pc(ctx));
2208
gen_op_addr_add(ctx, t0, t0, t1);
2210
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2211
gen_store_gpr(t0, rt);
2214
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2215
ctx->default_tcg_memop_mask);
2216
gen_store_gpr(t0, rt);
2219
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2220
ctx->default_tcg_memop_mask);
2221
gen_store_gpr(t0, rt);
2224
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2225
ctx->default_tcg_memop_mask);
2226
gen_store_gpr(t0, rt);
2229
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2230
gen_store_gpr(t0, rt);
2233
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2234
gen_store_gpr(t0, rt);
2237
t1 = tcg_temp_new();
2238
/* Do a byte access to possibly trigger a page
2239
fault with the unaligned address. */
2240
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2241
tcg_gen_andi_tl(t1, t0, 3);
2242
#ifndef TARGET_WORDS_BIGENDIAN
2243
tcg_gen_xori_tl(t1, t1, 3);
2245
tcg_gen_shli_tl(t1, t1, 3);
2246
tcg_gen_andi_tl(t0, t0, ~3);
2247
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2248
tcg_gen_shl_tl(t0, t0, t1);
2249
t2 = tcg_const_tl(-1);
2250
tcg_gen_shl_tl(t2, t2, t1);
2251
gen_load_gpr(t1, rt);
2252
tcg_gen_andc_tl(t1, t1, t2);
2254
tcg_gen_or_tl(t0, t0, t1);
2256
tcg_gen_ext32s_tl(t0, t0);
2257
gen_store_gpr(t0, rt);
2260
t1 = tcg_temp_new();
2261
/* Do a byte access to possibly trigger a page
2262
fault with the unaligned address. */
2263
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2264
tcg_gen_andi_tl(t1, t0, 3);
2265
#ifdef TARGET_WORDS_BIGENDIAN
2266
tcg_gen_xori_tl(t1, t1, 3);
2268
tcg_gen_shli_tl(t1, t1, 3);
2269
tcg_gen_andi_tl(t0, t0, ~3);
2270
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2271
tcg_gen_shr_tl(t0, t0, t1);
2272
tcg_gen_xori_tl(t1, t1, 31);
2273
t2 = tcg_const_tl(0xfffffffeull);
2274
tcg_gen_shl_tl(t2, t2, t1);
2275
gen_load_gpr(t1, rt);
2276
tcg_gen_and_tl(t1, t1, t2);
2278
tcg_gen_or_tl(t0, t0, t1);
2280
tcg_gen_ext32s_tl(t0, t0);
2281
gen_store_gpr(t0, rt);
2285
op_ld_ll(t0, t0, ctx);
2286
gen_store_gpr(t0, rt);
2293
static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2294
int base, int16_t offset)
2296
TCGv t0 = tcg_temp_new();
2297
TCGv t1 = tcg_temp_new();
2299
gen_base_offset_addr(ctx, t0, base, offset);
2300
gen_load_gpr(t1, rt);
2302
#if defined(TARGET_MIPS64)
2304
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2305
ctx->default_tcg_memop_mask);
2308
gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2311
gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2315
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2316
ctx->default_tcg_memop_mask);
2319
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2320
ctx->default_tcg_memop_mask);
2323
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2326
gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2329
gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2337
/* Store conditional */
2338
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2339
int base, int16_t offset)
2343
#ifdef CONFIG_USER_ONLY
2344
t0 = tcg_temp_local_new();
2345
t1 = tcg_temp_local_new();
2347
t0 = tcg_temp_new();
2348
t1 = tcg_temp_new();
2350
gen_base_offset_addr(ctx, t0, base, offset);
2351
gen_load_gpr(t1, rt);
2353
#if defined(TARGET_MIPS64)
2356
op_st_scd(t1, t0, rt, ctx);
2361
op_st_sc(t1, t0, rt, ctx);
2368
/* Load and store */
2369
static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2370
int base, int16_t offset)
2372
TCGv t0 = tcg_temp_new();
2374
gen_base_offset_addr(ctx, t0, base, offset);
2375
/* Don't do NOP if destination is zero: we must perform the actual
2380
TCGv_i32 fp0 = tcg_temp_new_i32();
2381
tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2382
ctx->default_tcg_memop_mask);
2383
gen_store_fpr32(ctx, fp0, ft);
2384
tcg_temp_free_i32(fp0);
2389
TCGv_i32 fp0 = tcg_temp_new_i32();
2390
gen_load_fpr32(ctx, fp0, ft);
2391
tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2392
ctx->default_tcg_memop_mask);
2393
tcg_temp_free_i32(fp0);
2398
TCGv_i64 fp0 = tcg_temp_new_i64();
2399
tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2400
ctx->default_tcg_memop_mask);
2401
gen_store_fpr64(ctx, fp0, ft);
2402
tcg_temp_free_i64(fp0);
2407
TCGv_i64 fp0 = tcg_temp_new_i64();
2408
gen_load_fpr64(ctx, fp0, ft);
2409
tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2410
ctx->default_tcg_memop_mask);
2411
tcg_temp_free_i64(fp0);
2415
MIPS_INVAL("flt_ldst");
2416
generate_exception_end(ctx, EXCP_RI);
2423
static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2424
int rs, int16_t imm)
2426
if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2427
check_cp1_enabled(ctx);
2431
check_insn(ctx, ISA_MIPS2);
2434
gen_flt_ldst(ctx, op, rt, rs, imm);
2437
generate_exception_err(ctx, EXCP_CpU, 1);
2441
/* Arithmetic with immediate operand */
2442
static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2443
int rt, int rs, int16_t imm)
2445
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2447
if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2448
/* If no destination, treat it as a NOP.
2449
For addi, we must generate the overflow exception when needed. */
2455
TCGv t0 = tcg_temp_local_new();
2456
TCGv t1 = tcg_temp_new();
2457
TCGv t2 = tcg_temp_new();
2458
TCGLabel *l1 = gen_new_label();
2460
gen_load_gpr(t1, rs);
2461
tcg_gen_addi_tl(t0, t1, uimm);
2462
tcg_gen_ext32s_tl(t0, t0);
2464
tcg_gen_xori_tl(t1, t1, ~uimm);
2465
tcg_gen_xori_tl(t2, t0, uimm);
2466
tcg_gen_and_tl(t1, t1, t2);
2468
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2470
/* operands of same sign, result different sign */
2471
generate_exception(ctx, EXCP_OVERFLOW);
2473
tcg_gen_ext32s_tl(t0, t0);
2474
gen_store_gpr(t0, rt);
2480
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2481
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2483
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2486
#if defined(TARGET_MIPS64)
2489
TCGv t0 = tcg_temp_local_new();
2490
TCGv t1 = tcg_temp_new();
2491
TCGv t2 = tcg_temp_new();
2492
TCGLabel *l1 = gen_new_label();
2494
gen_load_gpr(t1, rs);
2495
tcg_gen_addi_tl(t0, t1, uimm);
2497
tcg_gen_xori_tl(t1, t1, ~uimm);
2498
tcg_gen_xori_tl(t2, t0, uimm);
2499
tcg_gen_and_tl(t1, t1, t2);
2501
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2503
/* operands of same sign, result different sign */
2504
generate_exception(ctx, EXCP_OVERFLOW);
2506
gen_store_gpr(t0, rt);
2512
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2514
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2521
/* Logic with immediate operand */
2522
static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2523
int rt, int rs, int16_t imm)
2528
/* If no destination, treat it as a NOP. */
2531
uimm = (uint16_t)imm;
2534
if (likely(rs != 0))
2535
tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2537
tcg_gen_movi_tl(cpu_gpr[rt], 0);
2541
tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2543
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2546
if (likely(rs != 0))
2547
tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2549
tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2552
if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2554
tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2555
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2557
tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2566
/* Set on less than with immediate operand */
2567
static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2568
int rt, int rs, int16_t imm)
2570
target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2574
/* If no destination, treat it as a NOP. */
2577
t0 = tcg_temp_new();
2578
gen_load_gpr(t0, rs);
2581
tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2584
tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2590
/* Shifts with immediate operand */
2591
static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2592
int rt, int rs, int16_t imm)
2594
target_ulong uimm = ((uint16_t)imm) & 0x1f;
2598
/* If no destination, treat it as a NOP. */
2602
t0 = tcg_temp_new();
2603
gen_load_gpr(t0, rs);
2606
tcg_gen_shli_tl(t0, t0, uimm);
2607
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2610
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2614
tcg_gen_ext32u_tl(t0, t0);
2615
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2617
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2622
TCGv_i32 t1 = tcg_temp_new_i32();
2624
tcg_gen_trunc_tl_i32(t1, t0);
2625
tcg_gen_rotri_i32(t1, t1, uimm);
2626
tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2627
tcg_temp_free_i32(t1);
2629
tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2632
#if defined(TARGET_MIPS64)
2634
tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2637
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2640
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2644
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2646
tcg_gen_mov_tl(cpu_gpr[rt], t0);
2650
tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2653
tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2656
tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2659
tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2667
static void gen_arith(DisasContext *ctx, uint32_t opc,
2668
int rd, int rs, int rt)
2670
if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2671
&& opc != OPC_DADD && opc != OPC_DSUB) {
2672
/* If no destination, treat it as a NOP.
2673
For add & sub, we must generate the overflow exception when needed. */
2680
TCGv t0 = tcg_temp_local_new();
2681
TCGv t1 = tcg_temp_new();
2682
TCGv t2 = tcg_temp_new();
2683
TCGLabel *l1 = gen_new_label();
2685
gen_load_gpr(t1, rs);
2686
gen_load_gpr(t2, rt);
2687
tcg_gen_add_tl(t0, t1, t2);
2688
tcg_gen_ext32s_tl(t0, t0);
2689
tcg_gen_xor_tl(t1, t1, t2);
2690
tcg_gen_xor_tl(t2, t0, t2);
2691
tcg_gen_andc_tl(t1, t2, t1);
2693
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2695
/* operands of same sign, result different sign */
2696
generate_exception(ctx, EXCP_OVERFLOW);
2698
gen_store_gpr(t0, rd);
2703
if (rs != 0 && rt != 0) {
2704
tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2705
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2706
} else if (rs == 0 && rt != 0) {
2707
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2708
} else if (rs != 0 && rt == 0) {
2709
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2711
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2716
TCGv t0 = tcg_temp_local_new();
2717
TCGv t1 = tcg_temp_new();
2718
TCGv t2 = tcg_temp_new();
2719
TCGLabel *l1 = gen_new_label();
2721
gen_load_gpr(t1, rs);
2722
gen_load_gpr(t2, rt);
2723
tcg_gen_sub_tl(t0, t1, t2);
2724
tcg_gen_ext32s_tl(t0, t0);
2725
tcg_gen_xor_tl(t2, t1, t2);
2726
tcg_gen_xor_tl(t1, t0, t1);
2727
tcg_gen_and_tl(t1, t1, t2);
2729
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2731
/* operands of different sign, first operand and result different sign */
2732
generate_exception(ctx, EXCP_OVERFLOW);
2734
gen_store_gpr(t0, rd);
2739
if (rs != 0 && rt != 0) {
2740
tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2741
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2742
} else if (rs == 0 && rt != 0) {
2743
tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2744
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2745
} else if (rs != 0 && rt == 0) {
2746
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2748
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2751
#if defined(TARGET_MIPS64)
2754
TCGv t0 = tcg_temp_local_new();
2755
TCGv t1 = tcg_temp_new();
2756
TCGv t2 = tcg_temp_new();
2757
TCGLabel *l1 = gen_new_label();
2759
gen_load_gpr(t1, rs);
2760
gen_load_gpr(t2, rt);
2761
tcg_gen_add_tl(t0, t1, t2);
2762
tcg_gen_xor_tl(t1, t1, t2);
2763
tcg_gen_xor_tl(t2, t0, t2);
2764
tcg_gen_andc_tl(t1, t2, t1);
2766
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2768
/* operands of same sign, result different sign */
2769
generate_exception(ctx, EXCP_OVERFLOW);
2771
gen_store_gpr(t0, rd);
2776
if (rs != 0 && rt != 0) {
2777
tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2778
} else if (rs == 0 && rt != 0) {
2779
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2780
} else if (rs != 0 && rt == 0) {
2781
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2783
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2788
TCGv t0 = tcg_temp_local_new();
2789
TCGv t1 = tcg_temp_new();
2790
TCGv t2 = tcg_temp_new();
2791
TCGLabel *l1 = gen_new_label();
2793
gen_load_gpr(t1, rs);
2794
gen_load_gpr(t2, rt);
2795
tcg_gen_sub_tl(t0, t1, t2);
2796
tcg_gen_xor_tl(t2, t1, t2);
2797
tcg_gen_xor_tl(t1, t0, t1);
2798
tcg_gen_and_tl(t1, t1, t2);
2800
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2802
/* operands of different sign, first operand and result different sign */
2803
generate_exception(ctx, EXCP_OVERFLOW);
2805
gen_store_gpr(t0, rd);
2810
if (rs != 0 && rt != 0) {
2811
tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2812
} else if (rs == 0 && rt != 0) {
2813
tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2814
} else if (rs != 0 && rt == 0) {
2815
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2817
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2822
if (likely(rs != 0 && rt != 0)) {
2823
tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2824
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2826
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2832
/* Conditional move */
2833
static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2834
int rd, int rs, int rt)
2839
/* If no destination, treat it as a NOP. */
2843
t0 = tcg_temp_new();
2844
gen_load_gpr(t0, rt);
2845
t1 = tcg_const_tl(0);
2846
t2 = tcg_temp_new();
2847
gen_load_gpr(t2, rs);
2850
tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2853
tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2856
tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2859
tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2868
static void gen_logic(DisasContext *ctx, uint32_t opc,
2869
int rd, int rs, int rt)
2872
/* If no destination, treat it as a NOP. */
2878
if (likely(rs != 0 && rt != 0)) {
2879
tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2881
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2885
if (rs != 0 && rt != 0) {
2886
tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2887
} else if (rs == 0 && rt != 0) {
2888
tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2889
} else if (rs != 0 && rt == 0) {
2890
tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2892
tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2896
if (likely(rs != 0 && rt != 0)) {
2897
tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2898
} else if (rs == 0 && rt != 0) {
2899
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2900
} else if (rs != 0 && rt == 0) {
2901
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2903
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2907
if (likely(rs != 0 && rt != 0)) {
2908
tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2909
} else if (rs == 0 && rt != 0) {
2910
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2911
} else if (rs != 0 && rt == 0) {
2912
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2914
tcg_gen_movi_tl(cpu_gpr[rd], 0);
2920
/* Set on lower than */
2921
static void gen_slt(DisasContext *ctx, uint32_t opc,
2922
int rd, int rs, int rt)
2927
/* If no destination, treat it as a NOP. */
2931
t0 = tcg_temp_new();
2932
t1 = tcg_temp_new();
2933
gen_load_gpr(t0, rs);
2934
gen_load_gpr(t1, rt);
2937
tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2940
tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2948
static void gen_shift(DisasContext *ctx, uint32_t opc,
2949
int rd, int rs, int rt)
2954
/* If no destination, treat it as a NOP.
2955
For add & sub, we must generate the overflow exception when needed. */
2959
t0 = tcg_temp_new();
2960
t1 = tcg_temp_new();
2961
gen_load_gpr(t0, rs);
2962
gen_load_gpr(t1, rt);
2965
tcg_gen_andi_tl(t0, t0, 0x1f);
2966
tcg_gen_shl_tl(t0, t1, t0);
2967
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2970
tcg_gen_andi_tl(t0, t0, 0x1f);
2971
tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2974
tcg_gen_ext32u_tl(t1, t1);
2975
tcg_gen_andi_tl(t0, t0, 0x1f);
2976
tcg_gen_shr_tl(t0, t1, t0);
2977
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2981
TCGv_i32 t2 = tcg_temp_new_i32();
2982
TCGv_i32 t3 = tcg_temp_new_i32();
2984
tcg_gen_trunc_tl_i32(t2, t0);
2985
tcg_gen_trunc_tl_i32(t3, t1);
2986
tcg_gen_andi_i32(t2, t2, 0x1f);
2987
tcg_gen_rotr_i32(t2, t3, t2);
2988
tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2989
tcg_temp_free_i32(t2);
2990
tcg_temp_free_i32(t3);
2993
#if defined(TARGET_MIPS64)
2995
tcg_gen_andi_tl(t0, t0, 0x3f);
2996
tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2999
tcg_gen_andi_tl(t0, t0, 0x3f);
3000
tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3003
tcg_gen_andi_tl(t0, t0, 0x3f);
3004
tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3007
tcg_gen_andi_tl(t0, t0, 0x3f);
3008
tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3016
/* Arithmetic on HI/LO registers */
3017
static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3019
if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3030
#if defined(TARGET_MIPS64)
3032
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3036
tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3040
#if defined(TARGET_MIPS64)
3042
tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3046
tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3051
#if defined(TARGET_MIPS64)
3053
tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3057
tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3060
tcg_gen_movi_tl(cpu_HI[acc], 0);
3065
#if defined(TARGET_MIPS64)
3067
tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3071
tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3074
tcg_gen_movi_tl(cpu_LO[acc], 0);
3080
static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3083
TCGv t0 = tcg_const_tl(addr);
3084
tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3085
gen_store_gpr(t0, reg);
3089
static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3095
switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3098
offset = sextract32(ctx->opcode << 2, 0, 21);
3099
addr = addr_add(ctx, pc, offset);
3100
tcg_gen_movi_tl(cpu_gpr[rs], addr);
3104
offset = sextract32(ctx->opcode << 2, 0, 21);
3105
addr = addr_add(ctx, pc, offset);
3106
gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3108
#if defined(TARGET_MIPS64)
3111
offset = sextract32(ctx->opcode << 2, 0, 21);
3112
addr = addr_add(ctx, pc, offset);
3113
gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3117
switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3120
offset = sextract32(ctx->opcode, 0, 16) << 16;
3121
addr = addr_add(ctx, pc, offset);
3122
tcg_gen_movi_tl(cpu_gpr[rs], addr);
3127
offset = sextract32(ctx->opcode, 0, 16) << 16;
3128
addr = ~0xFFFF & addr_add(ctx, pc, offset);
3129
tcg_gen_movi_tl(cpu_gpr[rs], addr);
3132
#if defined(TARGET_MIPS64)
3133
case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3134
case R6_OPC_LDPC + (1 << 16):
3135
case R6_OPC_LDPC + (2 << 16):
3136
case R6_OPC_LDPC + (3 << 16):
3138
offset = sextract32(ctx->opcode << 3, 0, 21);
3139
addr = addr_add(ctx, (pc & ~0x7), offset);
3140
gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3144
MIPS_INVAL("OPC_PCREL");
3145
generate_exception_end(ctx, EXCP_RI);
3152
static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3161
t0 = tcg_temp_new();
3162
t1 = tcg_temp_new();
3164
gen_load_gpr(t0, rs);
3165
gen_load_gpr(t1, rt);
3170
TCGv t2 = tcg_temp_new();
3171
TCGv t3 = tcg_temp_new();
3172
tcg_gen_ext32s_tl(t0, t0);
3173
tcg_gen_ext32s_tl(t1, t1);
3174
tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3175
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3176
tcg_gen_and_tl(t2, t2, t3);
3177
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3178
tcg_gen_or_tl(t2, t2, t3);
3179
tcg_gen_movi_tl(t3, 0);
3180
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3181
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3182
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3189
TCGv t2 = tcg_temp_new();
3190
TCGv t3 = tcg_temp_new();
3191
tcg_gen_ext32s_tl(t0, t0);
3192
tcg_gen_ext32s_tl(t1, t1);
3193
tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3194
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3195
tcg_gen_and_tl(t2, t2, t3);
3196
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3197
tcg_gen_or_tl(t2, t2, t3);
3198
tcg_gen_movi_tl(t3, 0);
3199
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3200
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3201
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3208
TCGv t2 = tcg_const_tl(0);
3209
TCGv t3 = tcg_const_tl(1);
3210
tcg_gen_ext32u_tl(t0, t0);
3211
tcg_gen_ext32u_tl(t1, t1);
3212
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3213
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3214
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3221
TCGv t2 = tcg_const_tl(0);
3222
TCGv t3 = tcg_const_tl(1);
3223
tcg_gen_ext32u_tl(t0, t0);
3224
tcg_gen_ext32u_tl(t1, t1);
3225
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3226
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3234
TCGv_i32 t2 = tcg_temp_new_i32();
3235
TCGv_i32 t3 = tcg_temp_new_i32();
3236
tcg_gen_trunc_tl_i32(t2, t0);
3237
tcg_gen_trunc_tl_i32(t3, t1);
3238
tcg_gen_mul_i32(t2, t2, t3);
3239
tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3240
tcg_temp_free_i32(t2);
3241
tcg_temp_free_i32(t3);
3246
TCGv_i32 t2 = tcg_temp_new_i32();
3247
TCGv_i32 t3 = tcg_temp_new_i32();
3248
tcg_gen_trunc_tl_i32(t2, t0);
3249
tcg_gen_trunc_tl_i32(t3, t1);
3250
tcg_gen_muls2_i32(t2, t3, t2, t3);
3251
tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3252
tcg_temp_free_i32(t2);
3253
tcg_temp_free_i32(t3);
3258
TCGv_i32 t2 = tcg_temp_new_i32();
3259
TCGv_i32 t3 = tcg_temp_new_i32();
3260
tcg_gen_trunc_tl_i32(t2, t0);
3261
tcg_gen_trunc_tl_i32(t3, t1);
3262
tcg_gen_mul_i32(t2, t2, t3);
3263
tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3264
tcg_temp_free_i32(t2);
3265
tcg_temp_free_i32(t3);
3270
TCGv_i32 t2 = tcg_temp_new_i32();
3271
TCGv_i32 t3 = tcg_temp_new_i32();
3272
tcg_gen_trunc_tl_i32(t2, t0);
3273
tcg_gen_trunc_tl_i32(t3, t1);
3274
tcg_gen_mulu2_i32(t2, t3, t2, t3);
3275
tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3276
tcg_temp_free_i32(t2);
3277
tcg_temp_free_i32(t3);
3280
#if defined(TARGET_MIPS64)
3283
TCGv t2 = tcg_temp_new();
3284
TCGv t3 = tcg_temp_new();
3285
tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3286
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3287
tcg_gen_and_tl(t2, t2, t3);
3288
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3289
tcg_gen_or_tl(t2, t2, t3);
3290
tcg_gen_movi_tl(t3, 0);
3291
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3292
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3299
TCGv t2 = tcg_temp_new();
3300
TCGv t3 = tcg_temp_new();
3301
tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3302
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3303
tcg_gen_and_tl(t2, t2, t3);
3304
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3305
tcg_gen_or_tl(t2, t2, t3);
3306
tcg_gen_movi_tl(t3, 0);
3307
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3308
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3315
TCGv t2 = tcg_const_tl(0);
3316
TCGv t3 = tcg_const_tl(1);
3317
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318
tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3325
TCGv t2 = tcg_const_tl(0);
3326
TCGv t3 = tcg_const_tl(1);
3327
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3328
tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3334
tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3338
TCGv t2 = tcg_temp_new();
3339
tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3344
tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3348
TCGv t2 = tcg_temp_new();
3349
tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3355
MIPS_INVAL("r6 mul/div");
3356
generate_exception_end(ctx, EXCP_RI);
3364
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3365
int acc, int rs, int rt)
3369
t0 = tcg_temp_new();
3370
t1 = tcg_temp_new();
3372
gen_load_gpr(t0, rs);
3373
gen_load_gpr(t1, rt);
3382
TCGv t2 = tcg_temp_new();
3383
TCGv t3 = tcg_temp_new();
3384
tcg_gen_ext32s_tl(t0, t0);
3385
tcg_gen_ext32s_tl(t1, t1);
3386
tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3387
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3388
tcg_gen_and_tl(t2, t2, t3);
3389
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3390
tcg_gen_or_tl(t2, t2, t3);
3391
tcg_gen_movi_tl(t3, 0);
3392
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3393
tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3394
tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3395
tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3396
tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3403
TCGv t2 = tcg_const_tl(0);
3404
TCGv t3 = tcg_const_tl(1);
3405
tcg_gen_ext32u_tl(t0, t0);
3406
tcg_gen_ext32u_tl(t1, t1);
3407
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3408
tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3409
tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3410
tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3411
tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3418
TCGv_i32 t2 = tcg_temp_new_i32();
3419
TCGv_i32 t3 = tcg_temp_new_i32();
3420
tcg_gen_trunc_tl_i32(t2, t0);
3421
tcg_gen_trunc_tl_i32(t3, t1);
3422
tcg_gen_muls2_i32(t2, t3, t2, t3);
3423
tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3424
tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3425
tcg_temp_free_i32(t2);
3426
tcg_temp_free_i32(t3);
3431
TCGv_i32 t2 = tcg_temp_new_i32();
3432
TCGv_i32 t3 = tcg_temp_new_i32();
3433
tcg_gen_trunc_tl_i32(t2, t0);
3434
tcg_gen_trunc_tl_i32(t3, t1);
3435
tcg_gen_mulu2_i32(t2, t3, t2, t3);
3436
tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3437
tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3438
tcg_temp_free_i32(t2);
3439
tcg_temp_free_i32(t3);
3442
#if defined(TARGET_MIPS64)
3445
TCGv t2 = tcg_temp_new();
3446
TCGv t3 = tcg_temp_new();
3447
tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3448
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3449
tcg_gen_and_tl(t2, t2, t3);
3450
tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3451
tcg_gen_or_tl(t2, t2, t3);
3452
tcg_gen_movi_tl(t3, 0);
3453
tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3454
tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3455
tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3462
TCGv t2 = tcg_const_tl(0);
3463
TCGv t3 = tcg_const_tl(1);
3464
tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3465
tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3466
tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3472
tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3475
tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3480
TCGv_i64 t2 = tcg_temp_new_i64();
3481
TCGv_i64 t3 = tcg_temp_new_i64();
3483
tcg_gen_ext_tl_i64(t2, t0);
3484
tcg_gen_ext_tl_i64(t3, t1);
3485
tcg_gen_mul_i64(t2, t2, t3);
3486
tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3487
tcg_gen_add_i64(t2, t2, t3);
3488
tcg_temp_free_i64(t3);
3489
gen_move_low32(cpu_LO[acc], t2);
3490
gen_move_high32(cpu_HI[acc], t2);
3491
tcg_temp_free_i64(t2);
3496
TCGv_i64 t2 = tcg_temp_new_i64();
3497
TCGv_i64 t3 = tcg_temp_new_i64();
3499
tcg_gen_ext32u_tl(t0, t0);
3500
tcg_gen_ext32u_tl(t1, t1);
3501
tcg_gen_extu_tl_i64(t2, t0);
3502
tcg_gen_extu_tl_i64(t3, t1);
3503
tcg_gen_mul_i64(t2, t2, t3);
3504
tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3505
tcg_gen_add_i64(t2, t2, t3);
3506
tcg_temp_free_i64(t3);
3507
gen_move_low32(cpu_LO[acc], t2);
3508
gen_move_high32(cpu_HI[acc], t2);
3509
tcg_temp_free_i64(t2);
3514
TCGv_i64 t2 = tcg_temp_new_i64();
3515
TCGv_i64 t3 = tcg_temp_new_i64();
3517
tcg_gen_ext_tl_i64(t2, t0);
3518
tcg_gen_ext_tl_i64(t3, t1);
3519
tcg_gen_mul_i64(t2, t2, t3);
3520
tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3521
tcg_gen_sub_i64(t2, t3, t2);
3522
tcg_temp_free_i64(t3);
3523
gen_move_low32(cpu_LO[acc], t2);
3524
gen_move_high32(cpu_HI[acc], t2);
3525
tcg_temp_free_i64(t2);
3530
TCGv_i64 t2 = tcg_temp_new_i64();
3531
TCGv_i64 t3 = tcg_temp_new_i64();
3533
tcg_gen_ext32u_tl(t0, t0);
3534
tcg_gen_ext32u_tl(t1, t1);
3535
tcg_gen_extu_tl_i64(t2, t0);
3536
tcg_gen_extu_tl_i64(t3, t1);
3537
tcg_gen_mul_i64(t2, t2, t3);
3538
tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3539
tcg_gen_sub_i64(t2, t3, t2);
3540
tcg_temp_free_i64(t3);
3541
gen_move_low32(cpu_LO[acc], t2);
3542
gen_move_high32(cpu_HI[acc], t2);
3543
tcg_temp_free_i64(t2);
3547
MIPS_INVAL("mul/div");
3548
generate_exception_end(ctx, EXCP_RI);
3556
static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3557
int rd, int rs, int rt)
3559
TCGv t0 = tcg_temp_new();
3560
TCGv t1 = tcg_temp_new();
3562
gen_load_gpr(t0, rs);
3563
gen_load_gpr(t1, rt);
3566
case OPC_VR54XX_MULS:
3567
gen_helper_muls(t0, cpu_env, t0, t1);
3569
case OPC_VR54XX_MULSU:
3570
gen_helper_mulsu(t0, cpu_env, t0, t1);
3572
case OPC_VR54XX_MACC:
3573
gen_helper_macc(t0, cpu_env, t0, t1);
3575
case OPC_VR54XX_MACCU:
3576
gen_helper_maccu(t0, cpu_env, t0, t1);
3578
case OPC_VR54XX_MSAC:
3579
gen_helper_msac(t0, cpu_env, t0, t1);
3581
case OPC_VR54XX_MSACU:
3582
gen_helper_msacu(t0, cpu_env, t0, t1);
3584
case OPC_VR54XX_MULHI:
3585
gen_helper_mulhi(t0, cpu_env, t0, t1);
3587
case OPC_VR54XX_MULHIU:
3588
gen_helper_mulhiu(t0, cpu_env, t0, t1);
3590
case OPC_VR54XX_MULSHI:
3591
gen_helper_mulshi(t0, cpu_env, t0, t1);
3593
case OPC_VR54XX_MULSHIU:
3594
gen_helper_mulshiu(t0, cpu_env, t0, t1);
3596
case OPC_VR54XX_MACCHI:
3597
gen_helper_macchi(t0, cpu_env, t0, t1);
3599
case OPC_VR54XX_MACCHIU:
3600
gen_helper_macchiu(t0, cpu_env, t0, t1);
3602
case OPC_VR54XX_MSACHI:
3603
gen_helper_msachi(t0, cpu_env, t0, t1);
3605
case OPC_VR54XX_MSACHIU:
3606
gen_helper_msachiu(t0, cpu_env, t0, t1);
3609
MIPS_INVAL("mul vr54xx");
3610
generate_exception_end(ctx, EXCP_RI);
3613
gen_store_gpr(t0, rd);
3620
static void gen_cl (DisasContext *ctx, uint32_t opc,
3629
t0 = tcg_temp_new();
3630
gen_load_gpr(t0, rs);
3634
gen_helper_clo(cpu_gpr[rd], t0);
3638
gen_helper_clz(cpu_gpr[rd], t0);
3640
#if defined(TARGET_MIPS64)
3643
gen_helper_dclo(cpu_gpr[rd], t0);
3647
gen_helper_dclz(cpu_gpr[rd], t0);
3654
/* Godson integer instructions */
3655
static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3656
int rd, int rs, int rt)
3668
case OPC_MULTU_G_2E:
3669
case OPC_MULTU_G_2F:
3670
#if defined(TARGET_MIPS64)
3671
case OPC_DMULT_G_2E:
3672
case OPC_DMULT_G_2F:
3673
case OPC_DMULTU_G_2E:
3674
case OPC_DMULTU_G_2F:
3676
t0 = tcg_temp_new();
3677
t1 = tcg_temp_new();
3680
t0 = tcg_temp_local_new();
3681
t1 = tcg_temp_local_new();
3685
gen_load_gpr(t0, rs);
3686
gen_load_gpr(t1, rt);
3691
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3692
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3694
case OPC_MULTU_G_2E:
3695
case OPC_MULTU_G_2F:
3696
tcg_gen_ext32u_tl(t0, t0);
3697
tcg_gen_ext32u_tl(t1, t1);
3698
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3699
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3704
TCGLabel *l1 = gen_new_label();
3705
TCGLabel *l2 = gen_new_label();
3706
TCGLabel *l3 = gen_new_label();
3707
tcg_gen_ext32s_tl(t0, t0);
3708
tcg_gen_ext32s_tl(t1, t1);
3709
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3710
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3713
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3714
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3715
tcg_gen_mov_tl(cpu_gpr[rd], t0);
3718
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3719
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3726
TCGLabel *l1 = gen_new_label();
3727
TCGLabel *l2 = gen_new_label();
3728
tcg_gen_ext32u_tl(t0, t0);
3729
tcg_gen_ext32u_tl(t1, t1);
3730
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3731
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3734
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3735
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3742
TCGLabel *l1 = gen_new_label();
3743
TCGLabel *l2 = gen_new_label();
3744
TCGLabel *l3 = gen_new_label();
3745
tcg_gen_ext32u_tl(t0, t0);
3746
tcg_gen_ext32u_tl(t1, t1);
3747
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3748
tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3749
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3751
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3754
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3755
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3762
TCGLabel *l1 = gen_new_label();
3763
TCGLabel *l2 = gen_new_label();
3764
tcg_gen_ext32u_tl(t0, t0);
3765
tcg_gen_ext32u_tl(t1, t1);
3766
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3767
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3770
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3771
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3775
#if defined(TARGET_MIPS64)
3776
case OPC_DMULT_G_2E:
3777
case OPC_DMULT_G_2F:
3778
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3780
case OPC_DMULTU_G_2E:
3781
case OPC_DMULTU_G_2F:
3782
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3787
TCGLabel *l1 = gen_new_label();
3788
TCGLabel *l2 = gen_new_label();
3789
TCGLabel *l3 = gen_new_label();
3790
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3791
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3794
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3795
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3796
tcg_gen_mov_tl(cpu_gpr[rd], t0);
3799
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3803
case OPC_DDIVU_G_2E:
3804
case OPC_DDIVU_G_2F:
3806
TCGLabel *l1 = gen_new_label();
3807
TCGLabel *l2 = gen_new_label();
3808
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3809
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3812
tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3819
TCGLabel *l1 = gen_new_label();
3820
TCGLabel *l2 = gen_new_label();
3821
TCGLabel *l3 = gen_new_label();
3822
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3823
tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3824
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3826
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3829
tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3833
case OPC_DMODU_G_2E:
3834
case OPC_DMODU_G_2F:
3836
TCGLabel *l1 = gen_new_label();
3837
TCGLabel *l2 = gen_new_label();
3838
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3839
tcg_gen_movi_tl(cpu_gpr[rd], 0);
3842
tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3853
/* Loongson multimedia instructions */
3854
static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3856
uint32_t opc, shift_max;
3859
opc = MASK_LMI(ctx->opcode);
3865
t0 = tcg_temp_local_new_i64();
3866
t1 = tcg_temp_local_new_i64();
3869
t0 = tcg_temp_new_i64();
3870
t1 = tcg_temp_new_i64();
3874
check_cp1_enabled(ctx);
3875
gen_load_fpr64(ctx, t0, rs);
3876
gen_load_fpr64(ctx, t1, rt);
3878
#define LMI_HELPER(UP, LO) \
3879
case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3880
#define LMI_HELPER_1(UP, LO) \
3881
case OPC_##UP: gen_helper_##LO(t0, t0); break
3882
#define LMI_DIRECT(UP, LO, OP) \
3883
case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3886
LMI_HELPER(PADDSH, paddsh);
3887
LMI_HELPER(PADDUSH, paddush);
3888
LMI_HELPER(PADDH, paddh);
3889
LMI_HELPER(PADDW, paddw);
3890
LMI_HELPER(PADDSB, paddsb);
3891
LMI_HELPER(PADDUSB, paddusb);
3892
LMI_HELPER(PADDB, paddb);
3894
LMI_HELPER(PSUBSH, psubsh);
3895
LMI_HELPER(PSUBUSH, psubush);
3896
LMI_HELPER(PSUBH, psubh);
3897
LMI_HELPER(PSUBW, psubw);
3898
LMI_HELPER(PSUBSB, psubsb);
3899
LMI_HELPER(PSUBUSB, psubusb);
3900
LMI_HELPER(PSUBB, psubb);
3902
LMI_HELPER(PSHUFH, pshufh);
3903
LMI_HELPER(PACKSSWH, packsswh);
3904
LMI_HELPER(PACKSSHB, packsshb);
3905
LMI_HELPER(PACKUSHB, packushb);
3907
LMI_HELPER(PUNPCKLHW, punpcklhw);
3908
LMI_HELPER(PUNPCKHHW, punpckhhw);
3909
LMI_HELPER(PUNPCKLBH, punpcklbh);
3910
LMI_HELPER(PUNPCKHBH, punpckhbh);
3911
LMI_HELPER(PUNPCKLWD, punpcklwd);
3912
LMI_HELPER(PUNPCKHWD, punpckhwd);
3914
LMI_HELPER(PAVGH, pavgh);
3915
LMI_HELPER(PAVGB, pavgb);
3916
LMI_HELPER(PMAXSH, pmaxsh);
3917
LMI_HELPER(PMINSH, pminsh);
3918
LMI_HELPER(PMAXUB, pmaxub);
3919
LMI_HELPER(PMINUB, pminub);
3921
LMI_HELPER(PCMPEQW, pcmpeqw);
3922
LMI_HELPER(PCMPGTW, pcmpgtw);
3923
LMI_HELPER(PCMPEQH, pcmpeqh);
3924
LMI_HELPER(PCMPGTH, pcmpgth);
3925
LMI_HELPER(PCMPEQB, pcmpeqb);
3926
LMI_HELPER(PCMPGTB, pcmpgtb);
3928
LMI_HELPER(PSLLW, psllw);
3929
LMI_HELPER(PSLLH, psllh);
3930
LMI_HELPER(PSRLW, psrlw);
3931
LMI_HELPER(PSRLH, psrlh);
3932
LMI_HELPER(PSRAW, psraw);
3933
LMI_HELPER(PSRAH, psrah);
3935
LMI_HELPER(PMULLH, pmullh);
3936
LMI_HELPER(PMULHH, pmulhh);
3937
LMI_HELPER(PMULHUH, pmulhuh);
3938
LMI_HELPER(PMADDHW, pmaddhw);
3940
LMI_HELPER(PASUBUB, pasubub);
3941
LMI_HELPER_1(BIADD, biadd);
3942
LMI_HELPER_1(PMOVMSKB, pmovmskb);
3944
LMI_DIRECT(PADDD, paddd, add);
3945
LMI_DIRECT(PSUBD, psubd, sub);
3946
LMI_DIRECT(XOR_CP2, xor, xor);
3947
LMI_DIRECT(NOR_CP2, nor, nor);
3948
LMI_DIRECT(AND_CP2, and, and);
3949
LMI_DIRECT(OR_CP2, or, or);
3952
tcg_gen_andc_i64(t0, t1, t0);
3956
tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3959
tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3962
tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3965
tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3969
tcg_gen_andi_i64(t1, t1, 3);
3970
tcg_gen_shli_i64(t1, t1, 4);
3971
tcg_gen_shr_i64(t0, t0, t1);
3972
tcg_gen_ext16u_i64(t0, t0);
3976
tcg_gen_add_i64(t0, t0, t1);
3977
tcg_gen_ext32s_i64(t0, t0);
3980
tcg_gen_sub_i64(t0, t0, t1);
3981
tcg_gen_ext32s_i64(t0, t0);
4003
/* Make sure shift count isn't TCG undefined behaviour. */
4004
tcg_gen_andi_i64(t1, t1, shift_max - 1);
4009
tcg_gen_shl_i64(t0, t0, t1);
4013
/* Since SRA is UndefinedResult without sign-extended inputs,
4014
we can treat SRA and DSRA the same. */
4015
tcg_gen_sar_i64(t0, t0, t1);
4018
/* We want to shift in zeros for SRL; zero-extend first. */
4019
tcg_gen_ext32u_i64(t0, t0);
4022
tcg_gen_shr_i64(t0, t0, t1);
4026
if (shift_max == 32) {
4027
tcg_gen_ext32s_i64(t0, t0);
4030
/* Shifts larger than MAX produce zero. */
4031
tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4032
tcg_gen_neg_i64(t1, t1);
4033
tcg_gen_and_i64(t0, t0, t1);
4039
TCGv_i64 t2 = tcg_temp_new_i64();
4040
TCGLabel *lab = gen_new_label();
4042
tcg_gen_mov_i64(t2, t0);
4043
tcg_gen_add_i64(t0, t1, t2);
4044
if (opc == OPC_ADD_CP2) {
4045
tcg_gen_ext32s_i64(t0, t0);
4047
tcg_gen_xor_i64(t1, t1, t2);
4048
tcg_gen_xor_i64(t2, t2, t0);
4049
tcg_gen_andc_i64(t1, t2, t1);
4050
tcg_temp_free_i64(t2);
4051
tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4052
generate_exception(ctx, EXCP_OVERFLOW);
4060
TCGv_i64 t2 = tcg_temp_new_i64();
4061
TCGLabel *lab = gen_new_label();
4063
tcg_gen_mov_i64(t2, t0);
4064
tcg_gen_sub_i64(t0, t1, t2);
4065
if (opc == OPC_SUB_CP2) {
4066
tcg_gen_ext32s_i64(t0, t0);
4068
tcg_gen_xor_i64(t1, t1, t2);
4069
tcg_gen_xor_i64(t2, t2, t0);
4070
tcg_gen_and_i64(t1, t1, t2);
4071
tcg_temp_free_i64(t2);
4072
tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4073
generate_exception(ctx, EXCP_OVERFLOW);
4079
tcg_gen_ext32u_i64(t0, t0);
4080
tcg_gen_ext32u_i64(t1, t1);
4081
tcg_gen_mul_i64(t0, t0, t1);
4090
/* ??? Document is unclear: Set FCC[CC]. Does that mean the
4091
FD field is the CC field? */
4093
MIPS_INVAL("loongson_cp2");
4094
generate_exception_end(ctx, EXCP_RI);
4101
gen_store_fpr64(ctx, t0, rd);
4103
tcg_temp_free_i64(t0);
4104
tcg_temp_free_i64(t1);
4108
static void gen_trap (DisasContext *ctx, uint32_t opc,
4109
int rs, int rt, int16_t imm)
4112
TCGv t0 = tcg_temp_new();
4113
TCGv t1 = tcg_temp_new();
4116
/* Load needed operands */
4124
/* Compare two registers */
4126
gen_load_gpr(t0, rs);
4127
gen_load_gpr(t1, rt);
4137
/* Compare register to immediate */
4138
if (rs != 0 || imm != 0) {
4139
gen_load_gpr(t0, rs);
4140
tcg_gen_movi_tl(t1, (int32_t)imm);
4147
case OPC_TEQ: /* rs == rs */
4148
case OPC_TEQI: /* r0 == 0 */
4149
case OPC_TGE: /* rs >= rs */
4150
case OPC_TGEI: /* r0 >= 0 */
4151
case OPC_TGEU: /* rs >= rs unsigned */
4152
case OPC_TGEIU: /* r0 >= 0 unsigned */
4154
generate_exception_end(ctx, EXCP_TRAP);
4156
case OPC_TLT: /* rs < rs */
4157
case OPC_TLTI: /* r0 < 0 */
4158
case OPC_TLTU: /* rs < rs unsigned */
4159
case OPC_TLTIU: /* r0 < 0 unsigned */
4160
case OPC_TNE: /* rs != rs */
4161
case OPC_TNEI: /* r0 != 0 */
4162
/* Never trap: treat as NOP. */
4166
TCGLabel *l1 = gen_new_label();
4171
tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4175
tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4179
tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4183
tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4187
tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4191
tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4194
generate_exception(ctx, EXCP_TRAP);
4201
static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4203
if (unlikely(ctx->singlestep_enabled)) {
4207
#ifndef CONFIG_USER_ONLY
4208
return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4214
static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4216
if (use_goto_tb(ctx, dest)) {
4219
tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4222
if (ctx->singlestep_enabled) {
4223
save_cpu_state(ctx, 0);
4224
gen_helper_raise_exception_debug(cpu_env);
4230
/* Branches (before delay slot) */
4231
static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4233
int rs, int rt, int32_t offset,
4236
target_ulong btgt = -1;
4238
int bcond_compute = 0;
4239
TCGv t0 = tcg_temp_new();
4240
TCGv t1 = tcg_temp_new();
4242
if (ctx->hflags & MIPS_HFLAG_BMASK) {
4243
#ifdef MIPS_DEBUG_DISAS
4244
LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4245
TARGET_FMT_lx "\n", ctx->pc);
4247
generate_exception_end(ctx, EXCP_RI);
4251
/* Load needed operands */
4257
/* Compare two registers */
4259
gen_load_gpr(t0, rs);
4260
gen_load_gpr(t1, rt);
4263
btgt = ctx->pc + insn_bytes + offset;
4277
/* Compare to zero */
4279
gen_load_gpr(t0, rs);
4282
btgt = ctx->pc + insn_bytes + offset;
4285
#if defined(TARGET_MIPS64)
4287
tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4289
tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4292
btgt = ctx->pc + insn_bytes + offset;
4297
/* Jump to immediate */
4298
btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4302
/* Jump to register */
4303
if (offset != 0 && offset != 16) {
4304
/* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4305
others are reserved. */
4306
MIPS_INVAL("jump hint");
4307
generate_exception_end(ctx, EXCP_RI);
4310
gen_load_gpr(btarget, rs);
4313
MIPS_INVAL("branch/jump");
4314
generate_exception_end(ctx, EXCP_RI);
4317
if (bcond_compute == 0) {
4318
/* No condition to be computed */
4320
case OPC_BEQ: /* rx == rx */
4321
case OPC_BEQL: /* rx == rx likely */
4322
case OPC_BGEZ: /* 0 >= 0 */
4323
case OPC_BGEZL: /* 0 >= 0 likely */
4324
case OPC_BLEZ: /* 0 <= 0 */
4325
case OPC_BLEZL: /* 0 <= 0 likely */
4327
ctx->hflags |= MIPS_HFLAG_B;
4329
case OPC_BGEZAL: /* 0 >= 0 */
4330
case OPC_BGEZALL: /* 0 >= 0 likely */
4331
/* Always take and link */
4333
ctx->hflags |= MIPS_HFLAG_B;
4335
case OPC_BNE: /* rx != rx */
4336
case OPC_BGTZ: /* 0 > 0 */
4337
case OPC_BLTZ: /* 0 < 0 */
4340
case OPC_BLTZAL: /* 0 < 0 */
4341
/* Handle as an unconditional branch to get correct delay
4344
btgt = ctx->pc + insn_bytes + delayslot_size;
4345
ctx->hflags |= MIPS_HFLAG_B;
4347
case OPC_BLTZALL: /* 0 < 0 likely */
4348
tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4349
/* Skip the instruction in the delay slot */
4352
case OPC_BNEL: /* rx != rx likely */
4353
case OPC_BGTZL: /* 0 > 0 likely */
4354
case OPC_BLTZL: /* 0 < 0 likely */
4355
/* Skip the instruction in the delay slot */
4359
ctx->hflags |= MIPS_HFLAG_B;
4362
ctx->hflags |= MIPS_HFLAG_BX;
4366
ctx->hflags |= MIPS_HFLAG_B;
4369
ctx->hflags |= MIPS_HFLAG_BR;
4373
ctx->hflags |= MIPS_HFLAG_BR;
4376
MIPS_INVAL("branch/jump");
4377
generate_exception_end(ctx, EXCP_RI);
4383
tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4386
tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4389
tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4392
tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4395
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4398
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4401
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4405
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4409
tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4412
tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4415
tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4418
tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4421
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4424
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4427
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4429
#if defined(TARGET_MIPS64)
4431
tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4435
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4438
ctx->hflags |= MIPS_HFLAG_BC;
4441
tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4444
ctx->hflags |= MIPS_HFLAG_BL;
4447
MIPS_INVAL("conditional branch/jump");
4448
generate_exception_end(ctx, EXCP_RI);
4453
ctx->btarget = btgt;
4455
switch (delayslot_size) {
4457
ctx->hflags |= MIPS_HFLAG_BDS16;
4460
ctx->hflags |= MIPS_HFLAG_BDS32;
4465
int post_delay = insn_bytes + delayslot_size;
4466
int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4468
tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4472
if (insn_bytes == 2)
4473
ctx->hflags |= MIPS_HFLAG_B16;
4478
/* special3 bitfield operations */
4479
static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4480
int rs, int lsb, int msb)
4482
TCGv t0 = tcg_temp_new();
4483
TCGv t1 = tcg_temp_new();
4485
gen_load_gpr(t1, rs);
4488
if (lsb + msb > 31) {
4491
tcg_gen_shri_tl(t0, t1, lsb);
4493
tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4495
tcg_gen_ext32s_tl(t0, t0);
4498
#if defined(TARGET_MIPS64)
4507
if (lsb + msb > 63) {
4510
tcg_gen_shri_tl(t0, t1, lsb);
4512
tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4520
gen_load_gpr(t0, rt);
4521
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4522
tcg_gen_ext32s_tl(t0, t0);
4524
#if defined(TARGET_MIPS64)
4535
gen_load_gpr(t0, rt);
4536
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4541
MIPS_INVAL("bitops");
4542
generate_exception_end(ctx, EXCP_RI);
4547
gen_store_gpr(t0, rt);
4552
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4557
/* If no destination, treat it as a NOP. */
4561
t0 = tcg_temp_new();
4562
gen_load_gpr(t0, rt);
4566
TCGv t1 = tcg_temp_new();
4568
tcg_gen_shri_tl(t1, t0, 8);
4569
tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4570
tcg_gen_shli_tl(t0, t0, 8);
4571
tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4572
tcg_gen_or_tl(t0, t0, t1);
4574
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4578
tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4581
tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4583
#if defined(TARGET_MIPS64)
4586
TCGv t1 = tcg_temp_new();
4588
tcg_gen_shri_tl(t1, t0, 8);
4589
tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4590
tcg_gen_shli_tl(t0, t0, 8);
4591
tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4592
tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4598
TCGv t1 = tcg_temp_new();
4600
tcg_gen_shri_tl(t1, t0, 16);
4601
tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4602
tcg_gen_shli_tl(t0, t0, 16);
4603
tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4604
tcg_gen_or_tl(t0, t0, t1);
4605
tcg_gen_shri_tl(t1, t0, 32);
4606
tcg_gen_shli_tl(t0, t0, 32);
4607
tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4613
MIPS_INVAL("bsfhl");
4614
generate_exception_end(ctx, EXCP_RI);
4621
static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4630
t0 = tcg_temp_new();
4631
t1 = tcg_temp_new();
4632
gen_load_gpr(t0, rs);
4633
gen_load_gpr(t1, rt);
4634
tcg_gen_shli_tl(t0, t0, imm2 + 1);
4635
tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4636
if (opc == OPC_LSA) {
4637
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4646
static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4654
t0 = tcg_temp_new();
4655
gen_load_gpr(t0, rt);
4659
tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4661
#if defined(TARGET_MIPS64)
4663
tcg_gen_mov_tl(cpu_gpr[rd], t0);
4668
TCGv t1 = tcg_temp_new();
4669
gen_load_gpr(t1, rs);
4673
TCGv_i64 t2 = tcg_temp_new_i64();
4674
tcg_gen_concat_tl_i64(t2, t1, t0);
4675
tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4676
gen_move_low32(cpu_gpr[rd], t2);
4677
tcg_temp_free_i64(t2);
4680
#if defined(TARGET_MIPS64)
4682
tcg_gen_shli_tl(t0, t0, 8 * bp);
4683
tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4684
tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4694
static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4701
t0 = tcg_temp_new();
4702
gen_load_gpr(t0, rt);
4705
gen_helper_bitswap(cpu_gpr[rd], t0);
4707
#if defined(TARGET_MIPS64)
4709
gen_helper_dbitswap(cpu_gpr[rd], t0);
4716
#ifndef CONFIG_USER_ONLY
4717
/* CP0 (MMU and control) */
4718
static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4720
TCGv_i64 t0 = tcg_temp_new_i64();
4721
TCGv_i64 t1 = tcg_temp_new_i64();
4723
tcg_gen_ext_tl_i64(t0, arg);
4724
tcg_gen_ld_i64(t1, cpu_env, off);
4725
#if defined(TARGET_MIPS64)
4726
tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4728
tcg_gen_concat32_i64(t1, t1, t0);
4730
tcg_gen_st_i64(t1, cpu_env, off);
4731
tcg_temp_free_i64(t1);
4732
tcg_temp_free_i64(t0);
4735
static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4737
TCGv_i64 t0 = tcg_temp_new_i64();
4738
TCGv_i64 t1 = tcg_temp_new_i64();
4740
tcg_gen_ext_tl_i64(t0, arg);
4741
tcg_gen_ld_i64(t1, cpu_env, off);
4742
tcg_gen_concat32_i64(t1, t1, t0);
4743
tcg_gen_st_i64(t1, cpu_env, off);
4744
tcg_temp_free_i64(t1);
4745
tcg_temp_free_i64(t0);
4748
static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4750
TCGv_i64 t0 = tcg_temp_new_i64();
4752
tcg_gen_ld_i64(t0, cpu_env, off);
4753
#if defined(TARGET_MIPS64)
4754
tcg_gen_shri_i64(t0, t0, 30);
4756
tcg_gen_shri_i64(t0, t0, 32);
4758
gen_move_low32(arg, t0);
4759
tcg_temp_free_i64(t0);
4762
static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4764
TCGv_i64 t0 = tcg_temp_new_i64();
4766
tcg_gen_ld_i64(t0, cpu_env, off);
4767
tcg_gen_shri_i64(t0, t0, 32 + shift);
4768
gen_move_low32(arg, t0);
4769
tcg_temp_free_i64(t0);
4772
static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4774
TCGv_i32 t0 = tcg_temp_new_i32();
4776
tcg_gen_ld_i32(t0, cpu_env, off);
4777
tcg_gen_ext_i32_tl(arg, t0);
4778
tcg_temp_free_i32(t0);
4781
static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4783
tcg_gen_ld_tl(arg, cpu_env, off);
4784
tcg_gen_ext32s_tl(arg, arg);
4787
static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4789
TCGv_i32 t0 = tcg_temp_new_i32();
4791
tcg_gen_trunc_tl_i32(t0, arg);
4792
tcg_gen_st_i32(t0, cpu_env, off);
4793
tcg_temp_free_i32(t0);
4796
#define CP0_CHECK(c) \
4799
goto cp0_unimplemented; \
4803
static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4805
const char *rn = "invalid";
4807
CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4813
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4817
goto cp0_unimplemented;
4823
gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4827
goto cp0_unimplemented;
4833
gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4834
ctx->CP0_LLAddr_shift);
4838
CP0_CHECK(ctx->mrp);
4839
gen_helper_mfhc0_maar(arg, cpu_env);
4843
goto cp0_unimplemented;
4852
gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4856
goto cp0_unimplemented;
4860
goto cp0_unimplemented;
4863
(void)rn; /* avoid a compiler warning */
4864
LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4868
LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4869
tcg_gen_movi_tl(arg, 0);
4872
static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4874
const char *rn = "invalid";
4875
uint64_t mask = ctx->PAMask >> 36;
4877
CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4883
tcg_gen_andi_tl(arg, arg, mask);
4884
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4888
goto cp0_unimplemented;
4894
tcg_gen_andi_tl(arg, arg, mask);
4895
gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4899
goto cp0_unimplemented;
4905
/* LLAddr is read-only (the only exception is bit 0 if LLB is
4906
supported); the CP0_LLAddr_rw_bitmask does not seem to be
4907
relevant for modern MIPS cores supporting MTHC0, therefore
4908
treating MTHC0 to LLAddr as NOP. */
4912
CP0_CHECK(ctx->mrp);
4913
gen_helper_mthc0_maar(cpu_env, arg);
4917
goto cp0_unimplemented;
4926
tcg_gen_andi_tl(arg, arg, mask);
4927
gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4931
goto cp0_unimplemented;
4935
goto cp0_unimplemented;
4938
(void)rn; /* avoid a compiler warning */
4940
LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4943
static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4945
if (ctx->insn_flags & ISA_MIPS32R6) {
4946
tcg_gen_movi_tl(arg, 0);
4948
tcg_gen_movi_tl(arg, ~0);
4952
static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4954
const char *rn = "invalid";
4957
check_insn(ctx, ISA_MIPS32);
4963
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4967
CP0_CHECK(ctx->insn_flags & ASE_MT);
4968
gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4972
CP0_CHECK(ctx->insn_flags & ASE_MT);
4973
gen_helper_mfc0_mvpconf0(arg, cpu_env);
4977
CP0_CHECK(ctx->insn_flags & ASE_MT);
4978
gen_helper_mfc0_mvpconf1(arg, cpu_env);
4983
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4987
goto cp0_unimplemented;
4993
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4994
gen_helper_mfc0_random(arg, cpu_env);
4998
CP0_CHECK(ctx->insn_flags & ASE_MT);
4999
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5003
CP0_CHECK(ctx->insn_flags & ASE_MT);
5004
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5008
CP0_CHECK(ctx->insn_flags & ASE_MT);
5009
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5013
CP0_CHECK(ctx->insn_flags & ASE_MT);
5014
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5018
CP0_CHECK(ctx->insn_flags & ASE_MT);
5019
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5023
CP0_CHECK(ctx->insn_flags & ASE_MT);
5024
gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5025
rn = "VPEScheFBack";
5028
CP0_CHECK(ctx->insn_flags & ASE_MT);
5029
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5033
goto cp0_unimplemented;
5040
TCGv_i64 tmp = tcg_temp_new_i64();
5041
tcg_gen_ld_i64(tmp, cpu_env,
5042
offsetof(CPUMIPSState, CP0_EntryLo0));
5043
#if defined(TARGET_MIPS64)
5045
/* Move RI/XI fields to bits 31:30 */
5046
tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5047
tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5050
gen_move_low32(arg, tmp);
5051
tcg_temp_free_i64(tmp);
5056
CP0_CHECK(ctx->insn_flags & ASE_MT);
5057
gen_helper_mfc0_tcstatus(arg, cpu_env);
5061
CP0_CHECK(ctx->insn_flags & ASE_MT);
5062
gen_helper_mfc0_tcbind(arg, cpu_env);
5066
CP0_CHECK(ctx->insn_flags & ASE_MT);
5067
gen_helper_mfc0_tcrestart(arg, cpu_env);
5071
CP0_CHECK(ctx->insn_flags & ASE_MT);
5072
gen_helper_mfc0_tchalt(arg, cpu_env);
5076
CP0_CHECK(ctx->insn_flags & ASE_MT);
5077
gen_helper_mfc0_tccontext(arg, cpu_env);
5081
CP0_CHECK(ctx->insn_flags & ASE_MT);
5082
gen_helper_mfc0_tcschedule(arg, cpu_env);
5086
CP0_CHECK(ctx->insn_flags & ASE_MT);
5087
gen_helper_mfc0_tcschefback(arg, cpu_env);
5091
goto cp0_unimplemented;
5098
TCGv_i64 tmp = tcg_temp_new_i64();
5099
tcg_gen_ld_i64(tmp, cpu_env,
5100
offsetof(CPUMIPSState, CP0_EntryLo1));
5101
#if defined(TARGET_MIPS64)
5103
/* Move RI/XI fields to bits 31:30 */
5104
tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5105
tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5108
gen_move_low32(arg, tmp);
5109
tcg_temp_free_i64(tmp);
5115
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5116
rn = "GlobalNumber";
5119
goto cp0_unimplemented;
5125
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5126
tcg_gen_ext32s_tl(arg, arg);
5130
// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5131
rn = "ContextConfig";
5132
goto cp0_unimplemented;
5135
CP0_CHECK(ctx->ulri);
5136
tcg_gen_ld32s_tl(arg, cpu_env,
5137
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5141
goto cp0_unimplemented;
5147
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5151
check_insn(ctx, ISA_MIPS32R2);
5152
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5156
goto cp0_unimplemented;
5162
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5166
check_insn(ctx, ISA_MIPS32R2);
5167
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5171
check_insn(ctx, ISA_MIPS32R2);
5172
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5176
check_insn(ctx, ISA_MIPS32R2);
5177
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5181
check_insn(ctx, ISA_MIPS32R2);
5182
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5186
check_insn(ctx, ISA_MIPS32R2);
5187
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5191
goto cp0_unimplemented;
5197
check_insn(ctx, ISA_MIPS32R2);
5198
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5202
goto cp0_unimplemented;
5208
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5209
tcg_gen_ext32s_tl(arg, arg);
5214
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5219
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5223
goto cp0_unimplemented;
5229
/* Mark as an IO operation because we read the time. */
5230
if (ctx->tb->cflags & CF_USE_ICOUNT) {
5233
gen_helper_mfc0_count(arg, cpu_env);
5234
if (ctx->tb->cflags & CF_USE_ICOUNT) {
5237
/* Break the TB to be able to take timer interrupts immediately
5238
after reading count. */
5239
ctx->bstate = BS_STOP;
5242
/* 6,7 are implementation dependent */
5244
goto cp0_unimplemented;
5250
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5251
tcg_gen_ext32s_tl(arg, arg);
5255
goto cp0_unimplemented;
5261
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5264
/* 6,7 are implementation dependent */
5266
goto cp0_unimplemented;
5272
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5276
check_insn(ctx, ISA_MIPS32R2);
5277
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5281
check_insn(ctx, ISA_MIPS32R2);
5282
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5286
check_insn(ctx, ISA_MIPS32R2);
5287
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5291
goto cp0_unimplemented;
5297
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5301
goto cp0_unimplemented;
5307
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5308
tcg_gen_ext32s_tl(arg, arg);
5312
goto cp0_unimplemented;
5318
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5322
check_insn(ctx, ISA_MIPS32R2);
5323
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5327
check_insn(ctx, ISA_MIPS32R2);
5328
CP0_CHECK(ctx->cmgcr);
5329
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5330
tcg_gen_ext32s_tl(arg, arg);
5334
goto cp0_unimplemented;
5340
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5344
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5348
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5352
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5356
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5360
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5363
/* 6,7 are implementation dependent */
5365
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5369
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5373
goto cp0_unimplemented;
5379
gen_helper_mfc0_lladdr(arg, cpu_env);
5383
CP0_CHECK(ctx->mrp);
5384
gen_helper_mfc0_maar(arg, cpu_env);
5388
CP0_CHECK(ctx->mrp);
5389
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5393
goto cp0_unimplemented;
5399
gen_helper_1e0i(mfc0_watchlo, arg, sel);
5403
goto cp0_unimplemented;
5409
gen_helper_1e0i(mfc0_watchhi, arg, sel);
5413
goto cp0_unimplemented;
5419
#if defined(TARGET_MIPS64)
5420
check_insn(ctx, ISA_MIPS3);
5421
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5422
tcg_gen_ext32s_tl(arg, arg);
5427
goto cp0_unimplemented;
5431
/* Officially reserved, but sel 0 is used for R1x000 framemask */
5432
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5435
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5439
goto cp0_unimplemented;
5443
tcg_gen_movi_tl(arg, 0); /* unimplemented */
5444
rn = "'Diagnostic"; /* implementation dependent */
5449
gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5453
// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5454
rn = "TraceControl";
5457
// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5458
rn = "TraceControl2";
5461
// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5462
rn = "UserTraceData";
5465
// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5469
goto cp0_unimplemented;
5476
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5477
tcg_gen_ext32s_tl(arg, arg);
5481
goto cp0_unimplemented;
5487
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5488
rn = "Performance0";
5491
// gen_helper_mfc0_performance1(arg);
5492
rn = "Performance1";
5495
// gen_helper_mfc0_performance2(arg);
5496
rn = "Performance2";
5499
// gen_helper_mfc0_performance3(arg);
5500
rn = "Performance3";
5503
// gen_helper_mfc0_performance4(arg);
5504
rn = "Performance4";
5507
// gen_helper_mfc0_performance5(arg);
5508
rn = "Performance5";
5511
// gen_helper_mfc0_performance6(arg);
5512
rn = "Performance6";
5515
// gen_helper_mfc0_performance7(arg);
5516
rn = "Performance7";
5519
goto cp0_unimplemented;
5525
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5529
goto cp0_unimplemented;
5535
tcg_gen_movi_tl(arg, 0); /* unimplemented */
5539
goto cp0_unimplemented;
5549
TCGv_i64 tmp = tcg_temp_new_i64();
5550
tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5551
gen_move_low32(arg, tmp);
5552
tcg_temp_free_i64(tmp);
5560
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5564
goto cp0_unimplemented;
5573
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5580
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5584
goto cp0_unimplemented;
5590
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5591
tcg_gen_ext32s_tl(arg, arg);
5595
goto cp0_unimplemented;
5602
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5606
CP0_CHECK(ctx->kscrexist & (1 << sel));
5607
tcg_gen_ld_tl(arg, cpu_env,
5608
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5609
tcg_gen_ext32s_tl(arg, arg);
5613
goto cp0_unimplemented;
5617
goto cp0_unimplemented;
5619
(void)rn; /* avoid a compiler warning */
5620
LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5624
LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5625
gen_mfc0_unimplemented(ctx, arg);
5628
static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5630
const char *rn = "invalid";
5633
check_insn(ctx, ISA_MIPS32);
5635
if (ctx->tb->cflags & CF_USE_ICOUNT) {
5643
gen_helper_mtc0_index(cpu_env, arg);
5647
CP0_CHECK(ctx->insn_flags & ASE_MT);
5648
gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5652
CP0_CHECK(ctx->insn_flags & ASE_MT);
5657
CP0_CHECK(ctx->insn_flags & ASE_MT);
5667
goto cp0_unimplemented;
5677
CP0_CHECK(ctx->insn_flags & ASE_MT);
5678
gen_helper_mtc0_vpecontrol(cpu_env, arg);
5682
CP0_CHECK(ctx->insn_flags & ASE_MT);
5683
gen_helper_mtc0_vpeconf0(cpu_env, arg);
5687
CP0_CHECK(ctx->insn_flags & ASE_MT);
5688
gen_helper_mtc0_vpeconf1(cpu_env, arg);
5692
CP0_CHECK(ctx->insn_flags & ASE_MT);
5693
gen_helper_mtc0_yqmask(cpu_env, arg);
5697
CP0_CHECK(ctx->insn_flags & ASE_MT);
5698
tcg_gen_st_tl(arg, cpu_env,
5699
offsetof(CPUMIPSState, CP0_VPESchedule));
5703
CP0_CHECK(ctx->insn_flags & ASE_MT);
5704
tcg_gen_st_tl(arg, cpu_env,
5705
offsetof(CPUMIPSState, CP0_VPEScheFBack));
5706
rn = "VPEScheFBack";
5709
CP0_CHECK(ctx->insn_flags & ASE_MT);
5710
gen_helper_mtc0_vpeopt(cpu_env, arg);
5714
goto cp0_unimplemented;
5720
gen_helper_mtc0_entrylo0(cpu_env, arg);
5724
CP0_CHECK(ctx->insn_flags & ASE_MT);
5725
gen_helper_mtc0_tcstatus(cpu_env, arg);
5729
CP0_CHECK(ctx->insn_flags & ASE_MT);
5730
gen_helper_mtc0_tcbind(cpu_env, arg);
5734
CP0_CHECK(ctx->insn_flags & ASE_MT);
5735
gen_helper_mtc0_tcrestart(cpu_env, arg);
5739
CP0_CHECK(ctx->insn_flags & ASE_MT);
5740
gen_helper_mtc0_tchalt(cpu_env, arg);
5744
CP0_CHECK(ctx->insn_flags & ASE_MT);
5745
gen_helper_mtc0_tccontext(cpu_env, arg);
5749
CP0_CHECK(ctx->insn_flags & ASE_MT);
5750
gen_helper_mtc0_tcschedule(cpu_env, arg);
5754
CP0_CHECK(ctx->insn_flags & ASE_MT);
5755
gen_helper_mtc0_tcschefback(cpu_env, arg);
5759
goto cp0_unimplemented;
5765
gen_helper_mtc0_entrylo1(cpu_env, arg);
5771
rn = "GlobalNumber";
5774
goto cp0_unimplemented;
5780
gen_helper_mtc0_context(cpu_env, arg);
5784
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5785
rn = "ContextConfig";
5786
goto cp0_unimplemented;
5789
CP0_CHECK(ctx->ulri);
5790
tcg_gen_st_tl(arg, cpu_env,
5791
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5795
goto cp0_unimplemented;
5801
gen_helper_mtc0_pagemask(cpu_env, arg);
5805
check_insn(ctx, ISA_MIPS32R2);
5806
gen_helper_mtc0_pagegrain(cpu_env, arg);
5808
ctx->bstate = BS_STOP;
5811
goto cp0_unimplemented;
5817
gen_helper_mtc0_wired(cpu_env, arg);
5821
check_insn(ctx, ISA_MIPS32R2);
5822
gen_helper_mtc0_srsconf0(cpu_env, arg);
5826
check_insn(ctx, ISA_MIPS32R2);
5827
gen_helper_mtc0_srsconf1(cpu_env, arg);
5831
check_insn(ctx, ISA_MIPS32R2);
5832
gen_helper_mtc0_srsconf2(cpu_env, arg);
5836
check_insn(ctx, ISA_MIPS32R2);
5837
gen_helper_mtc0_srsconf3(cpu_env, arg);
5841
check_insn(ctx, ISA_MIPS32R2);
5842
gen_helper_mtc0_srsconf4(cpu_env, arg);
5846
goto cp0_unimplemented;
5852
check_insn(ctx, ISA_MIPS32R2);
5853
gen_helper_mtc0_hwrena(cpu_env, arg);
5854
ctx->bstate = BS_STOP;
5858
goto cp0_unimplemented;
5876
goto cp0_unimplemented;
5882
gen_helper_mtc0_count(cpu_env, arg);
5885
/* 6,7 are implementation dependent */
5887
goto cp0_unimplemented;
5893
gen_helper_mtc0_entryhi(cpu_env, arg);
5897
goto cp0_unimplemented;
5903
gen_helper_mtc0_compare(cpu_env, arg);
5906
/* 6,7 are implementation dependent */
5908
goto cp0_unimplemented;
5914
save_cpu_state(ctx, 1);
5915
gen_helper_mtc0_status(cpu_env, arg);
5916
/* BS_STOP isn't good enough here, hflags may have changed. */
5917
gen_save_pc(ctx->pc + 4);
5918
ctx->bstate = BS_EXCP;
5922
check_insn(ctx, ISA_MIPS32R2);
5923
gen_helper_mtc0_intctl(cpu_env, arg);
5924
/* Stop translation as we may have switched the execution mode */
5925
ctx->bstate = BS_STOP;
5929
check_insn(ctx, ISA_MIPS32R2);
5930
gen_helper_mtc0_srsctl(cpu_env, arg);
5931
/* Stop translation as we may have switched the execution mode */
5932
ctx->bstate = BS_STOP;
5936
check_insn(ctx, ISA_MIPS32R2);
5937
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5938
/* Stop translation as we may have switched the execution mode */
5939
ctx->bstate = BS_STOP;
5943
goto cp0_unimplemented;
5949
save_cpu_state(ctx, 1);
5950
gen_helper_mtc0_cause(cpu_env, arg);
5954
goto cp0_unimplemented;
5960
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5964
goto cp0_unimplemented;
5974
check_insn(ctx, ISA_MIPS32R2);
5975
gen_helper_mtc0_ebase(cpu_env, arg);
5979
goto cp0_unimplemented;
5985
gen_helper_mtc0_config0(cpu_env, arg);
5987
/* Stop translation as we may have switched the execution mode */
5988
ctx->bstate = BS_STOP;
5991
/* ignored, read only */
5995
gen_helper_mtc0_config2(cpu_env, arg);
5997
/* Stop translation as we may have switched the execution mode */
5998
ctx->bstate = BS_STOP;
6001
gen_helper_mtc0_config3(cpu_env, arg);
6003
/* Stop translation as we may have switched the execution mode */
6004
ctx->bstate = BS_STOP;
6007
gen_helper_mtc0_config4(cpu_env, arg);
6009
ctx->bstate = BS_STOP;
6012
gen_helper_mtc0_config5(cpu_env, arg);
6014
/* Stop translation as we may have switched the execution mode */
6015
ctx->bstate = BS_STOP;
6017
/* 6,7 are implementation dependent */
6027
rn = "Invalid config selector";
6028
goto cp0_unimplemented;
6034
gen_helper_mtc0_lladdr(cpu_env, arg);
6038
CP0_CHECK(ctx->mrp);
6039
gen_helper_mtc0_maar(cpu_env, arg);
6043
CP0_CHECK(ctx->mrp);
6044
gen_helper_mtc0_maari(cpu_env, arg);
6048
goto cp0_unimplemented;
6054
gen_helper_0e1i(mtc0_watchlo, arg, sel);
6058
goto cp0_unimplemented;
6064
gen_helper_0e1i(mtc0_watchhi, arg, sel);
6068
goto cp0_unimplemented;
6074
#if defined(TARGET_MIPS64)
6075
check_insn(ctx, ISA_MIPS3);
6076
gen_helper_mtc0_xcontext(cpu_env, arg);
6081
goto cp0_unimplemented;
6085
/* Officially reserved, but sel 0 is used for R1x000 framemask */
6086
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6089
gen_helper_mtc0_framemask(cpu_env, arg);
6093
goto cp0_unimplemented;
6098
rn = "Diagnostic"; /* implementation dependent */
6103
gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6104
/* BS_STOP isn't good enough here, hflags may have changed. */
6105
gen_save_pc(ctx->pc + 4);
6106
ctx->bstate = BS_EXCP;
6110
// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6111
rn = "TraceControl";
6112
/* Stop translation as we may have switched the execution mode */
6113
ctx->bstate = BS_STOP;
6116
// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6117
rn = "TraceControl2";
6118
/* Stop translation as we may have switched the execution mode */
6119
ctx->bstate = BS_STOP;
6122
/* Stop translation as we may have switched the execution mode */
6123
ctx->bstate = BS_STOP;
6124
// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6125
rn = "UserTraceData";
6126
/* Stop translation as we may have switched the execution mode */
6127
ctx->bstate = BS_STOP;
6130
// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6131
/* Stop translation as we may have switched the execution mode */
6132
ctx->bstate = BS_STOP;
6136
goto cp0_unimplemented;
6143
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6147
goto cp0_unimplemented;
6153
gen_helper_mtc0_performance0(cpu_env, arg);
6154
rn = "Performance0";
6157
// gen_helper_mtc0_performance1(arg);
6158
rn = "Performance1";
6161
// gen_helper_mtc0_performance2(arg);
6162
rn = "Performance2";
6165
// gen_helper_mtc0_performance3(arg);
6166
rn = "Performance3";
6169
// gen_helper_mtc0_performance4(arg);
6170
rn = "Performance4";
6173
// gen_helper_mtc0_performance5(arg);
6174
rn = "Performance5";
6177
// gen_helper_mtc0_performance6(arg);
6178
rn = "Performance6";
6181
// gen_helper_mtc0_performance7(arg);
6182
rn = "Performance7";
6185
goto cp0_unimplemented;
6191
gen_helper_mtc0_errctl(cpu_env, arg);
6192
ctx->bstate = BS_STOP;
6196
goto cp0_unimplemented;
6206
goto cp0_unimplemented;
6215
gen_helper_mtc0_taglo(cpu_env, arg);
6222
gen_helper_mtc0_datalo(cpu_env, arg);
6226
goto cp0_unimplemented;
6235
gen_helper_mtc0_taghi(cpu_env, arg);
6242
gen_helper_mtc0_datahi(cpu_env, arg);
6247
goto cp0_unimplemented;
6253
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6257
goto cp0_unimplemented;
6264
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6268
CP0_CHECK(ctx->kscrexist & (1 << sel));
6269
tcg_gen_st_tl(arg, cpu_env,
6270
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6274
goto cp0_unimplemented;
6276
/* Stop translation as we may have switched the execution mode */
6277
ctx->bstate = BS_STOP;
6280
goto cp0_unimplemented;
6282
(void)rn; /* avoid a compiler warning */
6283
LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6284
/* For simplicity assume that all writes can cause interrupts. */
6285
if (ctx->tb->cflags & CF_USE_ICOUNT) {
6287
ctx->bstate = BS_STOP;
6292
LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6295
#if defined(TARGET_MIPS64)
6296
static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6298
const char *rn = "invalid";
6301
check_insn(ctx, ISA_MIPS64);
6307
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6311
CP0_CHECK(ctx->insn_flags & ASE_MT);
6312
gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6316
CP0_CHECK(ctx->insn_flags & ASE_MT);
6317
gen_helper_mfc0_mvpconf0(arg, cpu_env);
6321
CP0_CHECK(ctx->insn_flags & ASE_MT);
6322
gen_helper_mfc0_mvpconf1(arg, cpu_env);
6327
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6331
goto cp0_unimplemented;
6337
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6338
gen_helper_mfc0_random(arg, cpu_env);
6342
CP0_CHECK(ctx->insn_flags & ASE_MT);
6343
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6347
CP0_CHECK(ctx->insn_flags & ASE_MT);
6348
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6352
CP0_CHECK(ctx->insn_flags & ASE_MT);
6353
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6357
CP0_CHECK(ctx->insn_flags & ASE_MT);
6358
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6362
CP0_CHECK(ctx->insn_flags & ASE_MT);
6363
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6367
CP0_CHECK(ctx->insn_flags & ASE_MT);
6368
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6369
rn = "VPEScheFBack";
6372
CP0_CHECK(ctx->insn_flags & ASE_MT);
6373
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6377
goto cp0_unimplemented;
6383
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6387
CP0_CHECK(ctx->insn_flags & ASE_MT);
6388
gen_helper_mfc0_tcstatus(arg, cpu_env);
6392
CP0_CHECK(ctx->insn_flags & ASE_MT);
6393
gen_helper_mfc0_tcbind(arg, cpu_env);
6397
CP0_CHECK(ctx->insn_flags & ASE_MT);
6398
gen_helper_dmfc0_tcrestart(arg, cpu_env);
6402
CP0_CHECK(ctx->insn_flags & ASE_MT);
6403
gen_helper_dmfc0_tchalt(arg, cpu_env);
6407
CP0_CHECK(ctx->insn_flags & ASE_MT);
6408
gen_helper_dmfc0_tccontext(arg, cpu_env);
6412
CP0_CHECK(ctx->insn_flags & ASE_MT);
6413
gen_helper_dmfc0_tcschedule(arg, cpu_env);
6417
CP0_CHECK(ctx->insn_flags & ASE_MT);
6418
gen_helper_dmfc0_tcschefback(arg, cpu_env);
6422
goto cp0_unimplemented;
6428
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6433
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6434
rn = "GlobalNumber";
6437
goto cp0_unimplemented;
6443
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6447
// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6448
rn = "ContextConfig";
6449
goto cp0_unimplemented;
6452
CP0_CHECK(ctx->ulri);
6453
tcg_gen_ld_tl(arg, cpu_env,
6454
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6458
goto cp0_unimplemented;
6464
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6468
check_insn(ctx, ISA_MIPS32R2);
6469
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6473
goto cp0_unimplemented;
6479
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6483
check_insn(ctx, ISA_MIPS32R2);
6484
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6488
check_insn(ctx, ISA_MIPS32R2);
6489
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6493
check_insn(ctx, ISA_MIPS32R2);
6494
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6498
check_insn(ctx, ISA_MIPS32R2);
6499
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6503
check_insn(ctx, ISA_MIPS32R2);
6504
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6508
goto cp0_unimplemented;
6514
check_insn(ctx, ISA_MIPS32R2);
6515
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6519
goto cp0_unimplemented;
6525
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6530
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6535
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6539
goto cp0_unimplemented;
6545
/* Mark as an IO operation because we read the time. */
6546
if (ctx->tb->cflags & CF_USE_ICOUNT) {
6549
gen_helper_mfc0_count(arg, cpu_env);
6550
if (ctx->tb->cflags & CF_USE_ICOUNT) {
6553
/* Break the TB to be able to take timer interrupts immediately
6554
after reading count. */
6555
ctx->bstate = BS_STOP;
6558
/* 6,7 are implementation dependent */
6560
goto cp0_unimplemented;
6566
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6570
goto cp0_unimplemented;
6576
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6579
/* 6,7 are implementation dependent */
6581
goto cp0_unimplemented;
6587
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6591
check_insn(ctx, ISA_MIPS32R2);
6592
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6596
check_insn(ctx, ISA_MIPS32R2);
6597
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6601
check_insn(ctx, ISA_MIPS32R2);
6602
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6606
goto cp0_unimplemented;
6612
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6616
goto cp0_unimplemented;
6622
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6626
goto cp0_unimplemented;
6632
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6636
check_insn(ctx, ISA_MIPS32R2);
6637
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6641
check_insn(ctx, ISA_MIPS32R2);
6642
CP0_CHECK(ctx->cmgcr);
6643
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6647
goto cp0_unimplemented;
6653
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6657
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6661
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6665
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6669
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6673
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6676
/* 6,7 are implementation dependent */
6678
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6682
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6686
goto cp0_unimplemented;
6692
gen_helper_dmfc0_lladdr(arg, cpu_env);
6696
CP0_CHECK(ctx->mrp);
6697
gen_helper_dmfc0_maar(arg, cpu_env);
6701
CP0_CHECK(ctx->mrp);
6702
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6706
goto cp0_unimplemented;
6712
gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6716
goto cp0_unimplemented;
6722
gen_helper_1e0i(mfc0_watchhi, arg, sel);
6726
goto cp0_unimplemented;
6732
check_insn(ctx, ISA_MIPS3);
6733
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6737
goto cp0_unimplemented;
6741
/* Officially reserved, but sel 0 is used for R1x000 framemask */
6742
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6745
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6749
goto cp0_unimplemented;
6753
tcg_gen_movi_tl(arg, 0); /* unimplemented */
6754
rn = "'Diagnostic"; /* implementation dependent */
6759
gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6763
// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6764
rn = "TraceControl";
6767
// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6768
rn = "TraceControl2";
6771
// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6772
rn = "UserTraceData";
6775
// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6779
goto cp0_unimplemented;
6786
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6790
goto cp0_unimplemented;
6796
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6797
rn = "Performance0";
6800
// gen_helper_dmfc0_performance1(arg);
6801
rn = "Performance1";
6804
// gen_helper_dmfc0_performance2(arg);
6805
rn = "Performance2";
6808
// gen_helper_dmfc0_performance3(arg);
6809
rn = "Performance3";
6812
// gen_helper_dmfc0_performance4(arg);
6813
rn = "Performance4";
6816
// gen_helper_dmfc0_performance5(arg);
6817
rn = "Performance5";
6820
// gen_helper_dmfc0_performance6(arg);
6821
rn = "Performance6";
6824
// gen_helper_dmfc0_performance7(arg);
6825
rn = "Performance7";
6828
goto cp0_unimplemented;
6834
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6838
goto cp0_unimplemented;
6845
tcg_gen_movi_tl(arg, 0); /* unimplemented */
6849
goto cp0_unimplemented;
6858
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6865
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6869
goto cp0_unimplemented;
6878
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6885
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6889
goto cp0_unimplemented;
6895
tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6899
goto cp0_unimplemented;
6906
gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6910
CP0_CHECK(ctx->kscrexist & (1 << sel));
6911
tcg_gen_ld_tl(arg, cpu_env,
6912
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6916
goto cp0_unimplemented;
6920
goto cp0_unimplemented;
6922
(void)rn; /* avoid a compiler warning */
6923
LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6927
LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6928
gen_mfc0_unimplemented(ctx, arg);
6931
static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6933
const char *rn = "invalid";
6936
check_insn(ctx, ISA_MIPS64);
6938
if (ctx->tb->cflags & CF_USE_ICOUNT) {
6946
gen_helper_mtc0_index(cpu_env, arg);
6950
CP0_CHECK(ctx->insn_flags & ASE_MT);
6951
gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6955
CP0_CHECK(ctx->insn_flags & ASE_MT);
6960
CP0_CHECK(ctx->insn_flags & ASE_MT);
6970
goto cp0_unimplemented;
6980
CP0_CHECK(ctx->insn_flags & ASE_MT);
6981
gen_helper_mtc0_vpecontrol(cpu_env, arg);
6985
CP0_CHECK(ctx->insn_flags & ASE_MT);
6986
gen_helper_mtc0_vpeconf0(cpu_env, arg);
6990
CP0_CHECK(ctx->insn_flags & ASE_MT);
6991
gen_helper_mtc0_vpeconf1(cpu_env, arg);
6995
CP0_CHECK(ctx->insn_flags & ASE_MT);
6996
gen_helper_mtc0_yqmask(cpu_env, arg);
7000
CP0_CHECK(ctx->insn_flags & ASE_MT);
7001
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7005
CP0_CHECK(ctx->insn_flags & ASE_MT);
7006
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7007
rn = "VPEScheFBack";
7010
CP0_CHECK(ctx->insn_flags & ASE_MT);
7011
gen_helper_mtc0_vpeopt(cpu_env, arg);
7015
goto cp0_unimplemented;
7021
gen_helper_dmtc0_entrylo0(cpu_env, arg);
7025
CP0_CHECK(ctx->insn_flags & ASE_MT);
7026
gen_helper_mtc0_tcstatus(cpu_env, arg);
7030
CP0_CHECK(ctx->insn_flags & ASE_MT);
7031
gen_helper_mtc0_tcbind(cpu_env, arg);
7035
CP0_CHECK(ctx->insn_flags & ASE_MT);
7036
gen_helper_mtc0_tcrestart(cpu_env, arg);
7040
CP0_CHECK(ctx->insn_flags & ASE_MT);
7041
gen_helper_mtc0_tchalt(cpu_env, arg);
7045
CP0_CHECK(ctx->insn_flags & ASE_MT);
7046
gen_helper_mtc0_tccontext(cpu_env, arg);
7050
CP0_CHECK(ctx->insn_flags & ASE_MT);
7051
gen_helper_mtc0_tcschedule(cpu_env, arg);
7055
CP0_CHECK(ctx->insn_flags & ASE_MT);
7056
gen_helper_mtc0_tcschefback(cpu_env, arg);
7060
goto cp0_unimplemented;
7066
gen_helper_dmtc0_entrylo1(cpu_env, arg);
7072
rn = "GlobalNumber";
7075
goto cp0_unimplemented;
7081
gen_helper_mtc0_context(cpu_env, arg);
7085
// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7086
rn = "ContextConfig";
7087
goto cp0_unimplemented;
7090
CP0_CHECK(ctx->ulri);
7091
tcg_gen_st_tl(arg, cpu_env,
7092
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7096
goto cp0_unimplemented;
7102
gen_helper_mtc0_pagemask(cpu_env, arg);
7106
check_insn(ctx, ISA_MIPS32R2);
7107
gen_helper_mtc0_pagegrain(cpu_env, arg);
7111
goto cp0_unimplemented;
7117
gen_helper_mtc0_wired(cpu_env, arg);
7121
check_insn(ctx, ISA_MIPS32R2);
7122
gen_helper_mtc0_srsconf0(cpu_env, arg);
7126
check_insn(ctx, ISA_MIPS32R2);
7127
gen_helper_mtc0_srsconf1(cpu_env, arg);
7131
check_insn(ctx, ISA_MIPS32R2);
7132
gen_helper_mtc0_srsconf2(cpu_env, arg);
7136
check_insn(ctx, ISA_MIPS32R2);
7137
gen_helper_mtc0_srsconf3(cpu_env, arg);
7141
check_insn(ctx, ISA_MIPS32R2);
7142
gen_helper_mtc0_srsconf4(cpu_env, arg);
7146
goto cp0_unimplemented;
7152
check_insn(ctx, ISA_MIPS32R2);
7153
gen_helper_mtc0_hwrena(cpu_env, arg);
7154
ctx->bstate = BS_STOP;
7158
goto cp0_unimplemented;
7176
goto cp0_unimplemented;
7182
gen_helper_mtc0_count(cpu_env, arg);
7185
/* 6,7 are implementation dependent */
7187
goto cp0_unimplemented;
7189
/* Stop translation as we may have switched the execution mode */
7190
ctx->bstate = BS_STOP;
7195
gen_helper_mtc0_entryhi(cpu_env, arg);
7199
goto cp0_unimplemented;
7205
gen_helper_mtc0_compare(cpu_env, arg);
7208
/* 6,7 are implementation dependent */
7210
goto cp0_unimplemented;
7212
/* Stop translation as we may have switched the execution mode */
7213
ctx->bstate = BS_STOP;
7218
save_cpu_state(ctx, 1);
7219
gen_helper_mtc0_status(cpu_env, arg);
7220
/* BS_STOP isn't good enough here, hflags may have changed. */
7221
gen_save_pc(ctx->pc + 4);
7222
ctx->bstate = BS_EXCP;
7226
check_insn(ctx, ISA_MIPS32R2);
7227
gen_helper_mtc0_intctl(cpu_env, arg);
7228
/* Stop translation as we may have switched the execution mode */
7229
ctx->bstate = BS_STOP;
7233
check_insn(ctx, ISA_MIPS32R2);
7234
gen_helper_mtc0_srsctl(cpu_env, arg);
7235
/* Stop translation as we may have switched the execution mode */
7236
ctx->bstate = BS_STOP;
7240
check_insn(ctx, ISA_MIPS32R2);
7241
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7242
/* Stop translation as we may have switched the execution mode */
7243
ctx->bstate = BS_STOP;
7247
goto cp0_unimplemented;
7253
save_cpu_state(ctx, 1);
7254
/* Mark as an IO operation because we may trigger a software
7256
if (ctx->tb->cflags & CF_USE_ICOUNT) {
7259
gen_helper_mtc0_cause(cpu_env, arg);
7260
if (ctx->tb->cflags & CF_USE_ICOUNT) {
7263
/* Stop translation as we may have triggered an intetrupt */
7264
ctx->bstate = BS_STOP;
7268
goto cp0_unimplemented;
7274
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7278
goto cp0_unimplemented;
7288
check_insn(ctx, ISA_MIPS32R2);
7289
gen_helper_mtc0_ebase(cpu_env, arg);
7293
goto cp0_unimplemented;
7299
gen_helper_mtc0_config0(cpu_env, arg);
7301
/* Stop translation as we may have switched the execution mode */
7302
ctx->bstate = BS_STOP;
7305
/* ignored, read only */
7309
gen_helper_mtc0_config2(cpu_env, arg);
7311
/* Stop translation as we may have switched the execution mode */
7312
ctx->bstate = BS_STOP;
7315
gen_helper_mtc0_config3(cpu_env, arg);
7317
/* Stop translation as we may have switched the execution mode */
7318
ctx->bstate = BS_STOP;
7321
/* currently ignored */
7325
gen_helper_mtc0_config5(cpu_env, arg);
7327
/* Stop translation as we may have switched the execution mode */
7328
ctx->bstate = BS_STOP;
7330
/* 6,7 are implementation dependent */
7332
rn = "Invalid config selector";
7333
goto cp0_unimplemented;
7339
gen_helper_mtc0_lladdr(cpu_env, arg);
7343
CP0_CHECK(ctx->mrp);
7344
gen_helper_mtc0_maar(cpu_env, arg);
7348
CP0_CHECK(ctx->mrp);
7349
gen_helper_mtc0_maari(cpu_env, arg);
7353
goto cp0_unimplemented;
7359
gen_helper_0e1i(mtc0_watchlo, arg, sel);
7363
goto cp0_unimplemented;
7369
gen_helper_0e1i(mtc0_watchhi, arg, sel);
7373
goto cp0_unimplemented;
7379
check_insn(ctx, ISA_MIPS3);
7380
gen_helper_mtc0_xcontext(cpu_env, arg);
7384
goto cp0_unimplemented;
7388
/* Officially reserved, but sel 0 is used for R1x000 framemask */
7389
CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7392
gen_helper_mtc0_framemask(cpu_env, arg);
7396
goto cp0_unimplemented;
7401
rn = "Diagnostic"; /* implementation dependent */
7406
gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7407
/* BS_STOP isn't good enough here, hflags may have changed. */
7408
gen_save_pc(ctx->pc + 4);
7409
ctx->bstate = BS_EXCP;
7413
// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7414
/* Stop translation as we may have switched the execution mode */
7415
ctx->bstate = BS_STOP;
7416
rn = "TraceControl";
7419
// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7420
/* Stop translation as we may have switched the execution mode */
7421
ctx->bstate = BS_STOP;
7422
rn = "TraceControl2";
7425
// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7426
/* Stop translation as we may have switched the execution mode */
7427
ctx->bstate = BS_STOP;
7428
rn = "UserTraceData";
7431
// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7432
/* Stop translation as we may have switched the execution mode */
7433
ctx->bstate = BS_STOP;
7437
goto cp0_unimplemented;
7444
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7448
goto cp0_unimplemented;
7454
gen_helper_mtc0_performance0(cpu_env, arg);
7455
rn = "Performance0";
7458
// gen_helper_mtc0_performance1(cpu_env, arg);
7459
rn = "Performance1";
7462
// gen_helper_mtc0_performance2(cpu_env, arg);
7463
rn = "Performance2";
7466
// gen_helper_mtc0_performance3(cpu_env, arg);
7467
rn = "Performance3";
7470
// gen_helper_mtc0_performance4(cpu_env, arg);
7471
rn = "Performance4";
7474
// gen_helper_mtc0_performance5(cpu_env, arg);
7475
rn = "Performance5";
7478
// gen_helper_mtc0_performance6(cpu_env, arg);
7479
rn = "Performance6";
7482
// gen_helper_mtc0_performance7(cpu_env, arg);
7483
rn = "Performance7";
7486
goto cp0_unimplemented;
7492
gen_helper_mtc0_errctl(cpu_env, arg);
7493
ctx->bstate = BS_STOP;
7497
goto cp0_unimplemented;
7507
goto cp0_unimplemented;
7516
gen_helper_mtc0_taglo(cpu_env, arg);
7523
gen_helper_mtc0_datalo(cpu_env, arg);
7527
goto cp0_unimplemented;
7536
gen_helper_mtc0_taghi(cpu_env, arg);
7543
gen_helper_mtc0_datahi(cpu_env, arg);
7548
goto cp0_unimplemented;
7554
tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7558
goto cp0_unimplemented;
7565
gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7569
CP0_CHECK(ctx->kscrexist & (1 << sel));
7570
tcg_gen_st_tl(arg, cpu_env,
7571
offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7575
goto cp0_unimplemented;
7577
/* Stop translation as we may have switched the execution mode */
7578
ctx->bstate = BS_STOP;
7581
goto cp0_unimplemented;
7583
(void)rn; /* avoid a compiler warning */
7584
LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7585
/* For simplicity assume that all writes can cause interrupts. */
7586
if (ctx->tb->cflags & CF_USE_ICOUNT) {
7588
ctx->bstate = BS_STOP;
7593
LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7595
#endif /* TARGET_MIPS64 */
7597
static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7598
int u, int sel, int h)
7600
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7601
TCGv t0 = tcg_temp_local_new();
7603
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7604
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7605
(env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7606
tcg_gen_movi_tl(t0, -1);
7607
else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7608
(env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7609
tcg_gen_movi_tl(t0, -1);
7615
gen_helper_mftc0_vpecontrol(t0, cpu_env);
7618
gen_helper_mftc0_vpeconf0(t0, cpu_env);
7628
gen_helper_mftc0_tcstatus(t0, cpu_env);
7631
gen_helper_mftc0_tcbind(t0, cpu_env);
7634
gen_helper_mftc0_tcrestart(t0, cpu_env);
7637
gen_helper_mftc0_tchalt(t0, cpu_env);
7640
gen_helper_mftc0_tccontext(t0, cpu_env);
7643
gen_helper_mftc0_tcschedule(t0, cpu_env);
7646
gen_helper_mftc0_tcschefback(t0, cpu_env);
7649
gen_mfc0(ctx, t0, rt, sel);
7656
gen_helper_mftc0_entryhi(t0, cpu_env);
7659
gen_mfc0(ctx, t0, rt, sel);
7665
gen_helper_mftc0_status(t0, cpu_env);
7668
gen_mfc0(ctx, t0, rt, sel);
7674
gen_helper_mftc0_cause(t0, cpu_env);
7684
gen_helper_mftc0_epc(t0, cpu_env);
7694
gen_helper_mftc0_ebase(t0, cpu_env);
7704
gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7714
gen_helper_mftc0_debug(t0, cpu_env);
7717
gen_mfc0(ctx, t0, rt, sel);
7722
gen_mfc0(ctx, t0, rt, sel);
7724
} else switch (sel) {
7725
/* GPR registers. */
7727
gen_helper_1e0i(mftgpr, t0, rt);
7729
/* Auxiliary CPU registers */
7733
gen_helper_1e0i(mftlo, t0, 0);
7736
gen_helper_1e0i(mfthi, t0, 0);
7739
gen_helper_1e0i(mftacx, t0, 0);
7742
gen_helper_1e0i(mftlo, t0, 1);
7745
gen_helper_1e0i(mfthi, t0, 1);
7748
gen_helper_1e0i(mftacx, t0, 1);
7751
gen_helper_1e0i(mftlo, t0, 2);
7754
gen_helper_1e0i(mfthi, t0, 2);
7757
gen_helper_1e0i(mftacx, t0, 2);
7760
gen_helper_1e0i(mftlo, t0, 3);
7763
gen_helper_1e0i(mfthi, t0, 3);
7766
gen_helper_1e0i(mftacx, t0, 3);
7769
gen_helper_mftdsp(t0, cpu_env);
7775
/* Floating point (COP1). */
7777
/* XXX: For now we support only a single FPU context. */
7779
TCGv_i32 fp0 = tcg_temp_new_i32();
7781
gen_load_fpr32(ctx, fp0, rt);
7782
tcg_gen_ext_i32_tl(t0, fp0);
7783
tcg_temp_free_i32(fp0);
7785
TCGv_i32 fp0 = tcg_temp_new_i32();
7787
gen_load_fpr32h(ctx, fp0, rt);
7788
tcg_gen_ext_i32_tl(t0, fp0);
7789
tcg_temp_free_i32(fp0);
7793
/* XXX: For now we support only a single FPU context. */
7794
gen_helper_1e0i(cfc1, t0, rt);
7796
/* COP2: Not implemented. */
7803
LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7804
gen_store_gpr(t0, rd);
7810
LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7811
generate_exception_end(ctx, EXCP_RI);
7814
static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7815
int u, int sel, int h)
7817
int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7818
TCGv t0 = tcg_temp_local_new();
7820
gen_load_gpr(t0, rt);
7821
if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7822
((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7823
(env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7825
else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7826
(env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7833
gen_helper_mttc0_vpecontrol(cpu_env, t0);
7836
gen_helper_mttc0_vpeconf0(cpu_env, t0);
7846
gen_helper_mttc0_tcstatus(cpu_env, t0);
7849
gen_helper_mttc0_tcbind(cpu_env, t0);
7852
gen_helper_mttc0_tcrestart(cpu_env, t0);
7855
gen_helper_mttc0_tchalt(cpu_env, t0);
7858
gen_helper_mttc0_tccontext(cpu_env, t0);
7861
gen_helper_mttc0_tcschedule(cpu_env, t0);
7864
gen_helper_mttc0_tcschefback(cpu_env, t0);
7867
gen_mtc0(ctx, t0, rd, sel);
7874
gen_helper_mttc0_entryhi(cpu_env, t0);
7877
gen_mtc0(ctx, t0, rd, sel);
7883
gen_helper_mttc0_status(cpu_env, t0);
7886
gen_mtc0(ctx, t0, rd, sel);
7892
gen_helper_mttc0_cause(cpu_env, t0);
7902
gen_helper_mttc0_ebase(cpu_env, t0);
7912
gen_helper_mttc0_debug(cpu_env, t0);
7915
gen_mtc0(ctx, t0, rd, sel);
7920
gen_mtc0(ctx, t0, rd, sel);
7922
} else switch (sel) {
7923
/* GPR registers. */
7925
gen_helper_0e1i(mttgpr, t0, rd);
7927
/* Auxiliary CPU registers */
7931
gen_helper_0e1i(mttlo, t0, 0);
7934
gen_helper_0e1i(mtthi, t0, 0);
7937
gen_helper_0e1i(mttacx, t0, 0);
7940
gen_helper_0e1i(mttlo, t0, 1);
7943
gen_helper_0e1i(mtthi, t0, 1);
7946
gen_helper_0e1i(mttacx, t0, 1);
7949
gen_helper_0e1i(mttlo, t0, 2);
7952
gen_helper_0e1i(mtthi, t0, 2);
7955
gen_helper_0e1i(mttacx, t0, 2);
7958
gen_helper_0e1i(mttlo, t0, 3);
7961
gen_helper_0e1i(mtthi, t0, 3);
7964
gen_helper_0e1i(mttacx, t0, 3);
7967
gen_helper_mttdsp(cpu_env, t0);
7973
/* Floating point (COP1). */
7975
/* XXX: For now we support only a single FPU context. */
7977
TCGv_i32 fp0 = tcg_temp_new_i32();
7979
tcg_gen_trunc_tl_i32(fp0, t0);
7980
gen_store_fpr32(ctx, fp0, rd);
7981
tcg_temp_free_i32(fp0);
7983
TCGv_i32 fp0 = tcg_temp_new_i32();
7985
tcg_gen_trunc_tl_i32(fp0, t0);
7986
gen_store_fpr32h(ctx, fp0, rd);
7987
tcg_temp_free_i32(fp0);
7991
/* XXX: For now we support only a single FPU context. */
7993
TCGv_i32 fs_tmp = tcg_const_i32(rd);
7995
gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7996
tcg_temp_free_i32(fs_tmp);
7998
/* Stop translation as we may have changed hflags */
7999
ctx->bstate = BS_STOP;
8001
/* COP2: Not implemented. */
8008
LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8014
LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8015
generate_exception_end(ctx, EXCP_RI);
8018
static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8020
const char *opn = "ldst";
8022
check_cp0_enabled(ctx);
8029
gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8034
TCGv t0 = tcg_temp_new();
8036
gen_load_gpr(t0, rt);
8037
gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8042
#if defined(TARGET_MIPS64)
8044
check_insn(ctx, ISA_MIPS3);
8049
gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8053
check_insn(ctx, ISA_MIPS3);
8055
TCGv t0 = tcg_temp_new();
8057
gen_load_gpr(t0, rt);
8058
gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8070
gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8076
TCGv t0 = tcg_temp_new();
8077
gen_load_gpr(t0, rt);
8078
gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8084
check_insn(ctx, ASE_MT);
8089
gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8090
ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8094
check_insn(ctx, ASE_MT);
8095
gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8096
ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8101
if (!env->tlb->helper_tlbwi)
8103
gen_helper_tlbwi(cpu_env);
8108
if (!env->tlb->helper_tlbinv) {
8111
gen_helper_tlbinv(cpu_env);
8112
} /* treat as nop if TLBINV not supported */
8117
if (!env->tlb->helper_tlbinvf) {
8120
gen_helper_tlbinvf(cpu_env);
8121
} /* treat as nop if TLBINV not supported */
8125
if (!env->tlb->helper_tlbwr)
8127
gen_helper_tlbwr(cpu_env);
8131
if (!env->tlb->helper_tlbp)
8133
gen_helper_tlbp(cpu_env);
8137
if (!env->tlb->helper_tlbr)
8139
gen_helper_tlbr(cpu_env);
8141
case OPC_ERET: /* OPC_ERETNC */
8142
if ((ctx->insn_flags & ISA_MIPS32R6) &&
8143
(ctx->hflags & MIPS_HFLAG_BMASK)) {
8146
int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8147
if (ctx->opcode & (1 << bit_shift)) {
8150
check_insn(ctx, ISA_MIPS32R5);
8151
gen_helper_eretnc(cpu_env);
8155
check_insn(ctx, ISA_MIPS2);
8156
gen_helper_eret(cpu_env);
8158
ctx->bstate = BS_EXCP;
8163
check_insn(ctx, ISA_MIPS32);
8164
if ((ctx->insn_flags & ISA_MIPS32R6) &&
8165
(ctx->hflags & MIPS_HFLAG_BMASK)) {
8168
if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8170
generate_exception_end(ctx, EXCP_RI);
8172
gen_helper_deret(cpu_env);
8173
ctx->bstate = BS_EXCP;
8178
check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8179
if ((ctx->insn_flags & ISA_MIPS32R6) &&
8180
(ctx->hflags & MIPS_HFLAG_BMASK)) {
8183
/* If we get an exception, we want to restart at next instruction */
8185
save_cpu_state(ctx, 1);
8187
gen_helper_wait(cpu_env);
8188
ctx->bstate = BS_EXCP;
8193
generate_exception_end(ctx, EXCP_RI);
8196
(void)opn; /* avoid a compiler warning */
8198
#endif /* !CONFIG_USER_ONLY */
8200
/* CP1 Branches (before delay slot) */
8201
static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8202
int32_t cc, int32_t offset)
8204
target_ulong btarget;
8205
TCGv_i32 t0 = tcg_temp_new_i32();
8207
if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8208
generate_exception_end(ctx, EXCP_RI);
8213
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8215
btarget = ctx->pc + 4 + offset;
8219
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8220
tcg_gen_not_i32(t0, t0);
8221
tcg_gen_andi_i32(t0, t0, 1);
8222
tcg_gen_extu_i32_tl(bcond, t0);
8225
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8226
tcg_gen_not_i32(t0, t0);
8227
tcg_gen_andi_i32(t0, t0, 1);
8228
tcg_gen_extu_i32_tl(bcond, t0);
8231
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8232
tcg_gen_andi_i32(t0, t0, 1);
8233
tcg_gen_extu_i32_tl(bcond, t0);
8236
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8237
tcg_gen_andi_i32(t0, t0, 1);
8238
tcg_gen_extu_i32_tl(bcond, t0);
8240
ctx->hflags |= MIPS_HFLAG_BL;
8244
TCGv_i32 t1 = tcg_temp_new_i32();
8245
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8246
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8247
tcg_gen_nand_i32(t0, t0, t1);
8248
tcg_temp_free_i32(t1);
8249
tcg_gen_andi_i32(t0, t0, 1);
8250
tcg_gen_extu_i32_tl(bcond, t0);
8255
TCGv_i32 t1 = tcg_temp_new_i32();
8256
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8257
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8258
tcg_gen_or_i32(t0, t0, t1);
8259
tcg_temp_free_i32(t1);
8260
tcg_gen_andi_i32(t0, t0, 1);
8261
tcg_gen_extu_i32_tl(bcond, t0);
8266
TCGv_i32 t1 = tcg_temp_new_i32();
8267
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8268
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8269
tcg_gen_and_i32(t0, t0, t1);
8270
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8271
tcg_gen_and_i32(t0, t0, t1);
8272
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8273
tcg_gen_nand_i32(t0, t0, t1);
8274
tcg_temp_free_i32(t1);
8275
tcg_gen_andi_i32(t0, t0, 1);
8276
tcg_gen_extu_i32_tl(bcond, t0);
8281
TCGv_i32 t1 = tcg_temp_new_i32();
8282
tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8283
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8284
tcg_gen_or_i32(t0, t0, t1);
8285
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8286
tcg_gen_or_i32(t0, t0, t1);
8287
tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8288
tcg_gen_or_i32(t0, t0, t1);
8289
tcg_temp_free_i32(t1);
8290
tcg_gen_andi_i32(t0, t0, 1);
8291
tcg_gen_extu_i32_tl(bcond, t0);
8294
ctx->hflags |= MIPS_HFLAG_BC;
8297
MIPS_INVAL("cp1 cond branch");
8298
generate_exception_end(ctx, EXCP_RI);
8301
ctx->btarget = btarget;
8302
ctx->hflags |= MIPS_HFLAG_BDS32;
8304
tcg_temp_free_i32(t0);
8307
/* R6 CP1 Branches */
8308
static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8309
int32_t ft, int32_t offset,
8312
target_ulong btarget;
8313
TCGv_i64 t0 = tcg_temp_new_i64();
8315
if (ctx->hflags & MIPS_HFLAG_BMASK) {
8316
#ifdef MIPS_DEBUG_DISAS
8317
LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8320
generate_exception_end(ctx, EXCP_RI);
8324
gen_load_fpr64(ctx, t0, ft);
8325
tcg_gen_andi_i64(t0, t0, 1);
8327
btarget = addr_add(ctx, ctx->pc + 4, offset);
8331
tcg_gen_xori_i64(t0, t0, 1);
8332
ctx->hflags |= MIPS_HFLAG_BC;
8335
/* t0 already set */
8336
ctx->hflags |= MIPS_HFLAG_BC;
8339
MIPS_INVAL("cp1 cond branch");
8340
generate_exception_end(ctx, EXCP_RI);
8344
tcg_gen_trunc_i64_tl(bcond, t0);
8346
ctx->btarget = btarget;
8348
switch (delayslot_size) {
8350
ctx->hflags |= MIPS_HFLAG_BDS16;
8353
ctx->hflags |= MIPS_HFLAG_BDS32;
8358
tcg_temp_free_i64(t0);
8361
/* Coprocessor 1 (FPU) */
8363
#define FOP(func, fmt) (((fmt) << 21) | (func))
8366
OPC_ADD_S = FOP(0, FMT_S),
8367
OPC_SUB_S = FOP(1, FMT_S),
8368
OPC_MUL_S = FOP(2, FMT_S),
8369
OPC_DIV_S = FOP(3, FMT_S),
8370
OPC_SQRT_S = FOP(4, FMT_S),
8371
OPC_ABS_S = FOP(5, FMT_S),
8372
OPC_MOV_S = FOP(6, FMT_S),
8373
OPC_NEG_S = FOP(7, FMT_S),
8374
OPC_ROUND_L_S = FOP(8, FMT_S),
8375
OPC_TRUNC_L_S = FOP(9, FMT_S),
8376
OPC_CEIL_L_S = FOP(10, FMT_S),
8377
OPC_FLOOR_L_S = FOP(11, FMT_S),
8378
OPC_ROUND_W_S = FOP(12, FMT_S),
8379
OPC_TRUNC_W_S = FOP(13, FMT_S),
8380
OPC_CEIL_W_S = FOP(14, FMT_S),
8381
OPC_FLOOR_W_S = FOP(15, FMT_S),
8382
OPC_SEL_S = FOP(16, FMT_S),
8383
OPC_MOVCF_S = FOP(17, FMT_S),
8384
OPC_MOVZ_S = FOP(18, FMT_S),
8385
OPC_MOVN_S = FOP(19, FMT_S),
8386
OPC_SELEQZ_S = FOP(20, FMT_S),
8387
OPC_RECIP_S = FOP(21, FMT_S),
8388
OPC_RSQRT_S = FOP(22, FMT_S),
8389
OPC_SELNEZ_S = FOP(23, FMT_S),
8390
OPC_MADDF_S = FOP(24, FMT_S),
8391
OPC_MSUBF_S = FOP(25, FMT_S),
8392
OPC_RINT_S = FOP(26, FMT_S),
8393
OPC_CLASS_S = FOP(27, FMT_S),
8394
OPC_MIN_S = FOP(28, FMT_S),
8395
OPC_RECIP2_S = FOP(28, FMT_S),
8396
OPC_MINA_S = FOP(29, FMT_S),
8397
OPC_RECIP1_S = FOP(29, FMT_S),
8398
OPC_MAX_S = FOP(30, FMT_S),
8399
OPC_RSQRT1_S = FOP(30, FMT_S),
8400
OPC_MAXA_S = FOP(31, FMT_S),
8401
OPC_RSQRT2_S = FOP(31, FMT_S),
8402
OPC_CVT_D_S = FOP(33, FMT_S),
8403
OPC_CVT_W_S = FOP(36, FMT_S),
8404
OPC_CVT_L_S = FOP(37, FMT_S),
8405
OPC_CVT_PS_S = FOP(38, FMT_S),
8406
OPC_CMP_F_S = FOP (48, FMT_S),
8407
OPC_CMP_UN_S = FOP (49, FMT_S),
8408
OPC_CMP_EQ_S = FOP (50, FMT_S),
8409
OPC_CMP_UEQ_S = FOP (51, FMT_S),
8410
OPC_CMP_OLT_S = FOP (52, FMT_S),
8411
OPC_CMP_ULT_S = FOP (53, FMT_S),
8412
OPC_CMP_OLE_S = FOP (54, FMT_S),
8413
OPC_CMP_ULE_S = FOP (55, FMT_S),
8414
OPC_CMP_SF_S = FOP (56, FMT_S),
8415
OPC_CMP_NGLE_S = FOP (57, FMT_S),
8416
OPC_CMP_SEQ_S = FOP (58, FMT_S),
8417
OPC_CMP_NGL_S = FOP (59, FMT_S),
8418
OPC_CMP_LT_S = FOP (60, FMT_S),
8419
OPC_CMP_NGE_S = FOP (61, FMT_S),
8420
OPC_CMP_LE_S = FOP (62, FMT_S),
8421
OPC_CMP_NGT_S = FOP (63, FMT_S),
8423
OPC_ADD_D = FOP(0, FMT_D),
8424
OPC_SUB_D = FOP(1, FMT_D),
8425
OPC_MUL_D = FOP(2, FMT_D),
8426
OPC_DIV_D = FOP(3, FMT_D),
8427
OPC_SQRT_D = FOP(4, FMT_D),
8428
OPC_ABS_D = FOP(5, FMT_D),
8429
OPC_MOV_D = FOP(6, FMT_D),
8430
OPC_NEG_D = FOP(7, FMT_D),
8431
OPC_ROUND_L_D = FOP(8, FMT_D),
8432
OPC_TRUNC_L_D = FOP(9, FMT_D),
8433
OPC_CEIL_L_D = FOP(10, FMT_D),
8434
OPC_FLOOR_L_D = FOP(11, FMT_D),
8435
OPC_ROUND_W_D = FOP(12, FMT_D),
8436
OPC_TRUNC_W_D = FOP(13, FMT_D),
8437
OPC_CEIL_W_D = FOP(14, FMT_D),
8438
OPC_FLOOR_W_D = FOP(15, FMT_D),
8439
OPC_SEL_D = FOP(16, FMT_D),
8440
OPC_MOVCF_D = FOP(17, FMT_D),
8441
OPC_MOVZ_D = FOP(18, FMT_D),
8442
OPC_MOVN_D = FOP(19, FMT_D),
8443
OPC_SELEQZ_D = FOP(20, FMT_D),
8444
OPC_RECIP_D = FOP(21, FMT_D),
8445
OPC_RSQRT_D = FOP(22, FMT_D),
8446
OPC_SELNEZ_D = FOP(23, FMT_D),
8447
OPC_MADDF_D = FOP(24, FMT_D),
8448
OPC_MSUBF_D = FOP(25, FMT_D),
8449
OPC_RINT_D = FOP(26, FMT_D),
8450
OPC_CLASS_D = FOP(27, FMT_D),
8451
OPC_MIN_D = FOP(28, FMT_D),
8452
OPC_RECIP2_D = FOP(28, FMT_D),
8453
OPC_MINA_D = FOP(29, FMT_D),
8454
OPC_RECIP1_D = FOP(29, FMT_D),
8455
OPC_MAX_D = FOP(30, FMT_D),
8456
OPC_RSQRT1_D = FOP(30, FMT_D),
8457
OPC_MAXA_D = FOP(31, FMT_D),
8458
OPC_RSQRT2_D = FOP(31, FMT_D),
8459
OPC_CVT_S_D = FOP(32, FMT_D),
8460
OPC_CVT_W_D = FOP(36, FMT_D),
8461
OPC_CVT_L_D = FOP(37, FMT_D),
8462
OPC_CMP_F_D = FOP (48, FMT_D),
8463
OPC_CMP_UN_D = FOP (49, FMT_D),
8464
OPC_CMP_EQ_D = FOP (50, FMT_D),
8465
OPC_CMP_UEQ_D = FOP (51, FMT_D),
8466
OPC_CMP_OLT_D = FOP (52, FMT_D),
8467
OPC_CMP_ULT_D = FOP (53, FMT_D),
8468
OPC_CMP_OLE_D = FOP (54, FMT_D),
8469
OPC_CMP_ULE_D = FOP (55, FMT_D),
8470
OPC_CMP_SF_D = FOP (56, FMT_D),
8471
OPC_CMP_NGLE_D = FOP (57, FMT_D),
8472
OPC_CMP_SEQ_D = FOP (58, FMT_D),
8473
OPC_CMP_NGL_D = FOP (59, FMT_D),
8474
OPC_CMP_LT_D = FOP (60, FMT_D),
8475
OPC_CMP_NGE_D = FOP (61, FMT_D),
8476
OPC_CMP_LE_D = FOP (62, FMT_D),
8477
OPC_CMP_NGT_D = FOP (63, FMT_D),
8479
OPC_CVT_S_W = FOP(32, FMT_W),
8480
OPC_CVT_D_W = FOP(33, FMT_W),
8481
OPC_CVT_S_L = FOP(32, FMT_L),
8482
OPC_CVT_D_L = FOP(33, FMT_L),
8483
OPC_CVT_PS_PW = FOP(38, FMT_W),
8485
OPC_ADD_PS = FOP(0, FMT_PS),
8486
OPC_SUB_PS = FOP(1, FMT_PS),
8487
OPC_MUL_PS = FOP(2, FMT_PS),
8488
OPC_DIV_PS = FOP(3, FMT_PS),
8489
OPC_ABS_PS = FOP(5, FMT_PS),
8490
OPC_MOV_PS = FOP(6, FMT_PS),
8491
OPC_NEG_PS = FOP(7, FMT_PS),
8492
OPC_MOVCF_PS = FOP(17, FMT_PS),
8493
OPC_MOVZ_PS = FOP(18, FMT_PS),
8494
OPC_MOVN_PS = FOP(19, FMT_PS),
8495
OPC_ADDR_PS = FOP(24, FMT_PS),
8496
OPC_MULR_PS = FOP(26, FMT_PS),
8497
OPC_RECIP2_PS = FOP(28, FMT_PS),
8498
OPC_RECIP1_PS = FOP(29, FMT_PS),
8499
OPC_RSQRT1_PS = FOP(30, FMT_PS),
8500
OPC_RSQRT2_PS = FOP(31, FMT_PS),
8502
OPC_CVT_S_PU = FOP(32, FMT_PS),
8503
OPC_CVT_PW_PS = FOP(36, FMT_PS),
8504
OPC_CVT_S_PL = FOP(40, FMT_PS),
8505
OPC_PLL_PS = FOP(44, FMT_PS),
8506
OPC_PLU_PS = FOP(45, FMT_PS),
8507
OPC_PUL_PS = FOP(46, FMT_PS),
8508
OPC_PUU_PS = FOP(47, FMT_PS),
8509
OPC_CMP_F_PS = FOP (48, FMT_PS),
8510
OPC_CMP_UN_PS = FOP (49, FMT_PS),
8511
OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8512
OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8513
OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8514
OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8515
OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8516
OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8517
OPC_CMP_SF_PS = FOP (56, FMT_PS),
8518
OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8519
OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8520
OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8521
OPC_CMP_LT_PS = FOP (60, FMT_PS),
8522
OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8523
OPC_CMP_LE_PS = FOP (62, FMT_PS),
8524
OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8528
R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8529
R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8530
R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8531
R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8532
R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8533
R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8534
R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8535
R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8536
R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8537
R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8538
R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8539
R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8540
R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8541
R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8542
R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8543
R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8544
R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8545
R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8546
R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8547
R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8548
R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8549
R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8551
R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8552
R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8553
R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8554
R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8555
R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8556
R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8557
R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8558
R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8559
R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8560
R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8561
R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8562
R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8563
R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8564
R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8565
R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8566
R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8567
R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8568
R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8569
R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8570
R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8571
R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8572
R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8574
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8576
TCGv t0 = tcg_temp_new();
8581
TCGv_i32 fp0 = tcg_temp_new_i32();
8583
gen_load_fpr32(ctx, fp0, fs);
8584
tcg_gen_ext_i32_tl(t0, fp0);
8585
tcg_temp_free_i32(fp0);
8587
gen_store_gpr(t0, rt);
8590
gen_load_gpr(t0, rt);
8592
TCGv_i32 fp0 = tcg_temp_new_i32();
8594
tcg_gen_trunc_tl_i32(fp0, t0);
8595
gen_store_fpr32(ctx, fp0, fs);
8596
tcg_temp_free_i32(fp0);
8600
gen_helper_1e0i(cfc1, t0, fs);
8601
gen_store_gpr(t0, rt);
8604
gen_load_gpr(t0, rt);
8605
save_cpu_state(ctx, 0);
8607
TCGv_i32 fs_tmp = tcg_const_i32(fs);
8609
gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8610
tcg_temp_free_i32(fs_tmp);
8612
/* Stop translation as we may have changed hflags */
8613
ctx->bstate = BS_STOP;
8615
#if defined(TARGET_MIPS64)
8617
gen_load_fpr64(ctx, t0, fs);
8618
gen_store_gpr(t0, rt);
8621
gen_load_gpr(t0, rt);
8622
gen_store_fpr64(ctx, t0, fs);
8627
TCGv_i32 fp0 = tcg_temp_new_i32();
8629
gen_load_fpr32h(ctx, fp0, fs);
8630
tcg_gen_ext_i32_tl(t0, fp0);
8631
tcg_temp_free_i32(fp0);
8633
gen_store_gpr(t0, rt);
8636
gen_load_gpr(t0, rt);
8638
TCGv_i32 fp0 = tcg_temp_new_i32();
8640
tcg_gen_trunc_tl_i32(fp0, t0);
8641
gen_store_fpr32h(ctx, fp0, fs);
8642
tcg_temp_free_i32(fp0);
8646
MIPS_INVAL("cp1 move");
8647
generate_exception_end(ctx, EXCP_RI);
8655
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8671
l1 = gen_new_label();
8672
t0 = tcg_temp_new_i32();
8673
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8674
tcg_gen_brcondi_i32(cond, t0, 0, l1);
8675
tcg_temp_free_i32(t0);
8677
tcg_gen_movi_tl(cpu_gpr[rd], 0);
8679
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8684
static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8688
TCGv_i32 t0 = tcg_temp_new_i32();
8689
TCGLabel *l1 = gen_new_label();
8696
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8697
tcg_gen_brcondi_i32(cond, t0, 0, l1);
8698
gen_load_fpr32(ctx, t0, fs);
8699
gen_store_fpr32(ctx, t0, fd);
8701
tcg_temp_free_i32(t0);
8704
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8707
TCGv_i32 t0 = tcg_temp_new_i32();
8709
TCGLabel *l1 = gen_new_label();
8716
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8717
tcg_gen_brcondi_i32(cond, t0, 0, l1);
8718
tcg_temp_free_i32(t0);
8719
fp0 = tcg_temp_new_i64();
8720
gen_load_fpr64(ctx, fp0, fs);
8721
gen_store_fpr64(ctx, fp0, fd);
8722
tcg_temp_free_i64(fp0);
8726
static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8730
TCGv_i32 t0 = tcg_temp_new_i32();
8731
TCGLabel *l1 = gen_new_label();
8732
TCGLabel *l2 = gen_new_label();
8739
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8740
tcg_gen_brcondi_i32(cond, t0, 0, l1);
8741
gen_load_fpr32(ctx, t0, fs);
8742
gen_store_fpr32(ctx, t0, fd);
8745
tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8746
tcg_gen_brcondi_i32(cond, t0, 0, l2);
8747
gen_load_fpr32h(ctx, t0, fs);
8748
gen_store_fpr32h(ctx, t0, fd);
8749
tcg_temp_free_i32(t0);
8753
static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8756
TCGv_i32 t1 = tcg_const_i32(0);
8757
TCGv_i32 fp0 = tcg_temp_new_i32();
8758
TCGv_i32 fp1 = tcg_temp_new_i32();
8759
TCGv_i32 fp2 = tcg_temp_new_i32();
8760
gen_load_fpr32(ctx, fp0, fd);
8761
gen_load_fpr32(ctx, fp1, ft);
8762
gen_load_fpr32(ctx, fp2, fs);
8766
tcg_gen_andi_i32(fp0, fp0, 1);
8767
tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8770
tcg_gen_andi_i32(fp1, fp1, 1);
8771
tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8774
tcg_gen_andi_i32(fp1, fp1, 1);
8775
tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8778
MIPS_INVAL("gen_sel_s");
8779
generate_exception_end(ctx, EXCP_RI);
8783
gen_store_fpr32(ctx, fp0, fd);
8784
tcg_temp_free_i32(fp2);
8785
tcg_temp_free_i32(fp1);
8786
tcg_temp_free_i32(fp0);
8787
tcg_temp_free_i32(t1);
8790
static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8793
TCGv_i64 t1 = tcg_const_i64(0);
8794
TCGv_i64 fp0 = tcg_temp_new_i64();
8795
TCGv_i64 fp1 = tcg_temp_new_i64();
8796
TCGv_i64 fp2 = tcg_temp_new_i64();
8797
gen_load_fpr64(ctx, fp0, fd);
8798
gen_load_fpr64(ctx, fp1, ft);
8799
gen_load_fpr64(ctx, fp2, fs);
8803
tcg_gen_andi_i64(fp0, fp0, 1);
8804
tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8807
tcg_gen_andi_i64(fp1, fp1, 1);
8808
tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8811
tcg_gen_andi_i64(fp1, fp1, 1);
8812
tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8815
MIPS_INVAL("gen_sel_d");
8816
generate_exception_end(ctx, EXCP_RI);
8820
gen_store_fpr64(ctx, fp0, fd);
8821
tcg_temp_free_i64(fp2);
8822
tcg_temp_free_i64(fp1);
8823
tcg_temp_free_i64(fp0);
8824
tcg_temp_free_i64(t1);
8827
static void gen_farith (DisasContext *ctx, enum fopcode op1,
8828
int ft, int fs, int fd, int cc)
8830
uint32_t func = ctx->opcode & 0x3f;
8834
TCGv_i32 fp0 = tcg_temp_new_i32();
8835
TCGv_i32 fp1 = tcg_temp_new_i32();
8837
gen_load_fpr32(ctx, fp0, fs);
8838
gen_load_fpr32(ctx, fp1, ft);
8839
gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8840
tcg_temp_free_i32(fp1);
8841
gen_store_fpr32(ctx, fp0, fd);
8842
tcg_temp_free_i32(fp0);
8847
TCGv_i32 fp0 = tcg_temp_new_i32();
8848
TCGv_i32 fp1 = tcg_temp_new_i32();
8850
gen_load_fpr32(ctx, fp0, fs);
8851
gen_load_fpr32(ctx, fp1, ft);
8852
gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8853
tcg_temp_free_i32(fp1);
8854
gen_store_fpr32(ctx, fp0, fd);
8855
tcg_temp_free_i32(fp0);
8860
TCGv_i32 fp0 = tcg_temp_new_i32();
8861
TCGv_i32 fp1 = tcg_temp_new_i32();
8863
gen_load_fpr32(ctx, fp0, fs);
8864
gen_load_fpr32(ctx, fp1, ft);
8865
gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8866
tcg_temp_free_i32(fp1);
8867
gen_store_fpr32(ctx, fp0, fd);
8868
tcg_temp_free_i32(fp0);
8873
TCGv_i32 fp0 = tcg_temp_new_i32();
8874
TCGv_i32 fp1 = tcg_temp_new_i32();
8876
gen_load_fpr32(ctx, fp0, fs);
8877
gen_load_fpr32(ctx, fp1, ft);
8878
gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8879
tcg_temp_free_i32(fp1);
8880
gen_store_fpr32(ctx, fp0, fd);
8881
tcg_temp_free_i32(fp0);
8886
TCGv_i32 fp0 = tcg_temp_new_i32();
8888
gen_load_fpr32(ctx, fp0, fs);
8889
gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8890
gen_store_fpr32(ctx, fp0, fd);
8891
tcg_temp_free_i32(fp0);
8896
TCGv_i32 fp0 = tcg_temp_new_i32();
8898
gen_load_fpr32(ctx, fp0, fs);
8900
tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
8902
gen_helper_float_abs_s(fp0, fp0);
8904
gen_store_fpr32(ctx, fp0, fd);
8905
tcg_temp_free_i32(fp0);
8910
TCGv_i32 fp0 = tcg_temp_new_i32();
8912
gen_load_fpr32(ctx, fp0, fs);
8913
gen_store_fpr32(ctx, fp0, fd);
8914
tcg_temp_free_i32(fp0);
8919
TCGv_i32 fp0 = tcg_temp_new_i32();
8921
gen_load_fpr32(ctx, fp0, fs);
8923
tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
8925
gen_helper_float_chs_s(fp0, fp0);
8927
gen_store_fpr32(ctx, fp0, fd);
8928
tcg_temp_free_i32(fp0);
8932
check_cp1_64bitmode(ctx);
8934
TCGv_i32 fp32 = tcg_temp_new_i32();
8935
TCGv_i64 fp64 = tcg_temp_new_i64();
8937
gen_load_fpr32(ctx, fp32, fs);
8939
gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
8941
gen_helper_float_round_l_s(fp64, cpu_env, fp32);
8943
tcg_temp_free_i32(fp32);
8944
gen_store_fpr64(ctx, fp64, fd);
8945
tcg_temp_free_i64(fp64);
8949
check_cp1_64bitmode(ctx);
8951
TCGv_i32 fp32 = tcg_temp_new_i32();
8952
TCGv_i64 fp64 = tcg_temp_new_i64();
8954
gen_load_fpr32(ctx, fp32, fs);
8956
gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
8958
gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
8960
tcg_temp_free_i32(fp32);
8961
gen_store_fpr64(ctx, fp64, fd);
8962
tcg_temp_free_i64(fp64);
8966
check_cp1_64bitmode(ctx);
8968
TCGv_i32 fp32 = tcg_temp_new_i32();
8969
TCGv_i64 fp64 = tcg_temp_new_i64();
8971
gen_load_fpr32(ctx, fp32, fs);
8973
gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
8975
gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
8977
tcg_temp_free_i32(fp32);
8978
gen_store_fpr64(ctx, fp64, fd);
8979
tcg_temp_free_i64(fp64);
8983
check_cp1_64bitmode(ctx);
8985
TCGv_i32 fp32 = tcg_temp_new_i32();
8986
TCGv_i64 fp64 = tcg_temp_new_i64();
8988
gen_load_fpr32(ctx, fp32, fs);
8990
gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
8992
gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
8994
tcg_temp_free_i32(fp32);
8995
gen_store_fpr64(ctx, fp64, fd);
8996
tcg_temp_free_i64(fp64);
9001
TCGv_i32 fp0 = tcg_temp_new_i32();
9003
gen_load_fpr32(ctx, fp0, fs);
9005
gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9007
gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9009
gen_store_fpr32(ctx, fp0, fd);
9010
tcg_temp_free_i32(fp0);
9015
TCGv_i32 fp0 = tcg_temp_new_i32();
9017
gen_load_fpr32(ctx, fp0, fs);
9019
gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9021
gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9023
gen_store_fpr32(ctx, fp0, fd);
9024
tcg_temp_free_i32(fp0);
9029
TCGv_i32 fp0 = tcg_temp_new_i32();
9031
gen_load_fpr32(ctx, fp0, fs);
9033
gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9035
gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9037
gen_store_fpr32(ctx, fp0, fd);
9038
tcg_temp_free_i32(fp0);
9043
TCGv_i32 fp0 = tcg_temp_new_i32();
9045
gen_load_fpr32(ctx, fp0, fs);
9047
gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9049
gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9051
gen_store_fpr32(ctx, fp0, fd);
9052
tcg_temp_free_i32(fp0);
9056
check_insn(ctx, ISA_MIPS32R6);
9057
gen_sel_s(ctx, op1, fd, ft, fs);
9060
check_insn(ctx, ISA_MIPS32R6);
9061
gen_sel_s(ctx, op1, fd, ft, fs);
9064
check_insn(ctx, ISA_MIPS32R6);
9065
gen_sel_s(ctx, op1, fd, ft, fs);
9068
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9069
gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9072
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9074
TCGLabel *l1 = gen_new_label();
9078
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9080
fp0 = tcg_temp_new_i32();
9081
gen_load_fpr32(ctx, fp0, fs);
9082
gen_store_fpr32(ctx, fp0, fd);
9083
tcg_temp_free_i32(fp0);
9088
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9090
TCGLabel *l1 = gen_new_label();
9094
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9095
fp0 = tcg_temp_new_i32();
9096
gen_load_fpr32(ctx, fp0, fs);
9097
gen_store_fpr32(ctx, fp0, fd);
9098
tcg_temp_free_i32(fp0);
9105
TCGv_i32 fp0 = tcg_temp_new_i32();
9107
gen_load_fpr32(ctx, fp0, fs);
9108
gen_helper_float_recip_s(fp0, cpu_env, fp0);
9109
gen_store_fpr32(ctx, fp0, fd);
9110
tcg_temp_free_i32(fp0);
9115
TCGv_i32 fp0 = tcg_temp_new_i32();
9117
gen_load_fpr32(ctx, fp0, fs);
9118
gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9119
gen_store_fpr32(ctx, fp0, fd);
9120
tcg_temp_free_i32(fp0);
9124
check_insn(ctx, ISA_MIPS32R6);
9126
TCGv_i32 fp0 = tcg_temp_new_i32();
9127
TCGv_i32 fp1 = tcg_temp_new_i32();
9128
TCGv_i32 fp2 = tcg_temp_new_i32();
9129
gen_load_fpr32(ctx, fp0, fs);
9130
gen_load_fpr32(ctx, fp1, ft);
9131
gen_load_fpr32(ctx, fp2, fd);
9132
gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9133
gen_store_fpr32(ctx, fp2, fd);
9134
tcg_temp_free_i32(fp2);
9135
tcg_temp_free_i32(fp1);
9136
tcg_temp_free_i32(fp0);
9140
check_insn(ctx, ISA_MIPS32R6);
9142
TCGv_i32 fp0 = tcg_temp_new_i32();
9143
TCGv_i32 fp1 = tcg_temp_new_i32();
9144
TCGv_i32 fp2 = tcg_temp_new_i32();
9145
gen_load_fpr32(ctx, fp0, fs);
9146
gen_load_fpr32(ctx, fp1, ft);
9147
gen_load_fpr32(ctx, fp2, fd);
9148
gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9149
gen_store_fpr32(ctx, fp2, fd);
9150
tcg_temp_free_i32(fp2);
9151
tcg_temp_free_i32(fp1);
9152
tcg_temp_free_i32(fp0);
9156
check_insn(ctx, ISA_MIPS32R6);
9158
TCGv_i32 fp0 = tcg_temp_new_i32();
9159
gen_load_fpr32(ctx, fp0, fs);
9160
gen_helper_float_rint_s(fp0, cpu_env, fp0);
9161
gen_store_fpr32(ctx, fp0, fd);
9162
tcg_temp_free_i32(fp0);
9166
check_insn(ctx, ISA_MIPS32R6);
9168
TCGv_i32 fp0 = tcg_temp_new_i32();
9169
gen_load_fpr32(ctx, fp0, fs);
9170
gen_helper_float_class_s(fp0, cpu_env, fp0);
9171
gen_store_fpr32(ctx, fp0, fd);
9172
tcg_temp_free_i32(fp0);
9175
case OPC_MIN_S: /* OPC_RECIP2_S */
9176
if (ctx->insn_flags & ISA_MIPS32R6) {
9178
TCGv_i32 fp0 = tcg_temp_new_i32();
9179
TCGv_i32 fp1 = tcg_temp_new_i32();
9180
TCGv_i32 fp2 = tcg_temp_new_i32();
9181
gen_load_fpr32(ctx, fp0, fs);
9182
gen_load_fpr32(ctx, fp1, ft);
9183
gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9184
gen_store_fpr32(ctx, fp2, fd);
9185
tcg_temp_free_i32(fp2);
9186
tcg_temp_free_i32(fp1);
9187
tcg_temp_free_i32(fp0);
9190
check_cp1_64bitmode(ctx);
9192
TCGv_i32 fp0 = tcg_temp_new_i32();
9193
TCGv_i32 fp1 = tcg_temp_new_i32();
9195
gen_load_fpr32(ctx, fp0, fs);
9196
gen_load_fpr32(ctx, fp1, ft);
9197
gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9198
tcg_temp_free_i32(fp1);
9199
gen_store_fpr32(ctx, fp0, fd);
9200
tcg_temp_free_i32(fp0);
9204
case OPC_MINA_S: /* OPC_RECIP1_S */
9205
if (ctx->insn_flags & ISA_MIPS32R6) {
9207
TCGv_i32 fp0 = tcg_temp_new_i32();
9208
TCGv_i32 fp1 = tcg_temp_new_i32();
9209
TCGv_i32 fp2 = tcg_temp_new_i32();
9210
gen_load_fpr32(ctx, fp0, fs);
9211
gen_load_fpr32(ctx, fp1, ft);
9212
gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9213
gen_store_fpr32(ctx, fp2, fd);
9214
tcg_temp_free_i32(fp2);
9215
tcg_temp_free_i32(fp1);
9216
tcg_temp_free_i32(fp0);
9219
check_cp1_64bitmode(ctx);
9221
TCGv_i32 fp0 = tcg_temp_new_i32();
9223
gen_load_fpr32(ctx, fp0, fs);
9224
gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9225
gen_store_fpr32(ctx, fp0, fd);
9226
tcg_temp_free_i32(fp0);
9230
case OPC_MAX_S: /* OPC_RSQRT1_S */
9231
if (ctx->insn_flags & ISA_MIPS32R6) {
9233
TCGv_i32 fp0 = tcg_temp_new_i32();
9234
TCGv_i32 fp1 = tcg_temp_new_i32();
9235
gen_load_fpr32(ctx, fp0, fs);
9236
gen_load_fpr32(ctx, fp1, ft);
9237
gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9238
gen_store_fpr32(ctx, fp1, fd);
9239
tcg_temp_free_i32(fp1);
9240
tcg_temp_free_i32(fp0);
9243
check_cp1_64bitmode(ctx);
9245
TCGv_i32 fp0 = tcg_temp_new_i32();
9247
gen_load_fpr32(ctx, fp0, fs);
9248
gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9249
gen_store_fpr32(ctx, fp0, fd);
9250
tcg_temp_free_i32(fp0);
9254
case OPC_MAXA_S: /* OPC_RSQRT2_S */
9255
if (ctx->insn_flags & ISA_MIPS32R6) {
9257
TCGv_i32 fp0 = tcg_temp_new_i32();
9258
TCGv_i32 fp1 = tcg_temp_new_i32();
9259
gen_load_fpr32(ctx, fp0, fs);
9260
gen_load_fpr32(ctx, fp1, ft);
9261
gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9262
gen_store_fpr32(ctx, fp1, fd);
9263
tcg_temp_free_i32(fp1);
9264
tcg_temp_free_i32(fp0);
9267
check_cp1_64bitmode(ctx);
9269
TCGv_i32 fp0 = tcg_temp_new_i32();
9270
TCGv_i32 fp1 = tcg_temp_new_i32();
9272
gen_load_fpr32(ctx, fp0, fs);
9273
gen_load_fpr32(ctx, fp1, ft);
9274
gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9275
tcg_temp_free_i32(fp1);
9276
gen_store_fpr32(ctx, fp0, fd);
9277
tcg_temp_free_i32(fp0);
9282
check_cp1_registers(ctx, fd);
9284
TCGv_i32 fp32 = tcg_temp_new_i32();
9285
TCGv_i64 fp64 = tcg_temp_new_i64();
9287
gen_load_fpr32(ctx, fp32, fs);
9288
gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9289
tcg_temp_free_i32(fp32);
9290
gen_store_fpr64(ctx, fp64, fd);
9291
tcg_temp_free_i64(fp64);
9296
TCGv_i32 fp0 = tcg_temp_new_i32();
9298
gen_load_fpr32(ctx, fp0, fs);
9300
gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9302
gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9304
gen_store_fpr32(ctx, fp0, fd);
9305
tcg_temp_free_i32(fp0);
9309
check_cp1_64bitmode(ctx);
9311
TCGv_i32 fp32 = tcg_temp_new_i32();
9312
TCGv_i64 fp64 = tcg_temp_new_i64();
9314
gen_load_fpr32(ctx, fp32, fs);
9316
gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9318
gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9320
tcg_temp_free_i32(fp32);
9321
gen_store_fpr64(ctx, fp64, fd);
9322
tcg_temp_free_i64(fp64);
9328
TCGv_i64 fp64 = tcg_temp_new_i64();
9329
TCGv_i32 fp32_0 = tcg_temp_new_i32();
9330
TCGv_i32 fp32_1 = tcg_temp_new_i32();
9332
gen_load_fpr32(ctx, fp32_0, fs);
9333
gen_load_fpr32(ctx, fp32_1, ft);
9334
tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9335
tcg_temp_free_i32(fp32_1);
9336
tcg_temp_free_i32(fp32_0);
9337
gen_store_fpr64(ctx, fp64, fd);
9338
tcg_temp_free_i64(fp64);
9350
case OPC_CMP_NGLE_S:
9357
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9358
if (ctx->opcode & (1 << 6)) {
9359
gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9361
gen_cmp_s(ctx, func-48, ft, fs, cc);
9365
check_cp1_registers(ctx, fs | ft | fd);
9367
TCGv_i64 fp0 = tcg_temp_new_i64();
9368
TCGv_i64 fp1 = tcg_temp_new_i64();
9370
gen_load_fpr64(ctx, fp0, fs);
9371
gen_load_fpr64(ctx, fp1, ft);
9372
gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9373
tcg_temp_free_i64(fp1);
9374
gen_store_fpr64(ctx, fp0, fd);
9375
tcg_temp_free_i64(fp0);
9379
check_cp1_registers(ctx, fs | ft | fd);
9381
TCGv_i64 fp0 = tcg_temp_new_i64();
9382
TCGv_i64 fp1 = tcg_temp_new_i64();
9384
gen_load_fpr64(ctx, fp0, fs);
9385
gen_load_fpr64(ctx, fp1, ft);
9386
gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9387
tcg_temp_free_i64(fp1);
9388
gen_store_fpr64(ctx, fp0, fd);
9389
tcg_temp_free_i64(fp0);
9393
check_cp1_registers(ctx, fs | ft | fd);
9395
TCGv_i64 fp0 = tcg_temp_new_i64();
9396
TCGv_i64 fp1 = tcg_temp_new_i64();
9398
gen_load_fpr64(ctx, fp0, fs);
9399
gen_load_fpr64(ctx, fp1, ft);
9400
gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9401
tcg_temp_free_i64(fp1);
9402
gen_store_fpr64(ctx, fp0, fd);
9403
tcg_temp_free_i64(fp0);
9407
check_cp1_registers(ctx, fs | ft | fd);
9409
TCGv_i64 fp0 = tcg_temp_new_i64();
9410
TCGv_i64 fp1 = tcg_temp_new_i64();
9412
gen_load_fpr64(ctx, fp0, fs);
9413
gen_load_fpr64(ctx, fp1, ft);
9414
gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9415
tcg_temp_free_i64(fp1);
9416
gen_store_fpr64(ctx, fp0, fd);
9417
tcg_temp_free_i64(fp0);
9421
check_cp1_registers(ctx, fs | fd);
9423
TCGv_i64 fp0 = tcg_temp_new_i64();
9425
gen_load_fpr64(ctx, fp0, fs);
9426
gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9427
gen_store_fpr64(ctx, fp0, fd);
9428
tcg_temp_free_i64(fp0);
9432
check_cp1_registers(ctx, fs | fd);
9434
TCGv_i64 fp0 = tcg_temp_new_i64();
9436
gen_load_fpr64(ctx, fp0, fs);
9438
tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9440
gen_helper_float_abs_d(fp0, fp0);
9442
gen_store_fpr64(ctx, fp0, fd);
9443
tcg_temp_free_i64(fp0);
9447
check_cp1_registers(ctx, fs | fd);
9449
TCGv_i64 fp0 = tcg_temp_new_i64();
9451
gen_load_fpr64(ctx, fp0, fs);
9452
gen_store_fpr64(ctx, fp0, fd);
9453
tcg_temp_free_i64(fp0);
9457
check_cp1_registers(ctx, fs | fd);
9459
TCGv_i64 fp0 = tcg_temp_new_i64();
9461
gen_load_fpr64(ctx, fp0, fs);
9463
tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9465
gen_helper_float_chs_d(fp0, fp0);
9467
gen_store_fpr64(ctx, fp0, fd);
9468
tcg_temp_free_i64(fp0);
9472
check_cp1_64bitmode(ctx);
9474
TCGv_i64 fp0 = tcg_temp_new_i64();
9476
gen_load_fpr64(ctx, fp0, fs);
9478
gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9480
gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9482
gen_store_fpr64(ctx, fp0, fd);
9483
tcg_temp_free_i64(fp0);
9487
check_cp1_64bitmode(ctx);
9489
TCGv_i64 fp0 = tcg_temp_new_i64();
9491
gen_load_fpr64(ctx, fp0, fs);
9493
gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9495
gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9497
gen_store_fpr64(ctx, fp0, fd);
9498
tcg_temp_free_i64(fp0);
9502
check_cp1_64bitmode(ctx);
9504
TCGv_i64 fp0 = tcg_temp_new_i64();
9506
gen_load_fpr64(ctx, fp0, fs);
9508
gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9510
gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9512
gen_store_fpr64(ctx, fp0, fd);
9513
tcg_temp_free_i64(fp0);
9517
check_cp1_64bitmode(ctx);
9519
TCGv_i64 fp0 = tcg_temp_new_i64();
9521
gen_load_fpr64(ctx, fp0, fs);
9523
gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9525
gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9527
gen_store_fpr64(ctx, fp0, fd);
9528
tcg_temp_free_i64(fp0);
9532
check_cp1_registers(ctx, fs);
9534
TCGv_i32 fp32 = tcg_temp_new_i32();
9535
TCGv_i64 fp64 = tcg_temp_new_i64();
9537
gen_load_fpr64(ctx, fp64, fs);
9539
gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9541
gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9543
tcg_temp_free_i64(fp64);
9544
gen_store_fpr32(ctx, fp32, fd);
9545
tcg_temp_free_i32(fp32);
9549
check_cp1_registers(ctx, fs);
9551
TCGv_i32 fp32 = tcg_temp_new_i32();
9552
TCGv_i64 fp64 = tcg_temp_new_i64();
9554
gen_load_fpr64(ctx, fp64, fs);
9556
gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9558
gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9560
tcg_temp_free_i64(fp64);
9561
gen_store_fpr32(ctx, fp32, fd);
9562
tcg_temp_free_i32(fp32);
9566
check_cp1_registers(ctx, fs);
9568
TCGv_i32 fp32 = tcg_temp_new_i32();
9569
TCGv_i64 fp64 = tcg_temp_new_i64();
9571
gen_load_fpr64(ctx, fp64, fs);
9573
gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9575
gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9577
tcg_temp_free_i64(fp64);
9578
gen_store_fpr32(ctx, fp32, fd);
9579
tcg_temp_free_i32(fp32);
9583
check_cp1_registers(ctx, fs);
9585
TCGv_i32 fp32 = tcg_temp_new_i32();
9586
TCGv_i64 fp64 = tcg_temp_new_i64();
9588
gen_load_fpr64(ctx, fp64, fs);
9590
gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9592
gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9594
tcg_temp_free_i64(fp64);
9595
gen_store_fpr32(ctx, fp32, fd);
9596
tcg_temp_free_i32(fp32);
9600
check_insn(ctx, ISA_MIPS32R6);
9601
gen_sel_d(ctx, op1, fd, ft, fs);
9604
check_insn(ctx, ISA_MIPS32R6);
9605
gen_sel_d(ctx, op1, fd, ft, fs);
9608
check_insn(ctx, ISA_MIPS32R6);
9609
gen_sel_d(ctx, op1, fd, ft, fs);
9612
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9613
gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9616
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9618
TCGLabel *l1 = gen_new_label();
9622
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9624
fp0 = tcg_temp_new_i64();
9625
gen_load_fpr64(ctx, fp0, fs);
9626
gen_store_fpr64(ctx, fp0, fd);
9627
tcg_temp_free_i64(fp0);
9632
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9634
TCGLabel *l1 = gen_new_label();
9638
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9639
fp0 = tcg_temp_new_i64();
9640
gen_load_fpr64(ctx, fp0, fs);
9641
gen_store_fpr64(ctx, fp0, fd);
9642
tcg_temp_free_i64(fp0);
9648
check_cp1_registers(ctx, fs | fd);
9650
TCGv_i64 fp0 = tcg_temp_new_i64();
9652
gen_load_fpr64(ctx, fp0, fs);
9653
gen_helper_float_recip_d(fp0, cpu_env, fp0);
9654
gen_store_fpr64(ctx, fp0, fd);
9655
tcg_temp_free_i64(fp0);
9659
check_cp1_registers(ctx, fs | fd);
9661
TCGv_i64 fp0 = tcg_temp_new_i64();
9663
gen_load_fpr64(ctx, fp0, fs);
9664
gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9665
gen_store_fpr64(ctx, fp0, fd);
9666
tcg_temp_free_i64(fp0);
9670
check_insn(ctx, ISA_MIPS32R6);
9672
TCGv_i64 fp0 = tcg_temp_new_i64();
9673
TCGv_i64 fp1 = tcg_temp_new_i64();
9674
TCGv_i64 fp2 = tcg_temp_new_i64();
9675
gen_load_fpr64(ctx, fp0, fs);
9676
gen_load_fpr64(ctx, fp1, ft);
9677
gen_load_fpr64(ctx, fp2, fd);
9678
gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9679
gen_store_fpr64(ctx, fp2, fd);
9680
tcg_temp_free_i64(fp2);
9681
tcg_temp_free_i64(fp1);
9682
tcg_temp_free_i64(fp0);
9686
check_insn(ctx, ISA_MIPS32R6);
9688
TCGv_i64 fp0 = tcg_temp_new_i64();
9689
TCGv_i64 fp1 = tcg_temp_new_i64();
9690
TCGv_i64 fp2 = tcg_temp_new_i64();
9691
gen_load_fpr64(ctx, fp0, fs);
9692
gen_load_fpr64(ctx, fp1, ft);
9693
gen_load_fpr64(ctx, fp2, fd);
9694
gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9695
gen_store_fpr64(ctx, fp2, fd);
9696
tcg_temp_free_i64(fp2);
9697
tcg_temp_free_i64(fp1);
9698
tcg_temp_free_i64(fp0);
9702
check_insn(ctx, ISA_MIPS32R6);
9704
TCGv_i64 fp0 = tcg_temp_new_i64();
9705
gen_load_fpr64(ctx, fp0, fs);
9706
gen_helper_float_rint_d(fp0, cpu_env, fp0);
9707
gen_store_fpr64(ctx, fp0, fd);
9708
tcg_temp_free_i64(fp0);
9712
check_insn(ctx, ISA_MIPS32R6);
9714
TCGv_i64 fp0 = tcg_temp_new_i64();
9715
gen_load_fpr64(ctx, fp0, fs);
9716
gen_helper_float_class_d(fp0, cpu_env, fp0);
9717
gen_store_fpr64(ctx, fp0, fd);
9718
tcg_temp_free_i64(fp0);
9721
case OPC_MIN_D: /* OPC_RECIP2_D */
9722
if (ctx->insn_flags & ISA_MIPS32R6) {
9724
TCGv_i64 fp0 = tcg_temp_new_i64();
9725
TCGv_i64 fp1 = tcg_temp_new_i64();
9726
gen_load_fpr64(ctx, fp0, fs);
9727
gen_load_fpr64(ctx, fp1, ft);
9728
gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9729
gen_store_fpr64(ctx, fp1, fd);
9730
tcg_temp_free_i64(fp1);
9731
tcg_temp_free_i64(fp0);
9734
check_cp1_64bitmode(ctx);
9736
TCGv_i64 fp0 = tcg_temp_new_i64();
9737
TCGv_i64 fp1 = tcg_temp_new_i64();
9739
gen_load_fpr64(ctx, fp0, fs);
9740
gen_load_fpr64(ctx, fp1, ft);
9741
gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9742
tcg_temp_free_i64(fp1);
9743
gen_store_fpr64(ctx, fp0, fd);
9744
tcg_temp_free_i64(fp0);
9748
case OPC_MINA_D: /* OPC_RECIP1_D */
9749
if (ctx->insn_flags & ISA_MIPS32R6) {
9751
TCGv_i64 fp0 = tcg_temp_new_i64();
9752
TCGv_i64 fp1 = tcg_temp_new_i64();
9753
gen_load_fpr64(ctx, fp0, fs);
9754
gen_load_fpr64(ctx, fp1, ft);
9755
gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9756
gen_store_fpr64(ctx, fp1, fd);
9757
tcg_temp_free_i64(fp1);
9758
tcg_temp_free_i64(fp0);
9761
check_cp1_64bitmode(ctx);
9763
TCGv_i64 fp0 = tcg_temp_new_i64();
9765
gen_load_fpr64(ctx, fp0, fs);
9766
gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9767
gen_store_fpr64(ctx, fp0, fd);
9768
tcg_temp_free_i64(fp0);
9772
case OPC_MAX_D: /* OPC_RSQRT1_D */
9773
if (ctx->insn_flags & ISA_MIPS32R6) {
9775
TCGv_i64 fp0 = tcg_temp_new_i64();
9776
TCGv_i64 fp1 = tcg_temp_new_i64();
9777
gen_load_fpr64(ctx, fp0, fs);
9778
gen_load_fpr64(ctx, fp1, ft);
9779
gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9780
gen_store_fpr64(ctx, fp1, fd);
9781
tcg_temp_free_i64(fp1);
9782
tcg_temp_free_i64(fp0);
9785
check_cp1_64bitmode(ctx);
9787
TCGv_i64 fp0 = tcg_temp_new_i64();
9789
gen_load_fpr64(ctx, fp0, fs);
9790
gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9791
gen_store_fpr64(ctx, fp0, fd);
9792
tcg_temp_free_i64(fp0);
9796
case OPC_MAXA_D: /* OPC_RSQRT2_D */
9797
if (ctx->insn_flags & ISA_MIPS32R6) {
9799
TCGv_i64 fp0 = tcg_temp_new_i64();
9800
TCGv_i64 fp1 = tcg_temp_new_i64();
9801
gen_load_fpr64(ctx, fp0, fs);
9802
gen_load_fpr64(ctx, fp1, ft);
9803
gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9804
gen_store_fpr64(ctx, fp1, fd);
9805
tcg_temp_free_i64(fp1);
9806
tcg_temp_free_i64(fp0);
9809
check_cp1_64bitmode(ctx);
9811
TCGv_i64 fp0 = tcg_temp_new_i64();
9812
TCGv_i64 fp1 = tcg_temp_new_i64();
9814
gen_load_fpr64(ctx, fp0, fs);
9815
gen_load_fpr64(ctx, fp1, ft);
9816
gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9817
tcg_temp_free_i64(fp1);
9818
gen_store_fpr64(ctx, fp0, fd);
9819
tcg_temp_free_i64(fp0);
9832
case OPC_CMP_NGLE_D:
9839
check_insn_opc_removed(ctx, ISA_MIPS32R6);
9840
if (ctx->opcode & (1 << 6)) {
9841
gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9843
gen_cmp_d(ctx, func-48, ft, fs, cc);
9847
check_cp1_registers(ctx, fs);
9849
TCGv_i32 fp32 = tcg_temp_new_i32();
9850
TCGv_i64 fp64 = tcg_temp_new_i64();
9852
gen_load_fpr64(ctx, fp64, fs);
9853
gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9854
tcg_temp_free_i64(fp64);
9855
gen_store_fpr32(ctx, fp32, fd);
9856
tcg_temp_free_i32(fp32);
9860
check_cp1_registers(ctx, fs);
9862
TCGv_i32 fp32 = tcg_temp_new_i32();
9863
TCGv_i64 fp64 = tcg_temp_new_i64();
9865
gen_load_fpr64(ctx, fp64, fs);
9867
gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
9869
gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
9871
tcg_temp_free_i64(fp64);
9872
gen_store_fpr32(ctx, fp32, fd);
9873
tcg_temp_free_i32(fp32);
9877
check_cp1_64bitmode(ctx);
9879
TCGv_i64 fp0 = tcg_temp_new_i64();
9881
gen_load_fpr64(ctx, fp0, fs);
9883
gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
9885
gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
9887
gen_store_fpr64(ctx, fp0, fd);
9888
tcg_temp_free_i64(fp0);
9893
TCGv_i32 fp0 = tcg_temp_new_i32();
9895
gen_load_fpr32(ctx, fp0, fs);
9896
gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9897
gen_store_fpr32(ctx, fp0, fd);
9898
tcg_temp_free_i32(fp0);
9902
check_cp1_registers(ctx, fd);
9904
TCGv_i32 fp32 = tcg_temp_new_i32();
9905
TCGv_i64 fp64 = tcg_temp_new_i64();
9907
gen_load_fpr32(ctx, fp32, fs);
9908
gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9909
tcg_temp_free_i32(fp32);
9910
gen_store_fpr64(ctx, fp64, fd);
9911
tcg_temp_free_i64(fp64);
9915
check_cp1_64bitmode(ctx);
9917
TCGv_i32 fp32 = tcg_temp_new_i32();
9918
TCGv_i64 fp64 = tcg_temp_new_i64();
9920
gen_load_fpr64(ctx, fp64, fs);
9921
gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9922
tcg_temp_free_i64(fp64);
9923
gen_store_fpr32(ctx, fp32, fd);
9924
tcg_temp_free_i32(fp32);
9928
check_cp1_64bitmode(ctx);
9930
TCGv_i64 fp0 = tcg_temp_new_i64();
9932
gen_load_fpr64(ctx, fp0, fs);
9933
gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9934
gen_store_fpr64(ctx, fp0, fd);
9935
tcg_temp_free_i64(fp0);
9941
TCGv_i64 fp0 = tcg_temp_new_i64();
9943
gen_load_fpr64(ctx, fp0, fs);
9944
gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9945
gen_store_fpr64(ctx, fp0, fd);
9946
tcg_temp_free_i64(fp0);
9952
TCGv_i64 fp0 = tcg_temp_new_i64();
9953
TCGv_i64 fp1 = tcg_temp_new_i64();
9955
gen_load_fpr64(ctx, fp0, fs);
9956
gen_load_fpr64(ctx, fp1, ft);
9957
gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9958
tcg_temp_free_i64(fp1);
9959
gen_store_fpr64(ctx, fp0, fd);
9960
tcg_temp_free_i64(fp0);
9966
TCGv_i64 fp0 = tcg_temp_new_i64();
9967
TCGv_i64 fp1 = tcg_temp_new_i64();
9969
gen_load_fpr64(ctx, fp0, fs);
9970
gen_load_fpr64(ctx, fp1, ft);
9971
gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9972
tcg_temp_free_i64(fp1);
9973
gen_store_fpr64(ctx, fp0, fd);
9974
tcg_temp_free_i64(fp0);
9980
TCGv_i64 fp0 = tcg_temp_new_i64();
9981
TCGv_i64 fp1 = tcg_temp_new_i64();
9983
gen_load_fpr64(ctx, fp0, fs);
9984
gen_load_fpr64(ctx, fp1, ft);
9985
gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9986
tcg_temp_free_i64(fp1);
9987
gen_store_fpr64(ctx, fp0, fd);
9988
tcg_temp_free_i64(fp0);
9994
TCGv_i64 fp0 = tcg_temp_new_i64();
9996
gen_load_fpr64(ctx, fp0, fs);
9997
gen_helper_float_abs_ps(fp0, fp0);
9998
gen_store_fpr64(ctx, fp0, fd);
9999
tcg_temp_free_i64(fp0);
10005
TCGv_i64 fp0 = tcg_temp_new_i64();
10007
gen_load_fpr64(ctx, fp0, fs);
10008
gen_store_fpr64(ctx, fp0, fd);
10009
tcg_temp_free_i64(fp0);
10015
TCGv_i64 fp0 = tcg_temp_new_i64();
10017
gen_load_fpr64(ctx, fp0, fs);
10018
gen_helper_float_chs_ps(fp0, fp0);
10019
gen_store_fpr64(ctx, fp0, fd);
10020
tcg_temp_free_i64(fp0);
10025
gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10030
TCGLabel *l1 = gen_new_label();
10034
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10035
fp0 = tcg_temp_new_i64();
10036
gen_load_fpr64(ctx, fp0, fs);
10037
gen_store_fpr64(ctx, fp0, fd);
10038
tcg_temp_free_i64(fp0);
10045
TCGLabel *l1 = gen_new_label();
10049
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10050
fp0 = tcg_temp_new_i64();
10051
gen_load_fpr64(ctx, fp0, fs);
10052
gen_store_fpr64(ctx, fp0, fd);
10053
tcg_temp_free_i64(fp0);
10061
TCGv_i64 fp0 = tcg_temp_new_i64();
10062
TCGv_i64 fp1 = tcg_temp_new_i64();
10064
gen_load_fpr64(ctx, fp0, ft);
10065
gen_load_fpr64(ctx, fp1, fs);
10066
gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10067
tcg_temp_free_i64(fp1);
10068
gen_store_fpr64(ctx, fp0, fd);
10069
tcg_temp_free_i64(fp0);
10075
TCGv_i64 fp0 = tcg_temp_new_i64();
10076
TCGv_i64 fp1 = tcg_temp_new_i64();
10078
gen_load_fpr64(ctx, fp0, ft);
10079
gen_load_fpr64(ctx, fp1, fs);
10080
gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10081
tcg_temp_free_i64(fp1);
10082
gen_store_fpr64(ctx, fp0, fd);
10083
tcg_temp_free_i64(fp0);
10086
case OPC_RECIP2_PS:
10089
TCGv_i64 fp0 = tcg_temp_new_i64();
10090
TCGv_i64 fp1 = tcg_temp_new_i64();
10092
gen_load_fpr64(ctx, fp0, fs);
10093
gen_load_fpr64(ctx, fp1, ft);
10094
gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10095
tcg_temp_free_i64(fp1);
10096
gen_store_fpr64(ctx, fp0, fd);
10097
tcg_temp_free_i64(fp0);
10100
case OPC_RECIP1_PS:
10103
TCGv_i64 fp0 = tcg_temp_new_i64();
10105
gen_load_fpr64(ctx, fp0, fs);
10106
gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10107
gen_store_fpr64(ctx, fp0, fd);
10108
tcg_temp_free_i64(fp0);
10111
case OPC_RSQRT1_PS:
10114
TCGv_i64 fp0 = tcg_temp_new_i64();
10116
gen_load_fpr64(ctx, fp0, fs);
10117
gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10118
gen_store_fpr64(ctx, fp0, fd);
10119
tcg_temp_free_i64(fp0);
10122
case OPC_RSQRT2_PS:
10125
TCGv_i64 fp0 = tcg_temp_new_i64();
10126
TCGv_i64 fp1 = tcg_temp_new_i64();
10128
gen_load_fpr64(ctx, fp0, fs);
10129
gen_load_fpr64(ctx, fp1, ft);
10130
gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10131
tcg_temp_free_i64(fp1);
10132
gen_store_fpr64(ctx, fp0, fd);
10133
tcg_temp_free_i64(fp0);
10137
check_cp1_64bitmode(ctx);
10139
TCGv_i32 fp0 = tcg_temp_new_i32();
10141
gen_load_fpr32h(ctx, fp0, fs);
10142
gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10143
gen_store_fpr32(ctx, fp0, fd);
10144
tcg_temp_free_i32(fp0);
10147
case OPC_CVT_PW_PS:
10150
TCGv_i64 fp0 = tcg_temp_new_i64();
10152
gen_load_fpr64(ctx, fp0, fs);
10153
gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10154
gen_store_fpr64(ctx, fp0, fd);
10155
tcg_temp_free_i64(fp0);
10159
check_cp1_64bitmode(ctx);
10161
TCGv_i32 fp0 = tcg_temp_new_i32();
10163
gen_load_fpr32(ctx, fp0, fs);
10164
gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10165
gen_store_fpr32(ctx, fp0, fd);
10166
tcg_temp_free_i32(fp0);
10172
TCGv_i32 fp0 = tcg_temp_new_i32();
10173
TCGv_i32 fp1 = tcg_temp_new_i32();
10175
gen_load_fpr32(ctx, fp0, fs);
10176
gen_load_fpr32(ctx, fp1, ft);
10177
gen_store_fpr32h(ctx, fp0, fd);
10178
gen_store_fpr32(ctx, fp1, fd);
10179
tcg_temp_free_i32(fp0);
10180
tcg_temp_free_i32(fp1);
10186
TCGv_i32 fp0 = tcg_temp_new_i32();
10187
TCGv_i32 fp1 = tcg_temp_new_i32();
10189
gen_load_fpr32(ctx, fp0, fs);
10190
gen_load_fpr32h(ctx, fp1, ft);
10191
gen_store_fpr32(ctx, fp1, fd);
10192
gen_store_fpr32h(ctx, fp0, fd);
10193
tcg_temp_free_i32(fp0);
10194
tcg_temp_free_i32(fp1);
10200
TCGv_i32 fp0 = tcg_temp_new_i32();
10201
TCGv_i32 fp1 = tcg_temp_new_i32();
10203
gen_load_fpr32h(ctx, fp0, fs);
10204
gen_load_fpr32(ctx, fp1, ft);
10205
gen_store_fpr32(ctx, fp1, fd);
10206
gen_store_fpr32h(ctx, fp0, fd);
10207
tcg_temp_free_i32(fp0);
10208
tcg_temp_free_i32(fp1);
10214
TCGv_i32 fp0 = tcg_temp_new_i32();
10215
TCGv_i32 fp1 = tcg_temp_new_i32();
10217
gen_load_fpr32h(ctx, fp0, fs);
10218
gen_load_fpr32h(ctx, fp1, ft);
10219
gen_store_fpr32(ctx, fp1, fd);
10220
gen_store_fpr32h(ctx, fp0, fd);
10221
tcg_temp_free_i32(fp0);
10222
tcg_temp_free_i32(fp1);
10226
case OPC_CMP_UN_PS:
10227
case OPC_CMP_EQ_PS:
10228
case OPC_CMP_UEQ_PS:
10229
case OPC_CMP_OLT_PS:
10230
case OPC_CMP_ULT_PS:
10231
case OPC_CMP_OLE_PS:
10232
case OPC_CMP_ULE_PS:
10233
case OPC_CMP_SF_PS:
10234
case OPC_CMP_NGLE_PS:
10235
case OPC_CMP_SEQ_PS:
10236
case OPC_CMP_NGL_PS:
10237
case OPC_CMP_LT_PS:
10238
case OPC_CMP_NGE_PS:
10239
case OPC_CMP_LE_PS:
10240
case OPC_CMP_NGT_PS:
10241
if (ctx->opcode & (1 << 6)) {
10242
gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10244
gen_cmp_ps(ctx, func-48, ft, fs, cc);
10248
MIPS_INVAL("farith");
10249
generate_exception_end(ctx, EXCP_RI);
10254
/* Coprocessor 3 (FPU) */
10255
static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10256
int fd, int fs, int base, int index)
10258
TCGv t0 = tcg_temp_new();
10261
gen_load_gpr(t0, index);
10262
} else if (index == 0) {
10263
gen_load_gpr(t0, base);
10265
gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10267
/* Don't do NOP if destination is zero: we must perform the actual
10273
TCGv_i32 fp0 = tcg_temp_new_i32();
10275
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10276
tcg_gen_trunc_tl_i32(fp0, t0);
10277
gen_store_fpr32(ctx, fp0, fd);
10278
tcg_temp_free_i32(fp0);
10283
check_cp1_registers(ctx, fd);
10285
TCGv_i64 fp0 = tcg_temp_new_i64();
10286
tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10287
gen_store_fpr64(ctx, fp0, fd);
10288
tcg_temp_free_i64(fp0);
10292
check_cp1_64bitmode(ctx);
10293
tcg_gen_andi_tl(t0, t0, ~0x7);
10295
TCGv_i64 fp0 = tcg_temp_new_i64();
10297
tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10298
gen_store_fpr64(ctx, fp0, fd);
10299
tcg_temp_free_i64(fp0);
10305
TCGv_i32 fp0 = tcg_temp_new_i32();
10306
gen_load_fpr32(ctx, fp0, fs);
10307
tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10308
tcg_temp_free_i32(fp0);
10313
check_cp1_registers(ctx, fs);
10315
TCGv_i64 fp0 = tcg_temp_new_i64();
10316
gen_load_fpr64(ctx, fp0, fs);
10317
tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10318
tcg_temp_free_i64(fp0);
10322
check_cp1_64bitmode(ctx);
10323
tcg_gen_andi_tl(t0, t0, ~0x7);
10325
TCGv_i64 fp0 = tcg_temp_new_i64();
10326
gen_load_fpr64(ctx, fp0, fs);
10327
tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10328
tcg_temp_free_i64(fp0);
10335
static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10336
int fd, int fr, int fs, int ft)
10342
TCGv t0 = tcg_temp_local_new();
10343
TCGv_i32 fp = tcg_temp_new_i32();
10344
TCGv_i32 fph = tcg_temp_new_i32();
10345
TCGLabel *l1 = gen_new_label();
10346
TCGLabel *l2 = gen_new_label();
10348
gen_load_gpr(t0, fr);
10349
tcg_gen_andi_tl(t0, t0, 0x7);
10351
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10352
gen_load_fpr32(ctx, fp, fs);
10353
gen_load_fpr32h(ctx, fph, fs);
10354
gen_store_fpr32(ctx, fp, fd);
10355
gen_store_fpr32h(ctx, fph, fd);
10358
tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10360
#ifdef TARGET_WORDS_BIGENDIAN
10361
gen_load_fpr32(ctx, fp, fs);
10362
gen_load_fpr32h(ctx, fph, ft);
10363
gen_store_fpr32h(ctx, fp, fd);
10364
gen_store_fpr32(ctx, fph, fd);
10366
gen_load_fpr32h(ctx, fph, fs);
10367
gen_load_fpr32(ctx, fp, ft);
10368
gen_store_fpr32(ctx, fph, fd);
10369
gen_store_fpr32h(ctx, fp, fd);
10372
tcg_temp_free_i32(fp);
10373
tcg_temp_free_i32(fph);
10379
TCGv_i32 fp0 = tcg_temp_new_i32();
10380
TCGv_i32 fp1 = tcg_temp_new_i32();
10381
TCGv_i32 fp2 = tcg_temp_new_i32();
10383
gen_load_fpr32(ctx, fp0, fs);
10384
gen_load_fpr32(ctx, fp1, ft);
10385
gen_load_fpr32(ctx, fp2, fr);
10386
gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10387
tcg_temp_free_i32(fp0);
10388
tcg_temp_free_i32(fp1);
10389
gen_store_fpr32(ctx, fp2, fd);
10390
tcg_temp_free_i32(fp2);
10395
check_cp1_registers(ctx, fd | fs | ft | fr);
10397
TCGv_i64 fp0 = tcg_temp_new_i64();
10398
TCGv_i64 fp1 = tcg_temp_new_i64();
10399
TCGv_i64 fp2 = tcg_temp_new_i64();
10401
gen_load_fpr64(ctx, fp0, fs);
10402
gen_load_fpr64(ctx, fp1, ft);
10403
gen_load_fpr64(ctx, fp2, fr);
10404
gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10405
tcg_temp_free_i64(fp0);
10406
tcg_temp_free_i64(fp1);
10407
gen_store_fpr64(ctx, fp2, fd);
10408
tcg_temp_free_i64(fp2);
10414
TCGv_i64 fp0 = tcg_temp_new_i64();
10415
TCGv_i64 fp1 = tcg_temp_new_i64();
10416
TCGv_i64 fp2 = tcg_temp_new_i64();
10418
gen_load_fpr64(ctx, fp0, fs);
10419
gen_load_fpr64(ctx, fp1, ft);
10420
gen_load_fpr64(ctx, fp2, fr);
10421
gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10422
tcg_temp_free_i64(fp0);
10423
tcg_temp_free_i64(fp1);
10424
gen_store_fpr64(ctx, fp2, fd);
10425
tcg_temp_free_i64(fp2);
10431
TCGv_i32 fp0 = tcg_temp_new_i32();
10432
TCGv_i32 fp1 = tcg_temp_new_i32();
10433
TCGv_i32 fp2 = tcg_temp_new_i32();
10435
gen_load_fpr32(ctx, fp0, fs);
10436
gen_load_fpr32(ctx, fp1, ft);
10437
gen_load_fpr32(ctx, fp2, fr);
10438
gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10439
tcg_temp_free_i32(fp0);
10440
tcg_temp_free_i32(fp1);
10441
gen_store_fpr32(ctx, fp2, fd);
10442
tcg_temp_free_i32(fp2);
10447
check_cp1_registers(ctx, fd | fs | ft | fr);
10449
TCGv_i64 fp0 = tcg_temp_new_i64();
10450
TCGv_i64 fp1 = tcg_temp_new_i64();
10451
TCGv_i64 fp2 = tcg_temp_new_i64();
10453
gen_load_fpr64(ctx, fp0, fs);
10454
gen_load_fpr64(ctx, fp1, ft);
10455
gen_load_fpr64(ctx, fp2, fr);
10456
gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10457
tcg_temp_free_i64(fp0);
10458
tcg_temp_free_i64(fp1);
10459
gen_store_fpr64(ctx, fp2, fd);
10460
tcg_temp_free_i64(fp2);
10466
TCGv_i64 fp0 = tcg_temp_new_i64();
10467
TCGv_i64 fp1 = tcg_temp_new_i64();
10468
TCGv_i64 fp2 = tcg_temp_new_i64();
10470
gen_load_fpr64(ctx, fp0, fs);
10471
gen_load_fpr64(ctx, fp1, ft);
10472
gen_load_fpr64(ctx, fp2, fr);
10473
gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10474
tcg_temp_free_i64(fp0);
10475
tcg_temp_free_i64(fp1);
10476
gen_store_fpr64(ctx, fp2, fd);
10477
tcg_temp_free_i64(fp2);
10483
TCGv_i32 fp0 = tcg_temp_new_i32();
10484
TCGv_i32 fp1 = tcg_temp_new_i32();
10485
TCGv_i32 fp2 = tcg_temp_new_i32();
10487
gen_load_fpr32(ctx, fp0, fs);
10488
gen_load_fpr32(ctx, fp1, ft);
10489
gen_load_fpr32(ctx, fp2, fr);
10490
gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10491
tcg_temp_free_i32(fp0);
10492
tcg_temp_free_i32(fp1);
10493
gen_store_fpr32(ctx, fp2, fd);
10494
tcg_temp_free_i32(fp2);
10499
check_cp1_registers(ctx, fd | fs | ft | fr);
10501
TCGv_i64 fp0 = tcg_temp_new_i64();
10502
TCGv_i64 fp1 = tcg_temp_new_i64();
10503
TCGv_i64 fp2 = tcg_temp_new_i64();
10505
gen_load_fpr64(ctx, fp0, fs);
10506
gen_load_fpr64(ctx, fp1, ft);
10507
gen_load_fpr64(ctx, fp2, fr);
10508
gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10509
tcg_temp_free_i64(fp0);
10510
tcg_temp_free_i64(fp1);
10511
gen_store_fpr64(ctx, fp2, fd);
10512
tcg_temp_free_i64(fp2);
10518
TCGv_i64 fp0 = tcg_temp_new_i64();
10519
TCGv_i64 fp1 = tcg_temp_new_i64();
10520
TCGv_i64 fp2 = tcg_temp_new_i64();
10522
gen_load_fpr64(ctx, fp0, fs);
10523
gen_load_fpr64(ctx, fp1, ft);
10524
gen_load_fpr64(ctx, fp2, fr);
10525
gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10526
tcg_temp_free_i64(fp0);
10527
tcg_temp_free_i64(fp1);
10528
gen_store_fpr64(ctx, fp2, fd);
10529
tcg_temp_free_i64(fp2);
10535
TCGv_i32 fp0 = tcg_temp_new_i32();
10536
TCGv_i32 fp1 = tcg_temp_new_i32();
10537
TCGv_i32 fp2 = tcg_temp_new_i32();
10539
gen_load_fpr32(ctx, fp0, fs);
10540
gen_load_fpr32(ctx, fp1, ft);
10541
gen_load_fpr32(ctx, fp2, fr);
10542
gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10543
tcg_temp_free_i32(fp0);
10544
tcg_temp_free_i32(fp1);
10545
gen_store_fpr32(ctx, fp2, fd);
10546
tcg_temp_free_i32(fp2);
10551
check_cp1_registers(ctx, fd | fs | ft | fr);
10553
TCGv_i64 fp0 = tcg_temp_new_i64();
10554
TCGv_i64 fp1 = tcg_temp_new_i64();
10555
TCGv_i64 fp2 = tcg_temp_new_i64();
10557
gen_load_fpr64(ctx, fp0, fs);
10558
gen_load_fpr64(ctx, fp1, ft);
10559
gen_load_fpr64(ctx, fp2, fr);
10560
gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10561
tcg_temp_free_i64(fp0);
10562
tcg_temp_free_i64(fp1);
10563
gen_store_fpr64(ctx, fp2, fd);
10564
tcg_temp_free_i64(fp2);
10570
TCGv_i64 fp0 = tcg_temp_new_i64();
10571
TCGv_i64 fp1 = tcg_temp_new_i64();
10572
TCGv_i64 fp2 = tcg_temp_new_i64();
10574
gen_load_fpr64(ctx, fp0, fs);
10575
gen_load_fpr64(ctx, fp1, ft);
10576
gen_load_fpr64(ctx, fp2, fr);
10577
gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10578
tcg_temp_free_i64(fp0);
10579
tcg_temp_free_i64(fp1);
10580
gen_store_fpr64(ctx, fp2, fd);
10581
tcg_temp_free_i64(fp2);
10585
MIPS_INVAL("flt3_arith");
10586
generate_exception_end(ctx, EXCP_RI);
10591
static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10595
#if !defined(CONFIG_USER_ONLY)
10596
/* The Linux kernel will emulate rdhwr if it's not supported natively.
10597
Therefore only check the ISA in system mode. */
10598
check_insn(ctx, ISA_MIPS32R2);
10600
t0 = tcg_temp_new();
10604
gen_helper_rdhwr_cpunum(t0, cpu_env);
10605
gen_store_gpr(t0, rt);
10608
gen_helper_rdhwr_synci_step(t0, cpu_env);
10609
gen_store_gpr(t0, rt);
10612
gen_helper_rdhwr_cc(t0, cpu_env);
10613
gen_store_gpr(t0, rt);
10616
gen_helper_rdhwr_ccres(t0, cpu_env);
10617
gen_store_gpr(t0, rt);
10620
check_insn(ctx, ISA_MIPS32R6);
10622
/* Performance counter registers are not implemented other than
10623
* control register 0.
10625
generate_exception(ctx, EXCP_RI);
10627
gen_helper_rdhwr_performance(t0, cpu_env);
10628
gen_store_gpr(t0, rt);
10631
check_insn(ctx, ISA_MIPS32R6);
10632
gen_helper_rdhwr_xnp(t0, cpu_env);
10633
gen_store_gpr(t0, rt);
10636
#if defined(CONFIG_USER_ONLY)
10637
tcg_gen_ld_tl(t0, cpu_env,
10638
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10639
gen_store_gpr(t0, rt);
10642
if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10643
(ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10644
tcg_gen_ld_tl(t0, cpu_env,
10645
offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10646
gen_store_gpr(t0, rt);
10648
generate_exception_end(ctx, EXCP_RI);
10652
default: /* Invalid */
10653
MIPS_INVAL("rdhwr");
10654
generate_exception_end(ctx, EXCP_RI);
10660
static inline void clear_branch_hflags(DisasContext *ctx)
10662
ctx->hflags &= ~MIPS_HFLAG_BMASK;
10663
if (ctx->bstate == BS_NONE) {
10664
save_cpu_state(ctx, 0);
10666
/* it is not safe to save ctx->hflags as hflags may be changed
10667
in execution time by the instruction in delay / forbidden slot. */
10668
tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10672
static void gen_branch(DisasContext *ctx, int insn_bytes)
10674
if (ctx->hflags & MIPS_HFLAG_BMASK) {
10675
int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10676
/* Branches completion */
10677
clear_branch_hflags(ctx);
10678
ctx->bstate = BS_BRANCH;
10679
/* FIXME: Need to clear can_do_io. */
10680
switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10681
case MIPS_HFLAG_FBNSLOT:
10682
gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10685
/* unconditional branch */
10686
if (proc_hflags & MIPS_HFLAG_BX) {
10687
tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10689
gen_goto_tb(ctx, 0, ctx->btarget);
10691
case MIPS_HFLAG_BL:
10692
/* blikely taken case */
10693
gen_goto_tb(ctx, 0, ctx->btarget);
10695
case MIPS_HFLAG_BC:
10696
/* Conditional branch */
10698
TCGLabel *l1 = gen_new_label();
10700
tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10701
gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10703
gen_goto_tb(ctx, 0, ctx->btarget);
10706
case MIPS_HFLAG_BR:
10707
/* unconditional branch to register */
10708
if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10709
TCGv t0 = tcg_temp_new();
10710
TCGv_i32 t1 = tcg_temp_new_i32();
10712
tcg_gen_andi_tl(t0, btarget, 0x1);
10713
tcg_gen_trunc_tl_i32(t1, t0);
10715
tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10716
tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10717
tcg_gen_or_i32(hflags, hflags, t1);
10718
tcg_temp_free_i32(t1);
10720
tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10722
tcg_gen_mov_tl(cpu_PC, btarget);
10724
if (ctx->singlestep_enabled) {
10725
save_cpu_state(ctx, 0);
10726
gen_helper_raise_exception_debug(cpu_env);
10728
tcg_gen_exit_tb(0);
10731
fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10737
/* Compact Branches */
10738
static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10739
int rs, int rt, int32_t offset)
10741
int bcond_compute = 0;
10742
TCGv t0 = tcg_temp_new();
10743
TCGv t1 = tcg_temp_new();
10744
int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10746
if (ctx->hflags & MIPS_HFLAG_BMASK) {
10747
#ifdef MIPS_DEBUG_DISAS
10748
LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10751
generate_exception_end(ctx, EXCP_RI);
10755
/* Load needed operands and calculate btarget */
10757
/* compact branch */
10758
case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10759
case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10760
gen_load_gpr(t0, rs);
10761
gen_load_gpr(t1, rt);
10763
ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10764
if (rs <= rt && rs == 0) {
10765
/* OPC_BEQZALC, OPC_BNEZALC */
10766
tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10769
case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10770
case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10771
gen_load_gpr(t0, rs);
10772
gen_load_gpr(t1, rt);
10774
ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10776
case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10777
case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10778
if (rs == 0 || rs == rt) {
10779
/* OPC_BLEZALC, OPC_BGEZALC */
10780
/* OPC_BGTZALC, OPC_BLTZALC */
10781
tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10783
gen_load_gpr(t0, rs);
10784
gen_load_gpr(t1, rt);
10786
ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10790
ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10795
/* OPC_BEQZC, OPC_BNEZC */
10796
gen_load_gpr(t0, rs);
10798
ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10800
/* OPC_JIC, OPC_JIALC */
10801
TCGv tbase = tcg_temp_new();
10802
TCGv toffset = tcg_temp_new();
10804
gen_load_gpr(tbase, rt);
10805
tcg_gen_movi_tl(toffset, offset);
10806
gen_op_addr_add(ctx, btarget, tbase, toffset);
10807
tcg_temp_free(tbase);
10808
tcg_temp_free(toffset);
10812
MIPS_INVAL("Compact branch/jump");
10813
generate_exception_end(ctx, EXCP_RI);
10817
if (bcond_compute == 0) {
10818
/* Uncoditional compact branch */
10821
tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10824
ctx->hflags |= MIPS_HFLAG_BR;
10827
tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10830
ctx->hflags |= MIPS_HFLAG_B;
10833
MIPS_INVAL("Compact branch/jump");
10834
generate_exception_end(ctx, EXCP_RI);
10838
/* Generating branch here as compact branches don't have delay slot */
10839
gen_branch(ctx, 4);
10841
/* Conditional compact branch */
10842
TCGLabel *fs = gen_new_label();
10843
save_cpu_state(ctx, 0);
10846
case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10847
if (rs == 0 && rt != 0) {
10849
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10850
} else if (rs != 0 && rt != 0 && rs == rt) {
10852
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10855
tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10858
case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10859
if (rs == 0 && rt != 0) {
10861
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10862
} else if (rs != 0 && rt != 0 && rs == rt) {
10864
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10867
tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10870
case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10871
if (rs == 0 && rt != 0) {
10873
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10874
} else if (rs != 0 && rt != 0 && rs == rt) {
10876
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10879
tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10882
case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10883
if (rs == 0 && rt != 0) {
10885
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10886
} else if (rs != 0 && rt != 0 && rs == rt) {
10888
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10891
tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10894
case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10895
case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10897
/* OPC_BOVC, OPC_BNVC */
10898
TCGv t2 = tcg_temp_new();
10899
TCGv t3 = tcg_temp_new();
10900
TCGv t4 = tcg_temp_new();
10901
TCGv input_overflow = tcg_temp_new();
10903
gen_load_gpr(t0, rs);
10904
gen_load_gpr(t1, rt);
10905
tcg_gen_ext32s_tl(t2, t0);
10906
tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10907
tcg_gen_ext32s_tl(t3, t1);
10908
tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10909
tcg_gen_or_tl(input_overflow, input_overflow, t4);
10911
tcg_gen_add_tl(t4, t2, t3);
10912
tcg_gen_ext32s_tl(t4, t4);
10913
tcg_gen_xor_tl(t2, t2, t3);
10914
tcg_gen_xor_tl(t3, t4, t3);
10915
tcg_gen_andc_tl(t2, t3, t2);
10916
tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10917
tcg_gen_or_tl(t4, t4, input_overflow);
10918
if (opc == OPC_BOVC) {
10920
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10923
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10925
tcg_temp_free(input_overflow);
10929
} else if (rs < rt && rs == 0) {
10930
/* OPC_BEQZALC, OPC_BNEZALC */
10931
if (opc == OPC_BEQZALC) {
10933
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10936
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10939
/* OPC_BEQC, OPC_BNEC */
10940
if (opc == OPC_BEQC) {
10942
tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10945
tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10950
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10953
tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10956
MIPS_INVAL("Compact conditional branch/jump");
10957
generate_exception_end(ctx, EXCP_RI);
10961
/* Generating branch here as compact branches don't have delay slot */
10962
gen_goto_tb(ctx, 1, ctx->btarget);
10965
ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10973
/* ISA extensions (ASEs) */
10974
/* MIPS16 extension to MIPS32 */
10976
/* MIPS16 major opcodes */
10978
M16_OPC_ADDIUSP = 0x00,
10979
M16_OPC_ADDIUPC = 0x01,
10981
M16_OPC_JAL = 0x03,
10982
M16_OPC_BEQZ = 0x04,
10983
M16_OPC_BNEQZ = 0x05,
10984
M16_OPC_SHIFT = 0x06,
10986
M16_OPC_RRIA = 0x08,
10987
M16_OPC_ADDIU8 = 0x09,
10988
M16_OPC_SLTI = 0x0a,
10989
M16_OPC_SLTIU = 0x0b,
10992
M16_OPC_CMPI = 0x0e,
10996
M16_OPC_LWSP = 0x12,
10998
M16_OPC_LBU = 0x14,
10999
M16_OPC_LHU = 0x15,
11000
M16_OPC_LWPC = 0x16,
11001
M16_OPC_LWU = 0x17,
11004
M16_OPC_SWSP = 0x1a,
11006
M16_OPC_RRR = 0x1c,
11008
M16_OPC_EXTEND = 0x1e,
11012
/* I8 funct field */
11031
/* RR funct field */
11065
/* I64 funct field */
11073
I64_DADDIUPC = 0x6,
11077
/* RR ry field for CNVT */
11079
RR_RY_CNVT_ZEB = 0x0,
11080
RR_RY_CNVT_ZEH = 0x1,
11081
RR_RY_CNVT_ZEW = 0x2,
11082
RR_RY_CNVT_SEB = 0x4,
11083
RR_RY_CNVT_SEH = 0x5,
11084
RR_RY_CNVT_SEW = 0x6,
11087
static int xlat (int r)
11089
static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11094
static void gen_mips16_save (DisasContext *ctx,
11095
int xsregs, int aregs,
11096
int do_ra, int do_s0, int do_s1,
11099
TCGv t0 = tcg_temp_new();
11100
TCGv t1 = tcg_temp_new();
11101
TCGv t2 = tcg_temp_new();
11131
generate_exception_end(ctx, EXCP_RI);
11137
gen_base_offset_addr(ctx, t0, 29, 12);
11138
gen_load_gpr(t1, 7);
11139
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11142
gen_base_offset_addr(ctx, t0, 29, 8);
11143
gen_load_gpr(t1, 6);
11144
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11147
gen_base_offset_addr(ctx, t0, 29, 4);
11148
gen_load_gpr(t1, 5);
11149
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11152
gen_base_offset_addr(ctx, t0, 29, 0);
11153
gen_load_gpr(t1, 4);
11154
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11157
gen_load_gpr(t0, 29);
11159
#define DECR_AND_STORE(reg) do { \
11160
tcg_gen_movi_tl(t2, -4); \
11161
gen_op_addr_add(ctx, t0, t0, t2); \
11162
gen_load_gpr(t1, reg); \
11163
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11167
DECR_AND_STORE(31);
11172
DECR_AND_STORE(30);
11175
DECR_AND_STORE(23);
11178
DECR_AND_STORE(22);
11181
DECR_AND_STORE(21);
11184
DECR_AND_STORE(20);
11187
DECR_AND_STORE(19);
11190
DECR_AND_STORE(18);
11194
DECR_AND_STORE(17);
11197
DECR_AND_STORE(16);
11227
generate_exception_end(ctx, EXCP_RI);
11243
#undef DECR_AND_STORE
11245
tcg_gen_movi_tl(t2, -framesize);
11246
gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11252
static void gen_mips16_restore (DisasContext *ctx,
11253
int xsregs, int aregs,
11254
int do_ra, int do_s0, int do_s1,
11258
TCGv t0 = tcg_temp_new();
11259
TCGv t1 = tcg_temp_new();
11260
TCGv t2 = tcg_temp_new();
11262
tcg_gen_movi_tl(t2, framesize);
11263
gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11265
#define DECR_AND_LOAD(reg) do { \
11266
tcg_gen_movi_tl(t2, -4); \
11267
gen_op_addr_add(ctx, t0, t0, t2); \
11268
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11269
gen_store_gpr(t1, reg); \
11333
generate_exception_end(ctx, EXCP_RI);
11349
#undef DECR_AND_LOAD
11351
tcg_gen_movi_tl(t2, framesize);
11352
gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11358
static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11359
int is_64_bit, int extended)
11363
if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11364
generate_exception_end(ctx, EXCP_RI);
11368
t0 = tcg_temp_new();
11370
tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11371
tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11373
tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11379
static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11382
TCGv_i32 t0 = tcg_const_i32(op);
11383
TCGv t1 = tcg_temp_new();
11384
gen_base_offset_addr(ctx, t1, base, offset);
11385
gen_helper_cache(cpu_env, t1, t0);
11388
#if defined(TARGET_MIPS64)
11389
static void decode_i64_mips16 (DisasContext *ctx,
11390
int ry, int funct, int16_t offset,
11395
check_insn(ctx, ISA_MIPS3);
11396
check_mips_64(ctx);
11397
offset = extended ? offset : offset << 3;
11398
gen_ld(ctx, OPC_LD, ry, 29, offset);
11401
check_insn(ctx, ISA_MIPS3);
11402
check_mips_64(ctx);
11403
offset = extended ? offset : offset << 3;
11404
gen_st(ctx, OPC_SD, ry, 29, offset);
11407
check_insn(ctx, ISA_MIPS3);
11408
check_mips_64(ctx);
11409
offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11410
gen_st(ctx, OPC_SD, 31, 29, offset);
11413
check_insn(ctx, ISA_MIPS3);
11414
check_mips_64(ctx);
11415
offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11416
gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11419
check_insn(ctx, ISA_MIPS3);
11420
check_mips_64(ctx);
11421
if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11422
generate_exception_end(ctx, EXCP_RI);
11424
offset = extended ? offset : offset << 3;
11425
gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11429
check_insn(ctx, ISA_MIPS3);
11430
check_mips_64(ctx);
11431
offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11432
gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11435
check_insn(ctx, ISA_MIPS3);
11436
check_mips_64(ctx);
11437
offset = extended ? offset : offset << 2;
11438
gen_addiupc(ctx, ry, offset, 1, extended);
11441
check_insn(ctx, ISA_MIPS3);
11442
check_mips_64(ctx);
11443
offset = extended ? offset : offset << 2;
11444
gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11450
static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11452
int extend = cpu_lduw_code(env, ctx->pc + 2);
11453
int op, rx, ry, funct, sa;
11454
int16_t imm, offset;
11456
ctx->opcode = (ctx->opcode << 16) | extend;
11457
op = (ctx->opcode >> 11) & 0x1f;
11458
sa = (ctx->opcode >> 22) & 0x1f;
11459
funct = (ctx->opcode >> 8) & 0x7;
11460
rx = xlat((ctx->opcode >> 8) & 0x7);
11461
ry = xlat((ctx->opcode >> 5) & 0x7);
11462
offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11463
| ((ctx->opcode >> 21) & 0x3f) << 5
11464
| (ctx->opcode & 0x1f));
11466
/* The extended opcodes cleverly reuse the opcodes from their 16-bit
11469
case M16_OPC_ADDIUSP:
11470
gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11472
case M16_OPC_ADDIUPC:
11473
gen_addiupc(ctx, rx, imm, 0, 1);
11476
gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11477
/* No delay slot, so just process as a normal instruction */
11480
gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11481
/* No delay slot, so just process as a normal instruction */
11483
case M16_OPC_BNEQZ:
11484
gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11485
/* No delay slot, so just process as a normal instruction */
11487
case M16_OPC_SHIFT:
11488
switch (ctx->opcode & 0x3) {
11490
gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11493
#if defined(TARGET_MIPS64)
11494
check_mips_64(ctx);
11495
gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11497
generate_exception_end(ctx, EXCP_RI);
11501
gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11504
gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11508
#if defined(TARGET_MIPS64)
11510
check_insn(ctx, ISA_MIPS3);
11511
check_mips_64(ctx);
11512
gen_ld(ctx, OPC_LD, ry, rx, offset);
11516
imm = ctx->opcode & 0xf;
11517
imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11518
imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11519
imm = (int16_t) (imm << 1) >> 1;
11520
if ((ctx->opcode >> 4) & 0x1) {
11521
#if defined(TARGET_MIPS64)
11522
check_mips_64(ctx);
11523
gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11525
generate_exception_end(ctx, EXCP_RI);
11528
gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11531
case M16_OPC_ADDIU8:
11532
gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11535
gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11537
case M16_OPC_SLTIU:
11538
gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11543
gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11546
gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11549
gen_st(ctx, OPC_SW, 31, 29, imm);
11552
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11555
check_insn(ctx, ISA_MIPS32);
11557
int xsregs = (ctx->opcode >> 24) & 0x7;
11558
int aregs = (ctx->opcode >> 16) & 0xf;
11559
int do_ra = (ctx->opcode >> 6) & 0x1;
11560
int do_s0 = (ctx->opcode >> 5) & 0x1;
11561
int do_s1 = (ctx->opcode >> 4) & 0x1;
11562
int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11563
| (ctx->opcode & 0xf)) << 3;
11565
if (ctx->opcode & (1 << 7)) {
11566
gen_mips16_save(ctx, xsregs, aregs,
11567
do_ra, do_s0, do_s1,
11570
gen_mips16_restore(ctx, xsregs, aregs,
11571
do_ra, do_s0, do_s1,
11577
generate_exception_end(ctx, EXCP_RI);
11582
tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11585
tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11587
#if defined(TARGET_MIPS64)
11589
check_insn(ctx, ISA_MIPS3);
11590
check_mips_64(ctx);
11591
gen_st(ctx, OPC_SD, ry, rx, offset);
11595
gen_ld(ctx, OPC_LB, ry, rx, offset);
11598
gen_ld(ctx, OPC_LH, ry, rx, offset);
11601
gen_ld(ctx, OPC_LW, rx, 29, offset);
11604
gen_ld(ctx, OPC_LW, ry, rx, offset);
11607
gen_ld(ctx, OPC_LBU, ry, rx, offset);
11610
gen_ld(ctx, OPC_LHU, ry, rx, offset);
11613
gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11615
#if defined(TARGET_MIPS64)
11617
check_insn(ctx, ISA_MIPS3);
11618
check_mips_64(ctx);
11619
gen_ld(ctx, OPC_LWU, ry, rx, offset);
11623
gen_st(ctx, OPC_SB, ry, rx, offset);
11626
gen_st(ctx, OPC_SH, ry, rx, offset);
11629
gen_st(ctx, OPC_SW, rx, 29, offset);
11632
gen_st(ctx, OPC_SW, ry, rx, offset);
11634
#if defined(TARGET_MIPS64)
11636
decode_i64_mips16(ctx, ry, funct, offset, 1);
11640
generate_exception_end(ctx, EXCP_RI);
11647
static inline bool is_uhi(int sdbbp_code)
11649
#ifdef CONFIG_USER_ONLY
11652
return semihosting_enabled() && sdbbp_code == 1;
11656
static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11660
int op, cnvt_op, op1, offset;
11664
op = (ctx->opcode >> 11) & 0x1f;
11665
sa = (ctx->opcode >> 2) & 0x7;
11666
sa = sa == 0 ? 8 : sa;
11667
rx = xlat((ctx->opcode >> 8) & 0x7);
11668
cnvt_op = (ctx->opcode >> 5) & 0x7;
11669
ry = xlat((ctx->opcode >> 5) & 0x7);
11670
op1 = offset = ctx->opcode & 0x1f;
11675
case M16_OPC_ADDIUSP:
11677
int16_t imm = ((uint8_t) ctx->opcode) << 2;
11679
gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11682
case M16_OPC_ADDIUPC:
11683
gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11686
offset = (ctx->opcode & 0x7ff) << 1;
11687
offset = (int16_t)(offset << 4) >> 4;
11688
gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11689
/* No delay slot, so just process as a normal instruction */
11692
offset = cpu_lduw_code(env, ctx->pc + 2);
11693
offset = (((ctx->opcode & 0x1f) << 21)
11694
| ((ctx->opcode >> 5) & 0x1f) << 16
11696
op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11697
gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11701
gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11702
((int8_t)ctx->opcode) << 1, 0);
11703
/* No delay slot, so just process as a normal instruction */
11705
case M16_OPC_BNEQZ:
11706
gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11707
((int8_t)ctx->opcode) << 1, 0);
11708
/* No delay slot, so just process as a normal instruction */
11710
case M16_OPC_SHIFT:
11711
switch (ctx->opcode & 0x3) {
11713
gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11716
#if defined(TARGET_MIPS64)
11717
check_insn(ctx, ISA_MIPS3);
11718
check_mips_64(ctx);
11719
gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11721
generate_exception_end(ctx, EXCP_RI);
11725
gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11728
gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11732
#if defined(TARGET_MIPS64)
11734
check_insn(ctx, ISA_MIPS3);
11735
check_mips_64(ctx);
11736
gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11741
int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11743
if ((ctx->opcode >> 4) & 1) {
11744
#if defined(TARGET_MIPS64)
11745
check_insn(ctx, ISA_MIPS3);
11746
check_mips_64(ctx);
11747
gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11749
generate_exception_end(ctx, EXCP_RI);
11752
gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11756
case M16_OPC_ADDIU8:
11758
int16_t imm = (int8_t) ctx->opcode;
11760
gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11765
int16_t imm = (uint8_t) ctx->opcode;
11766
gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11769
case M16_OPC_SLTIU:
11771
int16_t imm = (uint8_t) ctx->opcode;
11772
gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11779
funct = (ctx->opcode >> 8) & 0x7;
11782
gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11783
((int8_t)ctx->opcode) << 1, 0);
11786
gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11787
((int8_t)ctx->opcode) << 1, 0);
11790
gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11793
gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11794
((int8_t)ctx->opcode) << 3);
11797
check_insn(ctx, ISA_MIPS32);
11799
int do_ra = ctx->opcode & (1 << 6);
11800
int do_s0 = ctx->opcode & (1 << 5);
11801
int do_s1 = ctx->opcode & (1 << 4);
11802
int framesize = ctx->opcode & 0xf;
11804
if (framesize == 0) {
11807
framesize = framesize << 3;
11810
if (ctx->opcode & (1 << 7)) {
11811
gen_mips16_save(ctx, 0, 0,
11812
do_ra, do_s0, do_s1, framesize);
11814
gen_mips16_restore(ctx, 0, 0,
11815
do_ra, do_s0, do_s1, framesize);
11821
int rz = xlat(ctx->opcode & 0x7);
11823
reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11824
((ctx->opcode >> 5) & 0x7);
11825
gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11829
reg32 = ctx->opcode & 0x1f;
11830
gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11833
generate_exception_end(ctx, EXCP_RI);
11840
int16_t imm = (uint8_t) ctx->opcode;
11842
gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11847
int16_t imm = (uint8_t) ctx->opcode;
11848
gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11851
#if defined(TARGET_MIPS64)
11853
check_insn(ctx, ISA_MIPS3);
11854
check_mips_64(ctx);
11855
gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11859
gen_ld(ctx, OPC_LB, ry, rx, offset);
11862
gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11865
gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11868
gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11871
gen_ld(ctx, OPC_LBU, ry, rx, offset);
11874
gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11877
gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11879
#if defined (TARGET_MIPS64)
11881
check_insn(ctx, ISA_MIPS3);
11882
check_mips_64(ctx);
11883
gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11887
gen_st(ctx, OPC_SB, ry, rx, offset);
11890
gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11893
gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11896
gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11900
int rz = xlat((ctx->opcode >> 2) & 0x7);
11903
switch (ctx->opcode & 0x3) {
11905
mips32_op = OPC_ADDU;
11908
mips32_op = OPC_SUBU;
11910
#if defined(TARGET_MIPS64)
11912
mips32_op = OPC_DADDU;
11913
check_insn(ctx, ISA_MIPS3);
11914
check_mips_64(ctx);
11917
mips32_op = OPC_DSUBU;
11918
check_insn(ctx, ISA_MIPS3);
11919
check_mips_64(ctx);
11923
generate_exception_end(ctx, EXCP_RI);
11927
gen_arith(ctx, mips32_op, rz, rx, ry);
11936
int nd = (ctx->opcode >> 7) & 0x1;
11937
int link = (ctx->opcode >> 6) & 0x1;
11938
int ra = (ctx->opcode >> 5) & 0x1;
11941
check_insn(ctx, ISA_MIPS32);
11950
gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11955
if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11956
gen_helper_do_semihosting(cpu_env);
11958
/* XXX: not clear which exception should be raised
11959
* when in debug mode...
11961
check_insn(ctx, ISA_MIPS32);
11962
generate_exception_end(ctx, EXCP_DBp);
11966
gen_slt(ctx, OPC_SLT, 24, rx, ry);
11969
gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11972
generate_exception_end(ctx, EXCP_BREAK);
11975
gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11978
gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11981
gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11983
#if defined (TARGET_MIPS64)
11985
check_insn(ctx, ISA_MIPS3);
11986
check_mips_64(ctx);
11987
gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11991
gen_logic(ctx, OPC_XOR, 24, rx, ry);
11994
gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11997
gen_logic(ctx, OPC_AND, rx, rx, ry);
12000
gen_logic(ctx, OPC_OR, rx, rx, ry);
12003
gen_logic(ctx, OPC_XOR, rx, rx, ry);
12006
gen_logic(ctx, OPC_NOR, rx, ry, 0);
12009
gen_HILO(ctx, OPC_MFHI, 0, rx);
12012
check_insn(ctx, ISA_MIPS32);
12014
case RR_RY_CNVT_ZEB:
12015
tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12017
case RR_RY_CNVT_ZEH:
12018
tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12020
case RR_RY_CNVT_SEB:
12021
tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12023
case RR_RY_CNVT_SEH:
12024
tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12026
#if defined (TARGET_MIPS64)
12027
case RR_RY_CNVT_ZEW:
12028
check_insn(ctx, ISA_MIPS64);
12029
check_mips_64(ctx);
12030
tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12032
case RR_RY_CNVT_SEW:
12033
check_insn(ctx, ISA_MIPS64);
12034
check_mips_64(ctx);
12035
tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12039
generate_exception_end(ctx, EXCP_RI);
12044
gen_HILO(ctx, OPC_MFLO, 0, rx);
12046
#if defined (TARGET_MIPS64)
12048
check_insn(ctx, ISA_MIPS3);
12049
check_mips_64(ctx);
12050
gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
12053
check_insn(ctx, ISA_MIPS3);
12054
check_mips_64(ctx);
12055
gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
12058
check_insn(ctx, ISA_MIPS3);
12059
check_mips_64(ctx);
12060
gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
12063
check_insn(ctx, ISA_MIPS3);
12064
check_mips_64(ctx);
12065
gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
12069
gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
12072
gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
12075
gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
12078
gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
12080
#if defined (TARGET_MIPS64)
12082
check_insn(ctx, ISA_MIPS3);
12083
check_mips_64(ctx);
12084
gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
12087
check_insn(ctx, ISA_MIPS3);
12088
check_mips_64(ctx);
12089
gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
12092
check_insn(ctx, ISA_MIPS3);
12093
check_mips_64(ctx);
12094
gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
12097
check_insn(ctx, ISA_MIPS3);
12098
check_mips_64(ctx);
12099
gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
12103
generate_exception_end(ctx, EXCP_RI);
12107
case M16_OPC_EXTEND:
12108
decode_extended_mips16_opc(env, ctx);
12111
#if defined(TARGET_MIPS64)
12113
funct = (ctx->opcode >> 8) & 0x7;
12114
decode_i64_mips16(ctx, ry, funct, offset, 0);
12118
generate_exception_end(ctx, EXCP_RI);
12125
/* microMIPS extension to MIPS32/MIPS64 */
12128
* microMIPS32/microMIPS64 major opcodes
12130
* 1. MIPS Architecture for Programmers Volume II-B:
12131
* The microMIPS32 Instruction Set (Revision 3.05)
12133
* Table 6.2 microMIPS32 Encoding of Major Opcode Field
12135
* 2. MIPS Architecture For Programmers Volume II-A:
12136
* The MIPS64 Instruction Set (Revision 3.51)
12166
POOL32S = 0x16, /* MIPS64 */
12167
DADDIU32 = 0x17, /* MIPS64 */
12196
/* 0x29 is reserved */
12209
/* 0x31 is reserved */
12222
SD32 = 0x36, /* MIPS64 */
12223
LD32 = 0x37, /* MIPS64 */
12225
/* 0x39 is reserved */
12241
/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12251
/* POOL32A encoding of minor opcode field */
12254
/* These opcodes are distinguished only by bits 9..6; those bits are
12255
* what are recorded below. */
12292
/* The following can be distinguished by their lower 6 bits. */
12302
/* POOL32AXF encoding of minor opcode field extension */
12305
* 1. MIPS Architecture for Programmers Volume II-B:
12306
* The microMIPS32 Instruction Set (Revision 3.05)
12308
* Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12310
* 2. MIPS Architecture for Programmers VolumeIV-e:
12311
* The MIPS DSP Application-Specific Extension
12312
* to the microMIPS32 Architecture (Revision 2.34)
12314
* Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12329
/* begin of microMIPS32 DSP */
12331
/* bits 13..12 for 0x01 */
12337
/* bits 13..12 for 0x2a */
12343
/* bits 13..12 for 0x32 */
12347
/* end of microMIPS32 DSP */
12349
/* bits 15..12 for 0x2c */
12366
/* bits 15..12 for 0x34 */
12374
/* bits 15..12 for 0x3c */
12376
JR = 0x0, /* alias */
12384
/* bits 15..12 for 0x05 */
12388
/* bits 15..12 for 0x0d */
12400
/* bits 15..12 for 0x15 */
12406
/* bits 15..12 for 0x1d */
12410
/* bits 15..12 for 0x2d */
12415
/* bits 15..12 for 0x35 */
12422
/* POOL32B encoding of minor opcode field (bits 15..12) */
12438
/* POOL32C encoding of minor opcode field (bits 15..12) */
12446
/* 0xa is reserved */
12453
/* 0x6 is reserved */
12459
/* POOL32F encoding of minor opcode field (bits 5..0) */
12462
/* These are the bit 7..6 values */
12471
/* These are the bit 8..6 values */
12496
MOVZ_FMT_05 = 0x05,
12530
CABS_COND_FMT = 0x1c, /* MIPS3D */
12537
/* POOL32Fxf encoding of minor opcode extension field */
12575
/* POOL32I encoding of minor opcode field (bits 25..21) */
12605
/* These overlap and are distinguished by bit16 of the instruction */
12614
/* POOL16A encoding of minor opcode field */
12621
/* POOL16B encoding of minor opcode field */
12628
/* POOL16C encoding of minor opcode field */
12648
/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12668
/* POOL16D encoding of minor opcode field */
12675
/* POOL16E encoding of minor opcode field */
12682
static int mmreg (int r)
12684
static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12689
/* Used for 16-bit store instructions. */
12690
static int mmreg2 (int r)
12692
static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12697
#define uMIPS_RD(op) ((op >> 7) & 0x7)
12698
#define uMIPS_RS(op) ((op >> 4) & 0x7)
12699
#define uMIPS_RS2(op) uMIPS_RS(op)
12700
#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12701
#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12702
#define uMIPS_RS5(op) (op & 0x1f)
12704
/* Signed immediate */
12705
#define SIMM(op, start, width) \
12706
((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12709
/* Zero-extended immediate */
12710
#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12712
static void gen_addiur1sp(DisasContext *ctx)
12714
int rd = mmreg(uMIPS_RD(ctx->opcode));
12716
gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12719
static void gen_addiur2(DisasContext *ctx)
12721
static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12722
int rd = mmreg(uMIPS_RD(ctx->opcode));
12723
int rs = mmreg(uMIPS_RS(ctx->opcode));
12725
gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12728
static void gen_addiusp(DisasContext *ctx)
12730
int encoded = ZIMM(ctx->opcode, 1, 9);
12733
if (encoded <= 1) {
12734
decoded = 256 + encoded;
12735
} else if (encoded <= 255) {
12737
} else if (encoded <= 509) {
12738
decoded = encoded - 512;
12740
decoded = encoded - 768;
12743
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12746
static void gen_addius5(DisasContext *ctx)
12748
int imm = SIMM(ctx->opcode, 1, 4);
12749
int rd = (ctx->opcode >> 5) & 0x1f;
12751
gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12754
static void gen_andi16(DisasContext *ctx)
12756
static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12757
31, 32, 63, 64, 255, 32768, 65535 };
12758
int rd = mmreg(uMIPS_RD(ctx->opcode));
12759
int rs = mmreg(uMIPS_RS(ctx->opcode));
12760
int encoded = ZIMM(ctx->opcode, 0, 4);
12762
gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12765
static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12766
int base, int16_t offset)
12771
if (ctx->hflags & MIPS_HFLAG_BMASK) {
12772
generate_exception_end(ctx, EXCP_RI);
12776
t0 = tcg_temp_new();
12778
gen_base_offset_addr(ctx, t0, base, offset);
12780
t1 = tcg_const_tl(reglist);
12781
t2 = tcg_const_i32(ctx->mem_idx);
12783
save_cpu_state(ctx, 1);
12786
gen_helper_lwm(cpu_env, t0, t1, t2);
12789
gen_helper_swm(cpu_env, t0, t1, t2);
12791
#ifdef TARGET_MIPS64
12793
gen_helper_ldm(cpu_env, t0, t1, t2);
12796
gen_helper_sdm(cpu_env, t0, t1, t2);
12802
tcg_temp_free_i32(t2);
12806
static void gen_pool16c_insn(DisasContext *ctx)
12808
int rd = mmreg((ctx->opcode >> 3) & 0x7);
12809
int rs = mmreg(ctx->opcode & 0x7);
12811
switch (((ctx->opcode) >> 4) & 0x3f) {
12816
gen_logic(ctx, OPC_NOR, rd, rs, 0);
12822
gen_logic(ctx, OPC_XOR, rd, rd, rs);
12828
gen_logic(ctx, OPC_AND, rd, rd, rs);
12834
gen_logic(ctx, OPC_OR, rd, rd, rs);
12841
static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12842
int offset = ZIMM(ctx->opcode, 0, 4);
12844
gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12853
static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12854
int offset = ZIMM(ctx->opcode, 0, 4);
12856
gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12863
int reg = ctx->opcode & 0x1f;
12865
gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12871
int reg = ctx->opcode & 0x1f;
12872
gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12873
/* Let normal delay slot handling in our caller take us
12874
to the branch target. */
12879
gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12880
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12884
gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12885
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12889
gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12893
gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12896
generate_exception_end(ctx, EXCP_BREAK);
12899
if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12900
gen_helper_do_semihosting(cpu_env);
12902
/* XXX: not clear which exception should be raised
12903
* when in debug mode...
12905
check_insn(ctx, ISA_MIPS32);
12906
generate_exception_end(ctx, EXCP_DBp);
12909
case JRADDIUSP + 0:
12910
case JRADDIUSP + 1:
12912
int imm = ZIMM(ctx->opcode, 0, 5);
12913
gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12914
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12915
/* Let normal delay slot handling in our caller take us
12916
to the branch target. */
12920
generate_exception_end(ctx, EXCP_RI);
12925
static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12928
int rd, rs, re, rt;
12929
static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12930
static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12931
static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12932
rd = rd_enc[enc_dest];
12933
re = re_enc[enc_dest];
12934
rs = rs_rt_enc[enc_rs];
12935
rt = rs_rt_enc[enc_rt];
12937
tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12939
tcg_gen_movi_tl(cpu_gpr[rd], 0);
12942
tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12944
tcg_gen_movi_tl(cpu_gpr[re], 0);
12948
static void gen_pool16c_r6_insn(DisasContext *ctx)
12950
int rt = mmreg((ctx->opcode >> 7) & 0x7);
12951
int rs = mmreg((ctx->opcode >> 4) & 0x7);
12953
switch (ctx->opcode & 0xf) {
12955
gen_logic(ctx, OPC_NOR, rt, rs, 0);
12958
gen_logic(ctx, OPC_AND, rt, rt, rs);
12962
int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12963
int offset = extract32(ctx->opcode, 4, 4);
12964
gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12967
case R6_JRC16: /* JRCADDIUSP */
12968
if ((ctx->opcode >> 4) & 1) {
12970
int imm = extract32(ctx->opcode, 5, 5);
12971
gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12972
gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12975
int rs = extract32(ctx->opcode, 5, 5);
12976
gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12979
case MOVEP ... MOVEP_07:
12980
case MOVEP_0C ... MOVEP_0F:
12982
int enc_dest = uMIPS_RD(ctx->opcode);
12983
int enc_rt = uMIPS_RS2(ctx->opcode);
12984
int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12985
gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12989
gen_logic(ctx, OPC_XOR, rt, rt, rs);
12992
gen_logic(ctx, OPC_OR, rt, rt, rs);
12996
int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12997
int offset = extract32(ctx->opcode, 4, 4);
12998
gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13001
case JALRC16: /* BREAK16, SDBBP16 */
13002
switch (ctx->opcode & 0x3f) {
13004
case JALRC16 + 0x20:
13006
gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13011
generate_exception(ctx, EXCP_BREAK);
13015
if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13016
gen_helper_do_semihosting(cpu_env);
13018
if (ctx->hflags & MIPS_HFLAG_SBRI) {
13019
generate_exception(ctx, EXCP_RI);
13021
generate_exception(ctx, EXCP_DBp);
13028
generate_exception(ctx, EXCP_RI);
13033
static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13035
TCGv t0 = tcg_temp_new();
13036
TCGv t1 = tcg_temp_new();
13038
gen_load_gpr(t0, base);
13041
gen_load_gpr(t1, index);
13042
tcg_gen_shli_tl(t1, t1, 2);
13043
gen_op_addr_add(ctx, t0, t1, t0);
13046
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13047
gen_store_gpr(t1, rd);
13053
static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13054
int base, int16_t offset)
13058
if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
13059
generate_exception_end(ctx, EXCP_RI);
13063
t0 = tcg_temp_new();
13064
t1 = tcg_temp_new();
13066
gen_base_offset_addr(ctx, t0, base, offset);
13071
generate_exception_end(ctx, EXCP_RI);
13074
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13075
gen_store_gpr(t1, rd);
13076
tcg_gen_movi_tl(t1, 4);
13077
gen_op_addr_add(ctx, t0, t0, t1);
13078
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13079
gen_store_gpr(t1, rd+1);
13082
gen_load_gpr(t1, rd);
13083
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13084
tcg_gen_movi_tl(t1, 4);
13085
gen_op_addr_add(ctx, t0, t0, t1);
13086
gen_load_gpr(t1, rd+1);
13087
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13089
#ifdef TARGET_MIPS64
13092
generate_exception_end(ctx, EXCP_RI);
13095
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13096
gen_store_gpr(t1, rd);
13097
tcg_gen_movi_tl(t1, 8);
13098
gen_op_addr_add(ctx, t0, t0, t1);
13099
tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13100
gen_store_gpr(t1, rd+1);
13103
gen_load_gpr(t1, rd);
13104
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13105
tcg_gen_movi_tl(t1, 8);
13106
gen_op_addr_add(ctx, t0, t0, t1);
13107
gen_load_gpr(t1, rd+1);
13108
tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13116
static void gen_sync(int stype)
13118
TCGBar tcg_mo = TCG_BAR_SC;
13121
case 0x4: /* SYNC_WMB */
13122
tcg_mo |= TCG_MO_ST_ST;
13124
case 0x10: /* SYNC_MB */
13125
tcg_mo |= TCG_MO_ALL;
13127
case 0x11: /* SYNC_ACQUIRE */
13128
tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13130
case 0x12: /* SYNC_RELEASE */
13131
tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13133
case 0x13: /* SYNC_RMB */
13134
tcg_mo |= TCG_MO_LD_LD;
13137
tcg_mo |= TCG_MO_ALL;
13141
tcg_gen_mb(tcg_mo);
13144
static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13146
int extension = (ctx->opcode >> 6) & 0x3f;
13147
int minor = (ctx->opcode >> 12) & 0xf;
13148
uint32_t mips32_op;
13150
switch (extension) {
13152
mips32_op = OPC_TEQ;
13155
mips32_op = OPC_TGE;
13158
mips32_op = OPC_TGEU;
13161
mips32_op = OPC_TLT;
13164
mips32_op = OPC_TLTU;
13167
mips32_op = OPC_TNE;
13169
gen_trap(ctx, mips32_op, rs, rt, -1);
13171
#ifndef CONFIG_USER_ONLY
13174
check_cp0_enabled(ctx);
13176
/* Treat as NOP. */
13179
gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13183
check_cp0_enabled(ctx);
13185
TCGv t0 = tcg_temp_new();
13187
gen_load_gpr(t0, rt);
13188
gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13194
switch (minor & 3) {
13196
gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13199
gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13202
gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13205
gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13208
goto pool32axf_invalid;
13212
switch (minor & 3) {
13214
gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13217
gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13220
goto pool32axf_invalid;
13226
check_insn(ctx, ISA_MIPS32R6);
13227
gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13230
gen_bshfl(ctx, OPC_SEB, rs, rt);
13233
gen_bshfl(ctx, OPC_SEH, rs, rt);
13236
mips32_op = OPC_CLO;
13239
mips32_op = OPC_CLZ;
13241
check_insn(ctx, ISA_MIPS32);
13242
gen_cl(ctx, mips32_op, rt, rs);
13245
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13246
gen_rdhwr(ctx, rt, rs, 0);
13249
gen_bshfl(ctx, OPC_WSBH, rs, rt);
13252
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13253
mips32_op = OPC_MULT;
13256
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13257
mips32_op = OPC_MULTU;
13260
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13261
mips32_op = OPC_DIV;
13264
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13265
mips32_op = OPC_DIVU;
13268
check_insn(ctx, ISA_MIPS32);
13269
gen_muldiv(ctx, mips32_op, 0, rs, rt);
13272
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13273
mips32_op = OPC_MADD;
13276
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13277
mips32_op = OPC_MADDU;
13280
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13281
mips32_op = OPC_MSUB;
13284
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13285
mips32_op = OPC_MSUBU;
13287
check_insn(ctx, ISA_MIPS32);
13288
gen_muldiv(ctx, mips32_op, 0, rs, rt);
13291
goto pool32axf_invalid;
13302
generate_exception_err(ctx, EXCP_CpU, 2);
13305
goto pool32axf_invalid;
13310
case JALR: /* JALRC */
13311
case JALR_HB: /* JALRC_HB */
13312
if (ctx->insn_flags & ISA_MIPS32R6) {
13313
/* JALRC, JALRC_HB */
13314
gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13316
/* JALR, JALR_HB */
13317
gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13318
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13323
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13324
gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13325
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13328
goto pool32axf_invalid;
13334
check_cp0_enabled(ctx);
13335
check_insn(ctx, ISA_MIPS32R2);
13336
gen_load_srsgpr(rs, rt);
13339
check_cp0_enabled(ctx);
13340
check_insn(ctx, ISA_MIPS32R2);
13341
gen_store_srsgpr(rs, rt);
13344
goto pool32axf_invalid;
13347
#ifndef CONFIG_USER_ONLY
13351
mips32_op = OPC_TLBP;
13354
mips32_op = OPC_TLBR;
13357
mips32_op = OPC_TLBWI;
13360
mips32_op = OPC_TLBWR;
13363
mips32_op = OPC_TLBINV;
13366
mips32_op = OPC_TLBINVF;
13369
mips32_op = OPC_WAIT;
13372
mips32_op = OPC_DERET;
13375
mips32_op = OPC_ERET;
13377
gen_cp0(env, ctx, mips32_op, rt, rs);
13380
goto pool32axf_invalid;
13386
check_cp0_enabled(ctx);
13388
TCGv t0 = tcg_temp_new();
13390
save_cpu_state(ctx, 1);
13391
gen_helper_di(t0, cpu_env);
13392
gen_store_gpr(t0, rs);
13393
/* Stop translation as we may have switched the execution mode */
13394
ctx->bstate = BS_STOP;
13399
check_cp0_enabled(ctx);
13401
TCGv t0 = tcg_temp_new();
13403
save_cpu_state(ctx, 1);
13404
gen_helper_ei(t0, cpu_env);
13405
gen_store_gpr(t0, rs);
13406
/* Stop translation as we may have switched the execution mode */
13407
ctx->bstate = BS_STOP;
13412
goto pool32axf_invalid;
13419
gen_sync(extract32(ctx->opcode, 16, 5));
13422
generate_exception_end(ctx, EXCP_SYSCALL);
13425
if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13426
gen_helper_do_semihosting(cpu_env);
13428
check_insn(ctx, ISA_MIPS32);
13429
if (ctx->hflags & MIPS_HFLAG_SBRI) {
13430
generate_exception_end(ctx, EXCP_RI);
13432
generate_exception_end(ctx, EXCP_DBp);
13437
goto pool32axf_invalid;
13441
switch (minor & 3) {
13443
gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13446
gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13449
gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13452
gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13455
goto pool32axf_invalid;
13459
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13462
gen_HILO(ctx, OPC_MFHI, 0, rs);
13465
gen_HILO(ctx, OPC_MFLO, 0, rs);
13468
gen_HILO(ctx, OPC_MTHI, 0, rs);
13471
gen_HILO(ctx, OPC_MTLO, 0, rs);
13474
goto pool32axf_invalid;
13479
MIPS_INVAL("pool32axf");
13480
generate_exception_end(ctx, EXCP_RI);
13485
/* Values for microMIPS fmt field. Variable-width, depending on which
13486
formats the instruction supports. */
13505
static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13507
int extension = (ctx->opcode >> 6) & 0x3ff;
13508
uint32_t mips32_op;
13510
#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13511
#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13512
#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13514
switch (extension) {
13515
case FLOAT_1BIT_FMT(CFC1, 0):
13516
mips32_op = OPC_CFC1;
13518
case FLOAT_1BIT_FMT(CTC1, 0):
13519
mips32_op = OPC_CTC1;
13521
case FLOAT_1BIT_FMT(MFC1, 0):
13522
mips32_op = OPC_MFC1;
13524
case FLOAT_1BIT_FMT(MTC1, 0):
13525
mips32_op = OPC_MTC1;
13527
case FLOAT_1BIT_FMT(MFHC1, 0):
13528
mips32_op = OPC_MFHC1;
13530
case FLOAT_1BIT_FMT(MTHC1, 0):
13531
mips32_op = OPC_MTHC1;
13533
gen_cp1(ctx, mips32_op, rt, rs);
13536
/* Reciprocal square root */
13537
case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13538
mips32_op = OPC_RSQRT_S;
13540
case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13541
mips32_op = OPC_RSQRT_D;
13545
case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13546
mips32_op = OPC_SQRT_S;
13548
case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13549
mips32_op = OPC_SQRT_D;
13553
case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13554
mips32_op = OPC_RECIP_S;
13556
case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13557
mips32_op = OPC_RECIP_D;
13561
case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13562
mips32_op = OPC_FLOOR_L_S;
13564
case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13565
mips32_op = OPC_FLOOR_L_D;
13567
case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13568
mips32_op = OPC_FLOOR_W_S;
13570
case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13571
mips32_op = OPC_FLOOR_W_D;
13575
case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13576
mips32_op = OPC_CEIL_L_S;
13578
case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13579
mips32_op = OPC_CEIL_L_D;
13581
case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13582
mips32_op = OPC_CEIL_W_S;
13584
case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13585
mips32_op = OPC_CEIL_W_D;
13589
case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13590
mips32_op = OPC_TRUNC_L_S;
13592
case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13593
mips32_op = OPC_TRUNC_L_D;
13595
case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13596
mips32_op = OPC_TRUNC_W_S;
13598
case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13599
mips32_op = OPC_TRUNC_W_D;
13603
case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13604
mips32_op = OPC_ROUND_L_S;
13606
case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13607
mips32_op = OPC_ROUND_L_D;
13609
case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13610
mips32_op = OPC_ROUND_W_S;
13612
case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13613
mips32_op = OPC_ROUND_W_D;
13616
/* Integer to floating-point conversion */
13617
case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13618
mips32_op = OPC_CVT_L_S;
13620
case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13621
mips32_op = OPC_CVT_L_D;
13623
case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13624
mips32_op = OPC_CVT_W_S;
13626
case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13627
mips32_op = OPC_CVT_W_D;
13630
/* Paired-foo conversions */
13631
case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13632
mips32_op = OPC_CVT_S_PL;
13634
case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13635
mips32_op = OPC_CVT_S_PU;
13637
case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13638
mips32_op = OPC_CVT_PW_PS;
13640
case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13641
mips32_op = OPC_CVT_PS_PW;
13644
/* Floating-point moves */
13645
case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13646
mips32_op = OPC_MOV_S;
13648
case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13649
mips32_op = OPC_MOV_D;
13651
case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13652
mips32_op = OPC_MOV_PS;
13655
/* Absolute value */
13656
case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13657
mips32_op = OPC_ABS_S;
13659
case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13660
mips32_op = OPC_ABS_D;
13662
case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13663
mips32_op = OPC_ABS_PS;
13667
case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13668
mips32_op = OPC_NEG_S;
13670
case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13671
mips32_op = OPC_NEG_D;
13673
case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13674
mips32_op = OPC_NEG_PS;
13677
/* Reciprocal square root step */
13678
case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13679
mips32_op = OPC_RSQRT1_S;
13681
case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13682
mips32_op = OPC_RSQRT1_D;
13684
case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13685
mips32_op = OPC_RSQRT1_PS;
13688
/* Reciprocal step */
13689
case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13690
mips32_op = OPC_RECIP1_S;
13692
case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13693
mips32_op = OPC_RECIP1_S;
13695
case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13696
mips32_op = OPC_RECIP1_PS;
13699
/* Conversions from double */
13700
case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13701
mips32_op = OPC_CVT_D_S;
13703
case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13704
mips32_op = OPC_CVT_D_W;
13706
case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13707
mips32_op = OPC_CVT_D_L;
13710
/* Conversions from single */
13711
case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13712
mips32_op = OPC_CVT_S_D;
13714
case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13715
mips32_op = OPC_CVT_S_W;
13717
case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13718
mips32_op = OPC_CVT_S_L;
13720
gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13723
/* Conditional moves on floating-point codes */
13724
case COND_FLOAT_MOV(MOVT, 0):
13725
case COND_FLOAT_MOV(MOVT, 1):
13726
case COND_FLOAT_MOV(MOVT, 2):
13727
case COND_FLOAT_MOV(MOVT, 3):
13728
case COND_FLOAT_MOV(MOVT, 4):
13729
case COND_FLOAT_MOV(MOVT, 5):
13730
case COND_FLOAT_MOV(MOVT, 6):
13731
case COND_FLOAT_MOV(MOVT, 7):
13732
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13733
gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13735
case COND_FLOAT_MOV(MOVF, 0):
13736
case COND_FLOAT_MOV(MOVF, 1):
13737
case COND_FLOAT_MOV(MOVF, 2):
13738
case COND_FLOAT_MOV(MOVF, 3):
13739
case COND_FLOAT_MOV(MOVF, 4):
13740
case COND_FLOAT_MOV(MOVF, 5):
13741
case COND_FLOAT_MOV(MOVF, 6):
13742
case COND_FLOAT_MOV(MOVF, 7):
13743
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13744
gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13747
MIPS_INVAL("pool32fxf");
13748
generate_exception_end(ctx, EXCP_RI);
13753
static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13757
int rt, rs, rd, rr;
13759
uint32_t op, minor, mips32_op;
13760
uint32_t cond, fmt, cc;
13762
insn = cpu_lduw_code(env, ctx->pc + 2);
13763
ctx->opcode = (ctx->opcode << 16) | insn;
13765
rt = (ctx->opcode >> 21) & 0x1f;
13766
rs = (ctx->opcode >> 16) & 0x1f;
13767
rd = (ctx->opcode >> 11) & 0x1f;
13768
rr = (ctx->opcode >> 6) & 0x1f;
13769
imm = (int16_t) ctx->opcode;
13771
op = (ctx->opcode >> 26) & 0x3f;
13774
minor = ctx->opcode & 0x3f;
13777
minor = (ctx->opcode >> 6) & 0xf;
13780
mips32_op = OPC_SLL;
13783
mips32_op = OPC_SRA;
13786
mips32_op = OPC_SRL;
13789
mips32_op = OPC_ROTR;
13791
gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13794
check_insn(ctx, ISA_MIPS32R6);
13795
gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13798
check_insn(ctx, ISA_MIPS32R6);
13799
gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13802
check_insn(ctx, ISA_MIPS32R6);
13803
gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13806
goto pool32a_invalid;
13810
minor = (ctx->opcode >> 6) & 0xf;
13814
mips32_op = OPC_ADD;
13817
mips32_op = OPC_ADDU;
13820
mips32_op = OPC_SUB;
13823
mips32_op = OPC_SUBU;
13826
check_insn_opc_removed(ctx, ISA_MIPS32R6);
13827
mips32_op = OPC_MUL;
13829
gen_arith(ctx, mips32_op, rd, rs, rt);
13833
mips32_op = OPC_SLLV;
13836
mips32_op = OPC_SRLV;
13839
mips32_op = OPC_SRAV;
13842
mips32_op = OPC_ROTRV;
13844
gen_shift(ctx, mips32_op, rd, rs, rt);
13846
/* Logical operations */
13848
mips32_op = OPC_AND;
13851
mips32_op = OPC_OR;
13854
mips32_op = OPC_NOR;
13857
mips32_op = OPC_XOR;
13859
gen_logic(ctx, mips32_op, rd, rs, rt);
13861
/* Set less than */
13863
mips32_op = OPC_SLT;
13866
mips32_op = OPC_SLTU;
13868
gen_slt(ctx, mips32_op, rd, rs, rt);
13871
goto pool32a_invalid;
13875
minor = (ctx->opcode >> 6) & 0xf;
13877
/* Conditional moves */
13878
case MOVN: /* MUL */
13879
if (ctx->insn_flags & ISA_MIPS32R6) {
13881
gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13884
gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13887
case MOVZ: /* MUH */
13888
if (ctx->insn_flags & ISA_MIPS32R6) {
13890
gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13893
gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13897
check_insn(ctx, ISA_MIPS32R6);
13898
gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13901
check_insn(ctx, ISA_MIPS32R6);
13902
gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13904
case LWXS: /* DIV */
13905
if (ctx->insn_flags & ISA_MIPS32R6) {
13907
gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13910
gen_ldxs(ctx, rs, rt, rd);
13914
check_insn(ctx, ISA_MIPS32R6);
13915
gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13918
check_insn(ctx, ISA_MIPS32R6);
13919
gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13922
check_insn(ctx, ISA_MIPS32R6);
13923
gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13926
goto pool32a_invalid;
13930
gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13933
check_insn(ctx, ISA_MIPS32R6);
13934
gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13935
extract32(ctx->opcode, 9, 2));
13938
check_insn(ctx, ISA_MIPS32R6);
13939
gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13940
extract32(ctx->opcode, 9, 2));
13943
gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13946
gen_pool32axf(env, ctx, rt, rs);
13949
generate_exception_end(ctx, EXCP_BREAK);
13952
check_insn(ctx, ISA_MIPS32R6);
13953
generate_exception_end(ctx, EXCP_RI);
13957
MIPS_INVAL("pool32a");
13958
generate_exception_end(ctx, EXCP_RI);
13963
minor = (ctx->opcode >> 12) & 0xf;
13966
check_cp0_enabled(ctx);
13967
if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13968
gen_cache_operation(ctx, rt, rs, imm);
13973
/* COP2: Not implemented. */
13974
generate_exception_err(ctx, EXCP_CpU, 2);
13976
#ifdef TARGET_MIPS64
13979
check_insn(ctx, ISA_MIPS3);
13980
check_mips_64(ctx);
13985
gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13987
#ifdef TARGET_MIPS64
13990
check_insn(ctx, ISA_MIPS3);
13991
check_mips_64(ctx);
13996
gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13999
MIPS_INVAL("pool32b");
14000
generate_exception_end(ctx, EXCP_RI);
14005
if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14006
minor = ctx->opcode & 0x3f;
14007
check_cp1_enabled(ctx);
14010
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14011
mips32_op = OPC_ALNV_PS;
14014
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14015
mips32_op = OPC_MADD_S;
14018
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14019
mips32_op = OPC_MADD_D;
14022
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14023
mips32_op = OPC_MADD_PS;
14026
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14027
mips32_op = OPC_MSUB_S;
14030
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14031
mips32_op = OPC_MSUB_D;
14034
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14035
mips32_op = OPC_MSUB_PS;
14038
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14039
mips32_op = OPC_NMADD_S;
14042
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14043
mips32_op = OPC_NMADD_D;
14046
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14047
mips32_op = OPC_NMADD_PS;
14050
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14051
mips32_op = OPC_NMSUB_S;
14054
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14055
mips32_op = OPC_NMSUB_D;
14058
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14059
mips32_op = OPC_NMSUB_PS;
14061
gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14063
case CABS_COND_FMT:
14064
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14065
cond = (ctx->opcode >> 6) & 0xf;
14066
cc = (ctx->opcode >> 13) & 0x7;
14067
fmt = (ctx->opcode >> 10) & 0x3;
14070
gen_cmpabs_s(ctx, cond, rt, rs, cc);
14073
gen_cmpabs_d(ctx, cond, rt, rs, cc);
14076
gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14079
goto pool32f_invalid;
14083
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14084
cond = (ctx->opcode >> 6) & 0xf;
14085
cc = (ctx->opcode >> 13) & 0x7;
14086
fmt = (ctx->opcode >> 10) & 0x3;
14089
gen_cmp_s(ctx, cond, rt, rs, cc);
14092
gen_cmp_d(ctx, cond, rt, rs, cc);
14095
gen_cmp_ps(ctx, cond, rt, rs, cc);
14098
goto pool32f_invalid;
14102
check_insn(ctx, ISA_MIPS32R6);
14103
gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14106
check_insn(ctx, ISA_MIPS32R6);
14107
gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14110
gen_pool32fxf(ctx, rt, rs);
14114
switch ((ctx->opcode >> 6) & 0x7) {
14116
mips32_op = OPC_PLL_PS;
14119
mips32_op = OPC_PLU_PS;
14122
mips32_op = OPC_PUL_PS;
14125
mips32_op = OPC_PUU_PS;
14128
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14129
mips32_op = OPC_CVT_PS_S;
14131
gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14134
goto pool32f_invalid;
14138
check_insn(ctx, ISA_MIPS32R6);
14139
switch ((ctx->opcode >> 9) & 0x3) {
14141
gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14144
gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14147
goto pool32f_invalid;
14152
switch ((ctx->opcode >> 6) & 0x7) {
14154
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14155
mips32_op = OPC_LWXC1;
14158
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14159
mips32_op = OPC_SWXC1;
14162
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14163
mips32_op = OPC_LDXC1;
14166
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14167
mips32_op = OPC_SDXC1;
14170
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14171
mips32_op = OPC_LUXC1;
14174
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14175
mips32_op = OPC_SUXC1;
14177
gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14180
goto pool32f_invalid;
14184
check_insn(ctx, ISA_MIPS32R6);
14185
switch ((ctx->opcode >> 9) & 0x3) {
14187
gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14190
gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14193
goto pool32f_invalid;
14198
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14199
fmt = (ctx->opcode >> 9) & 0x3;
14200
switch ((ctx->opcode >> 6) & 0x7) {
14204
mips32_op = OPC_RSQRT2_S;
14207
mips32_op = OPC_RSQRT2_D;
14210
mips32_op = OPC_RSQRT2_PS;
14213
goto pool32f_invalid;
14219
mips32_op = OPC_RECIP2_S;
14222
mips32_op = OPC_RECIP2_D;
14225
mips32_op = OPC_RECIP2_PS;
14228
goto pool32f_invalid;
14232
mips32_op = OPC_ADDR_PS;
14235
mips32_op = OPC_MULR_PS;
14237
gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14240
goto pool32f_invalid;
14244
/* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14245
cc = (ctx->opcode >> 13) & 0x7;
14246
fmt = (ctx->opcode >> 9) & 0x3;
14247
switch ((ctx->opcode >> 6) & 0x7) {
14248
case MOVF_FMT: /* RINT_FMT */
14249
if (ctx->insn_flags & ISA_MIPS32R6) {
14253
gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14256
gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14259
goto pool32f_invalid;
14265
gen_movcf_s(ctx, rs, rt, cc, 0);
14268
gen_movcf_d(ctx, rs, rt, cc, 0);
14272
gen_movcf_ps(ctx, rs, rt, cc, 0);
14275
goto pool32f_invalid;
14279
case MOVT_FMT: /* CLASS_FMT */
14280
if (ctx->insn_flags & ISA_MIPS32R6) {
14284
gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14287
gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14290
goto pool32f_invalid;
14296
gen_movcf_s(ctx, rs, rt, cc, 1);
14299
gen_movcf_d(ctx, rs, rt, cc, 1);
14303
gen_movcf_ps(ctx, rs, rt, cc, 1);
14306
goto pool32f_invalid;
14311
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14314
goto pool32f_invalid;
14317
#define FINSN_3ARG_SDPS(prfx) \
14318
switch ((ctx->opcode >> 8) & 0x3) { \
14320
mips32_op = OPC_##prfx##_S; \
14323
mips32_op = OPC_##prfx##_D; \
14325
case FMT_SDPS_PS: \
14327
mips32_op = OPC_##prfx##_PS; \
14330
goto pool32f_invalid; \
14333
check_insn(ctx, ISA_MIPS32R6);
14334
switch ((ctx->opcode >> 9) & 0x3) {
14336
gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14339
gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14342
goto pool32f_invalid;
14346
check_insn(ctx, ISA_MIPS32R6);
14347
switch ((ctx->opcode >> 9) & 0x3) {
14349
gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14352
gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14355
goto pool32f_invalid;
14359
/* regular FP ops */
14360
switch ((ctx->opcode >> 6) & 0x3) {
14362
FINSN_3ARG_SDPS(ADD);
14365
FINSN_3ARG_SDPS(SUB);
14368
FINSN_3ARG_SDPS(MUL);
14371
fmt = (ctx->opcode >> 8) & 0x3;
14373
mips32_op = OPC_DIV_D;
14374
} else if (fmt == 0) {
14375
mips32_op = OPC_DIV_S;
14377
goto pool32f_invalid;
14381
goto pool32f_invalid;
14386
switch ((ctx->opcode >> 6) & 0x7) {
14387
case MOVN_FMT: /* SELNEZ_FMT */
14388
if (ctx->insn_flags & ISA_MIPS32R6) {
14390
switch ((ctx->opcode >> 9) & 0x3) {
14392
gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14395
gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14398
goto pool32f_invalid;
14402
FINSN_3ARG_SDPS(MOVN);
14406
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14407
FINSN_3ARG_SDPS(MOVN);
14409
case MOVZ_FMT: /* SELEQZ_FMT */
14410
if (ctx->insn_flags & ISA_MIPS32R6) {
14412
switch ((ctx->opcode >> 9) & 0x3) {
14414
gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14417
gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14420
goto pool32f_invalid;
14424
FINSN_3ARG_SDPS(MOVZ);
14428
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14429
FINSN_3ARG_SDPS(MOVZ);
14432
check_insn(ctx, ISA_MIPS32R6);
14433
switch ((ctx->opcode >> 9) & 0x3) {
14435
gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14438
gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14441
goto pool32f_invalid;
14445
check_insn(ctx, ISA_MIPS32R6);
14446
switch ((ctx->opcode >> 9) & 0x3) {
14448
mips32_op = OPC_MADDF_S;
14451
mips32_op = OPC_MADDF_D;
14454
goto pool32f_invalid;
14458
check_insn(ctx, ISA_MIPS32R6);
14459
switch ((ctx->opcode >> 9) & 0x3) {
14461
mips32_op = OPC_MSUBF_S;
14464
mips32_op = OPC_MSUBF_D;
14467
goto pool32f_invalid;
14471
goto pool32f_invalid;
14475
gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14479
MIPS_INVAL("pool32f");
14480
generate_exception_end(ctx, EXCP_RI);
14484
generate_exception_err(ctx, EXCP_CpU, 1);
14488
minor = (ctx->opcode >> 21) & 0x1f;
14491
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14492
gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14495
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14496
gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14497
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14500
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14501
gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14502
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14505
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14506
gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14509
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14510
gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14511
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14514
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14515
gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14516
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14519
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14520
gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14523
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14524
gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14528
case TLTI: /* BC1EQZC */
14529
if (ctx->insn_flags & ISA_MIPS32R6) {
14531
check_cp1_enabled(ctx);
14532
gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14535
mips32_op = OPC_TLTI;
14539
case TGEI: /* BC1NEZC */
14540
if (ctx->insn_flags & ISA_MIPS32R6) {
14542
check_cp1_enabled(ctx);
14543
gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14546
mips32_op = OPC_TGEI;
14551
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14552
mips32_op = OPC_TLTIU;
14555
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14556
mips32_op = OPC_TGEIU;
14558
case TNEI: /* SYNCI */
14559
if (ctx->insn_flags & ISA_MIPS32R6) {
14561
/* Break the TB to be able to sync copied instructions
14563
ctx->bstate = BS_STOP;
14566
mips32_op = OPC_TNEI;
14571
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14572
mips32_op = OPC_TEQI;
14574
gen_trap(ctx, mips32_op, rs, -1, imm);
14579
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14580
gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14581
4, rs, 0, imm << 1, 0);
14582
/* Compact branches don't have a delay slot, so just let
14583
the normal delay slot handling take us to the branch
14587
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14588
gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14591
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14592
/* Break the TB to be able to sync copied instructions
14594
ctx->bstate = BS_STOP;
14598
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14599
/* COP2: Not implemented. */
14600
generate_exception_err(ctx, EXCP_CpU, 2);
14603
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14604
mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14607
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14608
mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14611
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14612
mips32_op = OPC_BC1FANY4;
14615
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14616
mips32_op = OPC_BC1TANY4;
14619
check_insn(ctx, ASE_MIPS3D);
14622
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14623
check_cp1_enabled(ctx);
14624
gen_compute_branch1(ctx, mips32_op,
14625
(ctx->opcode >> 18) & 0x7, imm << 1);
14627
generate_exception_err(ctx, EXCP_CpU, 1);
14632
/* MIPS DSP: not implemented */
14635
MIPS_INVAL("pool32i");
14636
generate_exception_end(ctx, EXCP_RI);
14641
minor = (ctx->opcode >> 12) & 0xf;
14642
offset = sextract32(ctx->opcode, 0,
14643
(ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14646
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14647
mips32_op = OPC_LWL;
14650
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14651
mips32_op = OPC_SWL;
14654
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14655
mips32_op = OPC_LWR;
14658
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14659
mips32_op = OPC_SWR;
14661
#if defined(TARGET_MIPS64)
14663
check_insn(ctx, ISA_MIPS3);
14664
check_mips_64(ctx);
14665
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14666
mips32_op = OPC_LDL;
14669
check_insn(ctx, ISA_MIPS3);
14670
check_mips_64(ctx);
14671
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14672
mips32_op = OPC_SDL;
14675
check_insn(ctx, ISA_MIPS3);
14676
check_mips_64(ctx);
14677
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14678
mips32_op = OPC_LDR;
14681
check_insn(ctx, ISA_MIPS3);
14682
check_mips_64(ctx);
14683
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14684
mips32_op = OPC_SDR;
14687
check_insn(ctx, ISA_MIPS3);
14688
check_mips_64(ctx);
14689
mips32_op = OPC_LWU;
14692
check_insn(ctx, ISA_MIPS3);
14693
check_mips_64(ctx);
14694
mips32_op = OPC_LLD;
14698
mips32_op = OPC_LL;
14701
gen_ld(ctx, mips32_op, rt, rs, offset);
14704
gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14707
gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14709
#if defined(TARGET_MIPS64)
14711
check_insn(ctx, ISA_MIPS3);
14712
check_mips_64(ctx);
14713
gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14717
/* Treat as no-op */
14718
if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14719
/* hint codes 24-31 are reserved and signal RI */
14720
generate_exception(ctx, EXCP_RI);
14724
MIPS_INVAL("pool32c");
14725
generate_exception_end(ctx, EXCP_RI);
14729
case ADDI32: /* AUI, LUI */
14730
if (ctx->insn_flags & ISA_MIPS32R6) {
14732
gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14735
mips32_op = OPC_ADDI;
14740
mips32_op = OPC_ADDIU;
14742
gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14745
/* Logical operations */
14747
mips32_op = OPC_ORI;
14750
mips32_op = OPC_XORI;
14753
mips32_op = OPC_ANDI;
14755
gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14758
/* Set less than immediate */
14760
mips32_op = OPC_SLTI;
14763
mips32_op = OPC_SLTIU;
14765
gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14768
check_insn_opc_removed(ctx, ISA_MIPS32R6);
14769
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14770
gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14771
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14773
case JALS32: /* BOVC, BEQC, BEQZALC */
14774
if (ctx->insn_flags & ISA_MIPS32R6) {
14777
mips32_op = OPC_BOVC;
14778
} else if (rs < rt && rs == 0) {
14780
mips32_op = OPC_BEQZALC;
14783
mips32_op = OPC_BEQC;
14785
gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14788
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14789
gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14790
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14793
case BEQ32: /* BC */
14794
if (ctx->insn_flags & ISA_MIPS32R6) {
14796
gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14797
sextract32(ctx->opcode << 1, 0, 27));
14800
gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14803
case BNE32: /* BALC */
14804
if (ctx->insn_flags & ISA_MIPS32R6) {
14806
gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14807
sextract32(ctx->opcode << 1, 0, 27));
14810
gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14813
case J32: /* BGTZC, BLTZC, BLTC */
14814
if (ctx->insn_flags & ISA_MIPS32R6) {
14815
if (rs == 0 && rt != 0) {
14817
mips32_op = OPC_BGTZC;
14818
} else if (rs != 0 && rt != 0 && rs == rt) {
14820
mips32_op = OPC_BLTZC;
14823
mips32_op = OPC_BLTC;
14825
gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14828
gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14829
(int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14832
case JAL32: /* BLEZC, BGEZC, BGEC */
14833
if (ctx->insn_flags & ISA_MIPS32R6) {
14834
if (rs == 0 && rt != 0) {
14836
mips32_op = OPC_BLEZC;
14837
} else if (rs != 0 && rt != 0 && rs == rt) {
14839
mips32_op = OPC_BGEZC;
14842
mips32_op = OPC_BGEC;
14844
gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14847
gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14848
(int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14849
ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14852
/* Floating point (COP1) */
14854
mips32_op = OPC_LWC1;
14857
mips32_op = OPC_LDC1;
14860
mips32_op = OPC_SWC1;
14863
mips32_op = OPC_SDC1;
14865
gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14867
case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14868
if (ctx->insn_flags & ISA_MIPS32R6) {
14869
/* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14870
switch ((ctx->opcode >> 16) & 0x1f) {
14871
case ADDIUPC_00 ... ADDIUPC_07:
14872
gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14875
gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14878
gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14880
case LWPC_08 ... LWPC_0F:
14881
gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14884
generate_exception(ctx, EXCP_RI);
14889
int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14890
int offset = SIMM(ctx->opcode, 0, 23) << 2;
14892
gen_addiupc(ctx, reg, offset, 0, 0);
14895
case BNVC: /* BNEC, BNEZALC */
14896
check_insn(ctx, ISA_MIPS32R6);
14899
mips32_op = OPC_BNVC;
14900
} else if (rs < rt && rs == 0) {
14902
mips32_op = OPC_BNEZALC;
14905
mips32_op = OPC_BNEC;
14907
gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14909
case R6_BNEZC: /* JIALC */
14910
check_insn(ctx, ISA_MIPS32R6);
14913
gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14914
sextract32(ctx->opcode << 1, 0, 22));
14917
gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14920
case R6_BEQZC: /* JIC */
14921
check_insn(ctx, ISA_MIPS32R6);
14924
gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14925
sextract32(ctx->opcode << 1, 0, 22));
14928
gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14931
case BLEZALC: /* BGEZALC, BGEUC */
14932
check_insn(ctx, ISA_MIPS32R6);
14933
if (rs == 0 && rt != 0) {
14935
mips32_op = OPC_BLEZALC;
14936
} else if (rs != 0 && rt != 0 && rs == rt) {
14938
mips32_op = OPC_BGEZALC;
14941
mips32_op = OPC_BGEUC;
14943
gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14945
case BGTZALC: /* BLTZALC, BLTUC */
14946
check_insn(ctx, ISA_MIPS32R6);
14947
if (rs == 0 && rt != 0) {
14949
mips32_op = OPC_BGTZALC;
14950
} else if (rs != 0 && rt != 0 && rs == rt) {
14952
mips32_op = OPC_BLTZALC;
14955
mips32_op = OPC_BLTUC;
14957
gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14959
/* Loads and stores */
14961
mips32_op = OPC_LB;
14964
mips32_op = OPC_LBU;
14967
mips32_op = OPC_LH;
14970
mips32_op = OPC_LHU;
14973
mips32_op = OPC_LW;
14975
#ifdef TARGET_MIPS64
14977
check_insn(ctx, ISA_MIPS3);
14978
check_mips_64(ctx);
14979
mips32_op = OPC_LD;
14982
check_insn(ctx, ISA_MIPS3);
14983
check_mips_64(ctx);
14984
mips32_op = OPC_SD;
14988
mips32_op = OPC_SB;
14991
mips32_op = OPC_SH;
14994
mips32_op = OPC_SW;
14997
gen_ld(ctx, mips32_op, rt, rs, imm);
15000
gen_st(ctx, mips32_op, rt, rs, imm);
15003
generate_exception_end(ctx, EXCP_RI);
15008
static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
15012
/* make sure instructions are on a halfword boundary */
15013
if (ctx->pc & 0x1) {
15014
env->CP0_BadVAddr = ctx->pc;
15015
generate_exception_end(ctx, EXCP_AdEL);
15019
op = (ctx->opcode >> 10) & 0x3f;
15020
/* Enforce properly-sized instructions in a delay slot */
15021
if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15022
switch (op & 0x7) { /* MSB-3..MSB-5 */
15024
/* POOL32A, POOL32B, POOL32I, POOL32C */
15026
/* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15028
/* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15030
/* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15032
/* LB32, LH32, LWC132, LDC132, LW32 */
15033
if (ctx->hflags & MIPS_HFLAG_BDS16) {
15034
generate_exception_end(ctx, EXCP_RI);
15039
/* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15041
/* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15043
/* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15044
if (ctx->hflags & MIPS_HFLAG_BDS32) {
15045
generate_exception_end(ctx, EXCP_RI);
15055
int rd = mmreg(uMIPS_RD(ctx->opcode));
15056
int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15057
int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15060
switch (ctx->opcode & 0x1) {
15068
if (ctx->insn_flags & ISA_MIPS32R6) {
15069
/* In the Release 6 the register number location in
15070
* the instruction encoding has changed.
15072
gen_arith(ctx, opc, rs1, rd, rs2);
15074
gen_arith(ctx, opc, rd, rs1, rs2);
15080
int rd = mmreg(uMIPS_RD(ctx->opcode));
15081
int rs = mmreg(uMIPS_RS(ctx->opcode));
15082
int amount = (ctx->opcode >> 1) & 0x7;
15084
amount = amount == 0 ? 8 : amount;
15086
switch (ctx->opcode & 0x1) {
15095
gen_shift_imm(ctx, opc, rd, rs, amount);
15099
if (ctx->insn_flags & ISA_MIPS32R6) {
15100
gen_pool16c_r6_insn(ctx);
15102
gen_pool16c_insn(ctx);
15107
int rd = mmreg(uMIPS_RD(ctx->opcode));
15108
int rb = 28; /* GP */
15109
int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15111
gen_ld(ctx, OPC_LW, rd, rb, offset);
15115
check_insn_opc_removed(ctx, ISA_MIPS32R6);
15116
if (ctx->opcode & 1) {
15117
generate_exception_end(ctx, EXCP_RI);
15120
int enc_dest = uMIPS_RD(ctx->opcode);
15121
int enc_rt = uMIPS_RS2(ctx->opcode);
15122
int enc_rs = uMIPS_RS1(ctx->opcode);
15123
gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15128
int rd = mmreg(uMIPS_RD(ctx->opcode));
15129
int rb = mmreg(uMIPS_RS(ctx->opcode));
15130
int16_t offset = ZIMM(ctx->opcode, 0, 4);
15131
offset = (offset == 0xf ? -1 : offset);
15133
gen_ld(ctx, OPC_LBU, rd, rb, offset);
15138
int rd = mmreg(uMIPS_RD(ctx->opcode));
15139
int rb = mmreg(uMIPS_RS(ctx->opcode));
15140
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15142
gen_ld(ctx, OPC_LHU, rd, rb, offset);
15147
int rd = (ctx->opcode >> 5) & 0x1f;
15148
int rb = 29; /* SP */
15149
int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15151
gen_ld(ctx, OPC_LW, rd, rb, offset);
15156
int rd = mmreg(uMIPS_RD(ctx->opcode));
15157
int rb = mmreg(uMIPS_RS(ctx->opcode));
15158
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15160
gen_ld(ctx, OPC_LW, rd, rb, offset);
15165
int rd = mmreg2(uMIPS_RD(ctx->opcode));
15166
int rb = mmreg(uMIPS_RS(ctx->opcode));
15167
int16_t offset = ZIMM(ctx->opcode, 0, 4);
15169
gen_st(ctx, OPC_SB, rd, rb, offset);
15174
int rd = mmreg2(uMIPS_RD(ctx->opcode));
15175
int rb = mmreg(uMIPS_RS(ctx->opcode));
15176
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15178
gen_st(ctx, OPC_SH, rd, rb, offset);
15183
int rd = (ctx->opcode >> 5) & 0x1f;
15184
int rb = 29; /* SP */
15185
int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15187
gen_st(ctx, OPC_SW, rd, rb, offset);
15192
int rd = mmreg2(uMIPS_RD(ctx->opcode));
15193
int rb = mmreg(uMIPS_RS(ctx->opcode));
15194
int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15196
gen_st(ctx, OPC_SW, rd, rb, offset);
15201
int rd = uMIPS_RD5(ctx->opcode);
15202
int rs = uMIPS_RS5(ctx->opcode);
15204
gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15211
switch (ctx->opcode & 0x1) {
15221
switch (ctx->opcode & 0x1) {
15226
gen_addiur1sp(ctx);
15230
case B16: /* BC16 */
15231
gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15232
sextract32(ctx->opcode, 0, 10) << 1,
15233
(ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15235
case BNEZ16: /* BNEZC16 */
15236
case BEQZ16: /* BEQZC16 */
15237
gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15238
mmreg(uMIPS_RD(ctx->opcode)),
15239
0, sextract32(ctx->opcode, 0, 7) << 1,
15240
(ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15245
int reg = mmreg(uMIPS_RD(ctx->opcode));
15246
int imm = ZIMM(ctx->opcode, 0, 7);
15248
imm = (imm == 0x7f ? -1 : imm);
15249
tcg_gen_movi_tl(cpu_gpr[reg], imm);
15255
generate_exception_end(ctx, EXCP_RI);
15258
decode_micromips32_opc(env, ctx);
15265
/* SmartMIPS extension to MIPS32 */
15267
#if defined(TARGET_MIPS64)
15269
/* MDMX extension to MIPS64 */
15273
/* MIPSDSP functions. */
15274
static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15275
int rd, int base, int offset)
15280
t0 = tcg_temp_new();
15283
gen_load_gpr(t0, offset);
15284
} else if (offset == 0) {
15285
gen_load_gpr(t0, base);
15287
gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15292
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15293
gen_store_gpr(t0, rd);
15296
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15297
gen_store_gpr(t0, rd);
15300
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15301
gen_store_gpr(t0, rd);
15303
#if defined(TARGET_MIPS64)
15305
tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15306
gen_store_gpr(t0, rd);
15313
static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15314
int ret, int v1, int v2)
15320
/* Treat as NOP. */
15324
v1_t = tcg_temp_new();
15325
v2_t = tcg_temp_new();
15327
gen_load_gpr(v1_t, v1);
15328
gen_load_gpr(v2_t, v2);
15331
/* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15332
case OPC_MULT_G_2E:
15336
gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15338
case OPC_ADDUH_R_QB:
15339
gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15342
gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15344
case OPC_ADDQH_R_PH:
15345
gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15348
gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15350
case OPC_ADDQH_R_W:
15351
gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15354
gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15356
case OPC_SUBUH_R_QB:
15357
gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15360
gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15362
case OPC_SUBQH_R_PH:
15363
gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15366
gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15368
case OPC_SUBQH_R_W:
15369
gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15373
case OPC_ABSQ_S_PH_DSP:
15375
case OPC_ABSQ_S_QB:
15377
gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15379
case OPC_ABSQ_S_PH:
15381
gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15385
gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15387
case OPC_PRECEQ_W_PHL:
15389
tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15390
tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15392
case OPC_PRECEQ_W_PHR:
15394
tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15395
tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15396
tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15398
case OPC_PRECEQU_PH_QBL:
15400
gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15402
case OPC_PRECEQU_PH_QBR:
15404
gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15406
case OPC_PRECEQU_PH_QBLA:
15408
gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15410
case OPC_PRECEQU_PH_QBRA:
15412
gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15414
case OPC_PRECEU_PH_QBL:
15416
gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15418
case OPC_PRECEU_PH_QBR:
15420
gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15422
case OPC_PRECEU_PH_QBLA:
15424
gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15426
case OPC_PRECEU_PH_QBRA:
15428
gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15432
case OPC_ADDU_QB_DSP:
15436
gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15438
case OPC_ADDQ_S_PH:
15440
gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15444
gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15448
gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15450
case OPC_ADDU_S_QB:
15452
gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15456
gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15458
case OPC_ADDU_S_PH:
15460
gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15464
gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15466
case OPC_SUBQ_S_PH:
15468
gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15472
gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15476
gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15478
case OPC_SUBU_S_QB:
15480
gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15484
gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15486
case OPC_SUBU_S_PH:
15488
gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15492
gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15496
gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15500
gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15502
case OPC_RADDU_W_QB:
15504
gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15508
case OPC_CMPU_EQ_QB_DSP:
15510
case OPC_PRECR_QB_PH:
15512
gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15514
case OPC_PRECRQ_QB_PH:
15516
gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15518
case OPC_PRECR_SRA_PH_W:
15521
TCGv_i32 sa_t = tcg_const_i32(v2);
15522
gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15524
tcg_temp_free_i32(sa_t);
15527
case OPC_PRECR_SRA_R_PH_W:
15530
TCGv_i32 sa_t = tcg_const_i32(v2);
15531
gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15533
tcg_temp_free_i32(sa_t);
15536
case OPC_PRECRQ_PH_W:
15538
gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15540
case OPC_PRECRQ_RS_PH_W:
15542
gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15544
case OPC_PRECRQU_S_QB_PH:
15546
gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15550
#ifdef TARGET_MIPS64
15551
case OPC_ABSQ_S_QH_DSP:
15553
case OPC_PRECEQ_L_PWL:
15555
tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15557
case OPC_PRECEQ_L_PWR:
15559
tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15561
case OPC_PRECEQ_PW_QHL:
15563
gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15565
case OPC_PRECEQ_PW_QHR:
15567
gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15569
case OPC_PRECEQ_PW_QHLA:
15571
gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15573
case OPC_PRECEQ_PW_QHRA:
15575
gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15577
case OPC_PRECEQU_QH_OBL:
15579
gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15581
case OPC_PRECEQU_QH_OBR:
15583
gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15585
case OPC_PRECEQU_QH_OBLA:
15587
gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15589
case OPC_PRECEQU_QH_OBRA:
15591
gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15593
case OPC_PRECEU_QH_OBL:
15595
gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15597
case OPC_PRECEU_QH_OBR:
15599
gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15601
case OPC_PRECEU_QH_OBLA:
15603
gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15605
case OPC_PRECEU_QH_OBRA:
15607
gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15609
case OPC_ABSQ_S_OB:
15611
gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15613
case OPC_ABSQ_S_PW:
15615
gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15617
case OPC_ABSQ_S_QH:
15619
gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15623
case OPC_ADDU_OB_DSP:
15625
case OPC_RADDU_L_OB:
15627
gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15631
gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15633
case OPC_SUBQ_S_PW:
15635
gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15639
gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15641
case OPC_SUBQ_S_QH:
15643
gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15647
gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15649
case OPC_SUBU_S_OB:
15651
gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15655
gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15657
case OPC_SUBU_S_QH:
15659
gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15663
gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15665
case OPC_SUBUH_R_OB:
15667
gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15671
gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15673
case OPC_ADDQ_S_PW:
15675
gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15679
gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15681
case OPC_ADDQ_S_QH:
15683
gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15687
gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15689
case OPC_ADDU_S_OB:
15691
gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15695
gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15697
case OPC_ADDU_S_QH:
15699
gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15703
gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15705
case OPC_ADDUH_R_OB:
15707
gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15711
case OPC_CMPU_EQ_OB_DSP:
15713
case OPC_PRECR_OB_QH:
15715
gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15717
case OPC_PRECR_SRA_QH_PW:
15720
TCGv_i32 ret_t = tcg_const_i32(ret);
15721
gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15722
tcg_temp_free_i32(ret_t);
15725
case OPC_PRECR_SRA_R_QH_PW:
15728
TCGv_i32 sa_v = tcg_const_i32(ret);
15729
gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15730
tcg_temp_free_i32(sa_v);
15733
case OPC_PRECRQ_OB_QH:
15735
gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15737
case OPC_PRECRQ_PW_L:
15739
gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15741
case OPC_PRECRQ_QH_PW:
15743
gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15745
case OPC_PRECRQ_RS_QH_PW:
15747
gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15749
case OPC_PRECRQU_S_OB_QH:
15751
gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15758
tcg_temp_free(v1_t);
15759
tcg_temp_free(v2_t);
15762
static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15763
int ret, int v1, int v2)
15771
/* Treat as NOP. */
15775
t0 = tcg_temp_new();
15776
v1_t = tcg_temp_new();
15777
v2_t = tcg_temp_new();
15779
tcg_gen_movi_tl(t0, v1);
15780
gen_load_gpr(v1_t, v1);
15781
gen_load_gpr(v2_t, v2);
15784
case OPC_SHLL_QB_DSP:
15786
op2 = MASK_SHLL_QB(ctx->opcode);
15790
gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15794
gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15798
gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15802
gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15804
case OPC_SHLL_S_PH:
15806
gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15808
case OPC_SHLLV_S_PH:
15810
gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15814
gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15816
case OPC_SHLLV_S_W:
15818
gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15822
gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15826
gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15830
gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15834
gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15838
gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15840
case OPC_SHRA_R_QB:
15842
gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15846
gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15848
case OPC_SHRAV_R_QB:
15850
gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15854
gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15856
case OPC_SHRA_R_PH:
15858
gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15862
gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15864
case OPC_SHRAV_R_PH:
15866
gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15870
gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15872
case OPC_SHRAV_R_W:
15874
gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15876
default: /* Invalid */
15877
MIPS_INVAL("MASK SHLL.QB");
15878
generate_exception_end(ctx, EXCP_RI);
15883
#ifdef TARGET_MIPS64
15884
case OPC_SHLL_OB_DSP:
15885
op2 = MASK_SHLL_OB(ctx->opcode);
15889
gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15893
gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15895
case OPC_SHLL_S_PW:
15897
gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15899
case OPC_SHLLV_S_PW:
15901
gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15905
gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15909
gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15913
gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15917
gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15919
case OPC_SHLL_S_QH:
15921
gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15923
case OPC_SHLLV_S_QH:
15925
gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15929
gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15933
gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15935
case OPC_SHRA_R_OB:
15937
gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15939
case OPC_SHRAV_R_OB:
15941
gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15945
gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15949
gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15951
case OPC_SHRA_R_PW:
15953
gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15955
case OPC_SHRAV_R_PW:
15957
gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15961
gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15965
gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15967
case OPC_SHRA_R_QH:
15969
gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15971
case OPC_SHRAV_R_QH:
15973
gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15977
gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15981
gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15985
gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15989
gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15991
default: /* Invalid */
15992
MIPS_INVAL("MASK SHLL.OB");
15993
generate_exception_end(ctx, EXCP_RI);
16001
tcg_temp_free(v1_t);
16002
tcg_temp_free(v2_t);
16005
static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16006
int ret, int v1, int v2, int check_ret)
16012
if ((ret == 0) && (check_ret == 1)) {
16013
/* Treat as NOP. */
16017
t0 = tcg_temp_new_i32();
16018
v1_t = tcg_temp_new();
16019
v2_t = tcg_temp_new();
16021
tcg_gen_movi_i32(t0, ret);
16022
gen_load_gpr(v1_t, v1);
16023
gen_load_gpr(v2_t, v2);
16026
/* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16027
* the same mask and op1. */
16028
case OPC_MULT_G_2E:
16032
gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16035
gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16038
gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16040
case OPC_MULQ_RS_W:
16041
gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16045
case OPC_DPA_W_PH_DSP:
16047
case OPC_DPAU_H_QBL:
16049
gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16051
case OPC_DPAU_H_QBR:
16053
gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16055
case OPC_DPSU_H_QBL:
16057
gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16059
case OPC_DPSU_H_QBR:
16061
gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16065
gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16067
case OPC_DPAX_W_PH:
16069
gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16071
case OPC_DPAQ_S_W_PH:
16073
gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16075
case OPC_DPAQX_S_W_PH:
16077
gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16079
case OPC_DPAQX_SA_W_PH:
16081
gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16085
gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16087
case OPC_DPSX_W_PH:
16089
gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16091
case OPC_DPSQ_S_W_PH:
16093
gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16095
case OPC_DPSQX_S_W_PH:
16097
gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16099
case OPC_DPSQX_SA_W_PH:
16101
gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16103
case OPC_MULSAQ_S_W_PH:
16105
gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16107
case OPC_DPAQ_SA_L_W:
16109
gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16111
case OPC_DPSQ_SA_L_W:
16113
gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16115
case OPC_MAQ_S_W_PHL:
16117
gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16119
case OPC_MAQ_S_W_PHR:
16121
gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16123
case OPC_MAQ_SA_W_PHL:
16125
gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16127
case OPC_MAQ_SA_W_PHR:
16129
gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16131
case OPC_MULSA_W_PH:
16133
gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16137
#ifdef TARGET_MIPS64
16138
case OPC_DPAQ_W_QH_DSP:
16140
int ac = ret & 0x03;
16141
tcg_gen_movi_i32(t0, ac);
16146
gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16150
gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16154
gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16158
gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16162
gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16164
case OPC_DPAQ_S_W_QH:
16166
gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16168
case OPC_DPAQ_SA_L_PW:
16170
gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16172
case OPC_DPAU_H_OBL:
16174
gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16176
case OPC_DPAU_H_OBR:
16178
gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16182
gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16184
case OPC_DPSQ_S_W_QH:
16186
gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16188
case OPC_DPSQ_SA_L_PW:
16190
gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16192
case OPC_DPSU_H_OBL:
16194
gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16196
case OPC_DPSU_H_OBR:
16198
gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16200
case OPC_MAQ_S_L_PWL:
16202
gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16204
case OPC_MAQ_S_L_PWR:
16206
gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16208
case OPC_MAQ_S_W_QHLL:
16210
gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16212
case OPC_MAQ_SA_W_QHLL:
16214
gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16216
case OPC_MAQ_S_W_QHLR:
16218
gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16220
case OPC_MAQ_SA_W_QHLR:
16222
gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16224
case OPC_MAQ_S_W_QHRL:
16226
gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16228
case OPC_MAQ_SA_W_QHRL:
16230
gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16232
case OPC_MAQ_S_W_QHRR:
16234
gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16236
case OPC_MAQ_SA_W_QHRR:
16238
gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16240
case OPC_MULSAQ_S_L_PW:
16242
gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16244
case OPC_MULSAQ_S_W_QH:
16246
gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16252
case OPC_ADDU_QB_DSP:
16254
case OPC_MULEU_S_PH_QBL:
16256
gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16258
case OPC_MULEU_S_PH_QBR:
16260
gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16262
case OPC_MULQ_RS_PH:
16264
gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16266
case OPC_MULEQ_S_W_PHL:
16268
gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16270
case OPC_MULEQ_S_W_PHR:
16272
gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16274
case OPC_MULQ_S_PH:
16276
gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16280
#ifdef TARGET_MIPS64
16281
case OPC_ADDU_OB_DSP:
16283
case OPC_MULEQ_S_PW_QHL:
16285
gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16287
case OPC_MULEQ_S_PW_QHR:
16289
gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16291
case OPC_MULEU_S_QH_OBL:
16293
gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16295
case OPC_MULEU_S_QH_OBR:
16297
gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16299
case OPC_MULQ_RS_QH:
16301
gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16308
tcg_temp_free_i32(t0);
16309
tcg_temp_free(v1_t);
16310
tcg_temp_free(v2_t);
16313
static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16321
/* Treat as NOP. */
16325
t0 = tcg_temp_new();
16326
val_t = tcg_temp_new();
16327
gen_load_gpr(val_t, val);
16330
case OPC_ABSQ_S_PH_DSP:
16334
gen_helper_bitrev(cpu_gpr[ret], val_t);
16339
target_long result;
16340
imm = (ctx->opcode >> 16) & 0xFF;
16341
result = (uint32_t)imm << 24 |
16342
(uint32_t)imm << 16 |
16343
(uint32_t)imm << 8 |
16345
result = (int32_t)result;
16346
tcg_gen_movi_tl(cpu_gpr[ret], result);
16351
tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16352
tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16353
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16354
tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16355
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16356
tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16361
imm = (ctx->opcode >> 16) & 0x03FF;
16362
imm = (int16_t)(imm << 6) >> 6;
16363
tcg_gen_movi_tl(cpu_gpr[ret], \
16364
(target_long)((int32_t)imm << 16 | \
16370
tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16371
tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16372
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16373
tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16377
#ifdef TARGET_MIPS64
16378
case OPC_ABSQ_S_QH_DSP:
16385
imm = (ctx->opcode >> 16) & 0xFF;
16386
temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16387
temp = (temp << 16) | temp;
16388
temp = (temp << 32) | temp;
16389
tcg_gen_movi_tl(cpu_gpr[ret], temp);
16397
imm = (ctx->opcode >> 16) & 0x03FF;
16398
imm = (int16_t)(imm << 6) >> 6;
16399
temp = ((target_long)imm << 32) \
16400
| ((target_long)imm & 0xFFFFFFFF);
16401
tcg_gen_movi_tl(cpu_gpr[ret], temp);
16409
imm = (ctx->opcode >> 16) & 0x03FF;
16410
imm = (int16_t)(imm << 6) >> 6;
16412
temp = ((uint64_t)(uint16_t)imm << 48) |
16413
((uint64_t)(uint16_t)imm << 32) |
16414
((uint64_t)(uint16_t)imm << 16) |
16415
(uint64_t)(uint16_t)imm;
16416
tcg_gen_movi_tl(cpu_gpr[ret], temp);
16421
tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16422
tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16423
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16424
tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16425
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16426
tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16427
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16431
tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16432
tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16433
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16437
tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16438
tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16439
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16440
tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16441
tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16448
tcg_temp_free(val_t);
16451
static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16452
uint32_t op1, uint32_t op2,
16453
int ret, int v1, int v2, int check_ret)
16459
if ((ret == 0) && (check_ret == 1)) {
16460
/* Treat as NOP. */
16464
t1 = tcg_temp_new();
16465
v1_t = tcg_temp_new();
16466
v2_t = tcg_temp_new();
16468
gen_load_gpr(v1_t, v1);
16469
gen_load_gpr(v2_t, v2);
16472
case OPC_CMPU_EQ_QB_DSP:
16474
case OPC_CMPU_EQ_QB:
16476
gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16478
case OPC_CMPU_LT_QB:
16480
gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16482
case OPC_CMPU_LE_QB:
16484
gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16486
case OPC_CMPGU_EQ_QB:
16488
gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16490
case OPC_CMPGU_LT_QB:
16492
gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16494
case OPC_CMPGU_LE_QB:
16496
gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16498
case OPC_CMPGDU_EQ_QB:
16500
gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16501
tcg_gen_mov_tl(cpu_gpr[ret], t1);
16502
tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16503
tcg_gen_shli_tl(t1, t1, 24);
16504
tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16506
case OPC_CMPGDU_LT_QB:
16508
gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16509
tcg_gen_mov_tl(cpu_gpr[ret], t1);
16510
tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16511
tcg_gen_shli_tl(t1, t1, 24);
16512
tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16514
case OPC_CMPGDU_LE_QB:
16516
gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16517
tcg_gen_mov_tl(cpu_gpr[ret], t1);
16518
tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16519
tcg_gen_shli_tl(t1, t1, 24);
16520
tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16522
case OPC_CMP_EQ_PH:
16524
gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16526
case OPC_CMP_LT_PH:
16528
gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16530
case OPC_CMP_LE_PH:
16532
gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16536
gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16540
gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16542
case OPC_PACKRL_PH:
16544
gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16548
#ifdef TARGET_MIPS64
16549
case OPC_CMPU_EQ_OB_DSP:
16551
case OPC_CMP_EQ_PW:
16553
gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16555
case OPC_CMP_LT_PW:
16557
gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16559
case OPC_CMP_LE_PW:
16561
gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16563
case OPC_CMP_EQ_QH:
16565
gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16567
case OPC_CMP_LT_QH:
16569
gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16571
case OPC_CMP_LE_QH:
16573
gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16575
case OPC_CMPGDU_EQ_OB:
16577
gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16579
case OPC_CMPGDU_LT_OB:
16581
gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16583
case OPC_CMPGDU_LE_OB:
16585
gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16587
case OPC_CMPGU_EQ_OB:
16589
gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16591
case OPC_CMPGU_LT_OB:
16593
gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16595
case OPC_CMPGU_LE_OB:
16597
gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16599
case OPC_CMPU_EQ_OB:
16601
gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16603
case OPC_CMPU_LT_OB:
16605
gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16607
case OPC_CMPU_LE_OB:
16609
gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16611
case OPC_PACKRL_PW:
16613
gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16617
gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16621
gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16625
gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16633
tcg_temp_free(v1_t);
16634
tcg_temp_free(v2_t);
16637
static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16638
uint32_t op1, int rt, int rs, int sa)
16645
/* Treat as NOP. */
16649
t0 = tcg_temp_new();
16650
gen_load_gpr(t0, rs);
16653
case OPC_APPEND_DSP:
16654
switch (MASK_APPEND(ctx->opcode)) {
16657
tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16659
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16663
tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16664
tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16665
tcg_gen_shli_tl(t0, t0, 32 - sa);
16666
tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16668
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16672
if (sa != 0 && sa != 2) {
16673
tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16674
tcg_gen_ext32u_tl(t0, t0);
16675
tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16676
tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16678
tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16680
default: /* Invalid */
16681
MIPS_INVAL("MASK APPEND");
16682
generate_exception_end(ctx, EXCP_RI);
16686
#ifdef TARGET_MIPS64
16687
case OPC_DAPPEND_DSP:
16688
switch (MASK_DAPPEND(ctx->opcode)) {
16691
tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16695
tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16696
tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16697
tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16701
tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16702
tcg_gen_shli_tl(t0, t0, 64 - sa);
16703
tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16708
if (sa != 0 && sa != 2 && sa != 4) {
16709
tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16710
tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16711
tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16714
default: /* Invalid */
16715
MIPS_INVAL("MASK DAPPEND");
16716
generate_exception_end(ctx, EXCP_RI);
16725
static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16726
int ret, int v1, int v2, int check_ret)
16735
if ((ret == 0) && (check_ret == 1)) {
16736
/* Treat as NOP. */
16740
t0 = tcg_temp_new();
16741
t1 = tcg_temp_new();
16742
v1_t = tcg_temp_new();
16743
v2_t = tcg_temp_new();
16745
gen_load_gpr(v1_t, v1);
16746
gen_load_gpr(v2_t, v2);
16749
case OPC_EXTR_W_DSP:
16753
tcg_gen_movi_tl(t0, v2);
16754
tcg_gen_movi_tl(t1, v1);
16755
gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16758
tcg_gen_movi_tl(t0, v2);
16759
tcg_gen_movi_tl(t1, v1);
16760
gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16762
case OPC_EXTR_RS_W:
16763
tcg_gen_movi_tl(t0, v2);
16764
tcg_gen_movi_tl(t1, v1);
16765
gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16768
tcg_gen_movi_tl(t0, v2);
16769
tcg_gen_movi_tl(t1, v1);
16770
gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16772
case OPC_EXTRV_S_H:
16773
tcg_gen_movi_tl(t0, v2);
16774
gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16777
tcg_gen_movi_tl(t0, v2);
16778
gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16780
case OPC_EXTRV_R_W:
16781
tcg_gen_movi_tl(t0, v2);
16782
gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16784
case OPC_EXTRV_RS_W:
16785
tcg_gen_movi_tl(t0, v2);
16786
gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16789
tcg_gen_movi_tl(t0, v2);
16790
tcg_gen_movi_tl(t1, v1);
16791
gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16794
tcg_gen_movi_tl(t0, v2);
16795
gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16798
tcg_gen_movi_tl(t0, v2);
16799
tcg_gen_movi_tl(t1, v1);
16800
gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16803
tcg_gen_movi_tl(t0, v2);
16804
gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16807
imm = (ctx->opcode >> 20) & 0x3F;
16808
tcg_gen_movi_tl(t0, ret);
16809
tcg_gen_movi_tl(t1, imm);
16810
gen_helper_shilo(t0, t1, cpu_env);
16813
tcg_gen_movi_tl(t0, ret);
16814
gen_helper_shilo(t0, v1_t, cpu_env);
16817
tcg_gen_movi_tl(t0, ret);
16818
gen_helper_mthlip(t0, v1_t, cpu_env);
16821
imm = (ctx->opcode >> 11) & 0x3FF;
16822
tcg_gen_movi_tl(t0, imm);
16823
gen_helper_wrdsp(v1_t, t0, cpu_env);
16826
imm = (ctx->opcode >> 16) & 0x03FF;
16827
tcg_gen_movi_tl(t0, imm);
16828
gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16832
#ifdef TARGET_MIPS64
16833
case OPC_DEXTR_W_DSP:
16837
tcg_gen_movi_tl(t0, ret);
16838
gen_helper_dmthlip(v1_t, t0, cpu_env);
16842
int shift = (ctx->opcode >> 19) & 0x7F;
16843
int ac = (ctx->opcode >> 11) & 0x03;
16844
tcg_gen_movi_tl(t0, shift);
16845
tcg_gen_movi_tl(t1, ac);
16846
gen_helper_dshilo(t0, t1, cpu_env);
16851
int ac = (ctx->opcode >> 11) & 0x03;
16852
tcg_gen_movi_tl(t0, ac);
16853
gen_helper_dshilo(v1_t, t0, cpu_env);
16857
tcg_gen_movi_tl(t0, v2);
16858
tcg_gen_movi_tl(t1, v1);
16860
gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16863
tcg_gen_movi_tl(t0, v2);
16864
gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16867
tcg_gen_movi_tl(t0, v2);
16868
tcg_gen_movi_tl(t1, v1);
16869
gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16872
tcg_gen_movi_tl(t0, v2);
16873
gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16876
tcg_gen_movi_tl(t0, v2);
16877
tcg_gen_movi_tl(t1, v1);
16878
gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16880
case OPC_DEXTR_R_L:
16881
tcg_gen_movi_tl(t0, v2);
16882
tcg_gen_movi_tl(t1, v1);
16883
gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16885
case OPC_DEXTR_RS_L:
16886
tcg_gen_movi_tl(t0, v2);
16887
tcg_gen_movi_tl(t1, v1);
16888
gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16891
tcg_gen_movi_tl(t0, v2);
16892
tcg_gen_movi_tl(t1, v1);
16893
gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16895
case OPC_DEXTR_R_W:
16896
tcg_gen_movi_tl(t0, v2);
16897
tcg_gen_movi_tl(t1, v1);
16898
gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16900
case OPC_DEXTR_RS_W:
16901
tcg_gen_movi_tl(t0, v2);
16902
tcg_gen_movi_tl(t1, v1);
16903
gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16905
case OPC_DEXTR_S_H:
16906
tcg_gen_movi_tl(t0, v2);
16907
tcg_gen_movi_tl(t1, v1);
16908
gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16910
case OPC_DEXTRV_S_H:
16911
tcg_gen_movi_tl(t0, v2);
16912
tcg_gen_movi_tl(t1, v1);
16913
gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16916
tcg_gen_movi_tl(t0, v2);
16917
gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16919
case OPC_DEXTRV_R_L:
16920
tcg_gen_movi_tl(t0, v2);
16921
gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16923
case OPC_DEXTRV_RS_L:
16924
tcg_gen_movi_tl(t0, v2);
16925
gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16928
tcg_gen_movi_tl(t0, v2);
16929
gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16931
case OPC_DEXTRV_R_W:
16932
tcg_gen_movi_tl(t0, v2);
16933
gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16935
case OPC_DEXTRV_RS_W:
16936
tcg_gen_movi_tl(t0, v2);
16937
gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16946
tcg_temp_free(v1_t);
16947
tcg_temp_free(v2_t);
16950
/* End MIPSDSP functions. */
16952
static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16954
int rs, rt, rd, sa;
16957
rs = (ctx->opcode >> 21) & 0x1f;
16958
rt = (ctx->opcode >> 16) & 0x1f;
16959
rd = (ctx->opcode >> 11) & 0x1f;
16960
sa = (ctx->opcode >> 6) & 0x1f;
16962
op1 = MASK_SPECIAL(ctx->opcode);
16965
gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16967
case OPC_MULT ... OPC_DIVU:
16968
op2 = MASK_R6_MULDIV(ctx->opcode);
16978
gen_r6_muldiv(ctx, op2, rd, rs, rt);
16981
MIPS_INVAL("special_r6 muldiv");
16982
generate_exception_end(ctx, EXCP_RI);
16988
gen_cond_move(ctx, op1, rd, rs, rt);
16992
if (rt == 0 && sa == 1) {
16993
/* Major opcode and function field is shared with preR6 MFHI/MTHI.
16994
We need additionally to check other fields */
16995
gen_cl(ctx, op1, rd, rs);
16997
generate_exception_end(ctx, EXCP_RI);
17001
if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17002
gen_helper_do_semihosting(cpu_env);
17004
if (ctx->hflags & MIPS_HFLAG_SBRI) {
17005
generate_exception_end(ctx, EXCP_RI);
17007
generate_exception_end(ctx, EXCP_DBp);
17011
#if defined(TARGET_MIPS64)
17013
check_mips_64(ctx);
17014
gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17018
if (rt == 0 && sa == 1) {
17019
/* Major opcode and function field is shared with preR6 MFHI/MTHI.
17020
We need additionally to check other fields */
17021
check_mips_64(ctx);
17022
gen_cl(ctx, op1, rd, rs);
17024
generate_exception_end(ctx, EXCP_RI);
17027
case OPC_DMULT ... OPC_DDIVU:
17028
op2 = MASK_R6_MULDIV(ctx->opcode);
17038
check_mips_64(ctx);
17039
gen_r6_muldiv(ctx, op2, rd, rs, rt);
17042
MIPS_INVAL("special_r6 muldiv");
17043
generate_exception_end(ctx, EXCP_RI);
17048
default: /* Invalid */
17049
MIPS_INVAL("special_r6");
17050
generate_exception_end(ctx, EXCP_RI);
17055
static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17057
int rs, rt, rd, sa;
17060
rs = (ctx->opcode >> 21) & 0x1f;
17061
rt = (ctx->opcode >> 16) & 0x1f;
17062
rd = (ctx->opcode >> 11) & 0x1f;
17063
sa = (ctx->opcode >> 6) & 0x1f;
17065
op1 = MASK_SPECIAL(ctx->opcode);
17067
case OPC_MOVN: /* Conditional move */
17069
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17070
INSN_LOONGSON2E | INSN_LOONGSON2F);
17071
gen_cond_move(ctx, op1, rd, rs, rt);
17073
case OPC_MFHI: /* Move from HI/LO */
17075
gen_HILO(ctx, op1, rs & 3, rd);
17078
case OPC_MTLO: /* Move to HI/LO */
17079
gen_HILO(ctx, op1, rd & 3, rs);
17082
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17083
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17084
check_cp1_enabled(ctx);
17085
gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17086
(ctx->opcode >> 16) & 1);
17088
generate_exception_err(ctx, EXCP_CpU, 1);
17094
check_insn(ctx, INSN_VR54XX);
17095
op1 = MASK_MUL_VR54XX(ctx->opcode);
17096
gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17098
gen_muldiv(ctx, op1, rd & 3, rs, rt);
17103
gen_muldiv(ctx, op1, 0, rs, rt);
17105
#if defined(TARGET_MIPS64)
17106
case OPC_DMULT ... OPC_DDIVU:
17107
check_insn(ctx, ISA_MIPS3);
17108
check_mips_64(ctx);
17109
gen_muldiv(ctx, op1, 0, rs, rt);
17113
gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17116
#ifdef MIPS_STRICT_STANDARD
17117
MIPS_INVAL("SPIM");
17118
generate_exception_end(ctx, EXCP_RI);
17120
/* Implemented as RI exception for now. */
17121
MIPS_INVAL("spim (unofficial)");
17122
generate_exception_end(ctx, EXCP_RI);
17125
default: /* Invalid */
17126
MIPS_INVAL("special_legacy");
17127
generate_exception_end(ctx, EXCP_RI);
17132
static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17134
int rs, rt, rd, sa;
17137
rs = (ctx->opcode >> 21) & 0x1f;
17138
rt = (ctx->opcode >> 16) & 0x1f;
17139
rd = (ctx->opcode >> 11) & 0x1f;
17140
sa = (ctx->opcode >> 6) & 0x1f;
17142
op1 = MASK_SPECIAL(ctx->opcode);
17144
case OPC_SLL: /* Shift with immediate */
17145
if (sa == 5 && rd == 0 &&
17146
rs == 0 && rt == 0) { /* PAUSE */
17147
if ((ctx->insn_flags & ISA_MIPS32R6) &&
17148
(ctx->hflags & MIPS_HFLAG_BMASK)) {
17149
generate_exception_end(ctx, EXCP_RI);
17155
gen_shift_imm(ctx, op1, rd, rt, sa);
17158
switch ((ctx->opcode >> 21) & 0x1f) {
17160
/* rotr is decoded as srl on non-R2 CPUs */
17161
if (ctx->insn_flags & ISA_MIPS32R2) {
17166
gen_shift_imm(ctx, op1, rd, rt, sa);
17169
generate_exception_end(ctx, EXCP_RI);
17173
case OPC_ADD ... OPC_SUBU:
17174
gen_arith(ctx, op1, rd, rs, rt);
17176
case OPC_SLLV: /* Shifts */
17178
gen_shift(ctx, op1, rd, rs, rt);
17181
switch ((ctx->opcode >> 6) & 0x1f) {
17183
/* rotrv is decoded as srlv on non-R2 CPUs */
17184
if (ctx->insn_flags & ISA_MIPS32R2) {
17189
gen_shift(ctx, op1, rd, rs, rt);
17192
generate_exception_end(ctx, EXCP_RI);
17196
case OPC_SLT: /* Set on less than */
17198
gen_slt(ctx, op1, rd, rs, rt);
17200
case OPC_AND: /* Logic*/
17204
gen_logic(ctx, op1, rd, rs, rt);
17207
gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17209
case OPC_TGE ... OPC_TEQ: /* Traps */
17211
check_insn(ctx, ISA_MIPS2);
17212
gen_trap(ctx, op1, rs, rt, -1);
17214
case OPC_LSA: /* OPC_PMON */
17215
if ((ctx->insn_flags & ISA_MIPS32R6) ||
17216
(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17217
decode_opc_special_r6(env, ctx);
17219
/* Pmon entry point, also R4010 selsl */
17220
#ifdef MIPS_STRICT_STANDARD
17221
MIPS_INVAL("PMON / selsl");
17222
generate_exception_end(ctx, EXCP_RI);
17224
gen_helper_0e0i(pmon, sa);
17229
generate_exception_end(ctx, EXCP_SYSCALL);
17232
generate_exception_end(ctx, EXCP_BREAK);
17235
check_insn(ctx, ISA_MIPS2);
17236
gen_sync(extract32(ctx->opcode, 6, 5));
17239
#if defined(TARGET_MIPS64)
17240
/* MIPS64 specific opcodes */
17245
check_insn(ctx, ISA_MIPS3);
17246
check_mips_64(ctx);
17247
gen_shift_imm(ctx, op1, rd, rt, sa);
17250
switch ((ctx->opcode >> 21) & 0x1f) {
17252
/* drotr is decoded as dsrl on non-R2 CPUs */
17253
if (ctx->insn_flags & ISA_MIPS32R2) {
17258
check_insn(ctx, ISA_MIPS3);
17259
check_mips_64(ctx);
17260
gen_shift_imm(ctx, op1, rd, rt, sa);
17263
generate_exception_end(ctx, EXCP_RI);
17268
switch ((ctx->opcode >> 21) & 0x1f) {
17270
/* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17271
if (ctx->insn_flags & ISA_MIPS32R2) {
17276
check_insn(ctx, ISA_MIPS3);
17277
check_mips_64(ctx);
17278
gen_shift_imm(ctx, op1, rd, rt, sa);
17281
generate_exception_end(ctx, EXCP_RI);
17285
case OPC_DADD ... OPC_DSUBU:
17286
check_insn(ctx, ISA_MIPS3);
17287
check_mips_64(ctx);
17288
gen_arith(ctx, op1, rd, rs, rt);
17292
check_insn(ctx, ISA_MIPS3);
17293
check_mips_64(ctx);
17294
gen_shift(ctx, op1, rd, rs, rt);
17297
switch ((ctx->opcode >> 6) & 0x1f) {
17299
/* drotrv is decoded as dsrlv on non-R2 CPUs */
17300
if (ctx->insn_flags & ISA_MIPS32R2) {
17305
check_insn(ctx, ISA_MIPS3);
17306
check_mips_64(ctx);
17307
gen_shift(ctx, op1, rd, rs, rt);
17310
generate_exception_end(ctx, EXCP_RI);
17315
if ((ctx->insn_flags & ISA_MIPS32R6) ||
17316
(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17317
decode_opc_special_r6(env, ctx);
17322
if (ctx->insn_flags & ISA_MIPS32R6) {
17323
decode_opc_special_r6(env, ctx);
17325
decode_opc_special_legacy(env, ctx);
17330
static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17335
check_insn_opc_removed(ctx, ISA_MIPS32R6);
17337
rs = (ctx->opcode >> 21) & 0x1f;
17338
rt = (ctx->opcode >> 16) & 0x1f;
17339
rd = (ctx->opcode >> 11) & 0x1f;
17341
op1 = MASK_SPECIAL2(ctx->opcode);
17343
case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17344
case OPC_MSUB ... OPC_MSUBU:
17345
check_insn(ctx, ISA_MIPS32);
17346
gen_muldiv(ctx, op1, rd & 3, rs, rt);
17349
gen_arith(ctx, op1, rd, rs, rt);
17352
case OPC_DIVU_G_2F:
17353
case OPC_MULT_G_2F:
17354
case OPC_MULTU_G_2F:
17356
case OPC_MODU_G_2F:
17357
check_insn(ctx, INSN_LOONGSON2F);
17358
gen_loongson_integer(ctx, op1, rd, rs, rt);
17362
check_insn(ctx, ISA_MIPS32);
17363
gen_cl(ctx, op1, rd, rs);
17366
if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17367
gen_helper_do_semihosting(cpu_env);
17369
/* XXX: not clear which exception should be raised
17370
* when in debug mode...
17372
check_insn(ctx, ISA_MIPS32);
17373
generate_exception_end(ctx, EXCP_DBp);
17376
#if defined(TARGET_MIPS64)
17379
check_insn(ctx, ISA_MIPS64);
17380
check_mips_64(ctx);
17381
gen_cl(ctx, op1, rd, rs);
17383
case OPC_DMULT_G_2F:
17384
case OPC_DMULTU_G_2F:
17385
case OPC_DDIV_G_2F:
17386
case OPC_DDIVU_G_2F:
17387
case OPC_DMOD_G_2F:
17388
case OPC_DMODU_G_2F:
17389
check_insn(ctx, INSN_LOONGSON2F);
17390
gen_loongson_integer(ctx, op1, rd, rs, rt);
17393
default: /* Invalid */
17394
MIPS_INVAL("special2_legacy");
17395
generate_exception_end(ctx, EXCP_RI);
17400
static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17402
int rs, rt, rd, sa;
17406
rs = (ctx->opcode >> 21) & 0x1f;
17407
rt = (ctx->opcode >> 16) & 0x1f;
17408
rd = (ctx->opcode >> 11) & 0x1f;
17409
sa = (ctx->opcode >> 6) & 0x1f;
17410
imm = (int16_t)ctx->opcode >> 7;
17412
op1 = MASK_SPECIAL3(ctx->opcode);
17416
/* hint codes 24-31 are reserved and signal RI */
17417
generate_exception_end(ctx, EXCP_RI);
17419
/* Treat as NOP. */
17422
check_cp0_enabled(ctx);
17423
if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17424
gen_cache_operation(ctx, rt, rs, imm);
17428
gen_st_cond(ctx, op1, rt, rs, imm);
17431
gen_ld(ctx, op1, rt, rs, imm);
17436
/* Treat as NOP. */
17439
op2 = MASK_BSHFL(ctx->opcode);
17441
case OPC_ALIGN ... OPC_ALIGN_END:
17442
gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17445
gen_bitswap(ctx, op2, rd, rt);
17450
#if defined(TARGET_MIPS64)
17452
gen_st_cond(ctx, op1, rt, rs, imm);
17455
gen_ld(ctx, op1, rt, rs, imm);
17458
check_mips_64(ctx);
17461
/* Treat as NOP. */
17464
op2 = MASK_DBSHFL(ctx->opcode);
17466
case OPC_DALIGN ... OPC_DALIGN_END:
17467
gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17470
gen_bitswap(ctx, op2, rd, rt);
17477
default: /* Invalid */
17478
MIPS_INVAL("special3_r6");
17479
generate_exception_end(ctx, EXCP_RI);
17484
static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17489
rs = (ctx->opcode >> 21) & 0x1f;
17490
rt = (ctx->opcode >> 16) & 0x1f;
17491
rd = (ctx->opcode >> 11) & 0x1f;
17493
op1 = MASK_SPECIAL3(ctx->opcode);
17495
case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17496
case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17497
case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17498
/* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17499
* the same mask and op1. */
17500
if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17501
op2 = MASK_ADDUH_QB(ctx->opcode);
17504
case OPC_ADDUH_R_QB:
17506
case OPC_ADDQH_R_PH:
17508
case OPC_ADDQH_R_W:
17510
case OPC_SUBUH_R_QB:
17512
case OPC_SUBQH_R_PH:
17514
case OPC_SUBQH_R_W:
17515
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17520
case OPC_MULQ_RS_W:
17521
gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17524
MIPS_INVAL("MASK ADDUH.QB");
17525
generate_exception_end(ctx, EXCP_RI);
17528
} else if (ctx->insn_flags & INSN_LOONGSON2E) {
17529
gen_loongson_integer(ctx, op1, rd, rs, rt);
17531
generate_exception_end(ctx, EXCP_RI);
17535
op2 = MASK_LX(ctx->opcode);
17537
#if defined(TARGET_MIPS64)
17543
gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17545
default: /* Invalid */
17546
MIPS_INVAL("MASK LX");
17547
generate_exception_end(ctx, EXCP_RI);
17551
case OPC_ABSQ_S_PH_DSP:
17552
op2 = MASK_ABSQ_S_PH(ctx->opcode);
17554
case OPC_ABSQ_S_QB:
17555
case OPC_ABSQ_S_PH:
17557
case OPC_PRECEQ_W_PHL:
17558
case OPC_PRECEQ_W_PHR:
17559
case OPC_PRECEQU_PH_QBL:
17560
case OPC_PRECEQU_PH_QBR:
17561
case OPC_PRECEQU_PH_QBLA:
17562
case OPC_PRECEQU_PH_QBRA:
17563
case OPC_PRECEU_PH_QBL:
17564
case OPC_PRECEU_PH_QBR:
17565
case OPC_PRECEU_PH_QBLA:
17566
case OPC_PRECEU_PH_QBRA:
17567
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17574
gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17577
MIPS_INVAL("MASK ABSQ_S.PH");
17578
generate_exception_end(ctx, EXCP_RI);
17582
case OPC_ADDU_QB_DSP:
17583
op2 = MASK_ADDU_QB(ctx->opcode);
17586
case OPC_ADDQ_S_PH:
17589
case OPC_ADDU_S_QB:
17591
case OPC_ADDU_S_PH:
17593
case OPC_SUBQ_S_PH:
17596
case OPC_SUBU_S_QB:
17598
case OPC_SUBU_S_PH:
17602
case OPC_RADDU_W_QB:
17603
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17605
case OPC_MULEU_S_PH_QBL:
17606
case OPC_MULEU_S_PH_QBR:
17607
case OPC_MULQ_RS_PH:
17608
case OPC_MULEQ_S_W_PHL:
17609
case OPC_MULEQ_S_W_PHR:
17610
case OPC_MULQ_S_PH:
17611
gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17613
default: /* Invalid */
17614
MIPS_INVAL("MASK ADDU.QB");
17615
generate_exception_end(ctx, EXCP_RI);
17620
case OPC_CMPU_EQ_QB_DSP:
17621
op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17623
case OPC_PRECR_SRA_PH_W:
17624
case OPC_PRECR_SRA_R_PH_W:
17625
gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17627
case OPC_PRECR_QB_PH:
17628
case OPC_PRECRQ_QB_PH:
17629
case OPC_PRECRQ_PH_W:
17630
case OPC_PRECRQ_RS_PH_W:
17631
case OPC_PRECRQU_S_QB_PH:
17632
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17634
case OPC_CMPU_EQ_QB:
17635
case OPC_CMPU_LT_QB:
17636
case OPC_CMPU_LE_QB:
17637
case OPC_CMP_EQ_PH:
17638
case OPC_CMP_LT_PH:
17639
case OPC_CMP_LE_PH:
17640
gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17642
case OPC_CMPGU_EQ_QB:
17643
case OPC_CMPGU_LT_QB:
17644
case OPC_CMPGU_LE_QB:
17645
case OPC_CMPGDU_EQ_QB:
17646
case OPC_CMPGDU_LT_QB:
17647
case OPC_CMPGDU_LE_QB:
17650
case OPC_PACKRL_PH:
17651
gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17653
default: /* Invalid */
17654
MIPS_INVAL("MASK CMPU.EQ.QB");
17655
generate_exception_end(ctx, EXCP_RI);
17659
case OPC_SHLL_QB_DSP:
17660
gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17662
case OPC_DPA_W_PH_DSP:
17663
op2 = MASK_DPA_W_PH(ctx->opcode);
17665
case OPC_DPAU_H_QBL:
17666
case OPC_DPAU_H_QBR:
17667
case OPC_DPSU_H_QBL:
17668
case OPC_DPSU_H_QBR:
17670
case OPC_DPAX_W_PH:
17671
case OPC_DPAQ_S_W_PH:
17672
case OPC_DPAQX_S_W_PH:
17673
case OPC_DPAQX_SA_W_PH:
17675
case OPC_DPSX_W_PH:
17676
case OPC_DPSQ_S_W_PH:
17677
case OPC_DPSQX_S_W_PH:
17678
case OPC_DPSQX_SA_W_PH:
17679
case OPC_MULSAQ_S_W_PH:
17680
case OPC_DPAQ_SA_L_W:
17681
case OPC_DPSQ_SA_L_W:
17682
case OPC_MAQ_S_W_PHL:
17683
case OPC_MAQ_S_W_PHR:
17684
case OPC_MAQ_SA_W_PHL:
17685
case OPC_MAQ_SA_W_PHR:
17686
case OPC_MULSA_W_PH:
17687
gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17689
default: /* Invalid */
17690
MIPS_INVAL("MASK DPAW.PH");
17691
generate_exception_end(ctx, EXCP_RI);
17696
op2 = MASK_INSV(ctx->opcode);
17707
t0 = tcg_temp_new();
17708
t1 = tcg_temp_new();
17710
gen_load_gpr(t0, rt);
17711
gen_load_gpr(t1, rs);
17713
gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17719
default: /* Invalid */
17720
MIPS_INVAL("MASK INSV");
17721
generate_exception_end(ctx, EXCP_RI);
17725
case OPC_APPEND_DSP:
17726
gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17728
case OPC_EXTR_W_DSP:
17729
op2 = MASK_EXTR_W(ctx->opcode);
17733
case OPC_EXTR_RS_W:
17735
case OPC_EXTRV_S_H:
17737
case OPC_EXTRV_R_W:
17738
case OPC_EXTRV_RS_W:
17743
gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17746
gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17752
gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17754
default: /* Invalid */
17755
MIPS_INVAL("MASK EXTR.W");
17756
generate_exception_end(ctx, EXCP_RI);
17760
#if defined(TARGET_MIPS64)
17761
case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17762
case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17763
case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17764
check_insn(ctx, INSN_LOONGSON2E);
17765
gen_loongson_integer(ctx, op1, rd, rs, rt);
17767
case OPC_ABSQ_S_QH_DSP:
17768
op2 = MASK_ABSQ_S_QH(ctx->opcode);
17770
case OPC_PRECEQ_L_PWL:
17771
case OPC_PRECEQ_L_PWR:
17772
case OPC_PRECEQ_PW_QHL:
17773
case OPC_PRECEQ_PW_QHR:
17774
case OPC_PRECEQ_PW_QHLA:
17775
case OPC_PRECEQ_PW_QHRA:
17776
case OPC_PRECEQU_QH_OBL:
17777
case OPC_PRECEQU_QH_OBR:
17778
case OPC_PRECEQU_QH_OBLA:
17779
case OPC_PRECEQU_QH_OBRA:
17780
case OPC_PRECEU_QH_OBL:
17781
case OPC_PRECEU_QH_OBR:
17782
case OPC_PRECEU_QH_OBLA:
17783
case OPC_PRECEU_QH_OBRA:
17784
case OPC_ABSQ_S_OB:
17785
case OPC_ABSQ_S_PW:
17786
case OPC_ABSQ_S_QH:
17787
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17795
gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17797
default: /* Invalid */
17798
MIPS_INVAL("MASK ABSQ_S.QH");
17799
generate_exception_end(ctx, EXCP_RI);
17803
case OPC_ADDU_OB_DSP:
17804
op2 = MASK_ADDU_OB(ctx->opcode);
17806
case OPC_RADDU_L_OB:
17808
case OPC_SUBQ_S_PW:
17810
case OPC_SUBQ_S_QH:
17812
case OPC_SUBU_S_OB:
17814
case OPC_SUBU_S_QH:
17816
case OPC_SUBUH_R_OB:
17818
case OPC_ADDQ_S_PW:
17820
case OPC_ADDQ_S_QH:
17822
case OPC_ADDU_S_OB:
17824
case OPC_ADDU_S_QH:
17826
case OPC_ADDUH_R_OB:
17827
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17829
case OPC_MULEQ_S_PW_QHL:
17830
case OPC_MULEQ_S_PW_QHR:
17831
case OPC_MULEU_S_QH_OBL:
17832
case OPC_MULEU_S_QH_OBR:
17833
case OPC_MULQ_RS_QH:
17834
gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17836
default: /* Invalid */
17837
MIPS_INVAL("MASK ADDU.OB");
17838
generate_exception_end(ctx, EXCP_RI);
17842
case OPC_CMPU_EQ_OB_DSP:
17843
op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17845
case OPC_PRECR_SRA_QH_PW:
17846
case OPC_PRECR_SRA_R_QH_PW:
17847
/* Return value is rt. */
17848
gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17850
case OPC_PRECR_OB_QH:
17851
case OPC_PRECRQ_OB_QH:
17852
case OPC_PRECRQ_PW_L:
17853
case OPC_PRECRQ_QH_PW:
17854
case OPC_PRECRQ_RS_QH_PW:
17855
case OPC_PRECRQU_S_OB_QH:
17856
gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17858
case OPC_CMPU_EQ_OB:
17859
case OPC_CMPU_LT_OB:
17860
case OPC_CMPU_LE_OB:
17861
case OPC_CMP_EQ_QH:
17862
case OPC_CMP_LT_QH:
17863
case OPC_CMP_LE_QH:
17864
case OPC_CMP_EQ_PW:
17865
case OPC_CMP_LT_PW:
17866
case OPC_CMP_LE_PW:
17867
gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17869
case OPC_CMPGDU_EQ_OB:
17870
case OPC_CMPGDU_LT_OB:
17871
case OPC_CMPGDU_LE_OB:
17872
case OPC_CMPGU_EQ_OB:
17873
case OPC_CMPGU_LT_OB:
17874
case OPC_CMPGU_LE_OB:
17875
case OPC_PACKRL_PW:
17879
gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17881
default: /* Invalid */
17882
MIPS_INVAL("MASK CMPU_EQ.OB");
17883
generate_exception_end(ctx, EXCP_RI);
17887
case OPC_DAPPEND_DSP:
17888
gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17890
case OPC_DEXTR_W_DSP:
17891
op2 = MASK_DEXTR_W(ctx->opcode);
17898
case OPC_DEXTR_R_L:
17899
case OPC_DEXTR_RS_L:
17901
case OPC_DEXTR_R_W:
17902
case OPC_DEXTR_RS_W:
17903
case OPC_DEXTR_S_H:
17905
case OPC_DEXTRV_R_L:
17906
case OPC_DEXTRV_RS_L:
17907
case OPC_DEXTRV_S_H:
17909
case OPC_DEXTRV_R_W:
17910
case OPC_DEXTRV_RS_W:
17911
gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17916
gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17918
default: /* Invalid */
17919
MIPS_INVAL("MASK EXTR.W");
17920
generate_exception_end(ctx, EXCP_RI);
17924
case OPC_DPAQ_W_QH_DSP:
17925
op2 = MASK_DPAQ_W_QH(ctx->opcode);
17927
case OPC_DPAU_H_OBL:
17928
case OPC_DPAU_H_OBR:
17929
case OPC_DPSU_H_OBL:
17930
case OPC_DPSU_H_OBR:
17932
case OPC_DPAQ_S_W_QH:
17934
case OPC_DPSQ_S_W_QH:
17935
case OPC_MULSAQ_S_W_QH:
17936
case OPC_DPAQ_SA_L_PW:
17937
case OPC_DPSQ_SA_L_PW:
17938
case OPC_MULSAQ_S_L_PW:
17939
gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17941
case OPC_MAQ_S_W_QHLL:
17942
case OPC_MAQ_S_W_QHLR:
17943
case OPC_MAQ_S_W_QHRL:
17944
case OPC_MAQ_S_W_QHRR:
17945
case OPC_MAQ_SA_W_QHLL:
17946
case OPC_MAQ_SA_W_QHLR:
17947
case OPC_MAQ_SA_W_QHRL:
17948
case OPC_MAQ_SA_W_QHRR:
17949
case OPC_MAQ_S_L_PWL:
17950
case OPC_MAQ_S_L_PWR:
17955
gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17957
default: /* Invalid */
17958
MIPS_INVAL("MASK DPAQ.W.QH");
17959
generate_exception_end(ctx, EXCP_RI);
17963
case OPC_DINSV_DSP:
17964
op2 = MASK_INSV(ctx->opcode);
17975
t0 = tcg_temp_new();
17976
t1 = tcg_temp_new();
17978
gen_load_gpr(t0, rt);
17979
gen_load_gpr(t1, rs);
17981
gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17987
default: /* Invalid */
17988
MIPS_INVAL("MASK DINSV");
17989
generate_exception_end(ctx, EXCP_RI);
17993
case OPC_SHLL_OB_DSP:
17994
gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17997
default: /* Invalid */
17998
MIPS_INVAL("special3_legacy");
17999
generate_exception_end(ctx, EXCP_RI);
18004
static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18006
int rs, rt, rd, sa;
18009
rs = (ctx->opcode >> 21) & 0x1f;
18010
rt = (ctx->opcode >> 16) & 0x1f;
18011
rd = (ctx->opcode >> 11) & 0x1f;
18012
sa = (ctx->opcode >> 6) & 0x1f;
18014
op1 = MASK_SPECIAL3(ctx->opcode);
18018
check_insn(ctx, ISA_MIPS32R2);
18019
gen_bitops(ctx, op1, rt, rs, sa, rd);
18022
op2 = MASK_BSHFL(ctx->opcode);
18024
case OPC_ALIGN ... OPC_ALIGN_END:
18026
check_insn(ctx, ISA_MIPS32R6);
18027
decode_opc_special3_r6(env, ctx);
18030
check_insn(ctx, ISA_MIPS32R2);
18031
gen_bshfl(ctx, op2, rt, rd);
18035
#if defined(TARGET_MIPS64)
18036
case OPC_DEXTM ... OPC_DEXT:
18037
case OPC_DINSM ... OPC_DINS:
18038
check_insn(ctx, ISA_MIPS64R2);
18039
check_mips_64(ctx);
18040
gen_bitops(ctx, op1, rt, rs, sa, rd);
18043
op2 = MASK_DBSHFL(ctx->opcode);
18045
case OPC_DALIGN ... OPC_DALIGN_END:
18047
check_insn(ctx, ISA_MIPS32R6);
18048
decode_opc_special3_r6(env, ctx);
18051
check_insn(ctx, ISA_MIPS64R2);
18052
check_mips_64(ctx);
18053
op2 = MASK_DBSHFL(ctx->opcode);
18054
gen_bshfl(ctx, op2, rt, rd);
18060
gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
18063
check_insn(ctx, ASE_MT);
18065
TCGv t0 = tcg_temp_new();
18066
TCGv t1 = tcg_temp_new();
18068
gen_load_gpr(t0, rt);
18069
gen_load_gpr(t1, rs);
18070
gen_helper_fork(t0, t1);
18076
check_insn(ctx, ASE_MT);
18078
TCGv t0 = tcg_temp_new();
18080
gen_load_gpr(t0, rs);
18081
gen_helper_yield(t0, cpu_env, t0);
18082
gen_store_gpr(t0, rd);
18087
if (ctx->insn_flags & ISA_MIPS32R6) {
18088
decode_opc_special3_r6(env, ctx);
18090
decode_opc_special3_legacy(env, ctx);
18095
/* MIPS SIMD Architecture (MSA) */
18096
static inline int check_msa_access(DisasContext *ctx)
18098
if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18099
!(ctx->hflags & MIPS_HFLAG_F64))) {
18100
generate_exception_end(ctx, EXCP_RI);
18104
if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18105
if (ctx->insn_flags & ASE_MSA) {
18106
generate_exception_end(ctx, EXCP_MSADIS);
18109
generate_exception_end(ctx, EXCP_RI);
18116
static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18118
/* generates tcg ops to check if any element is 0 */
18119
/* Note this function only works with MSA_WRLEN = 128 */
18120
uint64_t eval_zero_or_big = 0;
18121
uint64_t eval_big = 0;
18122
TCGv_i64 t0 = tcg_temp_new_i64();
18123
TCGv_i64 t1 = tcg_temp_new_i64();
18126
eval_zero_or_big = 0x0101010101010101ULL;
18127
eval_big = 0x8080808080808080ULL;
18130
eval_zero_or_big = 0x0001000100010001ULL;
18131
eval_big = 0x8000800080008000ULL;
18134
eval_zero_or_big = 0x0000000100000001ULL;
18135
eval_big = 0x8000000080000000ULL;
18138
eval_zero_or_big = 0x0000000000000001ULL;
18139
eval_big = 0x8000000000000000ULL;
18142
tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18143
tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18144
tcg_gen_andi_i64(t0, t0, eval_big);
18145
tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18146
tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18147
tcg_gen_andi_i64(t1, t1, eval_big);
18148
tcg_gen_or_i64(t0, t0, t1);
18149
/* if all bits are zero then all elements are not zero */
18150
/* if some bit is non-zero then some element is zero */
18151
tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18152
tcg_gen_trunc_i64_tl(tresult, t0);
18153
tcg_temp_free_i64(t0);
18154
tcg_temp_free_i64(t1);
18157
static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18159
uint8_t df = (ctx->opcode >> 21) & 0x3;
18160
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18161
int64_t s16 = (int16_t)ctx->opcode;
18163
check_msa_access(ctx);
18165
if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
18166
generate_exception_end(ctx, EXCP_RI);
18173
TCGv_i64 t0 = tcg_temp_new_i64();
18174
tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18175
tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18176
TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18177
tcg_gen_trunc_i64_tl(bcond, t0);
18178
tcg_temp_free_i64(t0);
18185
gen_check_zero_element(bcond, df, wt);
18191
gen_check_zero_element(bcond, df, wt);
18192
tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18196
ctx->btarget = ctx->pc + (s16 << 2) + 4;
18198
ctx->hflags |= MIPS_HFLAG_BC;
18199
ctx->hflags |= MIPS_HFLAG_BDS32;
18202
static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18204
#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18205
uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18206
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18207
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18209
TCGv_i32 twd = tcg_const_i32(wd);
18210
TCGv_i32 tws = tcg_const_i32(ws);
18211
TCGv_i32 ti8 = tcg_const_i32(i8);
18213
switch (MASK_MSA_I8(ctx->opcode)) {
18215
gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18218
gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18221
gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18224
gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18227
gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18230
gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18233
gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18239
uint8_t df = (ctx->opcode >> 24) & 0x3;
18240
if (df == DF_DOUBLE) {
18241
generate_exception_end(ctx, EXCP_RI);
18243
TCGv_i32 tdf = tcg_const_i32(df);
18244
gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18245
tcg_temp_free_i32(tdf);
18250
MIPS_INVAL("MSA instruction");
18251
generate_exception_end(ctx, EXCP_RI);
18255
tcg_temp_free_i32(twd);
18256
tcg_temp_free_i32(tws);
18257
tcg_temp_free_i32(ti8);
18260
static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18262
#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18263
uint8_t df = (ctx->opcode >> 21) & 0x3;
18264
int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18265
uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18266
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18267
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18269
TCGv_i32 tdf = tcg_const_i32(df);
18270
TCGv_i32 twd = tcg_const_i32(wd);
18271
TCGv_i32 tws = tcg_const_i32(ws);
18272
TCGv_i32 timm = tcg_temp_new_i32();
18273
tcg_gen_movi_i32(timm, u5);
18275
switch (MASK_MSA_I5(ctx->opcode)) {
18277
gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18280
gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18282
case OPC_MAXI_S_df:
18283
tcg_gen_movi_i32(timm, s5);
18284
gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18286
case OPC_MAXI_U_df:
18287
gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18289
case OPC_MINI_S_df:
18290
tcg_gen_movi_i32(timm, s5);
18291
gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18293
case OPC_MINI_U_df:
18294
gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18297
tcg_gen_movi_i32(timm, s5);
18298
gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18300
case OPC_CLTI_S_df:
18301
tcg_gen_movi_i32(timm, s5);
18302
gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18304
case OPC_CLTI_U_df:
18305
gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18307
case OPC_CLEI_S_df:
18308
tcg_gen_movi_i32(timm, s5);
18309
gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18311
case OPC_CLEI_U_df:
18312
gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18316
int32_t s10 = sextract32(ctx->opcode, 11, 10);
18317
tcg_gen_movi_i32(timm, s10);
18318
gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18322
MIPS_INVAL("MSA instruction");
18323
generate_exception_end(ctx, EXCP_RI);
18327
tcg_temp_free_i32(tdf);
18328
tcg_temp_free_i32(twd);
18329
tcg_temp_free_i32(tws);
18330
tcg_temp_free_i32(timm);
18333
static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18335
#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18336
uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18337
uint32_t df = 0, m = 0;
18338
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18339
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18346
if ((dfm & 0x40) == 0x00) {
18349
} else if ((dfm & 0x60) == 0x40) {
18352
} else if ((dfm & 0x70) == 0x60) {
18355
} else if ((dfm & 0x78) == 0x70) {
18359
generate_exception_end(ctx, EXCP_RI);
18363
tdf = tcg_const_i32(df);
18364
tm = tcg_const_i32(m);
18365
twd = tcg_const_i32(wd);
18366
tws = tcg_const_i32(ws);
18368
switch (MASK_MSA_BIT(ctx->opcode)) {
18370
gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18373
gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18376
gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18379
gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18382
gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18385
gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18387
case OPC_BINSLI_df:
18388
gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18390
case OPC_BINSRI_df:
18391
gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18394
gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18397
gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18400
gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18403
gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18406
MIPS_INVAL("MSA instruction");
18407
generate_exception_end(ctx, EXCP_RI);
18411
tcg_temp_free_i32(tdf);
18412
tcg_temp_free_i32(tm);
18413
tcg_temp_free_i32(twd);
18414
tcg_temp_free_i32(tws);
18417
static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18419
#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18420
uint8_t df = (ctx->opcode >> 21) & 0x3;
18421
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18422
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18423
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18425
TCGv_i32 tdf = tcg_const_i32(df);
18426
TCGv_i32 twd = tcg_const_i32(wd);
18427
TCGv_i32 tws = tcg_const_i32(ws);
18428
TCGv_i32 twt = tcg_const_i32(wt);
18430
switch (MASK_MSA_3R(ctx->opcode)) {
18432
gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18435
gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18438
gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18441
gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18443
case OPC_SUBS_S_df:
18444
gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18447
gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18450
gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18453
gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18456
gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18459
gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18461
case OPC_ADDS_A_df:
18462
gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18464
case OPC_SUBS_U_df:
18465
gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18468
gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18471
gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18474
gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18477
gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18480
gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18483
gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18485
case OPC_ADDS_S_df:
18486
gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18488
case OPC_SUBSUS_U_df:
18489
gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18492
gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18495
gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18498
gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18501
gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18504
gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18507
gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18509
case OPC_ADDS_U_df:
18510
gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18512
case OPC_SUBSUU_S_df:
18513
gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18516
gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18519
gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18522
gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18525
gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18528
gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18530
case OPC_ASUB_S_df:
18531
gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18534
gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18537
gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18540
gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18543
gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18546
gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18549
gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18551
case OPC_ASUB_U_df:
18552
gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18555
gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18558
gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18561
gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18564
gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18566
case OPC_AVER_S_df:
18567
gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18570
gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18573
gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18576
gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18579
gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18581
case OPC_AVER_U_df:
18582
gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18585
gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18588
gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18591
case OPC_DOTP_S_df:
18592
case OPC_DOTP_U_df:
18593
case OPC_DPADD_S_df:
18594
case OPC_DPADD_U_df:
18595
case OPC_DPSUB_S_df:
18596
case OPC_HADD_S_df:
18597
case OPC_DPSUB_U_df:
18598
case OPC_HADD_U_df:
18599
case OPC_HSUB_S_df:
18600
case OPC_HSUB_U_df:
18601
if (df == DF_BYTE) {
18602
generate_exception_end(ctx, EXCP_RI);
18605
switch (MASK_MSA_3R(ctx->opcode)) {
18606
case OPC_DOTP_S_df:
18607
gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18609
case OPC_DOTP_U_df:
18610
gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18612
case OPC_DPADD_S_df:
18613
gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18615
case OPC_DPADD_U_df:
18616
gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18618
case OPC_DPSUB_S_df:
18619
gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18621
case OPC_HADD_S_df:
18622
gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18624
case OPC_DPSUB_U_df:
18625
gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18627
case OPC_HADD_U_df:
18628
gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18630
case OPC_HSUB_S_df:
18631
gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18633
case OPC_HSUB_U_df:
18634
gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18639
MIPS_INVAL("MSA instruction");
18640
generate_exception_end(ctx, EXCP_RI);
18643
tcg_temp_free_i32(twd);
18644
tcg_temp_free_i32(tws);
18645
tcg_temp_free_i32(twt);
18646
tcg_temp_free_i32(tdf);
18649
static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18651
#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18652
uint8_t source = (ctx->opcode >> 11) & 0x1f;
18653
uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18654
TCGv telm = tcg_temp_new();
18655
TCGv_i32 tsr = tcg_const_i32(source);
18656
TCGv_i32 tdt = tcg_const_i32(dest);
18658
switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18660
gen_load_gpr(telm, source);
18661
gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18664
gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18665
gen_store_gpr(telm, dest);
18668
gen_helper_msa_move_v(cpu_env, tdt, tsr);
18671
MIPS_INVAL("MSA instruction");
18672
generate_exception_end(ctx, EXCP_RI);
18676
tcg_temp_free(telm);
18677
tcg_temp_free_i32(tdt);
18678
tcg_temp_free_i32(tsr);
18681
static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18684
#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18685
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18686
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18688
TCGv_i32 tws = tcg_const_i32(ws);
18689
TCGv_i32 twd = tcg_const_i32(wd);
18690
TCGv_i32 tn = tcg_const_i32(n);
18691
TCGv_i32 tdf = tcg_const_i32(df);
18693
switch (MASK_MSA_ELM(ctx->opcode)) {
18695
gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18697
case OPC_SPLATI_df:
18698
gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18701
gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18703
case OPC_COPY_S_df:
18704
case OPC_COPY_U_df:
18705
case OPC_INSERT_df:
18706
#if !defined(TARGET_MIPS64)
18707
/* Double format valid only for MIPS64 */
18708
if (df == DF_DOUBLE) {
18709
generate_exception_end(ctx, EXCP_RI);
18713
switch (MASK_MSA_ELM(ctx->opcode)) {
18714
case OPC_COPY_S_df:
18715
gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18717
case OPC_COPY_U_df:
18718
gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18720
case OPC_INSERT_df:
18721
gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18726
MIPS_INVAL("MSA instruction");
18727
generate_exception_end(ctx, EXCP_RI);
18729
tcg_temp_free_i32(twd);
18730
tcg_temp_free_i32(tws);
18731
tcg_temp_free_i32(tn);
18732
tcg_temp_free_i32(tdf);
18735
static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18737
uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18738
uint32_t df = 0, n = 0;
18740
if ((dfn & 0x30) == 0x00) {
18743
} else if ((dfn & 0x38) == 0x20) {
18746
} else if ((dfn & 0x3c) == 0x30) {
18749
} else if ((dfn & 0x3e) == 0x38) {
18752
} else if (dfn == 0x3E) {
18753
/* CTCMSA, CFCMSA, MOVE.V */
18754
gen_msa_elm_3e(env, ctx);
18757
generate_exception_end(ctx, EXCP_RI);
18761
gen_msa_elm_df(env, ctx, df, n);
18764
static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18766
#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18767
uint8_t df = (ctx->opcode >> 21) & 0x1;
18768
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18769
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18770
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18772
TCGv_i32 twd = tcg_const_i32(wd);
18773
TCGv_i32 tws = tcg_const_i32(ws);
18774
TCGv_i32 twt = tcg_const_i32(wt);
18775
TCGv_i32 tdf = tcg_temp_new_i32();
18777
/* adjust df value for floating-point instruction */
18778
tcg_gen_movi_i32(tdf, df + 2);
18780
switch (MASK_MSA_3RF(ctx->opcode)) {
18782
gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18785
gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18788
gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18791
gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18794
gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18797
gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18800
gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18803
gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18806
gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18809
gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18812
gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18815
gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18818
gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18821
tcg_gen_movi_i32(tdf, df + 1);
18822
gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18825
gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18828
gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18830
case OPC_MADD_Q_df:
18831
tcg_gen_movi_i32(tdf, df + 1);
18832
gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18835
gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18837
case OPC_MSUB_Q_df:
18838
tcg_gen_movi_i32(tdf, df + 1);
18839
gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18842
gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18845
gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18848
gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18851
gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18854
gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18857
gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18860
gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18863
gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18866
gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18869
gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18872
gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18875
gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18878
gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18880
case OPC_MULR_Q_df:
18881
tcg_gen_movi_i32(tdf, df + 1);
18882
gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18885
gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18887
case OPC_FMIN_A_df:
18888
gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18890
case OPC_MADDR_Q_df:
18891
tcg_gen_movi_i32(tdf, df + 1);
18892
gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18895
gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18898
gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18900
case OPC_MSUBR_Q_df:
18901
tcg_gen_movi_i32(tdf, df + 1);
18902
gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18905
gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18907
case OPC_FMAX_A_df:
18908
gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18911
MIPS_INVAL("MSA instruction");
18912
generate_exception_end(ctx, EXCP_RI);
18916
tcg_temp_free_i32(twd);
18917
tcg_temp_free_i32(tws);
18918
tcg_temp_free_i32(twt);
18919
tcg_temp_free_i32(tdf);
18922
static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18924
#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18925
(op & (0x7 << 18)))
18926
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18927
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18928
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18929
uint8_t df = (ctx->opcode >> 16) & 0x3;
18930
TCGv_i32 twd = tcg_const_i32(wd);
18931
TCGv_i32 tws = tcg_const_i32(ws);
18932
TCGv_i32 twt = tcg_const_i32(wt);
18933
TCGv_i32 tdf = tcg_const_i32(df);
18935
switch (MASK_MSA_2R(ctx->opcode)) {
18937
#if !defined(TARGET_MIPS64)
18938
/* Double format valid only for MIPS64 */
18939
if (df == DF_DOUBLE) {
18940
generate_exception_end(ctx, EXCP_RI);
18944
gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18947
gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18950
gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18953
gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18956
MIPS_INVAL("MSA instruction");
18957
generate_exception_end(ctx, EXCP_RI);
18961
tcg_temp_free_i32(twd);
18962
tcg_temp_free_i32(tws);
18963
tcg_temp_free_i32(twt);
18964
tcg_temp_free_i32(tdf);
18967
static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18969
#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18970
(op & (0xf << 17)))
18971
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18972
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18973
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18974
uint8_t df = (ctx->opcode >> 16) & 0x1;
18975
TCGv_i32 twd = tcg_const_i32(wd);
18976
TCGv_i32 tws = tcg_const_i32(ws);
18977
TCGv_i32 twt = tcg_const_i32(wt);
18978
/* adjust df value for floating-point instruction */
18979
TCGv_i32 tdf = tcg_const_i32(df + 2);
18981
switch (MASK_MSA_2RF(ctx->opcode)) {
18982
case OPC_FCLASS_df:
18983
gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18985
case OPC_FTRUNC_S_df:
18986
gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18988
case OPC_FTRUNC_U_df:
18989
gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18992
gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18994
case OPC_FRSQRT_df:
18995
gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18998
gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19001
gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19004
gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19006
case OPC_FEXUPL_df:
19007
gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19009
case OPC_FEXUPR_df:
19010
gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19013
gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19016
gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19018
case OPC_FTINT_S_df:
19019
gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19021
case OPC_FTINT_U_df:
19022
gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19024
case OPC_FFINT_S_df:
19025
gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19027
case OPC_FFINT_U_df:
19028
gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19032
tcg_temp_free_i32(twd);
19033
tcg_temp_free_i32(tws);
19034
tcg_temp_free_i32(twt);
19035
tcg_temp_free_i32(tdf);
19038
static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19040
#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19041
uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19042
uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19043
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19044
TCGv_i32 twd = tcg_const_i32(wd);
19045
TCGv_i32 tws = tcg_const_i32(ws);
19046
TCGv_i32 twt = tcg_const_i32(wt);
19048
switch (MASK_MSA_VEC(ctx->opcode)) {
19050
gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19053
gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19056
gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19059
gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19062
gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19065
gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19068
gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19071
MIPS_INVAL("MSA instruction");
19072
generate_exception_end(ctx, EXCP_RI);
19076
tcg_temp_free_i32(twd);
19077
tcg_temp_free_i32(tws);
19078
tcg_temp_free_i32(twt);
19081
static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19083
switch (MASK_MSA_VEC(ctx->opcode)) {
19091
gen_msa_vec_v(env, ctx);
19094
gen_msa_2r(env, ctx);
19097
gen_msa_2rf(env, ctx);
19100
MIPS_INVAL("MSA instruction");
19101
generate_exception_end(ctx, EXCP_RI);
19106
static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19108
uint32_t opcode = ctx->opcode;
19109
check_insn(ctx, ASE_MSA);
19110
check_msa_access(ctx);
19112
switch (MASK_MSA_MINOR(opcode)) {
19113
case OPC_MSA_I8_00:
19114
case OPC_MSA_I8_01:
19115
case OPC_MSA_I8_02:
19116
gen_msa_i8(env, ctx);
19118
case OPC_MSA_I5_06:
19119
case OPC_MSA_I5_07:
19120
gen_msa_i5(env, ctx);
19122
case OPC_MSA_BIT_09:
19123
case OPC_MSA_BIT_0A:
19124
gen_msa_bit(env, ctx);
19126
case OPC_MSA_3R_0D:
19127
case OPC_MSA_3R_0E:
19128
case OPC_MSA_3R_0F:
19129
case OPC_MSA_3R_10:
19130
case OPC_MSA_3R_11:
19131
case OPC_MSA_3R_12:
19132
case OPC_MSA_3R_13:
19133
case OPC_MSA_3R_14:
19134
case OPC_MSA_3R_15:
19135
gen_msa_3r(env, ctx);
19138
gen_msa_elm(env, ctx);
19140
case OPC_MSA_3RF_1A:
19141
case OPC_MSA_3RF_1B:
19142
case OPC_MSA_3RF_1C:
19143
gen_msa_3rf(env, ctx);
19146
gen_msa_vec(env, ctx);
19157
int32_t s10 = sextract32(ctx->opcode, 16, 10);
19158
uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19159
uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19160
uint8_t df = (ctx->opcode >> 0) & 0x3;
19162
TCGv_i32 twd = tcg_const_i32(wd);
19163
TCGv taddr = tcg_temp_new();
19164
gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19166
switch (MASK_MSA_MINOR(opcode)) {
19168
gen_helper_msa_ld_b(cpu_env, twd, taddr);
19171
gen_helper_msa_ld_h(cpu_env, twd, taddr);
19174
gen_helper_msa_ld_w(cpu_env, twd, taddr);
19177
gen_helper_msa_ld_d(cpu_env, twd, taddr);
19180
gen_helper_msa_st_b(cpu_env, twd, taddr);
19183
gen_helper_msa_st_h(cpu_env, twd, taddr);
19186
gen_helper_msa_st_w(cpu_env, twd, taddr);
19189
gen_helper_msa_st_d(cpu_env, twd, taddr);
19193
tcg_temp_free_i32(twd);
19194
tcg_temp_free(taddr);
19198
MIPS_INVAL("MSA instruction");
19199
generate_exception_end(ctx, EXCP_RI);
19205
static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19208
int rs, rt, rd, sa;
19212
/* make sure instructions are on a word boundary */
19213
if (ctx->pc & 0x3) {
19214
env->CP0_BadVAddr = ctx->pc;
19215
generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19219
/* Handle blikely not taken case */
19220
if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19221
TCGLabel *l1 = gen_new_label();
19223
tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19224
tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19225
gen_goto_tb(ctx, 1, ctx->pc + 4);
19229
op = MASK_OP_MAJOR(ctx->opcode);
19230
rs = (ctx->opcode >> 21) & 0x1f;
19231
rt = (ctx->opcode >> 16) & 0x1f;
19232
rd = (ctx->opcode >> 11) & 0x1f;
19233
sa = (ctx->opcode >> 6) & 0x1f;
19234
imm = (int16_t)ctx->opcode;
19237
decode_opc_special(env, ctx);
19240
decode_opc_special2_legacy(env, ctx);
19243
decode_opc_special3(env, ctx);
19246
op1 = MASK_REGIMM(ctx->opcode);
19248
case OPC_BLTZL: /* REGIMM branches */
19252
check_insn(ctx, ISA_MIPS2);
19253
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19257
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19261
if (ctx->insn_flags & ISA_MIPS32R6) {
19263
/* OPC_NAL, OPC_BAL */
19264
gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19266
generate_exception_end(ctx, EXCP_RI);
19269
gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19272
case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19274
check_insn(ctx, ISA_MIPS2);
19275
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19276
gen_trap(ctx, op1, rs, -1, imm);
19279
check_insn(ctx, ISA_MIPS32R6);
19280
generate_exception_end(ctx, EXCP_RI);
19283
check_insn(ctx, ISA_MIPS32R2);
19284
/* Break the TB to be able to sync copied instructions
19286
ctx->bstate = BS_STOP;
19288
case OPC_BPOSGE32: /* MIPS DSP branch */
19289
#if defined(TARGET_MIPS64)
19293
gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19295
#if defined(TARGET_MIPS64)
19297
check_insn(ctx, ISA_MIPS32R6);
19298
check_mips_64(ctx);
19300
tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19304
check_insn(ctx, ISA_MIPS32R6);
19305
check_mips_64(ctx);
19307
tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19311
default: /* Invalid */
19312
MIPS_INVAL("regimm");
19313
generate_exception_end(ctx, EXCP_RI);
19318
check_cp0_enabled(ctx);
19319
op1 = MASK_CP0(ctx->opcode);
19327
#if defined(TARGET_MIPS64)
19331
#ifndef CONFIG_USER_ONLY
19332
gen_cp0(env, ctx, op1, rt, rd);
19333
#endif /* !CONFIG_USER_ONLY */
19335
case OPC_C0_FIRST ... OPC_C0_LAST:
19336
#ifndef CONFIG_USER_ONLY
19337
gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19338
#endif /* !CONFIG_USER_ONLY */
19341
#ifndef CONFIG_USER_ONLY
19344
TCGv t0 = tcg_temp_new();
19346
op2 = MASK_MFMC0(ctx->opcode);
19349
check_insn(ctx, ASE_MT);
19350
gen_helper_dmt(t0);
19351
gen_store_gpr(t0, rt);
19354
check_insn(ctx, ASE_MT);
19355
gen_helper_emt(t0);
19356
gen_store_gpr(t0, rt);
19359
check_insn(ctx, ASE_MT);
19360
gen_helper_dvpe(t0, cpu_env);
19361
gen_store_gpr(t0, rt);
19364
check_insn(ctx, ASE_MT);
19365
gen_helper_evpe(t0, cpu_env);
19366
gen_store_gpr(t0, rt);
19369
check_insn(ctx, ISA_MIPS32R6);
19371
gen_helper_dvp(t0, cpu_env);
19372
gen_store_gpr(t0, rt);
19376
check_insn(ctx, ISA_MIPS32R6);
19378
gen_helper_evp(t0, cpu_env);
19379
gen_store_gpr(t0, rt);
19383
check_insn(ctx, ISA_MIPS32R2);
19384
save_cpu_state(ctx, 1);
19385
gen_helper_di(t0, cpu_env);
19386
gen_store_gpr(t0, rt);
19387
/* Stop translation as we may have switched
19388
the execution mode. */
19389
ctx->bstate = BS_STOP;
19392
check_insn(ctx, ISA_MIPS32R2);
19393
save_cpu_state(ctx, 1);
19394
gen_helper_ei(t0, cpu_env);
19395
gen_store_gpr(t0, rt);
19396
/* Stop translation as we may have switched
19397
the execution mode. */
19398
ctx->bstate = BS_STOP;
19400
default: /* Invalid */
19401
MIPS_INVAL("mfmc0");
19402
generate_exception_end(ctx, EXCP_RI);
19407
#endif /* !CONFIG_USER_ONLY */
19410
check_insn(ctx, ISA_MIPS32R2);
19411
gen_load_srsgpr(rt, rd);
19414
check_insn(ctx, ISA_MIPS32R2);
19415
gen_store_srsgpr(rt, rd);
19419
generate_exception_end(ctx, EXCP_RI);
19423
case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19424
if (ctx->insn_flags & ISA_MIPS32R6) {
19425
/* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19426
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19429
/* Arithmetic with immediate opcode */
19430
gen_arith_imm(ctx, op, rt, rs, imm);
19434
gen_arith_imm(ctx, op, rt, rs, imm);
19436
case OPC_SLTI: /* Set on less than with immediate opcode */
19438
gen_slt_imm(ctx, op, rt, rs, imm);
19440
case OPC_ANDI: /* Arithmetic with immediate opcode */
19441
case OPC_LUI: /* OPC_AUI */
19444
gen_logic_imm(ctx, op, rt, rs, imm);
19446
case OPC_J ... OPC_JAL: /* Jump */
19447
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19448
gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19451
case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19452
if (ctx->insn_flags & ISA_MIPS32R6) {
19454
generate_exception_end(ctx, EXCP_RI);
19457
/* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19458
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19461
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19464
case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19465
if (ctx->insn_flags & ISA_MIPS32R6) {
19467
generate_exception_end(ctx, EXCP_RI);
19470
/* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19471
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19474
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19477
case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19480
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19482
check_insn(ctx, ISA_MIPS32R6);
19483
/* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19484
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19487
case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19490
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19492
check_insn(ctx, ISA_MIPS32R6);
19493
/* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19494
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19499
check_insn(ctx, ISA_MIPS2);
19500
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19504
gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19506
case OPC_LL: /* Load and stores */
19507
check_insn(ctx, ISA_MIPS2);
19511
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19513
case OPC_LB ... OPC_LH:
19514
case OPC_LW ... OPC_LHU:
19515
gen_ld(ctx, op, rt, rs, imm);
19519
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19521
case OPC_SB ... OPC_SH:
19523
gen_st(ctx, op, rt, rs, imm);
19526
check_insn(ctx, ISA_MIPS2);
19527
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19528
gen_st_cond(ctx, op, rt, rs, imm);
19531
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19532
check_cp0_enabled(ctx);
19533
check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19534
if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19535
gen_cache_operation(ctx, rt, rs, imm);
19537
/* Treat as NOP. */
19540
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19541
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19542
/* Treat as NOP. */
19545
/* Floating point (COP1). */
19550
gen_cop1_ldst(ctx, op, rt, rs, imm);
19554
op1 = MASK_CP1(ctx->opcode);
19559
check_cp1_enabled(ctx);
19560
check_insn(ctx, ISA_MIPS32R2);
19565
check_cp1_enabled(ctx);
19566
gen_cp1(ctx, op1, rt, rd);
19568
#if defined(TARGET_MIPS64)
19571
check_cp1_enabled(ctx);
19572
check_insn(ctx, ISA_MIPS3);
19573
check_mips_64(ctx);
19574
gen_cp1(ctx, op1, rt, rd);
19577
case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19578
check_cp1_enabled(ctx);
19579
if (ctx->insn_flags & ISA_MIPS32R6) {
19581
gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19586
check_insn(ctx, ASE_MIPS3D);
19587
gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19588
(rt >> 2) & 0x7, imm << 2);
19592
check_cp1_enabled(ctx);
19593
check_insn(ctx, ISA_MIPS32R6);
19594
gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19598
check_cp1_enabled(ctx);
19599
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19601
check_insn(ctx, ASE_MIPS3D);
19604
check_cp1_enabled(ctx);
19605
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19606
gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19607
(rt >> 2) & 0x7, imm << 2);
19614
check_cp1_enabled(ctx);
19615
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19621
int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19622
check_cp1_enabled(ctx);
19623
if (ctx->insn_flags & ISA_MIPS32R6) {
19625
case R6_OPC_CMP_AF_S:
19626
case R6_OPC_CMP_UN_S:
19627
case R6_OPC_CMP_EQ_S:
19628
case R6_OPC_CMP_UEQ_S:
19629
case R6_OPC_CMP_LT_S:
19630
case R6_OPC_CMP_ULT_S:
19631
case R6_OPC_CMP_LE_S:
19632
case R6_OPC_CMP_ULE_S:
19633
case R6_OPC_CMP_SAF_S:
19634
case R6_OPC_CMP_SUN_S:
19635
case R6_OPC_CMP_SEQ_S:
19636
case R6_OPC_CMP_SEUQ_S:
19637
case R6_OPC_CMP_SLT_S:
19638
case R6_OPC_CMP_SULT_S:
19639
case R6_OPC_CMP_SLE_S:
19640
case R6_OPC_CMP_SULE_S:
19641
case R6_OPC_CMP_OR_S:
19642
case R6_OPC_CMP_UNE_S:
19643
case R6_OPC_CMP_NE_S:
19644
case R6_OPC_CMP_SOR_S:
19645
case R6_OPC_CMP_SUNE_S:
19646
case R6_OPC_CMP_SNE_S:
19647
gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19649
case R6_OPC_CMP_AF_D:
19650
case R6_OPC_CMP_UN_D:
19651
case R6_OPC_CMP_EQ_D:
19652
case R6_OPC_CMP_UEQ_D:
19653
case R6_OPC_CMP_LT_D:
19654
case R6_OPC_CMP_ULT_D:
19655
case R6_OPC_CMP_LE_D:
19656
case R6_OPC_CMP_ULE_D:
19657
case R6_OPC_CMP_SAF_D:
19658
case R6_OPC_CMP_SUN_D:
19659
case R6_OPC_CMP_SEQ_D:
19660
case R6_OPC_CMP_SEUQ_D:
19661
case R6_OPC_CMP_SLT_D:
19662
case R6_OPC_CMP_SULT_D:
19663
case R6_OPC_CMP_SLE_D:
19664
case R6_OPC_CMP_SULE_D:
19665
case R6_OPC_CMP_OR_D:
19666
case R6_OPC_CMP_UNE_D:
19667
case R6_OPC_CMP_NE_D:
19668
case R6_OPC_CMP_SOR_D:
19669
case R6_OPC_CMP_SUNE_D:
19670
case R6_OPC_CMP_SNE_D:
19671
gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19674
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19675
rt, rd, sa, (imm >> 8) & 0x7);
19680
gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19695
check_insn(ctx, ASE_MSA);
19696
gen_msa_branch(env, ctx, op1);
19700
generate_exception_end(ctx, EXCP_RI);
19705
/* Compact branches [R6] and COP2 [non-R6] */
19706
case OPC_BC: /* OPC_LWC2 */
19707
case OPC_BALC: /* OPC_SWC2 */
19708
if (ctx->insn_flags & ISA_MIPS32R6) {
19709
/* OPC_BC, OPC_BALC */
19710
gen_compute_compact_branch(ctx, op, 0, 0,
19711
sextract32(ctx->opcode << 2, 0, 28));
19713
/* OPC_LWC2, OPC_SWC2 */
19714
/* COP2: Not implemented. */
19715
generate_exception_err(ctx, EXCP_CpU, 2);
19718
case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19719
case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19720
if (ctx->insn_flags & ISA_MIPS32R6) {
19722
/* OPC_BEQZC, OPC_BNEZC */
19723
gen_compute_compact_branch(ctx, op, rs, 0,
19724
sextract32(ctx->opcode << 2, 0, 23));
19726
/* OPC_JIC, OPC_JIALC */
19727
gen_compute_compact_branch(ctx, op, 0, rt, imm);
19730
/* OPC_LWC2, OPC_SWC2 */
19731
/* COP2: Not implemented. */
19732
generate_exception_err(ctx, EXCP_CpU, 2);
19736
check_insn(ctx, INSN_LOONGSON2F);
19737
/* Note that these instructions use different fields. */
19738
gen_loongson_multimedia(ctx, sa, rd, rt);
19742
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19743
if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19744
check_cp1_enabled(ctx);
19745
op1 = MASK_CP3(ctx->opcode);
19749
check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19755
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19756
gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19759
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19760
/* Treat as NOP. */
19763
check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19777
check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19778
gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19782
generate_exception_end(ctx, EXCP_RI);
19786
generate_exception_err(ctx, EXCP_CpU, 1);
19790
#if defined(TARGET_MIPS64)
19791
/* MIPS64 opcodes */
19792
case OPC_LDL ... OPC_LDR:
19794
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19798
check_insn(ctx, ISA_MIPS3);
19799
check_mips_64(ctx);
19800
gen_ld(ctx, op, rt, rs, imm);
19802
case OPC_SDL ... OPC_SDR:
19803
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19806
check_insn(ctx, ISA_MIPS3);
19807
check_mips_64(ctx);
19808
gen_st(ctx, op, rt, rs, imm);
19811
check_insn_opc_removed(ctx, ISA_MIPS32R6);
19812
check_insn(ctx, ISA_MIPS3);
19813
check_mips_64(ctx);
19814
gen_st_cond(ctx, op, rt, rs, imm);
19816
case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19817
if (ctx->insn_flags & ISA_MIPS32R6) {
19818
/* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19819
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19822
check_insn(ctx, ISA_MIPS3);
19823
check_mips_64(ctx);
19824
gen_arith_imm(ctx, op, rt, rs, imm);
19828
check_insn(ctx, ISA_MIPS3);
19829
check_mips_64(ctx);
19830
gen_arith_imm(ctx, op, rt, rs, imm);
19833
case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19834
if (ctx->insn_flags & ISA_MIPS32R6) {
19835
gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19837
MIPS_INVAL("major opcode");
19838
generate_exception_end(ctx, EXCP_RI);
19842
case OPC_DAUI: /* OPC_JALX */
19843
if (ctx->insn_flags & ISA_MIPS32R6) {
19844
#if defined(TARGET_MIPS64)
19846
check_mips_64(ctx);
19848
generate_exception(ctx, EXCP_RI);
19849
} else if (rt != 0) {
19850
TCGv t0 = tcg_temp_new();
19851
gen_load_gpr(t0, rs);
19852
tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19856
generate_exception_end(ctx, EXCP_RI);
19857
MIPS_INVAL("major opcode");
19861
check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19862
offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19863
gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19866
case OPC_MSA: /* OPC_MDMX */
19867
/* MDMX: Not implemented. */
19871
check_insn(ctx, ISA_MIPS32R6);
19872
gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19874
default: /* Invalid */
19875
MIPS_INVAL("major opcode");
19876
generate_exception_end(ctx, EXCP_RI);
19881
void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19883
MIPSCPU *cpu = mips_env_get_cpu(env);
19884
CPUState *cs = CPU(cpu);
19886
target_ulong pc_start;
19887
target_ulong next_page_start;
19894
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19897
ctx.singlestep_enabled = cs->singlestep_enabled;
19898
ctx.insn_flags = env->insn_flags;
19899
ctx.CP0_Config1 = env->CP0_Config1;
19901
ctx.bstate = BS_NONE;
19903
ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19904
ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19905
ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19906
ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19907
ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19908
ctx.PAMask = env->PAMask;
19909
ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19910
ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19911
ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19912
/* Restore delay slot state from the tb context. */
19913
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19914
ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19915
ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19916
(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19917
ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19918
ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
19919
ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
19920
ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
19921
restore_cpu_state(env, &ctx);
19922
#ifdef CONFIG_USER_ONLY
19923
ctx.mem_idx = MIPS_HFLAG_UM;
19925
ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19927
ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19928
MO_UNALN : MO_ALIGN;
19930
max_insns = tb->cflags & CF_COUNT_MASK;
19931
if (max_insns == 0) {
19932
max_insns = CF_COUNT_MASK;
19934
if (max_insns > TCG_MAX_INSNS) {
19935
max_insns = TCG_MAX_INSNS;
19938
LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19940
while (ctx.bstate == BS_NONE) {
19941
tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19944
if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19945
save_cpu_state(&ctx, 1);
19946
ctx.bstate = BS_BRANCH;
19947
gen_helper_raise_exception_debug(cpu_env);
19948
/* The address covered by the breakpoint must be included in
19949
[tb->pc, tb->pc + tb->size) in order to for it to be
19950
properly cleared -- thus we increment the PC here so that
19951
the logic setting tb->size below does the right thing. */
19953
goto done_generating;
19956
if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19960
is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19961
if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19962
ctx.opcode = cpu_ldl_code(env, ctx.pc);
19964
decode_opc(env, &ctx);
19965
} else if (ctx.insn_flags & ASE_MICROMIPS) {
19966
ctx.opcode = cpu_lduw_code(env, ctx.pc);
19967
insn_bytes = decode_micromips_opc(env, &ctx);
19968
} else if (ctx.insn_flags & ASE_MIPS16) {
19969
ctx.opcode = cpu_lduw_code(env, ctx.pc);
19970
insn_bytes = decode_mips16_opc(env, &ctx);
19972
generate_exception_end(&ctx, EXCP_RI);
19976
if (ctx.hflags & MIPS_HFLAG_BMASK) {
19977
if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19978
MIPS_HFLAG_FBNSLOT))) {
19979
/* force to generate branch as there is neither delay nor
19983
if ((ctx.hflags & MIPS_HFLAG_M16) &&
19984
(ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19985
/* Force to generate branch as microMIPS R6 doesn't restrict
19986
branches in the forbidden slot. */
19991
gen_branch(&ctx, insn_bytes);
19993
ctx.pc += insn_bytes;
19995
/* Execute a branch and its delay slot as a single instruction.
19996
This is what GDB expects and is consistent with what the
19997
hardware does (e.g. if a delay slot instruction faults, the
19998
reported PC is the PC of the branch). */
19999
if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
20003
if (ctx.pc >= next_page_start) {
20007
if (tcg_op_buf_full()) {
20011
if (num_insns >= max_insns)
20017
if (tb->cflags & CF_LAST_IO) {
20020
if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
20021
save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
20022
gen_helper_raise_exception_debug(cpu_env);
20024
switch (ctx.bstate) {
20026
gen_goto_tb(&ctx, 0, ctx.pc);
20029
save_cpu_state(&ctx, 0);
20030
gen_goto_tb(&ctx, 0, ctx.pc);
20033
tcg_gen_exit_tb(0);
20041
gen_tb_end(tb, num_insns);
20043
tb->size = ctx.pc - pc_start;
20044
tb->icount = num_insns;
20048
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20049
&& qemu_log_in_addr_range(pc_start)) {
20051
qemu_log("IN: %s\n", lookup_symbol(pc_start));
20052
log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
20059
static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
20063
int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
20065
#define printfpr(fp) \
20068
fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20069
" fd:%13g fs:%13g psu: %13g\n", \
20070
(fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20071
(double)(fp)->fd, \
20072
(double)(fp)->fs[FP_ENDIAN_IDX], \
20073
(double)(fp)->fs[!FP_ENDIAN_IDX]); \
20076
tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20077
tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20078
fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20079
" fd:%13g fs:%13g psu:%13g\n", \
20080
tmp.w[FP_ENDIAN_IDX], tmp.d, \
20082
(double)tmp.fs[FP_ENDIAN_IDX], \
20083
(double)tmp.fs[!FP_ENDIAN_IDX]); \
20088
fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20089
env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
20090
get_float_exception_flags(&env->active_fpu.fp_status));
20091
for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20092
fpu_fprintf(f, "%3s: ", fregnames[i]);
20093
printfpr(&env->active_fpu.fpr[i]);
20099
void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20102
MIPSCPU *cpu = MIPS_CPU(cs);
20103
CPUMIPSState *env = &cpu->env;
20106
cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20107
" LO=0x" TARGET_FMT_lx " ds %04x "
20108
TARGET_FMT_lx " " TARGET_FMT_ld "\n",
20109
env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20110
env->hflags, env->btarget, env->bcond);
20111
for (i = 0; i < 32; i++) {
20113
cpu_fprintf(f, "GPR%02d:", i);
20114
cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
20116
cpu_fprintf(f, "\n");
20119
cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
20120
env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
20121
cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20123
env->CP0_Config0, env->CP0_Config1, env->lladdr);
20124
cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20125
env->CP0_Config2, env->CP0_Config3);
20126
cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20127
env->CP0_Config4, env->CP0_Config5);
20128
if (env->hflags & MIPS_HFLAG_FPU)
20129
fpu_dump_state(env, f, cpu_fprintf, flags);
20132
void mips_tcg_init(void)
20137
/* Initialize various static tables. */
20141
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
20142
tcg_ctx.tcg_env = cpu_env;
20144
TCGV_UNUSED(cpu_gpr[0]);
20145
for (i = 1; i < 32; i++)
20146
cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20147
offsetof(CPUMIPSState, active_tc.gpr[i]),
20150
for (i = 0; i < 32; i++) {
20151
int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20153
tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20154
/* The scalar floating-point unit (FPU) registers are mapped on
20155
* the MSA vector registers. */
20156
fpu_f64[i] = msa_wr_d[i * 2];
20157
off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20158
msa_wr_d[i * 2 + 1] =
20159
tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20162
cpu_PC = tcg_global_mem_new(cpu_env,
20163
offsetof(CPUMIPSState, active_tc.PC), "PC");
20164
for (i = 0; i < MIPS_DSP_ACC; i++) {
20165
cpu_HI[i] = tcg_global_mem_new(cpu_env,
20166
offsetof(CPUMIPSState, active_tc.HI[i]),
20168
cpu_LO[i] = tcg_global_mem_new(cpu_env,
20169
offsetof(CPUMIPSState, active_tc.LO[i]),
20172
cpu_dspctrl = tcg_global_mem_new(cpu_env,
20173
offsetof(CPUMIPSState, active_tc.DSPControl),
20175
bcond = tcg_global_mem_new(cpu_env,
20176
offsetof(CPUMIPSState, bcond), "bcond");
20177
btarget = tcg_global_mem_new(cpu_env,
20178
offsetof(CPUMIPSState, btarget), "btarget");
20179
hflags = tcg_global_mem_new_i32(cpu_env,
20180
offsetof(CPUMIPSState, hflags), "hflags");
20182
fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20183
offsetof(CPUMIPSState, active_fpu.fcr0),
20185
fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20186
offsetof(CPUMIPSState, active_fpu.fcr31),
20192
#include "translate_init.c"
20194
MIPSCPU *cpu_mips_init(const char *cpu_model)
20198
const mips_def_t *def;
20200
def = cpu_mips_find_by_name(cpu_model);
20203
cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20205
env->cpu_model = def;
20206
env->exception_base = (int32_t)0xBFC00000;
20208
#ifndef CONFIG_USER_ONLY
20209
mmu_init(env, def);
20211
fpu_init(env, def);
20212
mvp_init(env, def);
20214
object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20219
bool cpu_supports_cps_smp(const char *cpu_model)
20221
const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20226
return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20229
void cpu_set_exception_base(int vp_index, target_ulong address)
20231
MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20232
vp->env.exception_base = address;
20235
void cpu_state_reset(CPUMIPSState *env)
20237
MIPSCPU *cpu = mips_env_get_cpu(env);
20238
CPUState *cs = CPU(cpu);
20240
/* Reset registers to their default values */
20241
env->CP0_PRid = env->cpu_model->CP0_PRid;
20242
env->CP0_Config0 = env->cpu_model->CP0_Config0;
20243
#ifdef TARGET_WORDS_BIGENDIAN
20244
env->CP0_Config0 |= (1 << CP0C0_BE);
20246
env->CP0_Config1 = env->cpu_model->CP0_Config1;
20247
env->CP0_Config2 = env->cpu_model->CP0_Config2;
20248
env->CP0_Config3 = env->cpu_model->CP0_Config3;
20249
env->CP0_Config4 = env->cpu_model->CP0_Config4;
20250
env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20251
env->CP0_Config5 = env->cpu_model->CP0_Config5;
20252
env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20253
env->CP0_Config6 = env->cpu_model->CP0_Config6;
20254
env->CP0_Config7 = env->cpu_model->CP0_Config7;
20255
env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20256
<< env->cpu_model->CP0_LLAddr_shift;
20257
env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20258
env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20259
env->CCRes = env->cpu_model->CCRes;
20260
env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20261
env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20262
env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20263
env->current_tc = 0;
20264
env->SEGBITS = env->cpu_model->SEGBITS;
20265
env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20266
#if defined(TARGET_MIPS64)
20267
if (env->cpu_model->insn_flags & ISA_MIPS3) {
20268
env->SEGMask |= 3ULL << 62;
20271
env->PABITS = env->cpu_model->PABITS;
20272
env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20273
env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20274
env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20275
env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20276
env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20277
env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20278
env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20279
env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20280
env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20281
env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20282
env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20283
env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20284
env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20285
env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
20286
env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20287
env->msair = env->cpu_model->MSAIR;
20288
env->insn_flags = env->cpu_model->insn_flags;
20290
#if defined(CONFIG_USER_ONLY)
20291
env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20292
# ifdef TARGET_MIPS64
20293
/* Enable 64-bit register mode. */
20294
env->CP0_Status |= (1 << CP0St_PX);
20296
# ifdef TARGET_ABI_MIPSN64
20297
/* Enable 64-bit address mode. */
20298
env->CP0_Status |= (1 << CP0St_UX);
20300
/* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20301
hardware registers. */
20302
env->CP0_HWREna |= 0x0000000F;
20303
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20304
env->CP0_Status |= (1 << CP0St_CU1);
20306
if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20307
env->CP0_Status |= (1 << CP0St_MX);
20309
# if defined(TARGET_MIPS64)
20310
/* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20311
if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20312
(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20313
env->CP0_Status |= (1 << CP0St_FR);
20317
if (env->hflags & MIPS_HFLAG_BMASK) {
20318
/* If the exception was raised from a delay slot,
20319
come back to the jump. */
20320
env->CP0_ErrorEPC = (env->active_tc.PC
20321
- (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20323
env->CP0_ErrorEPC = env->active_tc.PC;
20325
env->active_tc.PC = env->exception_base;
20326
env->CP0_Random = env->tlb->nb_tlb - 1;
20327
env->tlb->tlb_in_use = env->tlb->nb_tlb;
20328
env->CP0_Wired = 0;
20329
env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20330
env->CP0_EBase = (cs->cpu_index & 0x3FF);
20331
if (kvm_enabled()) {
20332
env->CP0_EBase |= 0x40000000;
20334
env->CP0_EBase |= 0x80000000;
20336
if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20337
env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20339
env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20341
env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20342
/* vectored interrupts not implemented, timer on int 7,
20343
no performance counters. */
20344
env->CP0_IntCtl = 0xe0000000;
20348
for (i = 0; i < 7; i++) {
20349
env->CP0_WatchLo[i] = 0;
20350
env->CP0_WatchHi[i] = 0x80000000;
20352
env->CP0_WatchLo[7] = 0;
20353
env->CP0_WatchHi[7] = 0;
20355
/* Count register increments in debug mode, EJTAG version 1 */
20356
env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20358
cpu_mips_store_count(env, 1);
20360
if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20363
/* Only TC0 on VPE 0 starts as active. */
20364
for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20365
env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20366
env->tcs[i].CP0_TCHalt = 1;
20368
env->active_tc.CP0_TCHalt = 1;
20371
if (cs->cpu_index == 0) {
20372
/* VPE0 starts up enabled. */
20373
env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20374
env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20376
/* TC0 starts up unhalted. */
20378
env->active_tc.CP0_TCHalt = 0;
20379
env->tcs[0].CP0_TCHalt = 0;
20380
/* With thread 0 active. */
20381
env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20382
env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20386
if ((env->insn_flags & ISA_MIPS32R6) &&
20387
(env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20388
/* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20389
env->CP0_Status |= (1 << CP0St_FR);
20393
if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20397
compute_hflags(env);
20398
restore_fp_status(env);
20399
restore_pamask(env);
20400
cs->exception_index = EXCP_NONE;
20402
if (semihosting_get_argc()) {
20403
/* UHI interface can be used to obtain argc and argv */
20404
env->active_tc.gpr[4] = -1;
20408
void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20409
target_ulong *data)
20411
env->active_tc.PC = data[0];
20412
env->hflags &= ~MIPS_HFLAG_BMASK;
20413
env->hflags |= data[1];
20414
switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20415
case MIPS_HFLAG_BR:
20417
case MIPS_HFLAG_BC:
20418
case MIPS_HFLAG_BL:
20420
env->btarget = data[2];