2 * microMIPS translation routines
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
9 * SPDX-License-Identifier: LGPL-2.1-or-later
13 * microMIPS32/microMIPS64 major opcodes
15 * 1. MIPS Architecture for Programmers Volume II-B:
16 * The microMIPS32 Instruction Set (Revision 3.05)
18 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
20 * 2. MIPS Architecture For Programmers Volume II-A:
21 * The MIPS64 Instruction Set (Revision 3.51)
51 POOL32S = 0x16, /* MIPS64 */
52 DADDIU32 = 0x17, /* MIPS64 */
81 /* 0x29 is reserved */
94 /* 0x31 is reserved */
107 SD32 = 0x36, /* MIPS64 */
108 LD32 = 0x37, /* MIPS64 */
110 /* 0x39 is reserved */
126 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
148 /* POOL32A encoding of minor opcode field */
152 * These opcodes are distinguished only by bits 9..6; those bits are
153 * what are recorded below.
191 /* The following can be distinguished by their lower 6 bits. */
201 /* POOL32AXF encoding of minor opcode field extension */
204 * 1. MIPS Architecture for Programmers Volume II-B:
205 * The microMIPS32 Instruction Set (Revision 3.05)
207 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
209 * 2. MIPS Architecture for Programmers VolumeIV-e:
210 * The MIPS DSP Application-Specific Extension
211 * to the microMIPS32 Architecture (Revision 2.34)
213 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
228 /* begin of microMIPS32 DSP */
230 /* bits 13..12 for 0x01 */
236 /* bits 13..12 for 0x2a */
242 /* bits 13..12 for 0x32 */
246 /* end of microMIPS32 DSP */
248 /* bits 15..12 for 0x2c */
265 /* bits 15..12 for 0x34 */
273 /* bits 15..12 for 0x3c */
275 JR = 0x0, /* alias */
283 /* bits 15..12 for 0x05 */
287 /* bits 15..12 for 0x0d */
299 /* bits 15..12 for 0x15 */
305 /* bits 15..12 for 0x1d */
309 /* bits 15..12 for 0x2d */
314 /* bits 15..12 for 0x35 */
321 /* POOL32B encoding of minor opcode field (bits 15..12) */
337 /* POOL32C encoding of minor opcode field (bits 15..12) */
358 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
371 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
384 /* POOL32F encoding of minor opcode field (bits 5..0) */
387 /* These are the bit 7..6 values */
396 /* These are the bit 8..6 values */
455 CABS_COND_FMT = 0x1c, /* MIPS3D */
462 /* POOL32Fxf encoding of minor opcode extension field */
500 /* POOL32I encoding of minor opcode field (bits 25..21) */
528 /* These overlap and are distinguished by bit16 of the instruction */
537 /* POOL16A encoding of minor opcode field */
544 /* POOL16B encoding of minor opcode field */
551 /* POOL16C encoding of minor opcode field */
571 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
595 /* POOL16D encoding of minor opcode field */
602 /* POOL16E encoding of minor opcode field */
609 static int mmreg(int r)
611 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
616 /* Used for 16-bit store instructions. */
617 static int mmreg2(int r)
619 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
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)
631 /* Signed immediate */
632 #define SIMM(op, start, width) \
633 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
636 /* Zero-extended immediate */
637 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
639 static void gen_addiur1sp(DisasContext *ctx)
641 int rd = mmreg(uMIPS_RD(ctx->opcode));
643 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
646 static void gen_addiur2(DisasContext *ctx)
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));
652 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
655 static void gen_addiusp(DisasContext *ctx)
657 int encoded = ZIMM(ctx->opcode, 1, 9);
661 decoded = 256 + encoded;
662 } else if (encoded <= 255) {
664 } else if (encoded <= 509) {
665 decoded = encoded - 512;
667 decoded = encoded - 768;
670 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
673 static void gen_addius5(DisasContext *ctx)
675 int imm = SIMM(ctx->opcode, 1, 4);
676 int rd = (ctx->opcode >> 5) & 0x1f;
678 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
681 static void gen_andi16(DisasContext *ctx)
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);
689 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
692 static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
693 int base, int16_t offset)
698 if (ctx->hflags & MIPS_HFLAG_BMASK) {
699 gen_reserved_instruction(ctx);
705 gen_base_offset_addr(ctx, t0, base, offset);
707 t1 = tcg_constant_tl(reglist);
708 t2 = tcg_constant_i32(ctx->mem_idx);
710 save_cpu_state(ctx, 1);
713 gen_helper_lwm(tcg_env, t0, t1, t2);
716 gen_helper_swm(tcg_env, t0, t1, t2);
720 gen_helper_ldm(tcg_env, t0, t1, t2);
723 gen_helper_sdm(tcg_env, t0, t1, t2);
730 static void gen_pool16c_insn(DisasContext *ctx)
732 int rd = mmreg((ctx->opcode >> 3) & 0x7);
733 int rs = mmreg(ctx->opcode & 0x7);
735 switch (((ctx->opcode) >> 4) & 0x3f) {
740 gen_logic(ctx, OPC_NOR, rd, rs, 0);
746 gen_logic(ctx, OPC_XOR, rd, rd, rs);
752 gen_logic(ctx, OPC_AND, rd, rd, rs);
758 gen_logic(ctx, OPC_OR, rd, rd, rs);
765 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
766 int offset = ZIMM(ctx->opcode, 0, 4);
768 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
777 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
778 int offset = ZIMM(ctx->opcode, 0, 4);
780 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
787 int reg = ctx->opcode & 0x1f;
789 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
795 int reg = ctx->opcode & 0x1f;
796 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
798 * Let normal delay slot handling in our caller take us
799 * to the branch target.
805 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
806 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
810 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
811 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
815 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
819 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
822 generate_exception_break(ctx, extract32(ctx->opcode, 0, 4));
825 if (is_uhi(ctx, extract32(ctx->opcode, 0, 4))) {
826 ctx->base.is_jmp = DISAS_SEMIHOST;
829 * XXX: not clear which exception should be raised
830 * when in debug mode...
832 check_insn(ctx, ISA_MIPS_R1);
833 generate_exception_end(ctx, EXCP_DBp);
839 int imm = ZIMM(ctx->opcode, 0, 5);
840 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
841 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
843 * Let normal delay slot handling in our caller take us
844 * to the branch target.
849 gen_reserved_instruction(ctx);
854 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
858 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
859 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
860 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
862 rd = rd_enc[enc_dest];
863 re = re_enc[enc_dest];
864 gen_load_gpr(cpu_gpr[rd], rs_rt_enc[enc_rs]);
865 gen_load_gpr(cpu_gpr[re], rs_rt_enc[enc_rt]);
868 static void gen_pool16c_r6_insn(DisasContext *ctx)
870 int rt = mmreg((ctx->opcode >> 7) & 0x7);
871 int rs = mmreg((ctx->opcode >> 4) & 0x7);
873 switch (ctx->opcode & 0xf) {
875 gen_logic(ctx, OPC_NOR, rt, rs, 0);
878 gen_logic(ctx, OPC_AND, rt, rt, rs);
882 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
883 int offset = extract32(ctx->opcode, 4, 4);
884 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
887 case R6_JRC16: /* JRCADDIUSP */
888 if ((ctx->opcode >> 4) & 1) {
890 int imm = extract32(ctx->opcode, 5, 5);
891 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
892 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
895 rs = extract32(ctx->opcode, 5, 5);
896 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
908 int enc_dest = uMIPS_RD(ctx->opcode);
909 int enc_rt = uMIPS_RS2(ctx->opcode);
910 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
911 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
915 gen_logic(ctx, OPC_XOR, rt, rt, rs);
918 gen_logic(ctx, OPC_OR, rt, rt, rs);
922 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
923 int offset = extract32(ctx->opcode, 4, 4);
924 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
927 case JALRC16: /* BREAK16, SDBBP16 */
928 switch (ctx->opcode & 0x3f) {
932 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
937 generate_exception_break(ctx, extract32(ctx->opcode, 6, 4));
941 if (is_uhi(ctx, extract32(ctx->opcode, 6, 4))) {
942 ctx->base.is_jmp = DISAS_SEMIHOST;
944 if (ctx->hflags & MIPS_HFLAG_SBRI) {
945 generate_exception(ctx, EXCP_RI);
947 generate_exception(ctx, EXCP_DBp);
954 generate_exception(ctx, EXCP_RI);
959 static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
960 int base, int16_t offset)
964 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
965 gen_reserved_instruction(ctx);
972 gen_base_offset_addr(ctx, t0, base, offset);
977 gen_reserved_instruction(ctx);
980 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL |
981 ctx->default_tcg_memop_mask);
982 gen_store_gpr(t1, rd);
983 tcg_gen_movi_tl(t1, 4);
984 gen_op_addr_add(ctx, t0, t0, t1);
985 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL |
986 ctx->default_tcg_memop_mask);
987 gen_store_gpr(t1, rd + 1);
990 gen_load_gpr(t1, rd);
991 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
992 ctx->default_tcg_memop_mask);
993 tcg_gen_movi_tl(t1, 4);
994 gen_op_addr_add(ctx, t0, t0, t1);
995 gen_load_gpr(t1, rd + 1);
996 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
997 ctx->default_tcg_memop_mask);
1002 gen_reserved_instruction(ctx);
1005 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
1006 ctx->default_tcg_memop_mask);
1007 gen_store_gpr(t1, rd);
1008 tcg_gen_movi_tl(t1, 8);
1009 gen_op_addr_add(ctx, t0, t0, t1);
1010 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
1011 ctx->default_tcg_memop_mask);
1012 gen_store_gpr(t1, rd + 1);
1015 gen_load_gpr(t1, rd);
1016 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
1017 ctx->default_tcg_memop_mask);
1018 tcg_gen_movi_tl(t1, 8);
1019 gen_op_addr_add(ctx, t0, t0, t1);
1020 gen_load_gpr(t1, rd + 1);
1021 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
1022 ctx->default_tcg_memop_mask);
1028 static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
1030 int extension = (ctx->opcode >> 6) & 0x3f;
1031 int minor = (ctx->opcode >> 12) & 0xf;
1034 switch (extension) {
1036 mips32_op = OPC_TEQ;
1039 mips32_op = OPC_TGE;
1042 mips32_op = OPC_TGEU;
1045 mips32_op = OPC_TLT;
1048 mips32_op = OPC_TLTU;
1051 mips32_op = OPC_TNE;
1053 gen_trap(ctx, mips32_op, rs, rt, -1, extract32(ctx->opcode, 12, 4));
1055 #ifndef CONFIG_USER_ONLY
1058 check_cp0_enabled(ctx);
1063 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
1067 check_cp0_enabled(ctx);
1069 TCGv t0 = tcg_temp_new();
1071 gen_load_gpr(t0, rt);
1072 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
1077 switch (minor & 3) {
1079 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
1082 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
1085 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
1088 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
1091 goto pool32axf_invalid;
1095 switch (minor & 3) {
1097 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
1100 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
1103 goto pool32axf_invalid;
1109 check_insn(ctx, ISA_MIPS_R6);
1110 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
1113 gen_bshfl(ctx, OPC_SEB, rs, rt);
1116 gen_bshfl(ctx, OPC_SEH, rs, rt);
1119 mips32_op = OPC_CLO;
1122 mips32_op = OPC_CLZ;
1124 check_insn(ctx, ISA_MIPS_R1);
1125 gen_cl(ctx, mips32_op, rt, rs);
1128 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1129 gen_rdhwr(ctx, rt, rs, 0);
1132 gen_bshfl(ctx, OPC_WSBH, rs, rt);
1135 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1136 mips32_op = OPC_MULT;
1139 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1140 mips32_op = OPC_MULTU;
1143 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1144 mips32_op = OPC_DIV;
1147 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1148 mips32_op = OPC_DIVU;
1151 check_insn(ctx, ISA_MIPS_R1);
1152 gen_muldiv(ctx, mips32_op, 0, rs, rt);
1155 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1156 mips32_op = OPC_MADD;
1159 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1160 mips32_op = OPC_MADDU;
1163 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1164 mips32_op = OPC_MSUB;
1167 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1168 mips32_op = OPC_MSUBU;
1170 check_insn(ctx, ISA_MIPS_R1);
1171 gen_muldiv(ctx, mips32_op, 0, rs, rt);
1174 goto pool32axf_invalid;
1185 generate_exception_err(ctx, EXCP_CpU, 2);
1188 goto pool32axf_invalid;
1193 case JALR: /* JALRC */
1194 case JALR_HB: /* JALRC_HB */
1195 if (ctx->insn_flags & ISA_MIPS_R6) {
1196 /* JALRC, JALRC_HB */
1197 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
1200 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
1201 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
1206 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1207 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
1208 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
1211 goto pool32axf_invalid;
1217 check_cp0_enabled(ctx);
1218 check_insn(ctx, ISA_MIPS_R2);
1219 gen_load_srsgpr(rs, rt);
1222 check_cp0_enabled(ctx);
1223 check_insn(ctx, ISA_MIPS_R2);
1224 gen_store_srsgpr(rs, rt);
1227 goto pool32axf_invalid;
1230 #ifndef CONFIG_USER_ONLY
1234 mips32_op = OPC_TLBP;
1237 mips32_op = OPC_TLBR;
1240 mips32_op = OPC_TLBWI;
1243 mips32_op = OPC_TLBWR;
1246 mips32_op = OPC_TLBINV;
1249 mips32_op = OPC_TLBINVF;
1252 mips32_op = OPC_WAIT;
1255 mips32_op = OPC_DERET;
1258 mips32_op = OPC_ERET;
1260 gen_cp0(env, ctx, mips32_op, rt, rs);
1263 goto pool32axf_invalid;
1269 check_cp0_enabled(ctx);
1271 TCGv t0 = tcg_temp_new();
1273 save_cpu_state(ctx, 1);
1274 gen_helper_di(t0, tcg_env);
1275 gen_store_gpr(t0, rs);
1277 * Stop translation as we may have switched the execution
1280 ctx->base.is_jmp = DISAS_STOP;
1284 check_cp0_enabled(ctx);
1286 TCGv t0 = tcg_temp_new();
1288 save_cpu_state(ctx, 1);
1289 gen_helper_ei(t0, tcg_env);
1290 gen_store_gpr(t0, rs);
1292 * DISAS_STOP isn't sufficient, we need to ensure we break out
1293 * of translated code to check for pending interrupts.
1295 gen_save_pc(ctx->base.pc_next + 4);
1296 ctx->base.is_jmp = DISAS_EXIT;
1300 goto pool32axf_invalid;
1307 gen_sync(extract32(ctx->opcode, 16, 5));
1310 generate_exception_end(ctx, EXCP_SYSCALL);
1313 if (is_uhi(ctx, extract32(ctx->opcode, 16, 10))) {
1314 ctx->base.is_jmp = DISAS_SEMIHOST;
1316 check_insn(ctx, ISA_MIPS_R1);
1317 if (ctx->hflags & MIPS_HFLAG_SBRI) {
1318 gen_reserved_instruction(ctx);
1320 generate_exception_end(ctx, EXCP_DBp);
1325 goto pool32axf_invalid;
1329 switch (minor & 3) {
1331 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
1334 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
1337 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
1340 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
1343 goto pool32axf_invalid;
1347 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1350 gen_HILO(ctx, OPC_MFHI, 0, rs);
1353 gen_HILO(ctx, OPC_MFLO, 0, rs);
1356 gen_HILO(ctx, OPC_MTHI, 0, rs);
1359 gen_HILO(ctx, OPC_MTLO, 0, rs);
1362 goto pool32axf_invalid;
1367 MIPS_INVAL("pool32axf");
1368 gen_reserved_instruction(ctx);
1373 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
1375 int extension = (ctx->opcode >> 6) & 0x3ff;
1378 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
1379 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
1380 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
1382 switch (extension) {
1383 case FLOAT_1BIT_FMT(CFC1, 0):
1384 mips32_op = OPC_CFC1;
1386 case FLOAT_1BIT_FMT(CTC1, 0):
1387 mips32_op = OPC_CTC1;
1389 case FLOAT_1BIT_FMT(MFC1, 0):
1390 mips32_op = OPC_MFC1;
1392 case FLOAT_1BIT_FMT(MTC1, 0):
1393 mips32_op = OPC_MTC1;
1395 case FLOAT_1BIT_FMT(MFHC1, 0):
1396 mips32_op = OPC_MFHC1;
1398 case FLOAT_1BIT_FMT(MTHC1, 0):
1399 mips32_op = OPC_MTHC1;
1401 gen_cp1(ctx, mips32_op, rt, rs);
1404 /* Reciprocal square root */
1405 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
1406 mips32_op = OPC_RSQRT_S;
1408 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
1409 mips32_op = OPC_RSQRT_D;
1413 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
1414 mips32_op = OPC_SQRT_S;
1416 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
1417 mips32_op = OPC_SQRT_D;
1421 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
1422 mips32_op = OPC_RECIP_S;
1424 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
1425 mips32_op = OPC_RECIP_D;
1429 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
1430 mips32_op = OPC_FLOOR_L_S;
1432 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
1433 mips32_op = OPC_FLOOR_L_D;
1435 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
1436 mips32_op = OPC_FLOOR_W_S;
1438 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
1439 mips32_op = OPC_FLOOR_W_D;
1443 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
1444 mips32_op = OPC_CEIL_L_S;
1446 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
1447 mips32_op = OPC_CEIL_L_D;
1449 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
1450 mips32_op = OPC_CEIL_W_S;
1452 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
1453 mips32_op = OPC_CEIL_W_D;
1457 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
1458 mips32_op = OPC_TRUNC_L_S;
1460 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
1461 mips32_op = OPC_TRUNC_L_D;
1463 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
1464 mips32_op = OPC_TRUNC_W_S;
1466 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
1467 mips32_op = OPC_TRUNC_W_D;
1471 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
1472 mips32_op = OPC_ROUND_L_S;
1474 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
1475 mips32_op = OPC_ROUND_L_D;
1477 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
1478 mips32_op = OPC_ROUND_W_S;
1480 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
1481 mips32_op = OPC_ROUND_W_D;
1484 /* Integer to floating-point conversion */
1485 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
1486 mips32_op = OPC_CVT_L_S;
1488 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
1489 mips32_op = OPC_CVT_L_D;
1491 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
1492 mips32_op = OPC_CVT_W_S;
1494 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
1495 mips32_op = OPC_CVT_W_D;
1498 /* Paired-foo conversions */
1499 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
1500 mips32_op = OPC_CVT_S_PL;
1502 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
1503 mips32_op = OPC_CVT_S_PU;
1505 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
1506 mips32_op = OPC_CVT_PW_PS;
1508 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
1509 mips32_op = OPC_CVT_PS_PW;
1512 /* Floating-point moves */
1513 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
1514 mips32_op = OPC_MOV_S;
1516 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
1517 mips32_op = OPC_MOV_D;
1519 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
1520 mips32_op = OPC_MOV_PS;
1523 /* Absolute value */
1524 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
1525 mips32_op = OPC_ABS_S;
1527 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
1528 mips32_op = OPC_ABS_D;
1530 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
1531 mips32_op = OPC_ABS_PS;
1535 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
1536 mips32_op = OPC_NEG_S;
1538 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
1539 mips32_op = OPC_NEG_D;
1541 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
1542 mips32_op = OPC_NEG_PS;
1545 /* Reciprocal square root step */
1546 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
1547 mips32_op = OPC_RSQRT1_S;
1549 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
1550 mips32_op = OPC_RSQRT1_D;
1552 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
1553 mips32_op = OPC_RSQRT1_PS;
1556 /* Reciprocal step */
1557 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
1558 mips32_op = OPC_RECIP1_S;
1560 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
1561 mips32_op = OPC_RECIP1_S;
1563 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
1564 mips32_op = OPC_RECIP1_PS;
1567 /* Conversions from double */
1568 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
1569 mips32_op = OPC_CVT_D_S;
1571 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
1572 mips32_op = OPC_CVT_D_W;
1574 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
1575 mips32_op = OPC_CVT_D_L;
1578 /* Conversions from single */
1579 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
1580 mips32_op = OPC_CVT_S_D;
1582 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
1583 mips32_op = OPC_CVT_S_W;
1585 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
1586 mips32_op = OPC_CVT_S_L;
1588 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
1591 /* Conditional moves on floating-point codes */
1592 case COND_FLOAT_MOV(MOVT, 0):
1593 case COND_FLOAT_MOV(MOVT, 1):
1594 case COND_FLOAT_MOV(MOVT, 2):
1595 case COND_FLOAT_MOV(MOVT, 3):
1596 case COND_FLOAT_MOV(MOVT, 4):
1597 case COND_FLOAT_MOV(MOVT, 5):
1598 case COND_FLOAT_MOV(MOVT, 6):
1599 case COND_FLOAT_MOV(MOVT, 7):
1600 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1601 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
1603 case COND_FLOAT_MOV(MOVF, 0):
1604 case COND_FLOAT_MOV(MOVF, 1):
1605 case COND_FLOAT_MOV(MOVF, 2):
1606 case COND_FLOAT_MOV(MOVF, 3):
1607 case COND_FLOAT_MOV(MOVF, 4):
1608 case COND_FLOAT_MOV(MOVF, 5):
1609 case COND_FLOAT_MOV(MOVF, 6):
1610 case COND_FLOAT_MOV(MOVF, 7):
1611 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1612 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
1615 MIPS_INVAL("pool32fxf");
1616 gen_reserved_instruction(ctx);
1621 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
1627 uint32_t op, minor, minor2, mips32_op;
1628 uint32_t cond, fmt, cc;
1630 insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
1631 ctx->opcode = (ctx->opcode << 16) | insn;
1633 rt = (ctx->opcode >> 21) & 0x1f;
1634 rs = (ctx->opcode >> 16) & 0x1f;
1635 rd = (ctx->opcode >> 11) & 0x1f;
1636 rr = (ctx->opcode >> 6) & 0x1f;
1637 imm = (int16_t) ctx->opcode;
1639 op = (ctx->opcode >> 26) & 0x3f;
1642 minor = ctx->opcode & 0x3f;
1645 minor = (ctx->opcode >> 6) & 0xf;
1648 mips32_op = OPC_SLL;
1651 mips32_op = OPC_SRA;
1654 mips32_op = OPC_SRL;
1657 mips32_op = OPC_ROTR;
1659 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
1662 check_insn(ctx, ISA_MIPS_R6);
1663 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
1666 check_insn(ctx, ISA_MIPS_R6);
1667 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
1670 check_insn(ctx, ISA_MIPS_R6);
1671 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
1674 goto pool32a_invalid;
1678 minor = (ctx->opcode >> 6) & 0xf;
1682 mips32_op = OPC_ADD;
1685 mips32_op = OPC_ADDU;
1688 mips32_op = OPC_SUB;
1691 mips32_op = OPC_SUBU;
1694 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1695 mips32_op = OPC_MUL;
1697 gen_arith(ctx, mips32_op, rd, rs, rt);
1701 mips32_op = OPC_SLLV;
1704 mips32_op = OPC_SRLV;
1707 mips32_op = OPC_SRAV;
1710 mips32_op = OPC_ROTRV;
1712 gen_shift(ctx, mips32_op, rd, rs, rt);
1714 /* Logical operations */
1716 mips32_op = OPC_AND;
1722 mips32_op = OPC_NOR;
1725 mips32_op = OPC_XOR;
1727 gen_logic(ctx, mips32_op, rd, rs, rt);
1731 mips32_op = OPC_SLT;
1734 mips32_op = OPC_SLTU;
1736 gen_slt(ctx, mips32_op, rd, rs, rt);
1739 goto pool32a_invalid;
1743 minor = (ctx->opcode >> 6) & 0xf;
1745 /* Conditional moves */
1746 case MOVN: /* MUL */
1747 if (ctx->insn_flags & ISA_MIPS_R6) {
1749 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
1752 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
1755 case MOVZ: /* MUH */
1756 if (ctx->insn_flags & ISA_MIPS_R6) {
1758 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
1761 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
1765 check_insn(ctx, ISA_MIPS_R6);
1766 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
1769 check_insn(ctx, ISA_MIPS_R6);
1770 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
1772 case LWXS: /* DIV */
1773 if (ctx->insn_flags & ISA_MIPS_R6) {
1775 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
1778 gen_ldxs(ctx, rs, rt, rd);
1782 check_insn(ctx, ISA_MIPS_R6);
1783 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
1786 check_insn(ctx, ISA_MIPS_R6);
1787 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
1790 check_insn(ctx, ISA_MIPS_R6);
1791 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
1794 goto pool32a_invalid;
1798 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
1801 check_insn(ctx, ISA_MIPS_R6);
1802 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2));
1805 check_insn(ctx, ISA_MIPS_R6);
1806 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
1809 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
1812 gen_pool32axf(env, ctx, rt, rs);
1815 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
1818 check_insn(ctx, ISA_MIPS_R6);
1819 gen_reserved_instruction(ctx);
1823 MIPS_INVAL("pool32a");
1824 gen_reserved_instruction(ctx);
1829 minor = (ctx->opcode >> 12) & 0xf;
1832 check_cp0_enabled(ctx);
1833 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
1834 gen_cache_operation(ctx, rt, rs, imm);
1839 /* COP2: Not implemented. */
1840 generate_exception_err(ctx, EXCP_CpU, 2);
1842 #ifdef TARGET_MIPS64
1845 check_insn(ctx, ISA_MIPS3);
1851 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
1853 #ifdef TARGET_MIPS64
1856 check_insn(ctx, ISA_MIPS3);
1862 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
1865 MIPS_INVAL("pool32b");
1866 gen_reserved_instruction(ctx);
1871 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
1872 minor = ctx->opcode & 0x3f;
1873 check_cp1_enabled(ctx);
1876 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1877 mips32_op = OPC_ALNV_PS;
1880 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1881 mips32_op = OPC_MADD_S;
1884 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1885 mips32_op = OPC_MADD_D;
1888 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1889 mips32_op = OPC_MADD_PS;
1892 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1893 mips32_op = OPC_MSUB_S;
1896 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1897 mips32_op = OPC_MSUB_D;
1900 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1901 mips32_op = OPC_MSUB_PS;
1904 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1905 mips32_op = OPC_NMADD_S;
1908 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1909 mips32_op = OPC_NMADD_D;
1912 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1913 mips32_op = OPC_NMADD_PS;
1916 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1917 mips32_op = OPC_NMSUB_S;
1920 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1921 mips32_op = OPC_NMSUB_D;
1924 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1925 mips32_op = OPC_NMSUB_PS;
1927 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
1930 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1931 cond = (ctx->opcode >> 6) & 0xf;
1932 cc = (ctx->opcode >> 13) & 0x7;
1933 fmt = (ctx->opcode >> 10) & 0x3;
1936 gen_cmpabs_s(ctx, cond, rt, rs, cc);
1939 gen_cmpabs_d(ctx, cond, rt, rs, cc);
1942 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
1945 goto pool32f_invalid;
1949 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1950 cond = (ctx->opcode >> 6) & 0xf;
1951 cc = (ctx->opcode >> 13) & 0x7;
1952 fmt = (ctx->opcode >> 10) & 0x3;
1955 gen_cmp_s(ctx, cond, rt, rs, cc);
1958 gen_cmp_d(ctx, cond, rt, rs, cc);
1961 gen_cmp_ps(ctx, cond, rt, rs, cc);
1964 goto pool32f_invalid;
1968 check_insn(ctx, ISA_MIPS_R6);
1969 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
1972 check_insn(ctx, ISA_MIPS_R6);
1973 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
1976 gen_pool32fxf(ctx, rt, rs);
1980 switch ((ctx->opcode >> 6) & 0x7) {
1982 mips32_op = OPC_PLL_PS;
1985 mips32_op = OPC_PLU_PS;
1988 mips32_op = OPC_PUL_PS;
1991 mips32_op = OPC_PUU_PS;
1994 check_insn_opc_removed(ctx, ISA_MIPS_R6);
1995 mips32_op = OPC_CVT_PS_S;
1997 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
2000 goto pool32f_invalid;
2004 check_insn(ctx, ISA_MIPS_R6);
2005 switch ((ctx->opcode >> 9) & 0x3) {
2007 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
2010 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
2013 goto pool32f_invalid;
2018 switch ((ctx->opcode >> 6) & 0x7) {
2020 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2021 mips32_op = OPC_LWXC1;
2024 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2025 mips32_op = OPC_SWXC1;
2028 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2029 mips32_op = OPC_LDXC1;
2032 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2033 mips32_op = OPC_SDXC1;
2036 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2037 mips32_op = OPC_LUXC1;
2040 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2041 mips32_op = OPC_SUXC1;
2043 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
2046 goto pool32f_invalid;
2050 check_insn(ctx, ISA_MIPS_R6);
2051 switch ((ctx->opcode >> 9) & 0x3) {
2053 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
2056 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
2059 goto pool32f_invalid;
2064 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2065 fmt = (ctx->opcode >> 9) & 0x3;
2066 switch ((ctx->opcode >> 6) & 0x7) {
2070 mips32_op = OPC_RSQRT2_S;
2073 mips32_op = OPC_RSQRT2_D;
2076 mips32_op = OPC_RSQRT2_PS;
2079 goto pool32f_invalid;
2085 mips32_op = OPC_RECIP2_S;
2088 mips32_op = OPC_RECIP2_D;
2091 mips32_op = OPC_RECIP2_PS;
2094 goto pool32f_invalid;
2098 mips32_op = OPC_ADDR_PS;
2101 mips32_op = OPC_MULR_PS;
2103 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
2106 goto pool32f_invalid;
2110 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
2111 cc = (ctx->opcode >> 13) & 0x7;
2112 fmt = (ctx->opcode >> 9) & 0x3;
2113 switch ((ctx->opcode >> 6) & 0x7) {
2114 case MOVF_FMT: /* RINT_FMT */
2115 if (ctx->insn_flags & ISA_MIPS_R6) {
2119 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
2122 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
2125 goto pool32f_invalid;
2131 gen_movcf_s(ctx, rs, rt, cc, 0);
2134 gen_movcf_d(ctx, rs, rt, cc, 0);
2138 gen_movcf_ps(ctx, rs, rt, cc, 0);
2141 goto pool32f_invalid;
2145 case MOVT_FMT: /* CLASS_FMT */
2146 if (ctx->insn_flags & ISA_MIPS_R6) {
2150 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
2153 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
2156 goto pool32f_invalid;
2162 gen_movcf_s(ctx, rs, rt, cc, 1);
2165 gen_movcf_d(ctx, rs, rt, cc, 1);
2169 gen_movcf_ps(ctx, rs, rt, cc, 1);
2172 goto pool32f_invalid;
2177 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2180 goto pool32f_invalid;
2183 #define FINSN_3ARG_SDPS(prfx) \
2184 switch ((ctx->opcode >> 8) & 0x3) { \
2186 mips32_op = OPC_##prfx##_S; \
2189 mips32_op = OPC_##prfx##_D; \
2193 mips32_op = OPC_##prfx##_PS; \
2196 goto pool32f_invalid; \
2199 check_insn(ctx, ISA_MIPS_R6);
2200 switch ((ctx->opcode >> 9) & 0x3) {
2202 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
2205 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
2208 goto pool32f_invalid;
2212 check_insn(ctx, ISA_MIPS_R6);
2213 switch ((ctx->opcode >> 9) & 0x3) {
2215 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
2218 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
2221 goto pool32f_invalid;
2225 /* regular FP ops */
2226 switch ((ctx->opcode >> 6) & 0x3) {
2228 FINSN_3ARG_SDPS(ADD);
2231 FINSN_3ARG_SDPS(SUB);
2234 FINSN_3ARG_SDPS(MUL);
2237 fmt = (ctx->opcode >> 8) & 0x3;
2239 mips32_op = OPC_DIV_D;
2240 } else if (fmt == 0) {
2241 mips32_op = OPC_DIV_S;
2243 goto pool32f_invalid;
2247 goto pool32f_invalid;
2252 switch ((ctx->opcode >> 6) & 0x7) {
2253 case MOVN_FMT: /* SELEQZ_FMT */
2254 if (ctx->insn_flags & ISA_MIPS_R6) {
2256 switch ((ctx->opcode >> 9) & 0x3) {
2258 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2261 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2264 goto pool32f_invalid;
2268 FINSN_3ARG_SDPS(MOVN);
2272 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2273 FINSN_3ARG_SDPS(MOVN);
2275 case MOVZ_FMT: /* SELNEZ_FMT */
2276 if (ctx->insn_flags & ISA_MIPS_R6) {
2278 switch ((ctx->opcode >> 9) & 0x3) {
2280 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2283 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2286 goto pool32f_invalid;
2290 FINSN_3ARG_SDPS(MOVZ);
2294 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2295 FINSN_3ARG_SDPS(MOVZ);
2298 check_insn(ctx, ISA_MIPS_R6);
2299 switch ((ctx->opcode >> 9) & 0x3) {
2301 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
2304 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
2307 goto pool32f_invalid;
2311 check_insn(ctx, ISA_MIPS_R6);
2312 switch ((ctx->opcode >> 9) & 0x3) {
2314 mips32_op = OPC_MADDF_S;
2317 mips32_op = OPC_MADDF_D;
2320 goto pool32f_invalid;
2324 check_insn(ctx, ISA_MIPS_R6);
2325 switch ((ctx->opcode >> 9) & 0x3) {
2327 mips32_op = OPC_MSUBF_S;
2330 mips32_op = OPC_MSUBF_D;
2333 goto pool32f_invalid;
2337 goto pool32f_invalid;
2341 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
2345 MIPS_INVAL("pool32f");
2346 gen_reserved_instruction(ctx);
2350 generate_exception_err(ctx, EXCP_CpU, 1);
2354 minor = (ctx->opcode >> 21) & 0x1f;
2357 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2358 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
2361 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2362 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
2363 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2366 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2367 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
2368 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2371 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2372 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
2375 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2376 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
2377 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2380 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2381 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
2382 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2385 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2386 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
2389 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2390 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
2394 case TLTI: /* BC1EQZC */
2395 if (ctx->insn_flags & ISA_MIPS_R6) {
2397 check_cp1_enabled(ctx);
2398 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
2401 mips32_op = OPC_TLTI;
2405 case TGEI: /* BC1NEZC */
2406 if (ctx->insn_flags & ISA_MIPS_R6) {
2408 check_cp1_enabled(ctx);
2409 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
2412 mips32_op = OPC_TGEI;
2417 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2418 mips32_op = OPC_TLTIU;
2421 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2422 mips32_op = OPC_TGEIU;
2424 case TNEI: /* SYNCI */
2425 if (ctx->insn_flags & ISA_MIPS_R6) {
2428 * Break the TB to be able to sync copied instructions
2431 ctx->base.is_jmp = DISAS_STOP;
2434 mips32_op = OPC_TNEI;
2439 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2440 mips32_op = OPC_TEQI;
2442 gen_trap(ctx, mips32_op, rs, -1, imm, 0);
2447 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2448 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
2449 4, rs, 0, imm << 1, 0);
2451 * Compact branches don't have a delay slot, so just let
2452 * the normal delay slot handling take us to the branch
2457 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2458 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
2461 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2463 * Break the TB to be able to sync copied instructions
2466 ctx->base.is_jmp = DISAS_STOP;
2470 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2471 /* COP2: Not implemented. */
2472 generate_exception_err(ctx, EXCP_CpU, 2);
2475 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2476 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
2479 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2480 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
2483 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2484 mips32_op = OPC_BC1FANY4;
2487 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2488 mips32_op = OPC_BC1TANY4;
2491 check_insn(ctx, ASE_MIPS3D);
2494 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
2495 check_cp1_enabled(ctx);
2496 gen_compute_branch1(ctx, mips32_op,
2497 (ctx->opcode >> 18) & 0x7, imm << 1);
2499 generate_exception_err(ctx, EXCP_CpU, 1);
2503 MIPS_INVAL("pool32i");
2504 gen_reserved_instruction(ctx);
2509 minor = (ctx->opcode >> 12) & 0xf;
2510 offset = sextract32(ctx->opcode, 0,
2511 (ctx->insn_flags & ISA_MIPS_R6) ? 9 : 12);
2514 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2515 mips32_op = OPC_LWL;
2518 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2519 mips32_op = OPC_SWL;
2522 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2523 mips32_op = OPC_LWR;
2526 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2527 mips32_op = OPC_SWR;
2529 #if defined(TARGET_MIPS64)
2531 check_insn(ctx, ISA_MIPS3);
2533 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2534 mips32_op = OPC_LDL;
2537 check_insn(ctx, ISA_MIPS3);
2539 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2540 mips32_op = OPC_SDL;
2543 check_insn(ctx, ISA_MIPS3);
2545 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2546 mips32_op = OPC_LDR;
2549 check_insn(ctx, ISA_MIPS3);
2551 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2552 mips32_op = OPC_SDR;
2555 check_insn(ctx, ISA_MIPS3);
2557 mips32_op = OPC_LWU;
2560 check_insn(ctx, ISA_MIPS3);
2562 mips32_op = OPC_LLD;
2569 gen_ld(ctx, mips32_op, rt, rs, offset);
2572 gen_st(ctx, mips32_op, rt, rs, offset);
2575 gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
2577 #if defined(TARGET_MIPS64)
2579 check_insn(ctx, ISA_MIPS3);
2581 gen_st_cond(ctx, rt, rs, offset, MO_TEUQ, false);
2586 MIPS_INVAL("pool32c ld-eva");
2587 gen_reserved_instruction(ctx);
2590 check_cp0_enabled(ctx);
2592 minor2 = (ctx->opcode >> 9) & 0x7;
2593 offset = sextract32(ctx->opcode, 0, 9);
2596 mips32_op = OPC_LBUE;
2599 mips32_op = OPC_LHUE;
2602 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2603 mips32_op = OPC_LWLE;
2606 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2607 mips32_op = OPC_LWRE;
2610 mips32_op = OPC_LBE;
2613 mips32_op = OPC_LHE;
2616 mips32_op = OPC_LLE;
2619 mips32_op = OPC_LWE;
2625 MIPS_INVAL("pool32c st-eva");
2626 gen_reserved_instruction(ctx);
2629 check_cp0_enabled(ctx);
2631 minor2 = (ctx->opcode >> 9) & 0x7;
2632 offset = sextract32(ctx->opcode, 0, 9);
2635 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2636 mips32_op = OPC_SWLE;
2639 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2640 mips32_op = OPC_SWRE;
2643 /* Treat as no-op */
2644 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
2645 /* hint codes 24-31 are reserved and signal RI */
2646 generate_exception(ctx, EXCP_RI);
2650 /* Treat as no-op */
2651 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
2652 gen_cache_operation(ctx, rt, rs, offset);
2656 mips32_op = OPC_SBE;
2659 mips32_op = OPC_SHE;
2662 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
2665 mips32_op = OPC_SWE;
2670 /* Treat as no-op */
2671 if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
2672 /* hint codes 24-31 are reserved and signal RI */
2673 generate_exception(ctx, EXCP_RI);
2677 MIPS_INVAL("pool32c");
2678 gen_reserved_instruction(ctx);
2682 case ADDI32: /* AUI, LUI */
2683 if (ctx->insn_flags & ISA_MIPS_R6) {
2685 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
2688 mips32_op = OPC_ADDI;
2693 mips32_op = OPC_ADDIU;
2695 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
2698 /* Logical operations */
2700 mips32_op = OPC_ORI;
2703 mips32_op = OPC_XORI;
2706 mips32_op = OPC_ANDI;
2708 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
2711 /* Set less than immediate */
2713 mips32_op = OPC_SLTI;
2716 mips32_op = OPC_SLTIU;
2718 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
2721 check_insn_opc_removed(ctx, ISA_MIPS_R6);
2722 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
2723 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
2724 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2726 case JALS32: /* BOVC, BEQC, BEQZALC */
2727 if (ctx->insn_flags & ISA_MIPS_R6) {
2730 mips32_op = OPC_BOVC;
2731 } else if (rs < rt && rs == 0) {
2733 mips32_op = OPC_BEQZALC;
2736 mips32_op = OPC_BEQC;
2738 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2741 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
2742 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
2743 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2746 case BEQ32: /* BC */
2747 if (ctx->insn_flags & ISA_MIPS_R6) {
2749 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
2750 sextract32(ctx->opcode << 1, 0, 27));
2753 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
2756 case BNE32: /* BALC */
2757 if (ctx->insn_flags & ISA_MIPS_R6) {
2759 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
2760 sextract32(ctx->opcode << 1, 0, 27));
2763 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
2766 case J32: /* BGTZC, BLTZC, BLTC */
2767 if (ctx->insn_flags & ISA_MIPS_R6) {
2768 if (rs == 0 && rt != 0) {
2770 mips32_op = OPC_BGTZC;
2771 } else if (rs != 0 && rt != 0 && rs == rt) {
2773 mips32_op = OPC_BLTZC;
2776 mips32_op = OPC_BLTC;
2778 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2781 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
2782 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
2785 case JAL32: /* BLEZC, BGEZC, BGEC */
2786 if (ctx->insn_flags & ISA_MIPS_R6) {
2787 if (rs == 0 && rt != 0) {
2789 mips32_op = OPC_BLEZC;
2790 } else if (rs != 0 && rt != 0 && rs == rt) {
2792 mips32_op = OPC_BGEZC;
2795 mips32_op = OPC_BGEC;
2797 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2800 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
2801 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
2802 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
2805 /* Floating point (COP1) */
2807 mips32_op = OPC_LWC1;
2810 mips32_op = OPC_LDC1;
2813 mips32_op = OPC_SWC1;
2816 mips32_op = OPC_SDC1;
2818 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
2820 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
2821 if (ctx->insn_flags & ISA_MIPS_R6) {
2822 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
2823 switch ((ctx->opcode >> 16) & 0x1f) {
2832 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
2835 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
2838 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
2848 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
2851 generate_exception(ctx, EXCP_RI);
2856 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
2857 offset = SIMM(ctx->opcode, 0, 23) << 2;
2859 gen_addiupc(ctx, reg, offset, 0, 0);
2862 case BNVC: /* BNEC, BNEZALC */
2863 check_insn(ctx, ISA_MIPS_R6);
2866 mips32_op = OPC_BNVC;
2867 } else if (rs < rt && rs == 0) {
2869 mips32_op = OPC_BNEZALC;
2872 mips32_op = OPC_BNEC;
2874 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2876 case R6_BNEZC: /* JIALC */
2877 check_insn(ctx, ISA_MIPS_R6);
2880 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
2881 sextract32(ctx->opcode << 1, 0, 22));
2884 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
2887 case R6_BEQZC: /* JIC */
2888 check_insn(ctx, ISA_MIPS_R6);
2891 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
2892 sextract32(ctx->opcode << 1, 0, 22));
2895 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
2898 case BLEZALC: /* BGEZALC, BGEUC */
2899 check_insn(ctx, ISA_MIPS_R6);
2900 if (rs == 0 && rt != 0) {
2902 mips32_op = OPC_BLEZALC;
2903 } else if (rs != 0 && rt != 0 && rs == rt) {
2905 mips32_op = OPC_BGEZALC;
2908 mips32_op = OPC_BGEUC;
2910 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2912 case BGTZALC: /* BLTZALC, BLTUC */
2913 check_insn(ctx, ISA_MIPS_R6);
2914 if (rs == 0 && rt != 0) {
2916 mips32_op = OPC_BGTZALC;
2917 } else if (rs != 0 && rt != 0 && rs == rt) {
2919 mips32_op = OPC_BLTZALC;
2922 mips32_op = OPC_BLTUC;
2924 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
2926 /* Loads and stores */
2931 mips32_op = OPC_LBU;
2937 mips32_op = OPC_LHU;
2942 #ifdef TARGET_MIPS64
2944 check_insn(ctx, ISA_MIPS3);
2949 check_insn(ctx, ISA_MIPS3);
2964 gen_ld(ctx, mips32_op, rt, rs, imm);
2967 gen_st(ctx, mips32_op, rt, rs, imm);
2970 gen_reserved_instruction(ctx);
2975 static int decode_isa_micromips(CPUMIPSState *env, DisasContext *ctx)
2979 /* make sure instructions are on a halfword boundary */
2980 if (ctx->base.pc_next & 0x1) {
2981 env->CP0_BadVAddr = ctx->base.pc_next;
2982 generate_exception_end(ctx, EXCP_AdEL);
2986 op = (ctx->opcode >> 10) & 0x3f;
2987 /* Enforce properly-sized instructions in a delay slot */
2988 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
2989 switch (op & 0x7) { /* MSB-3..MSB-5 */
2991 /* POOL32A, POOL32B, POOL32I, POOL32C */
2993 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
2995 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
2997 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
2999 /* LB32, LH32, LWC132, LDC132, LW32 */
3000 if (ctx->hflags & MIPS_HFLAG_BDS16) {
3001 gen_reserved_instruction(ctx);
3006 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
3008 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
3010 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
3011 if (ctx->hflags & MIPS_HFLAG_BDS32) {
3012 gen_reserved_instruction(ctx);
3022 int rd = mmreg(uMIPS_RD(ctx->opcode));
3023 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
3024 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
3027 switch (ctx->opcode & 0x1) {
3035 if (ctx->insn_flags & ISA_MIPS_R6) {
3037 * In the Release 6, the register number location in
3038 * the instruction encoding has changed.
3040 gen_arith(ctx, opc, rs1, rd, rs2);
3042 gen_arith(ctx, opc, rd, rs1, rs2);
3048 int rd = mmreg(uMIPS_RD(ctx->opcode));
3049 int rs = mmreg(uMIPS_RS(ctx->opcode));
3050 int amount = (ctx->opcode >> 1) & 0x7;
3052 amount = amount == 0 ? 8 : amount;
3054 switch (ctx->opcode & 0x1) {
3063 gen_shift_imm(ctx, opc, rd, rs, amount);
3067 if (ctx->insn_flags & ISA_MIPS_R6) {
3068 gen_pool16c_r6_insn(ctx);
3070 gen_pool16c_insn(ctx);
3075 int rd = mmreg(uMIPS_RD(ctx->opcode));
3076 int rb = 28; /* GP */
3077 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
3079 gen_ld(ctx, OPC_LW, rd, rb, offset);
3083 check_insn_opc_removed(ctx, ISA_MIPS_R6);
3084 if (ctx->opcode & 1) {
3085 gen_reserved_instruction(ctx);
3088 int enc_dest = uMIPS_RD(ctx->opcode);
3089 int enc_rt = uMIPS_RS2(ctx->opcode);
3090 int enc_rs = uMIPS_RS1(ctx->opcode);
3091 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3096 int rd = mmreg(uMIPS_RD(ctx->opcode));
3097 int rb = mmreg(uMIPS_RS(ctx->opcode));
3098 int16_t offset = ZIMM(ctx->opcode, 0, 4);
3099 offset = (offset == 0xf ? -1 : offset);
3101 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3106 int rd = mmreg(uMIPS_RD(ctx->opcode));
3107 int rb = mmreg(uMIPS_RS(ctx->opcode));
3108 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
3110 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3115 int rd = (ctx->opcode >> 5) & 0x1f;
3116 int rb = 29; /* SP */
3117 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
3119 gen_ld(ctx, OPC_LW, rd, rb, offset);
3124 int rd = mmreg(uMIPS_RD(ctx->opcode));
3125 int rb = mmreg(uMIPS_RS(ctx->opcode));
3126 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
3128 gen_ld(ctx, OPC_LW, rd, rb, offset);
3133 int rd = mmreg2(uMIPS_RD(ctx->opcode));
3134 int rb = mmreg(uMIPS_RS(ctx->opcode));
3135 int16_t offset = ZIMM(ctx->opcode, 0, 4);
3137 gen_st(ctx, OPC_SB, rd, rb, offset);
3142 int rd = mmreg2(uMIPS_RD(ctx->opcode));
3143 int rb = mmreg(uMIPS_RS(ctx->opcode));
3144 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
3146 gen_st(ctx, OPC_SH, rd, rb, offset);
3151 int rd = (ctx->opcode >> 5) & 0x1f;
3152 int rb = 29; /* SP */
3153 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
3155 gen_st(ctx, OPC_SW, rd, rb, offset);
3160 int rd = mmreg2(uMIPS_RD(ctx->opcode));
3161 int rb = mmreg(uMIPS_RS(ctx->opcode));
3162 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
3164 gen_st(ctx, OPC_SW, rd, rb, offset);
3169 int rd = uMIPS_RD5(ctx->opcode);
3170 int rs = uMIPS_RS5(ctx->opcode);
3172 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3179 switch (ctx->opcode & 0x1) {
3189 switch (ctx->opcode & 0x1) {
3198 case B16: /* BC16 */
3199 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
3200 sextract32(ctx->opcode, 0, 10) << 1,
3201 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
3203 case BNEZ16: /* BNEZC16 */
3204 case BEQZ16: /* BEQZC16 */
3205 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
3206 mmreg(uMIPS_RD(ctx->opcode)),
3207 0, sextract32(ctx->opcode, 0, 7) << 1,
3208 (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
3213 int reg = mmreg(uMIPS_RD(ctx->opcode));
3214 int imm = ZIMM(ctx->opcode, 0, 7);
3216 imm = (imm == 0x7f ? -1 : imm);
3217 tcg_gen_movi_tl(cpu_gpr[reg], imm);
3223 gen_reserved_instruction(ctx);
3226 decode_micromips32_opc(env, ctx);