master
inc 3,236 lines 93.2 KB
Raw
1 /*
2 * microMIPS translation routines
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 *
9 * SPDX-License-Identifier: LGPL-2.1-or-later
10 */
11
12 /*
13 * microMIPS32/microMIPS64 major opcodes
14 *
15 * 1. MIPS Architecture for Programmers Volume II-B:
16 * The microMIPS32 Instruction Set (Revision 3.05)
17 *
18 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
19 *
20 * 2. MIPS Architecture For Programmers Volume II-A:
21 * The MIPS64 Instruction Set (Revision 3.51)
22 */
23
24 enum {
25 POOL32A = 0x00,
26 POOL16A = 0x01,
27 LBU16 = 0x02,
28 MOVE16 = 0x03,
29 ADDI32 = 0x04,
30 R6_LUI = 0x04,
31 AUI = 0x04,
32 LBU32 = 0x05,
33 SB32 = 0x06,
34 LB32 = 0x07,
35
36 POOL32B = 0x08,
37 POOL16B = 0x09,
38 LHU16 = 0x0a,
39 ANDI16 = 0x0b,
40 ADDIU32 = 0x0c,
41 LHU32 = 0x0d,
42 SH32 = 0x0e,
43 LH32 = 0x0f,
44
45 POOL32I = 0x10,
46 POOL16C = 0x11,
47 LWSP16 = 0x12,
48 POOL16D = 0x13,
49 ORI32 = 0x14,
50 POOL32F = 0x15,
51 POOL32S = 0x16, /* MIPS64 */
52 DADDIU32 = 0x17, /* MIPS64 */
53
54 POOL32C = 0x18,
55 LWGP16 = 0x19,
56 LW16 = 0x1a,
57 POOL16E = 0x1b,
58 XORI32 = 0x1c,
59 JALS32 = 0x1d,
60 BOVC = 0x1d,
61 BEQC = 0x1d,
62 BEQZALC = 0x1d,
63 ADDIUPC = 0x1e,
64 PCREL = 0x1e,
65 BNVC = 0x1f,
66 BNEC = 0x1f,
67 BNEZALC = 0x1f,
68
69 R6_BEQZC = 0x20,
70 JIC = 0x20,
71 POOL16F = 0x21,
72 SB16 = 0x22,
73 BEQZ16 = 0x23,
74 BEQZC16 = 0x23,
75 SLTI32 = 0x24,
76 BEQ32 = 0x25,
77 BC = 0x25,
78 SWC132 = 0x26,
79 LWC132 = 0x27,
80
81 /* 0x29 is reserved */
82 RES_29 = 0x29,
83 R6_BNEZC = 0x28,
84 JIALC = 0x28,
85 SH16 = 0x2a,
86 BNEZ16 = 0x2b,
87 BNEZC16 = 0x2b,
88 SLTIU32 = 0x2c,
89 BNE32 = 0x2d,
90 BALC = 0x2d,
91 SDC132 = 0x2e,
92 LDC132 = 0x2f,
93
94 /* 0x31 is reserved */
95 RES_31 = 0x31,
96 BLEZALC = 0x30,
97 BGEZALC = 0x30,
98 BGEUC = 0x30,
99 SWSP16 = 0x32,
100 B16 = 0x33,
101 BC16 = 0x33,
102 ANDI32 = 0x34,
103 J32 = 0x35,
104 BGTZC = 0x35,
105 BLTZC = 0x35,
106 BLTC = 0x35,
107 SD32 = 0x36, /* MIPS64 */
108 LD32 = 0x37, /* MIPS64 */
109
110 /* 0x39 is reserved */
111 RES_39 = 0x39,
112 BGTZALC = 0x38,
113 BLTZALC = 0x38,
114 BLTUC = 0x38,
115 SW16 = 0x3a,
116 LI16 = 0x3b,
117 JALX32 = 0x3c,
118 JAL32 = 0x3d,
119 BLEZC = 0x3d,
120 BGEZC = 0x3d,
121 BGEC = 0x3d,
122 SW32 = 0x3e,
123 LW32 = 0x3f
124 };
125
126 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
127 enum {
128 ADDIUPC_00 = 0x00,
129 ADDIUPC_01 = 0x01,
130 ADDIUPC_02 = 0x02,
131 ADDIUPC_03 = 0x03,
132 ADDIUPC_04 = 0x04,
133 ADDIUPC_05 = 0x05,
134 ADDIUPC_06 = 0x06,
135 ADDIUPC_07 = 0x07,
136 AUIPC = 0x1e,
137 ALUIPC = 0x1f,
138 LWPC_08 = 0x08,
139 LWPC_09 = 0x09,
140 LWPC_0A = 0x0A,
141 LWPC_0B = 0x0B,
142 LWPC_0C = 0x0C,
143 LWPC_0D = 0x0D,
144 LWPC_0E = 0x0E,
145 LWPC_0F = 0x0F,
146 };
147
148 /* POOL32A encoding of minor opcode field */
149
150 enum {
151 /*
152 * These opcodes are distinguished only by bits 9..6; those bits are
153 * what are recorded below.
154 */
155 SLL32 = 0x0,
156 SRL32 = 0x1,
157 SRA = 0x2,
158 ROTR = 0x3,
159 SELEQZ = 0x5,
160 SELNEZ = 0x6,
161 R6_RDHWR = 0x7,
162
163 SLLV = 0x0,
164 SRLV = 0x1,
165 SRAV = 0x2,
166 ROTRV = 0x3,
167 ADD = 0x4,
168 ADDU32 = 0x5,
169 SUB = 0x6,
170 SUBU32 = 0x7,
171 MUL = 0x8,
172 AND = 0x9,
173 OR32 = 0xa,
174 NOR = 0xb,
175 XOR32 = 0xc,
176 SLT = 0xd,
177 SLTU = 0xe,
178
179 MOVN = 0x0,
180 R6_MUL = 0x0,
181 MOVZ = 0x1,
182 MUH = 0x1,
183 MULU = 0x2,
184 MUHU = 0x3,
185 LWXS = 0x4,
186 R6_DIV = 0x4,
187 MOD = 0x5,
188 R6_DIVU = 0x6,
189 MODU = 0x7,
190
191 /* The following can be distinguished by their lower 6 bits. */
192 BREAK32 = 0x07,
193 INS = 0x0c,
194 LSA = 0x0f,
195 ALIGN = 0x1f,
196 EXT = 0x2c,
197 POOL32AXF = 0x3c,
198 SIGRIE = 0x3f
199 };
200
201 /* POOL32AXF encoding of minor opcode field extension */
202
203 /*
204 * 1. MIPS Architecture for Programmers Volume II-B:
205 * The microMIPS32 Instruction Set (Revision 3.05)
206 *
207 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
208 *
209 * 2. MIPS Architecture for Programmers VolumeIV-e:
210 * The MIPS DSP Application-Specific Extension
211 * to the microMIPS32 Architecture (Revision 2.34)
212 *
213 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
214 */
215
216 enum {
217 /* bits 11..6 */
218 TEQ = 0x00,
219 TGE = 0x08,
220 TGEU = 0x10,
221 TLT = 0x20,
222 TLTU = 0x28,
223 TNE = 0x30,
224
225 MFC0 = 0x03,
226 MTC0 = 0x0b,
227
228 /* begin of microMIPS32 DSP */
229
230 /* bits 13..12 for 0x01 */
231 MFHI_ACC = 0x0,
232 MFLO_ACC = 0x1,
233 MTHI_ACC = 0x2,
234 MTLO_ACC = 0x3,
235
236 /* bits 13..12 for 0x2a */
237 MADD_ACC = 0x0,
238 MADDU_ACC = 0x1,
239 MSUB_ACC = 0x2,
240 MSUBU_ACC = 0x3,
241
242 /* bits 13..12 for 0x32 */
243 MULT_ACC = 0x0,
244 MULTU_ACC = 0x1,
245
246 /* end of microMIPS32 DSP */
247
248 /* bits 15..12 for 0x2c */
249 BITSWAP = 0x0,
250 SEB = 0x2,
251 SEH = 0x3,
252 CLO = 0x4,
253 CLZ = 0x5,
254 RDHWR = 0x6,
255 WSBH = 0x7,
256 MULT = 0x8,
257 MULTU = 0x9,
258 DIV = 0xa,
259 DIVU = 0xb,
260 MADD = 0xc,
261 MADDU = 0xd,
262 MSUB = 0xe,
263 MSUBU = 0xf,
264
265 /* bits 15..12 for 0x34 */
266 MFC2 = 0x4,
267 MTC2 = 0x5,
268 MFHC2 = 0x8,
269 MTHC2 = 0x9,
270 CFC2 = 0xc,
271 CTC2 = 0xd,
272
273 /* bits 15..12 for 0x3c */
274 JALR = 0x0,
275 JR = 0x0, /* alias */
276 JALRC = 0x0,
277 JRC = 0x0,
278 JALR_HB = 0x1,
279 JALRC_HB = 0x1,
280 JALRS = 0x4,
281 JALRS_HB = 0x5,
282
283 /* bits 15..12 for 0x05 */
284 RDPGPR = 0xe,
285 WRPGPR = 0xf,
286
287 /* bits 15..12 for 0x0d */
288 TLBP = 0x0,
289 TLBR = 0x1,
290 TLBWI = 0x2,
291 TLBWR = 0x3,
292 TLBINV = 0x4,
293 TLBINVF = 0x5,
294 WAIT = 0x9,
295 IRET = 0xd,
296 DERET = 0xe,
297 ERET = 0xf,
298
299 /* bits 15..12 for 0x15 */
300 DMT = 0x0,
301 DVPE = 0x1,
302 EMT = 0x2,
303 EVPE = 0x3,
304
305 /* bits 15..12 for 0x1d */
306 DI = 0x4,
307 EI = 0x5,
308
309 /* bits 15..12 for 0x2d */
310 SYNC = 0x6,
311 SYSCALL = 0x8,
312 SDBBP = 0xd,
313
314 /* bits 15..12 for 0x35 */
315 MFHI32 = 0x0,
316 MFLO32 = 0x1,
317 MTHI32 = 0x2,
318 MTLO32 = 0x3,
319 };
320
321 /* POOL32B encoding of minor opcode field (bits 15..12) */
322
323 enum {
324 LWC2 = 0x0,
325 LWP = 0x1,
326 LDP = 0x4,
327 LWM32 = 0x5,
328 CACHE = 0x6,
329 LDM = 0x7,
330 SWC2 = 0x8,
331 SWP = 0x9,
332 SDP = 0xc,
333 SWM32 = 0xd,
334 SDM = 0xf
335 };
336
337 /* POOL32C encoding of minor opcode field (bits 15..12) */
338
339 enum {
340 LWL = 0x0,
341 SWL = 0x8,
342 LWR = 0x1,
343 SWR = 0x9,
344 PREF = 0x2,
345 ST_EVA = 0xa,
346 LL = 0x3,
347 SC = 0xb,
348 LDL = 0x4,
349 SDL = 0xc,
350 LDR = 0x5,
351 SDR = 0xd,
352 LD_EVA = 0x6,
353 LWU = 0xe,
354 LLD = 0x7,
355 SCD = 0xf
356 };
357
358 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
359
360 enum {
361 LBUE = 0x0,
362 LHUE = 0x1,
363 LWLE = 0x2,
364 LWRE = 0x3,
365 LBE = 0x4,
366 LHE = 0x5,
367 LLE = 0x6,
368 LWE = 0x7,
369 };
370
371 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
372
373 enum {
374 SWLE = 0x0,
375 SWRE = 0x1,
376 PREFE = 0x2,
377 CACHEE = 0x3,
378 SBE = 0x4,
379 SHE = 0x5,
380 SCE = 0x6,
381 SWE = 0x7,
382 };
383
384 /* POOL32F encoding of minor opcode field (bits 5..0) */
385
386 enum {
387 /* These are the bit 7..6 values */
388 ADD_FMT = 0x0,
389
390 SUB_FMT = 0x1,
391
392 MUL_FMT = 0x2,
393
394 DIV_FMT = 0x3,
395
396 /* These are the bit 8..6 values */
397 MOVN_FMT = 0x0,
398 RSQRT2_FMT = 0x0,
399 MOVF_FMT = 0x0,
400 RINT_FMT = 0x0,
401 SELNEZ_FMT = 0x0,
402
403 MOVZ_FMT = 0x1,
404 LWXC1 = 0x1,
405 MOVT_FMT = 0x1,
406 CLASS_FMT = 0x1,
407 SELEQZ_FMT = 0x1,
408
409 PLL_PS = 0x2,
410 SWXC1 = 0x2,
411 SEL_FMT = 0x2,
412
413 PLU_PS = 0x3,
414 LDXC1 = 0x3,
415
416 MOVN_FMT_04 = 0x4,
417 PUL_PS = 0x4,
418 SDXC1 = 0x4,
419 RECIP2_FMT = 0x4,
420
421 MOVZ_FMT_05 = 0x05,
422 PUU_PS = 0x5,
423 LUXC1 = 0x5,
424
425 CVT_PS_S = 0x6,
426 SUXC1 = 0x6,
427 ADDR_PS = 0x6,
428 PREFX = 0x6,
429 MADDF_FMT = 0x6,
430
431 MULR_PS = 0x7,
432 MSUBF_FMT = 0x7,
433
434 MADD_S = 0x01,
435 MADD_D = 0x09,
436 MADD_PS = 0x11,
437 ALNV_PS = 0x19,
438 MSUB_S = 0x21,
439 MSUB_D = 0x29,
440 MSUB_PS = 0x31,
441
442 NMADD_S = 0x02,
443 NMADD_D = 0x0a,
444 NMADD_PS = 0x12,
445 NMSUB_S = 0x22,
446 NMSUB_D = 0x2a,
447 NMSUB_PS = 0x32,
448
449 MIN_FMT = 0x3,
450 MAX_FMT = 0xb,
451 MINA_FMT = 0x23,
452 MAXA_FMT = 0x2b,
453 POOL32FXF = 0x3b,
454
455 CABS_COND_FMT = 0x1c, /* MIPS3D */
456 C_COND_FMT = 0x3c,
457
458 CMP_CONDN_S = 0x5,
459 CMP_CONDN_D = 0x15
460 };
461
462 /* POOL32Fxf encoding of minor opcode extension field */
463
464 enum {
465 CVT_L = 0x04,
466 RSQRT_FMT = 0x08,
467 FLOOR_L = 0x0c,
468 CVT_PW_PS = 0x1c,
469 CVT_W = 0x24,
470 SQRT_FMT = 0x28,
471 FLOOR_W = 0x2c,
472 CVT_PS_PW = 0x3c,
473 CFC1 = 0x40,
474 RECIP_FMT = 0x48,
475 CEIL_L = 0x4c,
476 CTC1 = 0x60,
477 CEIL_W = 0x6c,
478 MFC1 = 0x80,
479 CVT_S_PL = 0x84,
480 TRUNC_L = 0x8c,
481 MTC1 = 0xa0,
482 CVT_S_PU = 0xa4,
483 TRUNC_W = 0xac,
484 MFHC1 = 0xc0,
485 ROUND_L = 0xcc,
486 MTHC1 = 0xe0,
487 ROUND_W = 0xec,
488
489 MOV_FMT = 0x01,
490 MOVF = 0x05,
491 ABS_FMT = 0x0d,
492 RSQRT1_FMT = 0x1d,
493 MOVT = 0x25,
494 NEG_FMT = 0x2d,
495 CVT_D = 0x4d,
496 RECIP1_FMT = 0x5d,
497 CVT_S = 0x6d
498 };
499
500 /* POOL32I encoding of minor opcode field (bits 25..21) */
501
502 enum {
503 BLTZ = 0x00,
504 BLTZAL = 0x01,
505 BGEZ = 0x02,
506 BGEZAL = 0x03,
507 BLEZ = 0x04,
508 BNEZC = 0x05,
509 BGTZ = 0x06,
510 BEQZC = 0x07,
511 TLTI = 0x08,
512 BC1EQZC = 0x08,
513 TGEI = 0x09,
514 BC1NEZC = 0x09,
515 TLTIU = 0x0a,
516 BC2EQZC = 0x0a,
517 TGEIU = 0x0b,
518 BC2NEZC = 0x0a,
519 TNEI = 0x0c,
520 R6_SYNCI = 0x0c,
521 LUI = 0x0d,
522 TEQI = 0x0e,
523 SYNCI = 0x10,
524 BLTZALS = 0x11,
525 BGEZALS = 0x13,
526 BC2F = 0x14,
527 BC2T = 0x15,
528 /* These overlap and are distinguished by bit16 of the instruction */
529 BC1F = 0x1c,
530 BC1T = 0x1d,
531 BC1ANY2F = 0x1c,
532 BC1ANY2T = 0x1d,
533 BC1ANY4F = 0x1e,
534 BC1ANY4T = 0x1f
535 };
536
537 /* POOL16A encoding of minor opcode field */
538
539 enum {
540 ADDU16 = 0x0,
541 SUBU16 = 0x1
542 };
543
544 /* POOL16B encoding of minor opcode field */
545
546 enum {
547 SLL16 = 0x0,
548 SRL16 = 0x1
549 };
550
551 /* POOL16C encoding of minor opcode field */
552
553 enum {
554 NOT16 = 0x00,
555 XOR16 = 0x04,
556 AND16 = 0x08,
557 OR16 = 0x0c,
558 LWM16 = 0x10,
559 SWM16 = 0x14,
560 JR16 = 0x18,
561 JRC16 = 0x1a,
562 JALR16 = 0x1c,
563 JALR16S = 0x1e,
564 MFHI16 = 0x20,
565 MFLO16 = 0x24,
566 BREAK16 = 0x28,
567 SDBBP16 = 0x2c,
568 JRADDIUSP = 0x30
569 };
570
571 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
572
573 enum {
574 R6_NOT16 = 0x00,
575 R6_AND16 = 0x01,
576 R6_LWM16 = 0x02,
577 R6_JRC16 = 0x03,
578 MOVEP = 0x04,
579 MOVEP_05 = 0x05,
580 MOVEP_06 = 0x06,
581 MOVEP_07 = 0x07,
582 R6_XOR16 = 0x08,
583 R6_OR16 = 0x09,
584 R6_SWM16 = 0x0a,
585 JALRC16 = 0x0b,
586 MOVEP_0C = 0x0c,
587 MOVEP_0D = 0x0d,
588 MOVEP_0E = 0x0e,
589 MOVEP_0F = 0x0f,
590 JRCADDIUSP = 0x13,
591 R6_BREAK16 = 0x1b,
592 R6_SDBBP16 = 0x3b
593 };
594
595 /* POOL16D encoding of minor opcode field */
596
597 enum {
598 ADDIUS5 = 0x0,
599 ADDIUSP = 0x1
600 };
601
602 /* POOL16E encoding of minor opcode field */
603
604 enum {
605 ADDIUR2 = 0x0,
606 ADDIUR1SP = 0x1
607 };
608
609 static int mmreg(int r)
610 {
611 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
612
613 return map[r];
614 }
615
616 /* Used for 16-bit store instructions. */
617 static int mmreg2(int r)
618 {
619 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
620
621 return map[r];
622 }
623
624 #define uMIPS_RD(op) ((op >> 7) & 0x7)
625 #define uMIPS_RS(op) ((op >> 4) & 0x7)
626 #define uMIPS_RS2(op) uMIPS_RS(op)
627 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
628 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
629 #define uMIPS_RS5(op) (op & 0x1f)
630
631 /* Signed immediate */
632 #define SIMM(op, start, width) \
633 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
634 << (32 - width)) \
635 >> (32 - width))
636 /* Zero-extended immediate */
637 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
638
639 static void gen_addiur1sp(DisasContext *ctx)
640 {
641 int rd = mmreg(uMIPS_RD(ctx->opcode));
642
643 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
644 }
645
646 static void gen_addiur2(DisasContext *ctx)
647 {
648 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
649 int rd = mmreg(uMIPS_RD(ctx->opcode));
650 int rs = mmreg(uMIPS_RS(ctx->opcode));
651
652 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
653 }
654
655 static void gen_addiusp(DisasContext *ctx)
656 {
657 int encoded = ZIMM(ctx->opcode, 1, 9);
658 int decoded;
659
660 if (encoded <= 1) {
661 decoded = 256 + encoded;
662 } else if (encoded <= 255) {
663 decoded = encoded;
664 } else if (encoded <= 509) {
665 decoded = encoded - 512;
666 } else {
667 decoded = encoded - 768;
668 }
669
670 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
671 }
672
673 static void gen_addius5(DisasContext *ctx)
674 {
675 int imm = SIMM(ctx->opcode, 1, 4);
676 int rd = (ctx->opcode >> 5) & 0x1f;
677
678 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
679 }
680
681 static void gen_andi16(DisasContext *ctx)
682 {
683 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
684 31, 32, 63, 64, 255, 32768, 65535 };
685 int rd = mmreg(uMIPS_RD(ctx->opcode));
686 int rs = mmreg(uMIPS_RS(ctx->opcode));
687 int encoded = ZIMM(ctx->opcode, 0, 4);
688
689 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
690 }
691
692 static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
693 int base, int16_t offset)
694 {
695 TCGv t0, t1;
696 MemOp mop = ctx->default_tcg_memop_mask;
697 MemOpIdx oi;
698
699 if (ctx->hflags & MIPS_HFLAG_BMASK) {
700 gen_reserved_instruction(ctx);
701 return;
702 }
703
704 mop |= mo_endian(ctx);
705
706 t0 = tcg_temp_new();
707
708 gen_base_offset_addr(ctx, t0, base, offset);
709
710 t1 = tcg_constant_tl(reglist);
711
712 save_cpu_state(ctx, 1);
713 switch (opc) {
714 case LWM32:
715 oi = make_memop_idx(mop | MO_UL, ctx->mem_idx);
716 gen_helper_lwm(tcg_env, t0, t1, tcg_constant_i32(oi));
717 break;
718 case SWM32:
719 oi = make_memop_idx(mop | MO_UL, ctx->mem_idx);
720 gen_helper_swm(tcg_env, t0, t1, tcg_constant_i32(oi));
721 break;
722 #ifdef TARGET_MIPS64
723 case LDM:
724 oi = make_memop_idx(mop | MO_UQ, ctx->mem_idx);
725 gen_helper_ldm(tcg_env, t0, t1, tcg_constant_i32(oi));
726 break;
727 case SDM:
728 oi = make_memop_idx(mop | MO_UQ, ctx->mem_idx);
729 gen_helper_sdm(tcg_env, t0, t1, tcg_constant_i32(oi));
730 break;
731 #endif
732 }
733 }
734
735
736 static void gen_pool16c_insn(DisasContext *ctx)
737 {
738 int rd = mmreg((ctx->opcode >> 3) & 0x7);
739 int rs = mmreg(ctx->opcode & 0x7);
740
741 switch (((ctx->opcode) >> 4) & 0x3f) {
742 case NOT16 + 0:
743 case NOT16 + 1:
744 case NOT16 + 2:
745 case NOT16 + 3:
746 gen_logic(ctx, OPC_NOR, rd, rs, 0);
747 break;
748 case XOR16 + 0:
749 case XOR16 + 1:
750 case XOR16 + 2:
751 case XOR16 + 3:
752 gen_logic(ctx, OPC_XOR, rd, rd, rs);
753 break;
754 case AND16 + 0:
755 case AND16 + 1:
756 case AND16 + 2:
757 case AND16 + 3:
758 gen_logic(ctx, OPC_AND, rd, rd, rs);
759 break;
760 case OR16 + 0:
761 case OR16 + 1:
762 case OR16 + 2:
763 case OR16 + 3:
764 gen_logic(ctx, OPC_OR, rd, rd, rs);
765 break;
766 case LWM16 + 0:
767 case LWM16 + 1:
768 case LWM16 + 2:
769 case LWM16 + 3:
770 {
771 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
772 int offset = ZIMM(ctx->opcode, 0, 4);
773
774 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
775 29, offset << 2);
776 }
777 break;
778 case SWM16 + 0:
779 case SWM16 + 1:
780 case SWM16 + 2:
781 case SWM16 + 3:
782 {
783 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
784 int offset = ZIMM(ctx->opcode, 0, 4);
785
786 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
787 29, offset << 2);
788 }
789 break;
790 case JR16 + 0:
791 case JR16 + 1:
792 {
793 int reg = ctx->opcode & 0x1f;
794
795 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
796 }
797 break;
798 case JRC16 + 0:
799 case JRC16 + 1:
800 {
801 int reg = ctx->opcode & 0x1f;
802 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
803 /*
804 * Let normal delay slot handling in our caller take us
805 * to the branch target.
806 */
807 }
808 break;
809 case JALR16 + 0:
810 case JALR16 + 1:
811 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
812 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
813 break;
814 case JALR16S + 0:
815 case JALR16S + 1:
816 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
817 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
818 break;
819 case MFHI16 + 0:
820 case MFHI16 + 1:
821 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
822 break;
823 case MFLO16 + 0:
824 case MFLO16 + 1:
825 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
826 break;
827 case BREAK16:
828 generate_exception_break(ctx, extract32(ctx->opcode, 0, 4));
829 break;
830 case SDBBP16:
831 if (is_uhi(ctx, extract32(ctx->opcode, 0, 4))) {
832 ctx->base.is_jmp = DISAS_SEMIHOST;
833 } else {
834 /*
835 * XXX: not clear which exception should be raised
836 * when in debug mode...
837 */
838 check_insn(ctx, ISA_MIPS_R1);
839 generate_exception_end(ctx, EXCP_DBp);
840 }
841 break;
842 case JRADDIUSP + 0:
843 case JRADDIUSP + 1:
844 {
845 int imm = ZIMM(ctx->opcode, 0, 5);
846 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
847 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
848 /*
849 * Let normal delay slot handling in our caller take us
850 * to the branch target.
851 */
852 }
853 break;
854 default:
855 gen_reserved_instruction(ctx);
856 break;
857 }
858 }
859
860 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
861 int enc_rs)
862 {
863 int rd, re;
864 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
865 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
866 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
867
868 rd = rd_enc[enc_dest];
869 re = re_enc[enc_dest];
870 gen_load_gpr(cpu_gpr[rd], rs_rt_enc[enc_rs]);
871 gen_load_gpr(cpu_gpr[re], rs_rt_enc[enc_rt]);
872 }
873
874 static void gen_pool16c_r6_insn(DisasContext *ctx)
875 {
876 int rt = mmreg((ctx->opcode >> 7) & 0x7);
877 int rs = mmreg((ctx->opcode >> 4) & 0x7);
878
879 switch (ctx->opcode & 0xf) {
880 case R6_NOT16:
881 gen_logic(ctx, OPC_NOR, rt, rs, 0);
882 break;
883 case R6_AND16:
884 gen_logic(ctx, OPC_AND, rt, rt, rs);
885 break;
886 case R6_LWM16:
887 {
888 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
889 int offset = extract32(ctx->opcode, 4, 4);
890 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
891 }
892 break;
893 case R6_JRC16: /* JRCADDIUSP */
894 if ((ctx->opcode >> 4) & 1) {
895 /* JRCADDIUSP */
896 int imm = extract32(ctx->opcode, 5, 5);
897 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
898 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
899 } else {
900 /* JRC16 */
901 rs = extract32(ctx->opcode, 5, 5);
902 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
903 }
904 break;
905 case MOVEP:
906 case MOVEP_05:
907 case MOVEP_06:
908 case MOVEP_07:
909 case MOVEP_0C:
910 case MOVEP_0D:
911 case MOVEP_0E:
912 case MOVEP_0F:
913 {
914 int enc_dest = uMIPS_RD(ctx->opcode);
915 int enc_rt = uMIPS_RS2(ctx->opcode);
916 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
917 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
918 }
919 break;
920 case R6_XOR16:
921 gen_logic(ctx, OPC_XOR, rt, rt, rs);
922 break;
923 case R6_OR16:
924 gen_logic(ctx, OPC_OR, rt, rt, rs);
925 break;
926 case R6_SWM16:
927 {
928 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
929 int offset = extract32(ctx->opcode, 4, 4);
930 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
931 }
932 break;
933 case JALRC16: /* BREAK16, SDBBP16 */
934 switch (ctx->opcode & 0x3f) {
935 case JALRC16:
936 case JALRC16 + 0x20:
937 /* JALRC16 */
938 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
939 31, 0, 0);
940 break;
941 case R6_BREAK16:
942 /* BREAK16 */
943 generate_exception_break(ctx, extract32(ctx->opcode, 6, 4));
944 break;
945 case R6_SDBBP16:
946 /* SDBBP16 */
947 if (is_uhi(ctx, extract32(ctx->opcode, 6, 4))) {
948 ctx->base.is_jmp = DISAS_SEMIHOST;
949 } else {
950 if (ctx->hflags & MIPS_HFLAG_SBRI) {
951 generate_exception(ctx, EXCP_RI);
952 } else {
953 generate_exception(ctx, EXCP_DBp);
954 }
955 }
956 break;
957 }
958 break;
959 default:
960 generate_exception(ctx, EXCP_RI);
961 break;
962 }
963 }
964
965 static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
966 int base, int16_t offset)
967 {
968 TCGv t0, t1;
969
970 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
971 gen_reserved_instruction(ctx);
972 return;
973 }
974
975 t0 = tcg_temp_new();
976 t1 = tcg_temp_new();
977
978 gen_base_offset_addr(ctx, t0, base, offset);
979
980 switch (opc) {
981 case LWP:
982 if (rd == base) {
983 gen_reserved_instruction(ctx);
984 return;
985 }
986 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
987 ctx->default_tcg_memop_mask);
988 gen_store_gpr(t1, rd);
989 gen_op_addr_addi(ctx, t0, t0, 4);
990 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
991 ctx->default_tcg_memop_mask);
992 gen_store_gpr(t1, rd + 1);
993 break;
994 case SWP:
995 gen_load_gpr(t1, rd);
996 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
997 ctx->default_tcg_memop_mask);
998 gen_op_addr_addi(ctx, t0, t0, 4);
999 gen_load_gpr(t1, rd + 1);
1000 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
1001 ctx->default_tcg_memop_mask);
1002 break;
1003 #ifdef TARGET_MIPS64
1004 case LDP:
1005 if (rd == base) {
1006 gen_reserved_instruction(ctx);
1007 return;
1008 }
1009 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
1010 ctx->default_tcg_memop_mask);
1011 gen_store_gpr(t1, rd);
1012 gen_op_addr_addi(ctx, t0, t0, 8);
1013 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
1014 ctx->default_tcg_memop_mask);
1015 gen_store_gpr(t1, rd + 1);
1016 break;
1017 case SDP:
1018 gen_load_gpr(t1, rd);
1019 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
1020 ctx->default_tcg_memop_mask);
1021 gen_op_addr_addi(ctx, t0, t0, 8);
1022 gen_load_gpr(t1, rd + 1);
1023 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
1024 ctx->default_tcg_memop_mask);
1025 break;
1026 #endif
1027 }
1028 }
1029
1030 static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
1031 {
1032 int extension = (ctx->opcode >> 6) & 0x3f;
1033 int minor = (ctx->opcode >> 12) & 0xf;
1034 uint32_t mips32_op;
1035
1036 switch (extension) {
1037 case TEQ:
1038 mips32_op = OPC_TEQ;
1039 goto do_trap;
1040 case TGE:
1041 mips32_op = OPC_TGE;
1042 goto do_trap;
1043 case TGEU:
1044 mips32_op = OPC_TGEU;
1045 goto do_trap;
1046 case TLT:
1047 mips32_op = OPC_TLT;
1048 goto do_trap;
1049 case TLTU:
1050 mips32_op = OPC_TLTU;
1051 goto do_trap;
1052 case TNE:
1053 mips32_op = OPC_TNE;
1054 do_trap:
1055 gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));
1056 break;
1057 #ifndef CONFIG_USER_ONLY
1058 case MFC0:
1059 case MFC0 + 32:
1060 check_cp0_enabled(ctx);
1061 if (rt == 0) {
1062 /* Treat as NOP. */
1063 break;
1064 }
1065 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
1066 break;
1067 case MTC0:
1068 case MTC0 + 32:
1069 check_cp0_enabled(ctx);
1070 {
1071 TCGv t0 = tcg_temp_new();
1072
1073 gen_load_gpr(t0, rt);
1074 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
1075 }
1076 break;
1077 #endif
1078 case 0x2a:
1079 switch (minor & 3) {
1080 case MADD_ACC:
1081 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
1082 break;
1083 case MADDU_ACC:
1084 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
1085 break;
1086 case MSUB_ACC:
1087 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
1088 break;
1089 case MSUBU_ACC:
1090 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
1091 break;
1092 default:
1093 goto pool32axf_invalid;
1094 }
1095 break;
1096 case 0x32:
1097 switch (minor & 3) {
1098 case MULT_ACC:
1099 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
1100 break;
1101 case MULTU_ACC:
1102 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
1103 break;
1104 default:
1105 goto pool32axf_invalid;
1106 }
1107 break;
1108 case 0x2c:
1109 switch (minor) {
1110 case BITSWAP:
1111 check_insn(ctx, ISA_MIPS_R6);
1112 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
1113 break;
1114 case SEB:
1115 gen_bshfl(ctx, OPC_SEB, rs, rt);
1116 break;
1117 case SEH:
1118 gen_bshfl(ctx, OPC_SEH, rs, rt);
1119 break;
1120 case CLO:
1121 mips32_op = OPC_CLO;
1122 goto do_cl;
1123 case CLZ:
1124 mips32_op = OPC_CLZ;
1125 do_cl:
1126 check_insn(ctx, ISA_MIPS_R1);
1127 gen_cl(ctx, mips32_op, rt, rs);
1128 break;
1129 case RDHWR:
1130 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1131 gen_rdhwr(ctx, rt, rs, 0);
1132 break;
1133 case WSBH:
1134 gen_bshfl(ctx, OPC_WSBH, rs, rt);
1135 break;
1136 case MULT:
1137 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1138 mips32_op = OPC_MULT;
1139 goto do_mul;
1140 case MULTU:
1141 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1142 mips32_op = OPC_MULTU;
1143 goto do_mul;
1144 case DIV:
1145 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1146 mips32_op = OPC_DIV;
1147 goto do_div;
1148 case DIVU:
1149 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1150 mips32_op = OPC_DIVU;
1151 goto do_div;
1152 do_div:
1153 check_insn(ctx, ISA_MIPS_R1);
1154 gen_muldiv(ctx, mips32_op, 0, rs, rt);
1155 break;
1156 case MADD:
1157 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1158 mips32_op = OPC_MADD;
1159 goto do_mul;
1160 case MADDU:
1161 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1162 mips32_op = OPC_MADDU;
1163 goto do_mul;
1164 case MSUB:
1165 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1166 mips32_op = OPC_MSUB;
1167 goto do_mul;
1168 case MSUBU:
1169 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1170 mips32_op = OPC_MSUBU;
1171 do_mul:
1172 check_insn(ctx, ISA_MIPS_R1);
1173 gen_muldiv(ctx, mips32_op, 0, rs, rt);
1174 break;
1175 default:
1176 goto pool32axf_invalid;
1177 }
1178 break;
1179 case 0x34:
1180 switch (minor) {
1181 case MFC2:
1182 case MTC2:
1183 case MFHC2:
1184 case MTHC2:
1185 case CFC2:
1186 case CTC2:
1187 generate_exception_err(ctx, EXCP_CpU, 2);
1188 break;
1189 default:
1190 goto pool32axf_invalid;
1191 }
1192 break;
1193 case 0x3c:
1194 switch (minor) {
1195 case JALR: /* JALRC */
1196 case JALR_HB: /* JALRC_HB */
1197 if (ctx->insn_flags & ISA_MIPS_R6) {
1198 /* JALRC, JALRC_HB */
1199 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
1200 } else {
1201 /* JALR, JALR_HB */
1202 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
1203 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
1204 }
1205 break;
1206 case JALRS:
1207 case JALRS_HB:
1208 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1209 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
1210 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
1211 break;
1212 default:
1213 goto pool32axf_invalid;
1214 }
1215 break;
1216 case 0x05:
1217 switch (minor) {
1218 case RDPGPR:
1219 check_cp0_enabled(ctx);
1220 check_insn(ctx, ISA_MIPS_R2);
1221 gen_load_srsgpr(rs, rt);
1222 break;
1223 case WRPGPR:
1224 check_cp0_enabled(ctx);
1225 check_insn(ctx, ISA_MIPS_R2);
1226 gen_store_srsgpr(rs, rt);
1227 break;
1228 default:
1229 goto pool32axf_invalid;
1230 }
1231 break;
1232 #ifndef CONFIG_USER_ONLY
1233 case 0x0d:
1234 switch (minor) {
1235 case TLBP:
1236 mips32_op = OPC_TLBP;
1237 goto do_cp0;
1238 case TLBR:
1239 mips32_op = OPC_TLBR;
1240 goto do_cp0;
1241 case TLBWI:
1242 mips32_op = OPC_TLBWI;
1243 goto do_cp0;
1244 case TLBWR:
1245 mips32_op = OPC_TLBWR;
1246 goto do_cp0;
1247 case TLBINV:
1248 mips32_op = OPC_TLBINV;
1249 goto do_cp0;
1250 case TLBINVF:
1251 mips32_op = OPC_TLBINVF;
1252 goto do_cp0;
1253 case WAIT:
1254 mips32_op = OPC_WAIT;
1255 goto do_cp0;
1256 case DERET:
1257 mips32_op = OPC_DERET;
1258 goto do_cp0;
1259 case ERET:
1260 mips32_op = OPC_ERET;
1261 do_cp0:
1262 gen_cp0(env, ctx, mips32_op, rt, rs);
1263 break;
1264 default:
1265 goto pool32axf_invalid;
1266 }
1267 break;
1268 case 0x1d:
1269 switch (minor) {
1270 case DI:
1271 check_cp0_enabled(ctx);
1272 {
1273 TCGv t0 = tcg_temp_new();
1274
1275 save_cpu_state(ctx, 1);
1276 gen_helper_di(t0, tcg_env);
1277 gen_store_gpr(t0, rs);
1278 /*
1279 * Stop translation as we may have switched the execution
1280 * mode.
1281 */
1282 ctx->base.is_jmp = DISAS_STOP;
1283 }
1284 break;
1285 case EI:
1286 check_cp0_enabled(ctx);
1287 {
1288 TCGv t0 = tcg_temp_new();
1289
1290 save_cpu_state(ctx, 1);
1291 gen_helper_ei(t0, tcg_env);
1292 gen_store_gpr(t0, rs);
1293 /*
1294 * DISAS_STOP isn't sufficient, we need to ensure we break out
1295 * of translated code to check for pending interrupts.
1296 */
1297 gen_save_pc(ctx->base.pc_next + 4);
1298 ctx->base.is_jmp = DISAS_EXIT;
1299 }
1300 break;
1301 default:
1302 goto pool32axf_invalid;
1303 }
1304 break;
1305 #endif
1306 case 0x2d:
1307 switch (minor) {
1308 case SYNC:
1309 gen_sync(extract32(ctx->opcode, 16, 5));
1310 break;
1311 case SYSCALL:
1312 generate_exception_end(ctx, EXCP_SYSCALL);
1313 break;
1314 case SDBBP:
1315 if (is_uhi(ctx, extract32(ctx->opcode, 16, 10))) {
1316 ctx->base.is_jmp = DISAS_SEMIHOST;
1317 } else {
1318 check_insn(ctx, ISA_MIPS_R1);
1319 if (ctx->hflags & MIPS_HFLAG_SBRI) {
1320 gen_reserved_instruction(ctx);
1321 } else {
1322 generate_exception_end(ctx, EXCP_DBp);
1323 }
1324 }
1325 break;
1326 default:
1327 goto pool32axf_invalid;
1328 }
1329 break;
1330 case 0x01:
1331 switch (minor & 3) {
1332 case MFHI_ACC:
1333 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
1334 break;
1335 case MFLO_ACC:
1336 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
1337 break;
1338 case MTHI_ACC:
1339 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
1340 break;
1341 case MTLO_ACC:
1342 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
1343 break;
1344 default:
1345 goto pool32axf_invalid;
1346 }
1347 break;
1348 case 0x35:
1349 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1350 switch (minor) {
1351 case MFHI32:
1352 gen_HILO(ctx, OPC_MFHI, 0, rs);
1353 break;
1354 case MFLO32:
1355 gen_HILO(ctx, OPC_MFLO, 0, rs);
1356 break;
1357 case MTHI32:
1358 gen_HILO(ctx, OPC_MTHI, 0, rs);
1359 break;
1360 case MTLO32:
1361 gen_HILO(ctx, OPC_MTLO, 0, rs);
1362 break;
1363 default:
1364 goto pool32axf_invalid;
1365 }
1366 break;
1367 default:
1368 pool32axf_invalid:
1369 MIPS_INVAL("pool32axf");
1370 gen_reserved_instruction(ctx);
1371 break;
1372 }
1373 }
1374
1375 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
1376 {
1377 int extension = (ctx->opcode >> 6) & 0x3ff;
1378 uint32_t mips32_op;
1379
1380 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
1381 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
1382 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
1383
1384 switch (extension) {
1385 case FLOAT_1BIT_FMT(CFC1, 0):
1386 mips32_op = OPC_CFC1;
1387 goto do_cp1;
1388 case FLOAT_1BIT_FMT(CTC1, 0):
1389 mips32_op = OPC_CTC1;
1390 goto do_cp1;
1391 case FLOAT_1BIT_FMT(MFC1, 0):
1392 mips32_op = OPC_MFC1;
1393 goto do_cp1;
1394 case FLOAT_1BIT_FMT(MTC1, 0):
1395 mips32_op = OPC_MTC1;
1396 goto do_cp1;
1397 case FLOAT_1BIT_FMT(MFHC1, 0):
1398 mips32_op = OPC_MFHC1;
1399 goto do_cp1;
1400 case FLOAT_1BIT_FMT(MTHC1, 0):
1401 mips32_op = OPC_MTHC1;
1402 do_cp1:
1403 gen_cp1(ctx, mips32_op, rt, rs);
1404 break;
1405
1406 /* Reciprocal square root */
1407 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
1408 mips32_op = OPC_RSQRT_S;
1409 goto do_unaryfp;
1410 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
1411 mips32_op = OPC_RSQRT_D;
1412 goto do_unaryfp;
1413
1414 /* Square root */
1415 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
1416 mips32_op = OPC_SQRT_S;
1417 goto do_unaryfp;
1418 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
1419 mips32_op = OPC_SQRT_D;
1420 goto do_unaryfp;
1421
1422 /* Reciprocal */
1423 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
1424 mips32_op = OPC_RECIP_S;
1425 goto do_unaryfp;
1426 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
1427 mips32_op = OPC_RECIP_D;
1428 goto do_unaryfp;
1429
1430 /* Floor */
1431 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
1432 mips32_op = OPC_FLOOR_L_S;
1433 goto do_unaryfp;
1434 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
1435 mips32_op = OPC_FLOOR_L_D;
1436 goto do_unaryfp;
1437 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
1438 mips32_op = OPC_FLOOR_W_S;
1439 goto do_unaryfp;
1440 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
1441 mips32_op = OPC_FLOOR_W_D;
1442 goto do_unaryfp;
1443
1444 /* Ceiling */
1445 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
1446 mips32_op = OPC_CEIL_L_S;
1447 goto do_unaryfp;
1448 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
1449 mips32_op = OPC_CEIL_L_D;
1450 goto do_unaryfp;
1451 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
1452 mips32_op = OPC_CEIL_W_S;
1453 goto do_unaryfp;
1454 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
1455 mips32_op = OPC_CEIL_W_D;
1456 goto do_unaryfp;
1457
1458 /* Truncation */
1459 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
1460 mips32_op = OPC_TRUNC_L_S;
1461 goto do_unaryfp;
1462 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
1463 mips32_op = OPC_TRUNC_L_D;
1464 goto do_unaryfp;
1465 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
1466 mips32_op = OPC_TRUNC_W_S;
1467 goto do_unaryfp;
1468 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
1469 mips32_op = OPC_TRUNC_W_D;
1470 goto do_unaryfp;
1471
1472 /* Round */
1473 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
1474 mips32_op = OPC_ROUND_L_S;
1475 goto do_unaryfp;
1476 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
1477 mips32_op = OPC_ROUND_L_D;
1478 goto do_unaryfp;
1479 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
1480 mips32_op = OPC_ROUND_W_S;
1481 goto do_unaryfp;
1482 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
1483 mips32_op = OPC_ROUND_W_D;
1484 goto do_unaryfp;
1485
1486 /* Integer to floating-point conversion */
1487 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
1488 mips32_op = OPC_CVT_L_S;
1489 goto do_unaryfp;
1490 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
1491 mips32_op = OPC_CVT_L_D;
1492 goto do_unaryfp;
1493 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
1494 mips32_op = OPC_CVT_W_S;
1495 goto do_unaryfp;
1496 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
1497 mips32_op = OPC_CVT_W_D;
1498 goto do_unaryfp;
1499
1500 /* Paired-foo conversions */
1501 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
1502 mips32_op = OPC_CVT_S_PL;
1503 goto do_unaryfp;
1504 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
1505 mips32_op = OPC_CVT_S_PU;
1506 goto do_unaryfp;
1507 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
1508 mips32_op = OPC_CVT_PW_PS;
1509 goto do_unaryfp;
1510 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
1511 mips32_op = OPC_CVT_PS_PW;
1512 goto do_unaryfp;
1513
1514 /* Floating-point moves */
1515 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
1516 mips32_op = OPC_MOV_S;
1517 goto do_unaryfp;
1518 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
1519 mips32_op = OPC_MOV_D;
1520 goto do_unaryfp;
1521 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
1522 mips32_op = OPC_MOV_PS;
1523 goto do_unaryfp;
1524
1525 /* Absolute value */
1526 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
1527 mips32_op = OPC_ABS_S;
1528 goto do_unaryfp;
1529 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
1530 mips32_op = OPC_ABS_D;
1531 goto do_unaryfp;
1532 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
1533 mips32_op = OPC_ABS_PS;
1534 goto do_unaryfp;
1535
1536 /* Negation */
1537 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
1538 mips32_op = OPC_NEG_S;
1539 goto do_unaryfp;
1540 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
1541 mips32_op = OPC_NEG_D;
1542 goto do_unaryfp;
1543 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
1544 mips32_op = OPC_NEG_PS;
1545 goto do_unaryfp;
1546
1547 /* Reciprocal square root step */
1548 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
1549 mips32_op = OPC_RSQRT1_S;
1550 goto do_unaryfp;
1551 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
1552 mips32_op = OPC_RSQRT1_D;
1553 goto do_unaryfp;
1554 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
1555 mips32_op = OPC_RSQRT1_PS;
1556 goto do_unaryfp;
1557
1558 /* Reciprocal step */
1559 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
1560 mips32_op = OPC_RECIP1_S;
1561 goto do_unaryfp;
1562 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
1563 mips32_op = OPC_RECIP1_S;
1564 goto do_unaryfp;
1565 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
1566 mips32_op = OPC_RECIP1_PS;
1567 goto do_unaryfp;
1568
1569 /* Conversions from double */
1570 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
1571 mips32_op = OPC_CVT_D_S;
1572 goto do_unaryfp;
1573 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
1574 mips32_op = OPC_CVT_D_W;
1575 goto do_unaryfp;
1576 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
1577 mips32_op = OPC_CVT_D_L;
1578 goto do_unaryfp;
1579
1580 /* Conversions from single */
1581 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
1582 mips32_op = OPC_CVT_S_D;
1583 goto do_unaryfp;
1584 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
1585 mips32_op = OPC_CVT_S_W;
1586 goto do_unaryfp;
1587 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
1588 mips32_op = OPC_CVT_S_L;
1589 do_unaryfp:
1590 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
1591 break;
1592
1593 /* Conditional moves on floating-point codes */
1594 case COND_FLOAT_MOV(MOVT, 0):
1595 case COND_FLOAT_MOV(MOVT, 1):
1596 case COND_FLOAT_MOV(MOVT, 2):
1597 case COND_FLOAT_MOV(MOVT, 3):
1598 case COND_FLOAT_MOV(MOVT, 4):
1599 case COND_FLOAT_MOV(MOVT, 5):
1600 case COND_FLOAT_MOV(MOVT, 6):
1601 case COND_FLOAT_MOV(MOVT, 7):
1602 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1603 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
1604 break;
1605 case COND_FLOAT_MOV(MOVF, 0):
1606 case COND_FLOAT_MOV(MOVF, 1):
1607 case COND_FLOAT_MOV(MOVF, 2):
1608 case COND_FLOAT_MOV(MOVF, 3):
1609 case COND_FLOAT_MOV(MOVF, 4):
1610 case COND_FLOAT_MOV(MOVF, 5):
1611 case COND_FLOAT_MOV(MOVF, 6):
1612 case COND_FLOAT_MOV(MOVF, 7):
1613 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1614 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
1615 break;
1616 default:
1617 MIPS_INVAL("pool32fxf");
1618 gen_reserved_instruction(ctx);
1619 break;
1620 }
1621 }
1622
1623 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
1624 {
1625 int32_t offset;
1626 uint16_t insn;
1627 int rt, rs, rd, rr;
1628 int16_t imm;
1629 uint32_t op, minor, minor2, mips32_op;
1630 uint32_t cond, fmt, cc;
1631
1632 insn = translator_lduw_end(env, &ctx->base, ctx->base.pc_next + 2, mo_endian(ctx));
1633 ctx->opcode = (ctx->opcode << 16) | insn;
1634
1635 rt = (ctx->opcode >> 21) & 0x1f;
1636 rs = (ctx->opcode >> 16) & 0x1f;
1637 rd = (ctx->opcode >> 11) & 0x1f;
1638 rr = (ctx->opcode >> 6) & 0x1f;
1639 imm = (int16_t) ctx->opcode;
1640
1641 op = (ctx->opcode >> 26) & 0x3f;
1642 switch (op) {
1643 case POOL32A:
1644 minor = ctx->opcode & 0x3f;
1645 switch (minor) {
1646 case 0x00:
1647 minor = (ctx->opcode >> 6) & 0xf;
1648 switch (minor) {
1649 case SLL32:
1650 mips32_op = OPC_SLL;
1651 goto do_shifti;
1652 case SRA:
1653 mips32_op = OPC_SRA;
1654 goto do_shifti;
1655 case SRL32:
1656 mips32_op = OPC_SRL;
1657 goto do_shifti;
1658 case ROTR:
1659 mips32_op = OPC_ROTR;
1660 do_shifti:
1661 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
1662 break;
1663 case SELEQZ:
1664 check_insn(ctx, ISA_MIPS_R6);
1665 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
1666 break;
1667 case SELNEZ:
1668 check_insn(ctx, ISA_MIPS_R6);
1669 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
1670 break;
1671 case R6_RDHWR:
1672 check_insn(ctx, ISA_MIPS_R6);
1673 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
1674 break;
1675 default:
1676 goto pool32a_invalid;
1677 }
1678 break;
1679 case 0x10:
1680 minor = (ctx->opcode >> 6) & 0xf;
1681 switch (minor) {
1682 /* Arithmetic */
1683 case ADD:
1684 mips32_op = OPC_ADD;
1685 goto do_arith;
1686 case ADDU32:
1687 mips32_op = OPC_ADDU;
1688 goto do_arith;
1689 case SUB:
1690 mips32_op = OPC_SUB;
1691 goto do_arith;
1692 case SUBU32:
1693 mips32_op = OPC_SUBU;
1694 goto do_arith;
1695 case MUL:
1696 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1697 mips32_op = OPC_MUL;
1698 do_arith:
1699 gen_arith(ctx, mips32_op, rd, rs, rt);
1700 break;
1701 /* Shifts */
1702 case SLLV:
1703 mips32_op = OPC_SLLV;
1704 goto do_shift;
1705 case SRLV:
1706 mips32_op = OPC_SRLV;
1707 goto do_shift;
1708 case SRAV:
1709 mips32_op = OPC_SRAV;
1710 goto do_shift;
1711 case ROTRV:
1712 mips32_op = OPC_ROTRV;
1713 do_shift:
1714 gen_shift(ctx, mips32_op, rd, rs, rt);
1715 break;
1716 /* Logical operations */
1717 case AND:
1718 mips32_op = OPC_AND;
1719 goto do_logic;
1720 case OR32:
1721 mips32_op = OPC_OR;
1722 goto do_logic;
1723 case NOR:
1724 mips32_op = OPC_NOR;
1725 goto do_logic;
1726 case XOR32:
1727 mips32_op = OPC_XOR;
1728 do_logic:
1729 gen_logic(ctx, mips32_op, rd, rs, rt);
1730 break;
1731 /* Set less than */
1732 case SLT:
1733 mips32_op = OPC_SLT;
1734 goto do_slt;
1735 case SLTU:
1736 mips32_op = OPC_SLTU;
1737 do_slt:
1738 gen_slt(ctx, mips32_op, rd, rs, rt);
1739 break;
1740 default:
1741 goto pool32a_invalid;
1742 }
1743 break;
1744 case 0x18:
1745 minor = (ctx->opcode >> 6) & 0xf;
1746 switch (minor) {
1747 /* Conditional moves */
1748 case MOVN: /* MUL */
1749 if (ctx->insn_flags & ISA_MIPS_R6) {
1750 /* MUL */
1751 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
1752 } else {
1753 /* MOVN */
1754 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
1755 }
1756 break;
1757 case MOVZ: /* MUH */
1758 if (ctx->insn_flags & ISA_MIPS_R6) {
1759 /* MUH */
1760 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
1761 } else {
1762 /* MOVZ */
1763 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
1764 }
1765 break;
1766 case MULU:
1767 check_insn(ctx, ISA_MIPS_R6);
1768 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
1769 break;
1770 case MUHU:
1771 check_insn(ctx, ISA_MIPS_R6);
1772 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
1773 break;
1774 case LWXS: /* DIV */
1775 if (ctx->insn_flags & ISA_MIPS_R6) {
1776 /* DIV */
1777 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
1778 } else {
1779 /* LWXS */
1780 gen_ldxs(ctx, rs, rt, rd);
1781 }
1782 break;
1783 case MOD:
1784 check_insn(ctx, ISA_MIPS_R6);
1785 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
1786 break;
1787 case R6_DIVU:
1788 check_insn(ctx, ISA_MIPS_R6);
1789 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
1790 break;
1791 case MODU:
1792 check_insn(ctx, ISA_MIPS_R6);
1793 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
1794 break;
1795 default:
1796 goto pool32a_invalid;
1797 }
1798 break;
1799 case INS:
1800 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
1801 return;
1802 case LSA:
1803 check_insn(ctx, ISA_MIPS_R6);
1804 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) + 1);
1805 break;
1806 case ALIGN:
1807 check_insn(ctx, ISA_MIPS_R6);
1808 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
1809 break;
1810 case EXT:
1811 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
1812 return;
1813 case POOL32AXF:
1814 gen_pool32axf(env, ctx, rt, rs);
1815 break;
1816 case BREAK32:
1817 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
1818 break;
1819 case SIGRIE:
1820 check_insn(ctx, ISA_MIPS_R6);
1821 gen_reserved_instruction(ctx);
1822 break;
1823 default:
1824 pool32a_invalid:
1825 MIPS_INVAL("pool32a");
1826 gen_reserved_instruction(ctx);
1827 break;
1828 }
1829 break;
1830 case POOL32B:
1831 minor = (ctx->opcode >> 12) & 0xf;
1832 switch (minor) {
1833 case CACHE:
1834 check_cp0_enabled(ctx);
1835 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
1836 gen_cache_operation(ctx, rt, rs, imm);
1837 }
1838 break;
1839 case LWC2:
1840 case SWC2:
1841 /* COP2: Not implemented. */
1842 generate_exception_err(ctx, EXCP_CpU, 2);
1843 break;
1844 #ifdef TARGET_MIPS64
1845 case LDP:
1846 case SDP:
1847 check_insn(ctx, ISA_MIPS3);
1848 check_mips_64(ctx);
1849 #endif
1850 /* fall through */
1851 case LWP:
1852 case SWP:
1853 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
1854 break;
1855 #ifdef TARGET_MIPS64
1856 case LDM:
1857 case SDM:
1858 check_insn(ctx, ISA_MIPS3);
1859 check_mips_64(ctx);
1860 #endif
1861 /* fall through */
1862 case LWM32:
1863 case SWM32:
1864 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
1865 break;
1866 default:
1867 MIPS_INVAL("pool32b");
1868 gen_reserved_instruction(ctx);
1869 break;
1870 }
1871 break;
1872 case POOL32F:
1873 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
1874 minor = ctx->opcode & 0x3f;
1875 check_cp1_enabled(ctx);
1876 switch (minor) {
1877 case ALNV_PS:
1878 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1879 mips32_op = OPC_ALNV_PS;
1880 goto do_madd;
1881 case MADD_S:
1882 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1883 mips32_op = OPC_MADD_S;
1884 goto do_madd;
1885 case MADD_D:
1886 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1887 mips32_op = OPC_MADD_D;
1888 goto do_madd;
1889 case MADD_PS:
1890 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1891 mips32_op = OPC_MADD_PS;
1892 goto do_madd;
1893 case MSUB_S:
1894 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1895 mips32_op = OPC_MSUB_S;
1896 goto do_madd;
1897 case MSUB_D:
1898 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1899 mips32_op = OPC_MSUB_D;
1900 goto do_madd;
1901 case MSUB_PS:
1902 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1903 mips32_op = OPC_MSUB_PS;
1904 goto do_madd;
1905 case NMADD_S:
1906 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1907 mips32_op = OPC_NMADD_S;
1908 goto do_madd;
1909 case NMADD_D:
1910 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1911 mips32_op = OPC_NMADD_D;
1912 goto do_madd;
1913 case NMADD_PS:
1914 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1915 mips32_op = OPC_NMADD_PS;
1916 goto do_madd;
1917 case NMSUB_S:
1918 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1919 mips32_op = OPC_NMSUB_S;
1920 goto do_madd;
1921 case NMSUB_D:
1922 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1923 mips32_op = OPC_NMSUB_D;
1924 goto do_madd;
1925 case NMSUB_PS:
1926 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1927 mips32_op = OPC_NMSUB_PS;
1928 do_madd:
1929 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
1930 break;
1931 case CABS_COND_FMT:
1932 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1933 cond = (ctx->opcode >> 6) & 0xf;
1934 cc = (ctx->opcode >> 13) & 0x7;
1935 fmt = (ctx->opcode >> 10) & 0x3;
1936 switch (fmt) {
1937 case 0x0:
1938 gen_cmpabs_s(ctx, cond, rt, rs, cc);
1939 break;
1940 case 0x1:
1941 gen_cmpabs_d(ctx, cond, rt, rs, cc);
1942 break;
1943 case 0x2:
1944 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
1945 break;
1946 default:
1947 goto pool32f_invalid;
1948 }
1949 break;
1950 case C_COND_FMT:
1951 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1952 cond = (ctx->opcode >> 6) & 0xf;
1953 cc = (ctx->opcode >> 13) & 0x7;
1954 fmt = (ctx->opcode >> 10) & 0x3;
1955 switch (fmt) {
1956 case 0x0:
1957 gen_cmp_s(ctx, cond, rt, rs, cc);
1958 break;
1959 case 0x1:
1960 gen_cmp_d(ctx, cond, rt, rs, cc);
1961 break;
1962 case 0x2:
1963 gen_cmp_ps(ctx, cond, rt, rs, cc);
1964 break;
1965 default:
1966 goto pool32f_invalid;
1967 }
1968 break;
1969 case CMP_CONDN_S:
1970 check_insn(ctx, ISA_MIPS_R6);
1971 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
1972 break;
1973 case CMP_CONDN_D:
1974 check_insn(ctx, ISA_MIPS_R6);
1975 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
1976 break;
1977 case POOL32FXF:
1978 gen_pool32fxf(ctx, rt, rs);
1979 break;
1980 case 0x00:
1981 /* PLL foo */
1982 switch ((ctx->opcode >> 6) & 0x7) {
1983 case PLL_PS:
1984 mips32_op = OPC_PLL_PS;
1985 goto do_ps;
1986 case PLU_PS:
1987 mips32_op = OPC_PLU_PS;
1988 goto do_ps;
1989 case PUL_PS:
1990 mips32_op = OPC_PUL_PS;
1991 goto do_ps;
1992 case PUU_PS:
1993 mips32_op = OPC_PUU_PS;
1994 goto do_ps;
1995 case CVT_PS_S:
1996 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1997 mips32_op = OPC_CVT_PS_S;
1998 do_ps:
1999 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
2000 break;
2001 default:
2002 goto pool32f_invalid;
2003 }
2004 break;
2005 case MIN_FMT:
2006 check_insn(ctx, ISA_MIPS_R6);
2007 switch ((ctx->opcode >> 9) & 0x3) {
2008 case FMT_SDPS_S:
2009 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
2010 break;
2011 case FMT_SDPS_D:
2012 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
2013 break;
2014 default:
2015 goto pool32f_invalid;
2016 }
2017 break;
2018 case 0x08:
2019 /* [LS][WDU]XC1 */
2020 switch ((ctx->opcode >> 6) & 0x7) {
2021 case LWXC1:
2022 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2023 mips32_op = OPC_LWXC1;
2024 goto do_ldst_cp1;
2025 case SWXC1:
2026 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2027 mips32_op = OPC_SWXC1;
2028 goto do_ldst_cp1;
2029 case LDXC1:
2030 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2031 mips32_op = OPC_LDXC1;
2032 goto do_ldst_cp1;
2033 case SDXC1:
2034 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2035 mips32_op = OPC_SDXC1;
2036 goto do_ldst_cp1;
2037 case LUXC1:
2038 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2039 mips32_op = OPC_LUXC1;
2040 goto do_ldst_cp1;
2041 case SUXC1:
2042 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2043 mips32_op = OPC_SUXC1;
2044 do_ldst_cp1:
2045 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
2046 break;
2047 default:
2048 goto pool32f_invalid;
2049 }
2050 break;
2051 case MAX_FMT:
2052 check_insn(ctx, ISA_MIPS_R6);
2053 switch ((ctx->opcode >> 9) & 0x3) {
2054 case FMT_SDPS_S:
2055 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
2056 break;
2057 case FMT_SDPS_D:
2058 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
2059 break;
2060 default:
2061 goto pool32f_invalid;
2062 }
2063 break;
2064 case 0x18:
2065 /* 3D insns */
2066 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2067 fmt = (ctx->opcode >> 9) & 0x3;
2068 switch ((ctx->opcode >> 6) & 0x7) {
2069 case RSQRT2_FMT:
2070 switch (fmt) {
2071 case FMT_SDPS_S:
2072 mips32_op = OPC_RSQRT2_S;
2073 goto do_3d;
2074 case FMT_SDPS_D:
2075 mips32_op = OPC_RSQRT2_D;
2076 goto do_3d;
2077 case FMT_SDPS_PS:
2078 mips32_op = OPC_RSQRT2_PS;
2079 goto do_3d;
2080 default:
2081 goto pool32f_invalid;
2082 }
2083 break;
2084 case RECIP2_FMT:
2085 switch (fmt) {
2086 case FMT_SDPS_S:
2087 mips32_op = OPC_RECIP2_S;
2088 goto do_3d;
2089 case FMT_SDPS_D:
2090 mips32_op = OPC_RECIP2_D;
2091 goto do_3d;
2092 case FMT_SDPS_PS:
2093 mips32_op = OPC_RECIP2_PS;
2094 goto do_3d;
2095 default:
2096 goto pool32f_invalid;
2097 }
2098 break;
2099 case ADDR_PS:
2100 mips32_op = OPC_ADDR_PS;
2101 goto do_3d;
2102 case MULR_PS:
2103 mips32_op = OPC_MULR_PS;
2104 do_3d:
2105 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
2106 break;
2107 default:
2108 goto pool32f_invalid;
2109 }
2110 break;
2111 case 0x20:
2112 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
2113 cc = (ctx->opcode >> 13) & 0x7;
2114 fmt = (ctx->opcode >> 9) & 0x3;
2115 switch ((ctx->opcode >> 6) & 0x7) {
2116 case MOVF_FMT: /* RINT_FMT */
2117 if (ctx->insn_flags & ISA_MIPS_R6) {
2118 /* RINT_FMT */
2119 switch (fmt) {
2120 case FMT_SDPS_S:
2121 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
2122 break;
2123 case FMT_SDPS_D:
2124 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
2125 break;
2126 default:
2127 goto pool32f_invalid;
2128 }
2129 } else {
2130 /* MOVF_FMT */
2131 switch (fmt) {
2132 case FMT_SDPS_S:
2133 gen_movcf_s(ctx, rs, rt, cc, 0);
2134 break;
2135 case FMT_SDPS_D:
2136 gen_movcf_d(ctx, rs, rt, cc, 0);
2137 break;
2138 case FMT_SDPS_PS:
2139 check_ps(ctx);
2140 gen_movcf_ps(ctx, rs, rt, cc, 0);
2141 break;
2142 default:
2143 goto pool32f_invalid;
2144 }
2145 }
2146 break;
2147 case MOVT_FMT: /* CLASS_FMT */
2148 if (ctx->insn_flags & ISA_MIPS_R6) {
2149 /* CLASS_FMT */
2150 switch (fmt) {
2151 case FMT_SDPS_S:
2152 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
2153 break;
2154 case FMT_SDPS_D:
2155 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
2156 break;
2157 default:
2158 goto pool32f_invalid;
2159 }
2160 } else {
2161 /* MOVT_FMT */
2162 switch (fmt) {
2163 case FMT_SDPS_S:
2164 gen_movcf_s(ctx, rs, rt, cc, 1);
2165 break;
2166 case FMT_SDPS_D:
2167 gen_movcf_d(ctx, rs, rt, cc, 1);
2168 break;
2169 case FMT_SDPS_PS:
2170 check_ps(ctx);
2171 gen_movcf_ps(ctx, rs, rt, cc, 1);
2172 break;
2173 default:
2174 goto pool32f_invalid;
2175 }
2176 }
2177 break;
2178 case PREFX:
2179 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2180 break;
2181 default:
2182 goto pool32f_invalid;
2183 }
2184 break;
2185 #define FINSN_3ARG_SDPS(prfx) \
2186 switch ((ctx->opcode >> 8) & 0x3) { \
2187 case FMT_SDPS_S: \
2188 mips32_op = OPC_##prfx##_S; \
2189 goto do_fpop; \
2190 case FMT_SDPS_D: \
2191 mips32_op = OPC_##prfx##_D; \
2192 goto do_fpop; \
2193 case FMT_SDPS_PS: \
2194 check_ps(ctx); \
2195 mips32_op = OPC_##prfx##_PS; \
2196 goto do_fpop; \
2197 default: \
2198 goto pool32f_invalid; \
2199 }
2200 case MINA_FMT:
2201 check_insn(ctx, ISA_MIPS_R6);
2202 switch ((ctx->opcode >> 9) & 0x3) {
2203 case FMT_SDPS_S:
2204 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
2205 break;
2206 case FMT_SDPS_D:
2207 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
2208 break;
2209 default:
2210 goto pool32f_invalid;
2211 }
2212 break;
2213 case MAXA_FMT:
2214 check_insn(ctx, ISA_MIPS_R6);
2215 switch ((ctx->opcode >> 9) & 0x3) {
2216 case FMT_SDPS_S:
2217 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
2218 break;
2219 case FMT_SDPS_D:
2220 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
2221 break;
2222 default:
2223 goto pool32f_invalid;
2224 }
2225 break;
2226 case 0x30:
2227 /* regular FP ops */
2228 switch ((ctx->opcode >> 6) & 0x3) {
2229 case ADD_FMT:
2230 FINSN_3ARG_SDPS(ADD);
2231 break;
2232 case SUB_FMT:
2233 FINSN_3ARG_SDPS(SUB);
2234 break;
2235 case MUL_FMT:
2236 FINSN_3ARG_SDPS(MUL);
2237 break;
2238 case DIV_FMT:
2239 fmt = (ctx->opcode >> 8) & 0x3;
2240 if (fmt == 1) {
2241 mips32_op = OPC_DIV_D;
2242 } else if (fmt == 0) {
2243 mips32_op = OPC_DIV_S;
2244 } else {
2245 goto pool32f_invalid;
2246 }
2247 goto do_fpop;
2248 default:
2249 goto pool32f_invalid;
2250 }
2251 break;
2252 case 0x38:
2253 /* cmovs */
2254 switch ((ctx->opcode >> 6) & 0x7) {
2255 case MOVN_FMT: /* SELEQZ_FMT */
2256 if (ctx->insn_flags & ISA_MIPS_R6) {
2257 /* SELEQZ_FMT */
2258 switch ((ctx->opcode >> 9) & 0x3) {
2259 case FMT_SDPS_S:
2260 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2261 break;
2262 case FMT_SDPS_D:
2263 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2264 break;
2265 default:
2266 goto pool32f_invalid;
2267 }
2268 } else {
2269 /* MOVN_FMT */
2270 FINSN_3ARG_SDPS(MOVN);
2271 }
2272 break;
2273 case MOVN_FMT_04:
2274 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2275 FINSN_3ARG_SDPS(MOVN);
2276 break;
2277 case MOVZ_FMT: /* SELNEZ_FMT */
2278 if (ctx->insn_flags & ISA_MIPS_R6) {
2279 /* SELNEZ_FMT */
2280 switch ((ctx->opcode >> 9) & 0x3) {
2281 case FMT_SDPS_S:
2282 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2283 break;
2284 case FMT_SDPS_D:
2285 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2286 break;
2287 default:
2288 goto pool32f_invalid;
2289 }
2290 } else {
2291 /* MOVZ_FMT */
2292 FINSN_3ARG_SDPS(MOVZ);
2293 }
2294 break;
2295 case MOVZ_FMT_05:
2296 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2297 FINSN_3ARG_SDPS(MOVZ);
2298 break;
2299 case SEL_FMT:
2300 check_insn(ctx, ISA_MIPS_R6);
2301 switch ((ctx->opcode >> 9) & 0x3) {
2302 case FMT_SDPS_S:
2303 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
2304 break;
2305 case FMT_SDPS_D:
2306 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
2307 break;
2308 default:
2309 goto pool32f_invalid;
2310 }
2311 break;
2312 case MADDF_FMT:
2313 check_insn(ctx, ISA_MIPS_R6);
2314 switch ((ctx->opcode >> 9) & 0x3) {
2315 case FMT_SDPS_S:
2316 mips32_op = OPC_MADDF_S;
2317 goto do_fpop;
2318 case FMT_SDPS_D:
2319 mips32_op = OPC_MADDF_D;
2320 goto do_fpop;
2321 default:
2322 goto pool32f_invalid;
2323 }
2324 break;
2325 case MSUBF_FMT:
2326 check_insn(ctx, ISA_MIPS_R6);
2327 switch ((ctx->opcode >> 9) & 0x3) {
2328 case FMT_SDPS_S:
2329 mips32_op = OPC_MSUBF_S;
2330 goto do_fpop;
2331 case FMT_SDPS_D:
2332 mips32_op = OPC_MSUBF_D;
2333 goto do_fpop;
2334 default:
2335 goto pool32f_invalid;
2336 }
2337 break;
2338 default:
2339 goto pool32f_invalid;
2340 }
2341 break;
2342 do_fpop:
2343 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
2344 break;
2345 default:
2346 pool32f_invalid:
2347 MIPS_INVAL("pool32f");
2348 gen_reserved_instruction(ctx);
2349 break;
2350 }
2351 } else {
2352 generate_exception_err(ctx, EXCP_CpU, 1);
2353 }
2354 break;
2355 case POOL32I:
2356 minor = (ctx->opcode >> 21) & 0x1f;
2357 switch (minor) {
2358 case BLTZ:
2359 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2360 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
2361 break;
2362 case BLTZAL:
2363 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2364 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
2365 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2366 break;
2367 case BLTZALS:
2368 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2369 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
2370 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2371 break;
2372 case BGEZ:
2373 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2374 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
2375 break;
2376 case BGEZAL:
2377 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2378 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
2379 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2380 break;
2381 case BGEZALS:
2382 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2383 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
2384 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2385 break;
2386 case BLEZ:
2387 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2388 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
2389 break;
2390 case BGTZ:
2391 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2392 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
2393 break;
2394
2395 /* Traps */
2396 case TLTI: /* BC1EQZC */
2397 if (ctx->insn_flags & ISA_MIPS_R6) {
2398 /* BC1EQZC */
2399 check_cp1_enabled(ctx);
2400 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
2401 } else {
2402 /* TLTI */
2403 mips32_op = OPC_TLTI;
2404 goto do_trapi;
2405 }
2406 break;
2407 case TGEI: /* BC1NEZC */
2408 if (ctx->insn_flags & ISA_MIPS_R6) {
2409 /* BC1NEZC */
2410 check_cp1_enabled(ctx);
2411 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
2412 } else {
2413 /* TGEI */
2414 mips32_op = OPC_TGEI;
2415 goto do_trapi;
2416 }
2417 break;
2418 case TLTIU:
2419 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2420 mips32_op = OPC_TLTIU;
2421 goto do_trapi;
2422 case TGEIU:
2423 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2424 mips32_op = OPC_TGEIU;
2425 goto do_trapi;
2426 case TNEI: /* SYNCI */
2427 if (ctx->insn_flags & ISA_MIPS_R6) {
2428 /* SYNCI */
2429 /*
2430 * Break the TB to be able to sync copied instructions
2431 * immediately.
2432 */
2433 ctx->base.is_jmp = DISAS_STOP;
2434 } else {
2435 /* TNEI */
2436 mips32_op = OPC_TNEI;
2437 goto do_trapi;
2438 }
2439 break;
2440 case TEQI:
2441 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2442 mips32_op = OPC_TEQI;
2443 do_trapi:
2444 gen_trap(ctx, mips32_op, rs, -1, imm, 0);
2445 break;
2446
2447 case BNEZC:
2448 case BEQZC:
2449 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2450 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
2451 4, rs, 0, imm << 1, 0);
2452 /*
2453 * Compact branches don't have a delay slot, so just let
2454 * the normal delay slot handling take us to the branch
2455 * target.
2456 */
2457 break;
2458 case LUI:
2459 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2460 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
2461 break;
2462 case SYNCI:
2463 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2464 /*
2465 * Break the TB to be able to sync copied instructions
2466 * immediately.
2467 */
2468 ctx->base.is_jmp = DISAS_STOP;
2469 break;
2470 case BC2F:
2471 case BC2T:
2472 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2473 /* COP2: Not implemented. */
2474 generate_exception_err(ctx, EXCP_CpU, 2);
2475 break;
2476 case BC1F:
2477 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2478 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
2479 goto do_cp1branch;
2480 case BC1T:
2481 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2482 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
2483 goto do_cp1branch;
2484 case BC1ANY4F:
2485 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2486 mips32_op = OPC_BC1FANY4;
2487 goto do_cp1mips3d;
2488 case BC1ANY4T:
2489 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2490 mips32_op = OPC_BC1TANY4;
2491 do_cp1mips3d:
2492 check_cop1x(ctx);
2493 if (!ase_3d_available(env)) {
2494 gen_reserved_instruction(ctx);
2495 break;
2496 }
2497 /* Fall through */
2498 do_cp1branch:
2499 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
2500 check_cp1_enabled(ctx);
2501 gen_compute_branch1(ctx, mips32_op,
2502 (ctx->opcode >> 18) & 0x7, imm << 1);
2503 } else {
2504 generate_exception_err(ctx, EXCP_CpU, 1);
2505 }
2506 break;
2507 default:
2508 MIPS_INVAL("pool32i");
2509 gen_reserved_instruction(ctx);
2510 break;
2511 }
2512 break;
2513 case POOL32C:
2514 minor = (ctx->opcode >> 12) & 0xf;
2515 offset = sextract32(ctx->opcode, 0,
2516 (ctx->insn_flags & ISA_MIPS_R6) ? 9 : 12);
2517 switch (minor) {
2518 case LWL:
2519 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2520 mips32_op = OPC_LWL;
2521 goto do_ld_lr;
2522 case SWL:
2523 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2524 mips32_op = OPC_SWL;
2525 goto do_st_lr;
2526 case LWR:
2527 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2528 mips32_op = OPC_LWR;
2529 goto do_ld_lr;
2530 case SWR:
2531 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2532 mips32_op = OPC_SWR;
2533 goto do_st_lr;
2534 #if defined(TARGET_MIPS64)
2535 case LDL:
2536 check_insn(ctx, ISA_MIPS3);
2537 check_mips_64(ctx);
2538 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2539 mips32_op = OPC_LDL;
2540 goto do_ld_lr;
2541 case SDL:
2542 check_insn(ctx, ISA_MIPS3);
2543 check_mips_64(ctx);
2544 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2545 mips32_op = OPC_SDL;
2546 goto do_st_lr;
2547 case LDR:
2548 check_insn(ctx, ISA_MIPS3);
2549 check_mips_64(ctx);
2550 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2551 mips32_op = OPC_LDR;
2552 goto do_ld_lr;
2553 case SDR:
2554 check_insn(ctx, ISA_MIPS3);
2555 check_mips_64(ctx);
2556 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2557 mips32_op = OPC_SDR;
2558 goto do_st_lr;
2559 case LWU:
2560 check_insn(ctx, ISA_MIPS3);
2561 check_mips_64(ctx);
2562 mips32_op = OPC_LWU;
2563 goto do_ld_lr;
2564 case LLD:
2565 check_insn(ctx, ISA_MIPS3);
2566 check_mips_64(ctx);
2567 mips32_op = OPC_LLD;
2568 goto do_ld_lr;
2569 #endif
2570 case LL:
2571 mips32_op = OPC_LL;
2572 goto do_ld_lr;
2573 do_ld_lr:
2574 gen_ld(ctx, mips32_op, rt, rs, offset);
2575 break;
2576 do_st_lr:
2577 gen_st(ctx, mips32_op, rt, rs, offset);
2578 break;
2579 case SC:
2580 gen_st_cond(ctx, rt, rs, offset, mo_endian(ctx) | MO_SL, false);
2581 break;
2582 #if defined(TARGET_MIPS64)
2583 case SCD:
2584 check_insn(ctx, ISA_MIPS3);
2585 check_mips_64(ctx);
2586 gen_st_cond(ctx, rt, rs, offset, mo_endian(ctx) | MO_UQ, false);
2587 break;
2588 #endif
2589 case LD_EVA:
2590 if (!ctx->eva) {
2591 MIPS_INVAL("pool32c ld-eva");
2592 gen_reserved_instruction(ctx);
2593 break;
2594 }
2595 check_cp0_enabled(ctx);
2596
2597 minor2 = (ctx->opcode >> 9) & 0x7;
2598 offset = sextract32(ctx->opcode, 0, 9);
2599 switch (minor2) {
2600 case LBUE:
2601 mips32_op = OPC_LBUE;
2602 goto do_ld_lr;
2603 case LHUE:
2604 mips32_op = OPC_LHUE;
2605 goto do_ld_lr;
2606 case LWLE:
2607 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2608 mips32_op = OPC_LWLE;
2609 goto do_ld_lr;
2610 case LWRE:
2611 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2612 mips32_op = OPC_LWRE;
2613 goto do_ld_lr;
2614 case LBE:
2615 mips32_op = OPC_LBE;
2616 goto do_ld_lr;
2617 case LHE:
2618 mips32_op = OPC_LHE;
2619 goto do_ld_lr;
2620 case LLE:
2621 mips32_op = OPC_LLE;
2622 goto do_ld_lr;
2623 case LWE:
2624 mips32_op = OPC_LWE;
2625 goto do_ld_lr;
2626 };
2627 break;
2628 case ST_EVA:
2629 if (!ctx->eva) {
2630 MIPS_INVAL("pool32c st-eva");
2631 gen_reserved_instruction(ctx);
2632 break;
2633 }
2634 check_cp0_enabled(ctx);
2635
2636 minor2 = (ctx->opcode >> 9) & 0x7;
2637 offset = sextract32(ctx->opcode, 0, 9);
2638 switch (minor2) {
2639 case SWLE:
2640 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2641 mips32_op = OPC_SWLE;
2642 goto do_st_lr;
2643 case SWRE:
2644 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2645 mips32_op = OPC_SWRE;
2646 goto do_st_lr;
2647 case PREFE:
2648 /* Treat as no-op */
2649 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
2650 /* hint codes 24-31 are reserved and signal RI */
2651 generate_exception(ctx, EXCP_RI);
2652 }
2653 break;
2654 case CACHEE:
2655 /* Treat as no-op */
2656 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
2657 gen_cache_operation(ctx, rt, rs, offset);
2658 }
2659 break;
2660 case SBE:
2661 mips32_op = OPC_SBE;
2662 goto do_st_lr;
2663 case SHE:
2664 mips32_op = OPC_SHE;
2665 goto do_st_lr;
2666 case SCE:
2667 gen_st_cond(ctx, rt, rs, offset, mo_endian(ctx) | MO_SL, true);
2668 break;
2669 case SWE:
2670 mips32_op = OPC_SWE;
2671 goto do_st_lr;
2672 };
2673 break;
2674 case PREF:
2675 /* Treat as no-op */
2676 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
2677 /* hint codes 24-31 are reserved and signal RI */
2678 generate_exception(ctx, EXCP_RI);
2679 }
2680 break;
2681 default:
2682 MIPS_INVAL("pool32c");
2683 gen_reserved_instruction(ctx);
2684 break;
2685 }
2686 break;
2687 case ADDI32: /* AUI, LUI */
2688 if (ctx->insn_flags & ISA_MIPS_R6) {
2689 /* AUI, LUI */
2690 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
2691 } else {
2692 /* ADDI32 */
2693 mips32_op = OPC_ADDI;
2694 goto do_addi;
2695 }
2696 break;
2697 case ADDIU32:
2698 mips32_op = OPC_ADDIU;
2699 do_addi:
2700 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
2701 break;
2702
2703 /* Logical operations */
2704 case ORI32:
2705 mips32_op = OPC_ORI;
2706 goto do_logici;
2707 case XORI32:
2708 mips32_op = OPC_XORI;
2709 goto do_logici;
2710 case ANDI32:
2711 mips32_op = OPC_ANDI;
2712 do_logici:
2713 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
2714 break;
2715
2716 /* Set less than immediate */
2717 case SLTI32:
2718 mips32_op = OPC_SLTI;
2719 goto do_slti;
2720 case SLTIU32:
2721 mips32_op = OPC_SLTIU;
2722 do_slti:
2723 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
2724 break;
2725 case JALX32:
2726 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2727 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
2728 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
2729 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2730 break;
2731 case JALS32: /* BOVC, BEQC, BEQZALC */
2732 if (ctx->insn_flags & ISA_MIPS_R6) {
2733 if (rs >= rt) {
2734 /* BOVC */
2735 mips32_op = OPC_BOVC;
2736 } else if (rs < rt && rs == 0) {
2737 /* BEQZALC */
2738 mips32_op = OPC_BEQZALC;
2739 } else {
2740 /* BEQC */
2741 mips32_op = OPC_BEQC;
2742 }
2743 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2744 } else {
2745 /* JALS32 */
2746 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
2747 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
2748 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2749 }
2750 break;
2751 case BEQ32: /* BC */
2752 if (ctx->insn_flags & ISA_MIPS_R6) {
2753 /* BC */
2754 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
2755 sextract32(ctx->opcode << 1, 0, 27));
2756 } else {
2757 /* BEQ32 */
2758 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
2759 }
2760 break;
2761 case BNE32: /* BALC */
2762 if (ctx->insn_flags & ISA_MIPS_R6) {
2763 /* BALC */
2764 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
2765 sextract32(ctx->opcode << 1, 0, 27));
2766 } else {
2767 /* BNE32 */
2768 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
2769 }
2770 break;
2771 case J32: /* BGTZC, BLTZC, BLTC */
2772 if (ctx->insn_flags & ISA_MIPS_R6) {
2773 if (rs == 0 && rt != 0) {
2774 /* BGTZC */
2775 mips32_op = OPC_BGTZC;
2776 } else if (rs != 0 && rt != 0 && rs == rt) {
2777 /* BLTZC */
2778 mips32_op = OPC_BLTZC;
2779 } else {
2780 /* BLTC */
2781 mips32_op = OPC_BLTC;
2782 }
2783 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2784 } else {
2785 /* J32 */
2786 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
2787 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
2788 }
2789 break;
2790 case JAL32: /* BLEZC, BGEZC, BGEC */
2791 if (ctx->insn_flags & ISA_MIPS_R6) {
2792 if (rs == 0 && rt != 0) {
2793 /* BLEZC */
2794 mips32_op = OPC_BLEZC;
2795 } else if (rs != 0 && rt != 0 && rs == rt) {
2796 /* BGEZC */
2797 mips32_op = OPC_BGEZC;
2798 } else {
2799 /* BGEC */
2800 mips32_op = OPC_BGEC;
2801 }
2802 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2803 } else {
2804 /* JAL32 */
2805 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
2806 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
2807 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2808 }
2809 break;
2810 /* Floating point (COP1) */
2811 case LWC132:
2812 mips32_op = OPC_LWC1;
2813 goto do_cop1;
2814 case LDC132:
2815 mips32_op = OPC_LDC1;
2816 goto do_cop1;
2817 case SWC132:
2818 mips32_op = OPC_SWC1;
2819 goto do_cop1;
2820 case SDC132:
2821 mips32_op = OPC_SDC1;
2822 do_cop1:
2823 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
2824 break;
2825 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
2826 if (ctx->insn_flags & ISA_MIPS_R6) {
2827 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
2828 switch ((ctx->opcode >> 16) & 0x1f) {
2829 case ADDIUPC_00:
2830 case ADDIUPC_01:
2831 case ADDIUPC_02:
2832 case ADDIUPC_03:
2833 case ADDIUPC_04:
2834 case ADDIUPC_05:
2835 case ADDIUPC_06:
2836 case ADDIUPC_07:
2837 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
2838 break;
2839 case AUIPC:
2840 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
2841 break;
2842 case ALUIPC:
2843 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
2844 break;
2845 case LWPC_08:
2846 case LWPC_09:
2847 case LWPC_0A:
2848 case LWPC_0B:
2849 case LWPC_0C:
2850 case LWPC_0D:
2851 case LWPC_0E:
2852 case LWPC_0F:
2853 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
2854 break;
2855 default:
2856 generate_exception(ctx, EXCP_RI);
2857 break;
2858 }
2859 } else {
2860 /* ADDIUPC */
2861 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
2862 offset = SIMM(ctx->opcode, 0, 23) << 2;
2863
2864 gen_addiupc(ctx, reg, offset, 0, 0);
2865 }
2866 break;
2867 case BNVC: /* BNEC, BNEZALC */
2868 check_insn(ctx, ISA_MIPS_R6);
2869 if (rs >= rt) {
2870 /* BNVC */
2871 mips32_op = OPC_BNVC;
2872 } else if (rs < rt && rs == 0) {
2873 /* BNEZALC */
2874 mips32_op = OPC_BNEZALC;
2875 } else {
2876 /* BNEC */
2877 mips32_op = OPC_BNEC;
2878 }
2879 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2880 break;
2881 case R6_BNEZC: /* JIALC */
2882 check_insn(ctx, ISA_MIPS_R6);
2883 if (rt != 0) {
2884 /* BNEZC */
2885 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
2886 sextract32(ctx->opcode << 1, 0, 22));
2887 } else {
2888 /* JIALC */
2889 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
2890 }
2891 break;
2892 case R6_BEQZC: /* JIC */
2893 check_insn(ctx, ISA_MIPS_R6);
2894 if (rt != 0) {
2895 /* BEQZC */
2896 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
2897 sextract32(ctx->opcode << 1, 0, 22));
2898 } else {
2899 /* JIC */
2900 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
2901 }
2902 break;
2903 case BLEZALC: /* BGEZALC, BGEUC */
2904 check_insn(ctx, ISA_MIPS_R6);
2905 if (rs == 0 && rt != 0) {
2906 /* BLEZALC */
2907 mips32_op = OPC_BLEZALC;
2908 } else if (rs != 0 && rt != 0 && rs == rt) {
2909 /* BGEZALC */
2910 mips32_op = OPC_BGEZALC;
2911 } else {
2912 /* BGEUC */
2913 mips32_op = OPC_BGEUC;
2914 }
2915 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2916 break;
2917 case BGTZALC: /* BLTZALC, BLTUC */
2918 check_insn(ctx, ISA_MIPS_R6);
2919 if (rs == 0 && rt != 0) {
2920 /* BGTZALC */
2921 mips32_op = OPC_BGTZALC;
2922 } else if (rs != 0 && rt != 0 && rs == rt) {
2923 /* BLTZALC */
2924 mips32_op = OPC_BLTZALC;
2925 } else {
2926 /* BLTUC */
2927 mips32_op = OPC_BLTUC;
2928 }
2929 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2930 break;
2931 /* Loads and stores */
2932 case LB32:
2933 mips32_op = OPC_LB;
2934 goto do_ld;
2935 case LBU32:
2936 mips32_op = OPC_LBU;
2937 goto do_ld;
2938 case LH32:
2939 mips32_op = OPC_LH;
2940 goto do_ld;
2941 case LHU32:
2942 mips32_op = OPC_LHU;
2943 goto do_ld;
2944 case LW32:
2945 mips32_op = OPC_LW;
2946 goto do_ld;
2947 #ifdef TARGET_MIPS64
2948 case LD32:
2949 check_insn(ctx, ISA_MIPS3);
2950 check_mips_64(ctx);
2951 mips32_op = OPC_LD;
2952 goto do_ld;
2953 case SD32:
2954 check_insn(ctx, ISA_MIPS3);
2955 check_mips_64(ctx);
2956 mips32_op = OPC_SD;
2957 goto do_st;
2958 #endif
2959 case SB32:
2960 mips32_op = OPC_SB;
2961 goto do_st;
2962 case SH32:
2963 mips32_op = OPC_SH;
2964 goto do_st;
2965 case SW32:
2966 mips32_op = OPC_SW;
2967 goto do_st;
2968 do_ld:
2969 gen_ld(ctx, mips32_op, rt, rs, imm);
2970 break;
2971 do_st:
2972 gen_st(ctx, mips32_op, rt, rs, imm);
2973 break;
2974 default:
2975 gen_reserved_instruction(ctx);
2976 break;
2977 }
2978 }
2979
2980 static int decode_isa_micromips(CPUMIPSState *env, DisasContext *ctx)
2981 {
2982 uint32_t op;
2983
2984 /* make sure instructions are on a halfword boundary */
2985 if (ctx->base.pc_next & 0x1) {
2986 env->CP0_BadVAddr = ctx->base.pc_next;
2987 generate_exception_end(ctx, EXCP_AdEL);
2988 return 2;
2989 }
2990
2991 op = (ctx->opcode >> 10) & 0x3f;
2992 /* Enforce properly-sized instructions in a delay slot */
2993 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
2994 switch (op & 0x7) { /* MSB-3..MSB-5 */
2995 case 0:
2996 /* POOL32A, POOL32B, POOL32I, POOL32C */
2997 case 4:
2998 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
2999 case 5:
3000 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
3001 case 6:
3002 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
3003 case 7:
3004 /* LB32, LH32, LWC132, LDC132, LW32 */
3005 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3006 gen_reserved_instruction(ctx);
3007 return 2;
3008 }
3009 break;
3010 case 1:
3011 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
3012 case 2:
3013 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
3014 case 3:
3015 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
3016 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3017 gen_reserved_instruction(ctx);
3018 return 2;
3019 }
3020 break;
3021 }
3022 }
3023
3024 switch (op) {
3025 case POOL16A:
3026 {
3027 int rd = mmreg(uMIPS_RD(ctx->opcode));
3028 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
3029 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
3030 uint32_t opc = 0;
3031
3032 switch (ctx->opcode & 0x1) {
3033 case ADDU16:
3034 opc = OPC_ADDU;
3035 break;
3036 case SUBU16:
3037 opc = OPC_SUBU;
3038 break;
3039 }
3040 if (ctx->insn_flags & ISA_MIPS_R6) {
3041 /*
3042 * In the Release 6, the register number location in
3043 * the instruction encoding has changed.
3044 */
3045 gen_arith(ctx, opc, rs1, rd, rs2);
3046 } else {
3047 gen_arith(ctx, opc, rd, rs1, rs2);
3048 }
3049 }
3050 break;
3051 case POOL16B:
3052 {
3053 int rd = mmreg(uMIPS_RD(ctx->opcode));
3054 int rs = mmreg(uMIPS_RS(ctx->opcode));
3055 int amount = (ctx->opcode >> 1) & 0x7;
3056 uint32_t opc = 0;
3057 amount = amount == 0 ? 8 : amount;
3058
3059 switch (ctx->opcode & 0x1) {
3060 case SLL16:
3061 opc = OPC_SLL;
3062 break;
3063 case SRL16:
3064 opc = OPC_SRL;
3065 break;
3066 }
3067
3068 gen_shift_imm(ctx, opc, rd, rs, amount);
3069 }
3070 break;
3071 case POOL16C:
3072 if (ctx->insn_flags & ISA_MIPS_R6) {
3073 gen_pool16c_r6_insn(ctx);
3074 } else {
3075 gen_pool16c_insn(ctx);
3076 }
3077 break;
3078 case LWGP16:
3079 {
3080 int rd = mmreg(uMIPS_RD(ctx->opcode));
3081 int rb = 28; /* GP */
3082 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
3083
3084 gen_ld(ctx, OPC_LW, rd, rb, offset);
3085 }
3086 break;
3087 case POOL16F:
3088 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3089 if (ctx->opcode & 1) {
3090 gen_reserved_instruction(ctx);
3091 } else {
3092 /* MOVEP */
3093 int enc_dest = uMIPS_RD(ctx->opcode);
3094 int enc_rt = uMIPS_RS2(ctx->opcode);
3095 int enc_rs = uMIPS_RS1(ctx->opcode);
3096 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3097 }
3098 break;
3099 case LBU16:
3100 {
3101 int rd = mmreg(uMIPS_RD(ctx->opcode));
3102 int rb = mmreg(uMIPS_RS(ctx->opcode));
3103 int16_t offset = ZIMM(ctx->opcode, 0, 4);
3104 offset = (offset == 0xf ? -1 : offset);
3105
3106 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3107 }
3108 break;
3109 case LHU16:
3110 {
3111 int rd = mmreg(uMIPS_RD(ctx->opcode));
3112 int rb = mmreg(uMIPS_RS(ctx->opcode));
3113 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
3114
3115 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3116 }
3117 break;
3118 case LWSP16:
3119 {
3120 int rd = (ctx->opcode >> 5) & 0x1f;
3121 int rb = 29; /* SP */
3122 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
3123
3124 gen_ld(ctx, OPC_LW, rd, rb, offset);
3125 }
3126 break;
3127 case LW16:
3128 {
3129 int rd = mmreg(uMIPS_RD(ctx->opcode));
3130 int rb = mmreg(uMIPS_RS(ctx->opcode));
3131 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
3132
3133 gen_ld(ctx, OPC_LW, rd, rb, offset);
3134 }
3135 break;
3136 case SB16:
3137 {
3138 int rd = mmreg2(uMIPS_RD(ctx->opcode));
3139 int rb = mmreg(uMIPS_RS(ctx->opcode));
3140 int16_t offset = ZIMM(ctx->opcode, 0, 4);
3141
3142 gen_st(ctx, OPC_SB, rd, rb, offset);
3143 }
3144 break;
3145 case SH16:
3146 {
3147 int rd = mmreg2(uMIPS_RD(ctx->opcode));
3148 int rb = mmreg(uMIPS_RS(ctx->opcode));
3149 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
3150
3151 gen_st(ctx, OPC_SH, rd, rb, offset);
3152 }
3153 break;
3154 case SWSP16:
3155 {
3156 int rd = (ctx->opcode >> 5) & 0x1f;
3157 int rb = 29; /* SP */
3158 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
3159
3160 gen_st(ctx, OPC_SW, rd, rb, offset);
3161 }
3162 break;
3163 case SW16:
3164 {
3165 int rd = mmreg2(uMIPS_RD(ctx->opcode));
3166 int rb = mmreg(uMIPS_RS(ctx->opcode));
3167 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
3168
3169 gen_st(ctx, OPC_SW, rd, rb, offset);
3170 }
3171 break;
3172 case MOVE16:
3173 {
3174 int rd = uMIPS_RD5(ctx->opcode);
3175 int rs = uMIPS_RS5(ctx->opcode);
3176
3177 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3178 }
3179 break;
3180 case ANDI16:
3181 gen_andi16(ctx);
3182 break;
3183 case POOL16D:
3184 switch (ctx->opcode & 0x1) {
3185 case ADDIUS5:
3186 gen_addius5(ctx);
3187 break;
3188 case ADDIUSP:
3189 gen_addiusp(ctx);
3190 break;
3191 }
3192 break;
3193 case POOL16E:
3194 switch (ctx->opcode & 0x1) {
3195 case ADDIUR2:
3196 gen_addiur2(ctx);
3197 break;
3198 case ADDIUR1SP:
3199 gen_addiur1sp(ctx);
3200 break;
3201 }
3202 break;
3203 case B16: /* BC16 */
3204 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
3205 sextract32(ctx->opcode, 0, 10) << 1,
3206 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
3207 break;
3208 case BNEZ16: /* BNEZC16 */
3209 case BEQZ16: /* BEQZC16 */
3210 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
3211 mmreg(uMIPS_RD(ctx->opcode)),
3212 0, sextract32(ctx->opcode, 0, 7) << 1,
3213 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
3214
3215 break;
3216 case LI16:
3217 {
3218 int reg = mmreg(uMIPS_RD(ctx->opcode));
3219 int imm = ZIMM(ctx->opcode, 0, 7);
3220
3221 imm = (imm == 0x7f ? -1 : imm);
3222 tcg_gen_movi_tl(cpu_gpr[reg], imm);
3223 }
3224 break;
3225 case RES_29:
3226 case RES_31:
3227 case RES_39:
3228 gen_reserved_instruction(ctx);
3229 break;
3230 default:
3231 decode_micromips32_opc(env, ctx);
3232 return 4;
3233 }
3234
3235 return 2;
3236 }