2 * MIPS emulation for QEMU - nanoMIPS translation routines
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * SPDX-License-Identifier: LGPL-2.1-or-later
13 /* MAJOR, P16, and P32 pools opcodes */
70 /* POOL32A instruction pool */
80 /* P.GP.W instruction pool */
87 /* P48I instruction pool */
97 /* P.U12 instruction pool */
113 /* POOL32F instruction pool */
120 /* POOL32S instruction pool */
126 /* P.LUI instruction pool */
132 /* P.GP.BH instruction pool */
143 /* P.LS.U12 instruction pool */
161 /* P.LS.S9 instruction pool */
170 /* P.BAL instruction pool */
176 /* P.J instruction pool */
183 /* P.BR1 instruction pool */
191 /* P.BR2 instruction pool */
198 /* P.BRI instruction pool */
210 /* P16.SHIFT instruction pool */
216 /* POOL16C instruction pool */
222 /* P16.A1 instruction pool */
227 /* P16.A2 instruction pool */
230 NM_P_ADDIURS5 = 0x01,
233 /* P16.ADDU instruction pool */
239 /* P16.SR instruction pool */
242 NM_RESTORE_JRC16 = 0x01,
245 /* P16.4X4 instruction pool */
251 /* P16.LB instruction pool */
258 /* P16.LH instruction pool */
265 /* P.RI instruction pool */
273 /* POOL32A0 instruction pool */
308 NM_D_E_MT_VPE = 0x56,
316 /* CRC32 instruction pool */
326 /* POOL32A5 instruction pool */
331 NM_CMPGU_EQ_QB = 0x18,
332 NM_CMPGU_LT_QB = 0x20,
333 NM_CMPGU_LE_QB = 0x28,
334 NM_CMPGDU_EQ_QB = 0x30,
335 NM_CMPGDU_LT_QB = 0x38,
336 NM_CMPGDU_LE_QB = 0x40,
337 NM_CMPU_EQ_QB = 0x48,
338 NM_CMPU_LT_QB = 0x50,
339 NM_CMPU_LE_QB = 0x58,
346 NM_ADDQH_R_PH = 0x09,
350 NM_ADDUH_R_QB = 0x29,
351 NM_SHRAV_R_PH = 0x31,
352 NM_SHRAV_R_QB = 0x39,
354 NM_SUBQH_R_PH = 0x49,
358 NM_SUBUH_R_QB = 0x69,
359 NM_SHLLV_S_PH = 0x71,
360 NM_PRECR_SRA_R_PH_W = 0x79,
362 NM_MULEU_S_PH_QBL = 0x12,
363 NM_MULEU_S_PH_QBR = 0x1a,
364 NM_MULQ_RS_PH = 0x22,
378 NM_MULEQ_S_W_PHL = 0x04,
379 NM_MULEQ_S_W_PHR = 0x0c,
382 NM_PRECR_QB_PH = 0x0d,
383 NM_PRECRQ_QB_PH = 0x15,
384 NM_PRECRQ_PH_W = 0x1d,
385 NM_PRECRQ_RS_PH_W = 0x25,
386 NM_PRECRQU_S_QB_PH = 0x2d,
399 /* POOL32A7 instruction pool */
407 /* P.SR instruction pool */
413 /* P.SHIFT instruction pool */
421 /* P.ROTX instruction pool */
426 /* P.INS instruction pool */
431 /* P.EXT instruction pool */
436 /* POOL32F_0 (fmt) instruction pool */
462 /* POOL32F_3 instruction pool */
471 /* POOL32F_5 instruction pool */
473 NM_CMP_CONDN_S = 0x00,
474 NM_CMP_CONDN_D = 0x02,
477 /* P.GP.LH instruction pool */
483 /* P.GP.SH instruction pool */
488 /* P.GP.CP1 instruction pool */
496 /* P.LS.S0 instruction pool */
519 /* P.LS.S1 instruction pool */
529 /* P.LS.E0 instruction pool */
545 /* P.PREFE instruction pool */
551 /* P.LLE instruction pool */
557 /* P.SCE instruction pool */
563 /* P.LS.WM instruction pool */
569 /* P.LS.UAWM instruction pool */
575 /* P.BR3A instruction pool */
584 /* P16.RI instruction pool */
586 NM_P16_SYSCALL = 0x01,
591 /* POOL16C_0 instruction pool */
593 NM_POOL16C_00 = 0x00,
596 /* P16.JRC instruction pool */
602 /* P.SYSCALL instruction pool */
608 /* P.TRAP instruction pool */
614 /* P.CMOVE instruction pool */
620 /* POOL32Axf instruction pool */
622 NM_POOL32AXF_1 = 0x01,
623 NM_POOL32AXF_2 = 0x02,
624 NM_POOL32AXF_4 = 0x04,
625 NM_POOL32AXF_5 = 0x05,
626 NM_POOL32AXF_7 = 0x07,
629 /* POOL32Axf_1 instruction pool */
631 NM_POOL32AXF_1_0 = 0x00,
632 NM_POOL32AXF_1_1 = 0x01,
633 NM_POOL32AXF_1_3 = 0x03,
634 NM_POOL32AXF_1_4 = 0x04,
635 NM_POOL32AXF_1_5 = 0x05,
636 NM_POOL32AXF_1_7 = 0x07,
639 /* POOL32Axf_2 instruction pool */
641 NM_POOL32AXF_2_0_7 = 0x00,
642 NM_POOL32AXF_2_8_15 = 0x01,
643 NM_POOL32AXF_2_16_23 = 0x02,
644 NM_POOL32AXF_2_24_31 = 0x03,
647 /* POOL32Axf_7 instruction pool */
654 /* POOL32Axf_1_0 instruction pool */
662 /* POOL32Axf_1_1 instruction pool */
668 /* POOL32Axf_1_3 instruction pool */
676 /* POOL32Axf_1_4 instruction pool */
682 /* POOL32Axf_1_5 instruction pool */
684 NM_MAQ_S_W_PHR = 0x0,
685 NM_MAQ_S_W_PHL = 0x1,
686 NM_MAQ_SA_W_PHR = 0x2,
687 NM_MAQ_SA_W_PHL = 0x3,
690 /* POOL32Axf_1_7 instruction pool */
698 /* POOL32Axf_2_0_7 instruction pool */
701 NM_DPAQ_S_W_PH = 0x1,
703 NM_DPSQ_S_W_PH = 0x3,
710 /* POOL32Axf_2_8_15 instruction pool */
713 NM_DPAQ_SA_L_W = 0x1,
715 NM_DPSQ_SA_L_W = 0x3,
721 /* POOL32Axf_2_16_23 instruction pool */
724 NM_DPAQX_S_W_PH = 0x1,
726 NM_DPSQX_S_W_PH = 0x3,
733 /* POOL32Axf_2_24_31 instruction pool */
736 NM_DPAQX_SA_W_PH = 0x1,
738 NM_DPSQX_SA_W_PH = 0x3,
741 NM_MULSAQ_S_W_PH = 0x6,
745 /* POOL32Axf_{4, 5} instruction pool */
764 /* nanoMIPS DSP instructions */
768 NM_PRECEQ_W_PHL = 0x28,
769 NM_PRECEQ_W_PHR = 0x30,
770 NM_PRECEQU_PH_QBL = 0x38,
771 NM_PRECEQU_PH_QBR = 0x48,
772 NM_PRECEU_PH_QBL = 0x58,
773 NM_PRECEU_PH_QBR = 0x68,
774 NM_PRECEQU_PH_QBLA = 0x39,
775 NM_PRECEQU_PH_QBRA = 0x49,
776 NM_PRECEU_PH_QBLA = 0x59,
777 NM_PRECEU_PH_QBRA = 0x69,
782 NM_RADDU_W_QB = 0x78,
788 /* PP.SR instruction pool */
792 NM_RESTORE_JRC = 0x03,
795 /* P.SR.F instruction pool */
801 /* P16.SYSCALL instruction pool */
807 /* POOL16C_00 instruction pool */
815 /* PP.LSX and PP.LSXS instruction pool */
853 /* ERETx instruction pool */
859 /* POOL32FxF_{0, 1} insturction pool */
885 NM_FLOOR_L_S = 0x00c,
886 NM_FLOOR_L_D = 0x10c,
888 NM_FLOOR_W_S = 0x02c,
889 NM_FLOOR_W_D = 0x12c,
895 NM_TRUNC_L_S = 0x08c,
896 NM_TRUNC_L_D = 0x18c,
897 NM_TRUNC_W_S = 0x0ac,
898 NM_TRUNC_W_D = 0x1ac,
899 NM_ROUND_L_S = 0x0cc,
900 NM_ROUND_L_D = 0x1cc,
901 NM_ROUND_W_S = 0x0ec,
902 NM_ROUND_W_D = 0x1ec,
918 /* P.LL instruction pool */
924 /* P.SC instruction pool */
930 /* P.DVP instruction pool */
939 * nanoMIPS decoding engine
944 /* extraction utilities */
946 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
947 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
948 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
949 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
950 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
952 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
953 static inline int decode_gpr_gpr3(int r)
955 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
960 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
961 static inline int decode_gpr_gpr3_src_store(int r)
963 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
968 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
969 static inline int decode_gpr_gpr4(int r)
971 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
972 16, 17, 18, 19, 20, 21, 22, 23 };
977 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
978 static inline int decode_gpr_gpr4_zero(int r)
980 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
981 16, 17, 18, 19, 20, 21, 22, 23 };
986 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
989 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
992 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
993 uint32_t reg1, uint32_t reg2)
995 TCGv taddr = tcg_temp_new();
996 TCGv_i64 tval = tcg_temp_new_i64();
997 TCGv tmp1 = tcg_temp_new();
998 TCGv tmp2 = tcg_temp_new();
1000 gen_base_offset_addr(ctx, taddr, base, offset);
1001 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
1002 #ifdef TARGET_WORDS_BIGENDIAN
1003 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
1005 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
1007 gen_store_gpr(tmp1, reg1);
1008 tcg_temp_free(tmp1);
1009 gen_store_gpr(tmp2, reg2);
1010 tcg_temp_free(tmp2);
1011 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
1012 tcg_temp_free_i64(tval);
1013 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
1014 tcg_temp_free(taddr);
1017 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
1018 uint32_t reg1, uint32_t reg2, bool eva)
1020 TCGv taddr = tcg_temp_local_new();
1021 TCGv lladdr = tcg_temp_local_new();
1022 TCGv_i64 tval = tcg_temp_new_i64();
1023 TCGv_i64 llval = tcg_temp_new_i64();
1024 TCGv_i64 val = tcg_temp_new_i64();
1025 TCGv tmp1 = tcg_temp_new();
1026 TCGv tmp2 = tcg_temp_new();
1027 TCGLabel *lab_fail = gen_new_label();
1028 TCGLabel *lab_done = gen_new_label();
1030 gen_base_offset_addr(ctx, taddr, base, offset);
1032 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
1033 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
1035 gen_load_gpr(tmp1, reg1);
1036 gen_load_gpr(tmp2, reg2);
1038 #ifdef TARGET_WORDS_BIGENDIAN
1039 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
1041 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
1044 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
1045 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
1046 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
1048 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
1050 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
1052 gen_set_label(lab_fail);
1055 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
1057 gen_set_label(lab_done);
1058 tcg_gen_movi_tl(lladdr, -1);
1059 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
1062 static void gen_adjust_sp(DisasContext *ctx, int u)
1064 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
1067 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
1068 uint8_t gp, uint16_t u)
1071 TCGv va = tcg_temp_new();
1072 TCGv t0 = tcg_temp_new();
1074 while (counter != count) {
1075 bool use_gp = gp && (counter == count - 1);
1076 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
1077 int this_offset = -((counter + 1) << 2);
1078 gen_base_offset_addr(ctx, va, 29, this_offset);
1079 gen_load_gpr(t0, this_rt);
1080 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
1081 (MO_TEUL | ctx->default_tcg_memop_mask));
1085 /* adjust stack pointer */
1086 gen_adjust_sp(ctx, -u);
1092 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
1093 uint8_t gp, uint16_t u)
1096 TCGv va = tcg_temp_new();
1097 TCGv t0 = tcg_temp_new();
1099 while (counter != count) {
1100 bool use_gp = gp && (counter == count - 1);
1101 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
1102 int this_offset = u - ((counter + 1) << 2);
1103 gen_base_offset_addr(ctx, va, 29, this_offset);
1104 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
1105 ctx->default_tcg_memop_mask);
1106 tcg_gen_ext32s_tl(t0, t0);
1107 gen_store_gpr(t0, this_rt);
1111 /* adjust stack pointer */
1112 gen_adjust_sp(ctx, u);
1118 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
1120 int rs, int rt, int32_t offset)
1122 target_ulong btgt = -1;
1123 int bcond_compute = 0;
1124 TCGv t0 = tcg_temp_new();
1125 TCGv t1 = tcg_temp_new();
1127 /* Load needed operands */
1131 /* Compare two registers */
1133 gen_load_gpr(t0, rs);
1134 gen_load_gpr(t1, rt);
1137 btgt = ctx->base.pc_next + insn_bytes + offset;
1140 /* Compare to zero */
1142 gen_load_gpr(t0, rs);
1145 btgt = ctx->base.pc_next + insn_bytes + offset;
1148 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
1150 btgt = ctx->base.pc_next + insn_bytes + offset;
1154 /* Jump to register */
1155 if (offset != 0 && offset != 16) {
1157 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1158 * others are reserved.
1160 MIPS_INVAL("jump hint");
1161 gen_reserved_instruction(ctx);
1164 gen_load_gpr(btarget, rs);
1167 MIPS_INVAL("branch/jump");
1168 gen_reserved_instruction(ctx);
1171 if (bcond_compute == 0) {
1172 /* No condition to be computed */
1174 case OPC_BEQ: /* rx == rx */
1176 ctx->hflags |= MIPS_HFLAG_B;
1178 case OPC_BGEZAL: /* 0 >= 0 */
1179 /* Always take and link */
1180 tcg_gen_movi_tl(cpu_gpr[31],
1181 ctx->base.pc_next + insn_bytes);
1182 ctx->hflags |= MIPS_HFLAG_B;
1184 case OPC_BNE: /* rx != rx */
1185 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
1186 /* Skip the instruction in the delay slot */
1187 ctx->base.pc_next += 4;
1190 ctx->hflags |= MIPS_HFLAG_BR;
1194 tcg_gen_movi_tl(cpu_gpr[rt],
1195 ctx->base.pc_next + insn_bytes);
1197 ctx->hflags |= MIPS_HFLAG_BR;
1200 MIPS_INVAL("branch/jump");
1201 gen_reserved_instruction(ctx);
1207 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1210 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1213 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1214 tcg_gen_movi_tl(cpu_gpr[31],
1215 ctx->base.pc_next + insn_bytes);
1218 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
1220 ctx->hflags |= MIPS_HFLAG_BC;
1223 MIPS_INVAL("conditional branch/jump");
1224 gen_reserved_instruction(ctx);
1229 ctx->btarget = btgt;
1232 if (insn_bytes == 2) {
1233 ctx->hflags |= MIPS_HFLAG_B16;
1239 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
1241 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
1242 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
1244 switch (extract32(ctx->opcode, 2, 2)) {
1246 gen_logic(ctx, OPC_NOR, rt, rs, 0);
1249 gen_logic(ctx, OPC_AND, rt, rt, rs);
1252 gen_logic(ctx, OPC_XOR, rt, rt, rs);
1255 gen_logic(ctx, OPC_OR, rt, rt, rs);
1260 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
1262 int rt = extract32(ctx->opcode, 21, 5);
1263 int rs = extract32(ctx->opcode, 16, 5);
1264 int rd = extract32(ctx->opcode, 11, 5);
1266 switch (extract32(ctx->opcode, 3, 7)) {
1268 switch (extract32(ctx->opcode, 10, 1)) {
1271 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
1275 gen_trap(ctx, OPC_TNE, rs, rt, -1);
1281 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
1285 gen_bshfl(ctx, OPC_SEB, rs, rt);
1288 gen_bshfl(ctx, OPC_SEH, rs, rt);
1291 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
1294 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
1297 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
1300 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
1303 gen_arith(ctx, OPC_ADD, rd, rs, rt);
1306 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
1310 gen_arith(ctx, OPC_SUB, rd, rs, rt);
1313 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
1316 switch (extract32(ctx->opcode, 10, 1)) {
1318 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
1321 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
1326 gen_logic(ctx, OPC_AND, rd, rs, rt);
1329 gen_logic(ctx, OPC_OR, rd, rs, rt);
1332 gen_logic(ctx, OPC_NOR, rd, rs, rt);
1335 gen_logic(ctx, OPC_XOR, rd, rs, rt);
1338 gen_slt(ctx, OPC_SLT, rd, rs, rt);
1343 #ifndef CONFIG_USER_ONLY
1344 TCGv t0 = tcg_temp_new();
1345 switch (extract32(ctx->opcode, 10, 1)) {
1348 check_cp0_enabled(ctx);
1349 gen_helper_dvp(t0, cpu_env);
1350 gen_store_gpr(t0, rt);
1355 check_cp0_enabled(ctx);
1356 gen_helper_evp(t0, cpu_env);
1357 gen_store_gpr(t0, rt);
1364 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
1369 TCGv t0 = tcg_temp_new();
1370 TCGv t1 = tcg_temp_new();
1371 TCGv t2 = tcg_temp_new();
1373 gen_load_gpr(t1, rs);
1374 gen_load_gpr(t2, rt);
1375 tcg_gen_add_tl(t0, t1, t2);
1376 tcg_gen_ext32s_tl(t0, t0);
1377 tcg_gen_xor_tl(t1, t1, t2);
1378 tcg_gen_xor_tl(t2, t0, t2);
1379 tcg_gen_andc_tl(t1, t2, t1);
1381 /* operands of same sign, result different sign */
1382 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
1383 gen_store_gpr(t0, rd);
1391 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
1394 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
1397 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
1400 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
1403 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
1406 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
1409 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
1412 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
1414 #ifndef CONFIG_USER_ONLY
1416 check_cp0_enabled(ctx);
1421 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
1424 check_cp0_enabled(ctx);
1426 TCGv t0 = tcg_temp_new();
1428 gen_load_gpr(t0, rt);
1429 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
1435 uint8_t sc = extract32(ctx->opcode, 10, 1);
1436 TCGv t0 = tcg_temp_new();
1444 gen_store_gpr(t0, rt);
1445 } else if (rs == 0) {
1448 gen_helper_dvpe(t0, cpu_env);
1449 gen_store_gpr(t0, rt);
1451 gen_reserved_instruction(ctx);
1459 gen_store_gpr(t0, rt);
1460 } else if (rs == 0) {
1463 gen_helper_evpe(t0, cpu_env);
1464 gen_store_gpr(t0, rt);
1466 gen_reserved_instruction(ctx);
1477 TCGv t0 = tcg_temp_new();
1478 TCGv t1 = tcg_temp_new();
1480 gen_load_gpr(t0, rt);
1481 gen_load_gpr(t1, rs);
1482 gen_helper_fork(t0, t1);
1489 check_cp0_enabled(ctx);
1494 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
1495 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
1499 check_cp0_enabled(ctx);
1500 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
1501 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
1506 TCGv t0 = tcg_temp_new();
1508 gen_load_gpr(t0, rs);
1509 gen_helper_yield(t0, cpu_env, t0);
1510 gen_store_gpr(t0, rt);
1516 gen_reserved_instruction(ctx);
1522 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
1523 int ret, int v1, int v2)
1529 t0 = tcg_temp_new_i32();
1531 v0_t = tcg_temp_new();
1532 v1_t = tcg_temp_new();
1534 tcg_gen_movi_i32(t0, v2 >> 3);
1536 gen_load_gpr(v0_t, ret);
1537 gen_load_gpr(v1_t, v1);
1540 case NM_MAQ_S_W_PHR:
1542 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
1544 case NM_MAQ_S_W_PHL:
1546 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
1548 case NM_MAQ_SA_W_PHR:
1550 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
1552 case NM_MAQ_SA_W_PHL:
1554 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
1557 gen_reserved_instruction(ctx);
1561 tcg_temp_free_i32(t0);
1563 tcg_temp_free(v0_t);
1564 tcg_temp_free(v1_t);
1568 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
1569 int ret, int v1, int v2)
1572 TCGv t0 = tcg_temp_new();
1573 TCGv t1 = tcg_temp_new();
1574 TCGv v0_t = tcg_temp_new();
1576 gen_load_gpr(v0_t, v1);
1579 case NM_POOL32AXF_1_0:
1581 switch (extract32(ctx->opcode, 12, 2)) {
1583 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
1586 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
1589 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
1592 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
1596 case NM_POOL32AXF_1_1:
1598 switch (extract32(ctx->opcode, 12, 2)) {
1600 tcg_gen_movi_tl(t0, v2);
1601 gen_helper_mthlip(t0, v0_t, cpu_env);
1604 tcg_gen_movi_tl(t0, v2 >> 3);
1605 gen_helper_shilo(t0, v0_t, cpu_env);
1608 gen_reserved_instruction(ctx);
1612 case NM_POOL32AXF_1_3:
1614 imm = extract32(ctx->opcode, 14, 7);
1615 switch (extract32(ctx->opcode, 12, 2)) {
1617 tcg_gen_movi_tl(t0, imm);
1618 gen_helper_rddsp(t0, t0, cpu_env);
1619 gen_store_gpr(t0, ret);
1622 gen_load_gpr(t0, ret);
1623 tcg_gen_movi_tl(t1, imm);
1624 gen_helper_wrdsp(t0, t1, cpu_env);
1627 tcg_gen_movi_tl(t0, v2 >> 3);
1628 tcg_gen_movi_tl(t1, v1);
1629 gen_helper_extp(t0, t0, t1, cpu_env);
1630 gen_store_gpr(t0, ret);
1633 tcg_gen_movi_tl(t0, v2 >> 3);
1634 tcg_gen_movi_tl(t1, v1);
1635 gen_helper_extpdp(t0, t0, t1, cpu_env);
1636 gen_store_gpr(t0, ret);
1640 case NM_POOL32AXF_1_4:
1642 tcg_gen_movi_tl(t0, v2 >> 2);
1643 switch (extract32(ctx->opcode, 12, 1)) {
1645 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
1646 gen_store_gpr(t0, ret);
1649 gen_helper_shrl_qb(t0, t0, v0_t);
1650 gen_store_gpr(t0, ret);
1654 case NM_POOL32AXF_1_5:
1655 opc = extract32(ctx->opcode, 12, 2);
1656 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
1658 case NM_POOL32AXF_1_7:
1660 tcg_gen_movi_tl(t0, v2 >> 3);
1661 tcg_gen_movi_tl(t1, v1);
1662 switch (extract32(ctx->opcode, 12, 2)) {
1664 gen_helper_extr_w(t0, t0, t1, cpu_env);
1665 gen_store_gpr(t0, ret);
1668 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
1669 gen_store_gpr(t0, ret);
1672 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
1673 gen_store_gpr(t0, ret);
1676 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
1677 gen_store_gpr(t0, ret);
1682 gen_reserved_instruction(ctx);
1688 tcg_temp_free(v0_t);
1691 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
1692 TCGv v0, TCGv v1, int rd)
1696 t0 = tcg_temp_new_i32();
1698 tcg_gen_movi_i32(t0, rd >> 3);
1701 case NM_POOL32AXF_2_0_7:
1702 switch (extract32(ctx->opcode, 9, 3)) {
1705 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
1707 case NM_DPAQ_S_W_PH:
1709 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
1713 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
1715 case NM_DPSQ_S_W_PH:
1717 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
1720 gen_reserved_instruction(ctx);
1724 case NM_POOL32AXF_2_8_15:
1725 switch (extract32(ctx->opcode, 9, 3)) {
1728 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
1730 case NM_DPAQ_SA_L_W:
1732 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
1736 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
1738 case NM_DPSQ_SA_L_W:
1740 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
1743 gen_reserved_instruction(ctx);
1747 case NM_POOL32AXF_2_16_23:
1748 switch (extract32(ctx->opcode, 9, 3)) {
1751 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
1753 case NM_DPAQX_S_W_PH:
1755 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
1759 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
1761 case NM_DPSQX_S_W_PH:
1763 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
1767 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
1770 gen_reserved_instruction(ctx);
1774 case NM_POOL32AXF_2_24_31:
1775 switch (extract32(ctx->opcode, 9, 3)) {
1778 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
1780 case NM_DPAQX_SA_W_PH:
1782 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
1786 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
1788 case NM_DPSQX_SA_W_PH:
1790 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
1792 case NM_MULSAQ_S_W_PH:
1794 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
1797 gen_reserved_instruction(ctx);
1802 gen_reserved_instruction(ctx);
1806 tcg_temp_free_i32(t0);
1809 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
1810 int rt, int rs, int rd)
1813 TCGv t0 = tcg_temp_new();
1814 TCGv t1 = tcg_temp_new();
1815 TCGv v0_t = tcg_temp_new();
1816 TCGv v1_t = tcg_temp_new();
1818 gen_load_gpr(v0_t, rt);
1819 gen_load_gpr(v1_t, rs);
1822 case NM_POOL32AXF_2_0_7:
1823 switch (extract32(ctx->opcode, 9, 3)) {
1825 case NM_DPAQ_S_W_PH:
1827 case NM_DPSQ_S_W_PH:
1828 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1833 gen_load_gpr(t0, rs);
1835 if (rd != 0 && rd != 2) {
1836 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
1837 tcg_gen_ext32u_tl(t0, t0);
1838 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
1839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
1841 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
1847 int acc = extract32(ctx->opcode, 14, 2);
1848 TCGv_i64 t2 = tcg_temp_new_i64();
1849 TCGv_i64 t3 = tcg_temp_new_i64();
1851 gen_load_gpr(t0, rt);
1852 gen_load_gpr(t1, rs);
1853 tcg_gen_ext_tl_i64(t2, t0);
1854 tcg_gen_ext_tl_i64(t3, t1);
1855 tcg_gen_mul_i64(t2, t2, t3);
1856 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1857 tcg_gen_add_i64(t2, t2, t3);
1858 tcg_temp_free_i64(t3);
1859 gen_move_low32(cpu_LO[acc], t2);
1860 gen_move_high32(cpu_HI[acc], t2);
1861 tcg_temp_free_i64(t2);
1867 int acc = extract32(ctx->opcode, 14, 2);
1868 TCGv_i32 t2 = tcg_temp_new_i32();
1869 TCGv_i32 t3 = tcg_temp_new_i32();
1871 gen_load_gpr(t0, rs);
1872 gen_load_gpr(t1, rt);
1873 tcg_gen_trunc_tl_i32(t2, t0);
1874 tcg_gen_trunc_tl_i32(t3, t1);
1875 tcg_gen_muls2_i32(t2, t3, t2, t3);
1876 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
1877 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
1878 tcg_temp_free_i32(t2);
1879 tcg_temp_free_i32(t3);
1884 gen_load_gpr(v1_t, rs);
1885 tcg_gen_movi_tl(t0, rd >> 3);
1886 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
1887 gen_store_gpr(t0, ret);
1891 case NM_POOL32AXF_2_8_15:
1892 switch (extract32(ctx->opcode, 9, 3)) {
1894 case NM_DPAQ_SA_L_W:
1896 case NM_DPSQ_SA_L_W:
1897 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1902 int acc = extract32(ctx->opcode, 14, 2);
1903 TCGv_i64 t2 = tcg_temp_new_i64();
1904 TCGv_i64 t3 = tcg_temp_new_i64();
1906 gen_load_gpr(t0, rs);
1907 gen_load_gpr(t1, rt);
1908 tcg_gen_ext32u_tl(t0, t0);
1909 tcg_gen_ext32u_tl(t1, t1);
1910 tcg_gen_extu_tl_i64(t2, t0);
1911 tcg_gen_extu_tl_i64(t3, t1);
1912 tcg_gen_mul_i64(t2, t2, t3);
1913 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1914 tcg_gen_add_i64(t2, t2, t3);
1915 tcg_temp_free_i64(t3);
1916 gen_move_low32(cpu_LO[acc], t2);
1917 gen_move_high32(cpu_HI[acc], t2);
1918 tcg_temp_free_i64(t2);
1924 int acc = extract32(ctx->opcode, 14, 2);
1925 TCGv_i32 t2 = tcg_temp_new_i32();
1926 TCGv_i32 t3 = tcg_temp_new_i32();
1928 gen_load_gpr(t0, rs);
1929 gen_load_gpr(t1, rt);
1930 tcg_gen_trunc_tl_i32(t2, t0);
1931 tcg_gen_trunc_tl_i32(t3, t1);
1932 tcg_gen_mulu2_i32(t2, t3, t2, t3);
1933 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
1934 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
1935 tcg_temp_free_i32(t2);
1936 tcg_temp_free_i32(t3);
1941 tcg_gen_movi_tl(t0, rd >> 3);
1942 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
1943 gen_store_gpr(t0, ret);
1946 gen_reserved_instruction(ctx);
1950 case NM_POOL32AXF_2_16_23:
1951 switch (extract32(ctx->opcode, 9, 3)) {
1953 case NM_DPAQX_S_W_PH:
1955 case NM_DPSQX_S_W_PH:
1957 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
1961 tcg_gen_movi_tl(t0, rd >> 3);
1962 gen_helper_extp(t0, t0, v1_t, cpu_env);
1963 gen_store_gpr(t0, ret);
1968 int acc = extract32(ctx->opcode, 14, 2);
1969 TCGv_i64 t2 = tcg_temp_new_i64();
1970 TCGv_i64 t3 = tcg_temp_new_i64();
1972 gen_load_gpr(t0, rs);
1973 gen_load_gpr(t1, rt);
1974 tcg_gen_ext_tl_i64(t2, t0);
1975 tcg_gen_ext_tl_i64(t3, t1);
1976 tcg_gen_mul_i64(t2, t2, t3);
1977 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
1978 tcg_gen_sub_i64(t2, t3, t2);
1979 tcg_temp_free_i64(t3);
1980 gen_move_low32(cpu_LO[acc], t2);
1981 gen_move_high32(cpu_HI[acc], t2);
1982 tcg_temp_free_i64(t2);
1987 tcg_gen_movi_tl(t0, rd >> 3);
1988 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
1989 gen_store_gpr(t0, ret);
1993 case NM_POOL32AXF_2_24_31:
1994 switch (extract32(ctx->opcode, 9, 3)) {
1996 case NM_DPAQX_SA_W_PH:
1998 case NM_DPSQX_SA_W_PH:
1999 case NM_MULSAQ_S_W_PH:
2000 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
2004 tcg_gen_movi_tl(t0, rd >> 3);
2005 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
2006 gen_store_gpr(t0, ret);
2011 int acc = extract32(ctx->opcode, 14, 2);
2012 TCGv_i64 t2 = tcg_temp_new_i64();
2013 TCGv_i64 t3 = tcg_temp_new_i64();
2015 gen_load_gpr(t0, rs);
2016 gen_load_gpr(t1, rt);
2017 tcg_gen_ext32u_tl(t0, t0);
2018 tcg_gen_ext32u_tl(t1, t1);
2019 tcg_gen_extu_tl_i64(t2, t0);
2020 tcg_gen_extu_tl_i64(t3, t1);
2021 tcg_gen_mul_i64(t2, t2, t3);
2022 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2023 tcg_gen_sub_i64(t2, t3, t2);
2024 tcg_temp_free_i64(t3);
2025 gen_move_low32(cpu_LO[acc], t2);
2026 gen_move_high32(cpu_HI[acc], t2);
2027 tcg_temp_free_i64(t2);
2032 tcg_gen_movi_tl(t0, rd >> 3);
2033 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
2034 gen_store_gpr(t0, ret);
2039 gen_reserved_instruction(ctx);
2046 tcg_temp_free(v0_t);
2047 tcg_temp_free(v1_t);
2050 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
2054 TCGv t0 = tcg_temp_new();
2055 TCGv v0_t = tcg_temp_new();
2057 gen_load_gpr(v0_t, rs);
2062 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
2063 gen_store_gpr(v0_t, ret);
2067 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
2068 gen_store_gpr(v0_t, ret);
2072 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
2073 gen_store_gpr(v0_t, ret);
2075 case NM_PRECEQ_W_PHL:
2077 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
2078 tcg_gen_ext32s_tl(v0_t, v0_t);
2079 gen_store_gpr(v0_t, ret);
2081 case NM_PRECEQ_W_PHR:
2083 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
2084 tcg_gen_shli_tl(v0_t, v0_t, 16);
2085 tcg_gen_ext32s_tl(v0_t, v0_t);
2086 gen_store_gpr(v0_t, ret);
2088 case NM_PRECEQU_PH_QBL:
2090 gen_helper_precequ_ph_qbl(v0_t, v0_t);
2091 gen_store_gpr(v0_t, ret);
2093 case NM_PRECEQU_PH_QBR:
2095 gen_helper_precequ_ph_qbr(v0_t, v0_t);
2096 gen_store_gpr(v0_t, ret);
2098 case NM_PRECEQU_PH_QBLA:
2100 gen_helper_precequ_ph_qbla(v0_t, v0_t);
2101 gen_store_gpr(v0_t, ret);
2103 case NM_PRECEQU_PH_QBRA:
2105 gen_helper_precequ_ph_qbra(v0_t, v0_t);
2106 gen_store_gpr(v0_t, ret);
2108 case NM_PRECEU_PH_QBL:
2110 gen_helper_preceu_ph_qbl(v0_t, v0_t);
2111 gen_store_gpr(v0_t, ret);
2113 case NM_PRECEU_PH_QBR:
2115 gen_helper_preceu_ph_qbr(v0_t, v0_t);
2116 gen_store_gpr(v0_t, ret);
2118 case NM_PRECEU_PH_QBLA:
2120 gen_helper_preceu_ph_qbla(v0_t, v0_t);
2121 gen_store_gpr(v0_t, ret);
2123 case NM_PRECEU_PH_QBRA:
2125 gen_helper_preceu_ph_qbra(v0_t, v0_t);
2126 gen_store_gpr(v0_t, ret);
2130 tcg_gen_ext16u_tl(v0_t, v0_t);
2131 tcg_gen_shli_tl(t0, v0_t, 16);
2132 tcg_gen_or_tl(v0_t, v0_t, t0);
2133 tcg_gen_ext32s_tl(v0_t, v0_t);
2134 gen_store_gpr(v0_t, ret);
2138 tcg_gen_ext8u_tl(v0_t, v0_t);
2139 tcg_gen_shli_tl(t0, v0_t, 8);
2140 tcg_gen_or_tl(v0_t, v0_t, t0);
2141 tcg_gen_shli_tl(t0, v0_t, 16);
2142 tcg_gen_or_tl(v0_t, v0_t, t0);
2143 tcg_gen_ext32s_tl(v0_t, v0_t);
2144 gen_store_gpr(v0_t, ret);
2148 gen_helper_bitrev(v0_t, v0_t);
2149 gen_store_gpr(v0_t, ret);
2154 TCGv tv0 = tcg_temp_new();
2156 gen_load_gpr(tv0, rt);
2157 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
2158 gen_store_gpr(v0_t, ret);
2164 gen_helper_raddu_w_qb(v0_t, v0_t);
2165 gen_store_gpr(v0_t, ret);
2168 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
2172 gen_cl(ctx, OPC_CLO, ret, rs);
2176 gen_cl(ctx, OPC_CLZ, ret, rs);
2179 gen_bshfl(ctx, OPC_WSBH, ret, rs);
2182 gen_reserved_instruction(ctx);
2186 tcg_temp_free(v0_t);
2190 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
2191 int rt, int rs, int rd)
2193 TCGv t0 = tcg_temp_new();
2194 TCGv rs_t = tcg_temp_new();
2196 gen_load_gpr(rs_t, rs);
2201 tcg_gen_movi_tl(t0, rd >> 2);
2202 switch (extract32(ctx->opcode, 12, 1)) {
2205 gen_helper_shra_qb(t0, t0, rs_t);
2206 gen_store_gpr(t0, rt);
2210 gen_helper_shra_r_qb(t0, t0, rs_t);
2211 gen_store_gpr(t0, rt);
2217 tcg_gen_movi_tl(t0, rd >> 1);
2218 gen_helper_shrl_ph(t0, t0, rs_t);
2219 gen_store_gpr(t0, rt);
2226 imm = extract32(ctx->opcode, 13, 8);
2227 result = (uint32_t)imm << 24 |
2228 (uint32_t)imm << 16 |
2229 (uint32_t)imm << 8 |
2231 result = (int32_t)result;
2232 tcg_gen_movi_tl(t0, result);
2233 gen_store_gpr(t0, rt);
2237 gen_reserved_instruction(ctx);
2241 tcg_temp_free(rs_t);
2245 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
2247 int rt = extract32(ctx->opcode, 21, 5);
2248 int rs = extract32(ctx->opcode, 16, 5);
2249 int rd = extract32(ctx->opcode, 11, 5);
2251 switch (extract32(ctx->opcode, 6, 3)) {
2252 case NM_POOL32AXF_1:
2254 int32_t op1 = extract32(ctx->opcode, 9, 3);
2255 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
2258 case NM_POOL32AXF_2:
2260 int32_t op1 = extract32(ctx->opcode, 12, 2);
2261 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
2264 case NM_POOL32AXF_4:
2266 int32_t op1 = extract32(ctx->opcode, 9, 7);
2267 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
2270 case NM_POOL32AXF_5:
2271 switch (extract32(ctx->opcode, 9, 7)) {
2272 #ifndef CONFIG_USER_ONLY
2274 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
2277 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
2280 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
2283 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
2286 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
2289 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
2292 check_cp0_enabled(ctx);
2294 TCGv t0 = tcg_temp_new();
2296 save_cpu_state(ctx, 1);
2297 gen_helper_di(t0, cpu_env);
2298 gen_store_gpr(t0, rt);
2299 /* Stop translation as we may have switched the execution mode */
2300 ctx->base.is_jmp = DISAS_STOP;
2305 check_cp0_enabled(ctx);
2307 TCGv t0 = tcg_temp_new();
2309 save_cpu_state(ctx, 1);
2310 gen_helper_ei(t0, cpu_env);
2311 gen_store_gpr(t0, rt);
2312 /* Stop translation as we may have switched the execution mode */
2313 ctx->base.is_jmp = DISAS_STOP;
2318 check_cp0_enabled(ctx);
2319 gen_load_srsgpr(rs, rt);
2322 check_cp0_enabled(ctx);
2323 gen_store_srsgpr(rs, rt);
2326 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
2329 gen_cp0(env, ctx, OPC_DERET, 0, 0);
2332 gen_cp0(env, ctx, OPC_ERET, 0, 0);
2336 gen_reserved_instruction(ctx);
2340 case NM_POOL32AXF_7:
2342 int32_t op1 = extract32(ctx->opcode, 9, 3);
2343 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
2347 gen_reserved_instruction(ctx);
2352 /* Immediate Value Compact Branches */
2353 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
2354 int rt, int32_t imm, int32_t offset)
2356 TCGCond cond = TCG_COND_ALWAYS;
2357 TCGv t0 = tcg_temp_new();
2358 TCGv t1 = tcg_temp_new();
2360 gen_load_gpr(t0, rt);
2361 tcg_gen_movi_tl(t1, imm);
2362 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2364 /* Load needed operands and calculate btarget */
2367 if (rt == 0 && imm == 0) {
2368 /* Unconditional branch */
2369 } else if (rt == 0 && imm != 0) {
2379 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
2380 gen_reserved_instruction(ctx);
2382 } else if (rt == 0 && opc == NM_BBEQZC) {
2383 /* Unconditional branch */
2384 } else if (rt == 0 && opc == NM_BBNEZC) {
2388 tcg_gen_shri_tl(t0, t0, imm);
2389 tcg_gen_andi_tl(t0, t0, 1);
2390 tcg_gen_movi_tl(t1, 0);
2391 if (opc == NM_BBEQZC) {
2399 if (rt == 0 && imm == 0) {
2402 } else if (rt == 0 && imm != 0) {
2403 /* Unconditional branch */
2409 if (rt == 0 && imm == 0) {
2410 /* Unconditional branch */
2419 if (rt == 0 && imm == 0) {
2420 /* Unconditional branch */
2422 cond = TCG_COND_GEU;
2426 cond = TCG_COND_LTU;
2429 MIPS_INVAL("Immediate Value Compact branch");
2430 gen_reserved_instruction(ctx);
2434 /* branch completion */
2435 clear_branch_hflags(ctx);
2436 ctx->base.is_jmp = DISAS_NORETURN;
2438 if (cond == TCG_COND_ALWAYS) {
2439 /* Uncoditional compact branch */
2440 gen_goto_tb(ctx, 0, ctx->btarget);
2442 /* Conditional compact branch */
2443 TCGLabel *fs = gen_new_label();
2445 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
2447 gen_goto_tb(ctx, 1, ctx->btarget);
2450 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
2458 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
2459 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
2462 TCGv t0 = tcg_temp_new();
2463 TCGv t1 = tcg_temp_new();
2466 gen_load_gpr(t0, rs);
2470 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
2473 /* calculate btarget */
2474 tcg_gen_shli_tl(t0, t0, 1);
2475 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
2476 gen_op_addr_add(ctx, btarget, t1, t0);
2478 /* branch completion */
2479 clear_branch_hflags(ctx);
2480 ctx->base.is_jmp = DISAS_NORETURN;
2482 /* unconditional branch to register */
2483 tcg_gen_mov_tl(cpu_PC, btarget);
2484 tcg_gen_lookup_and_goto_ptr();
2490 /* nanoMIPS Branches */
2491 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
2492 int rs, int rt, int32_t offset)
2494 int bcond_compute = 0;
2495 TCGv t0 = tcg_temp_new();
2496 TCGv t1 = tcg_temp_new();
2498 /* Load needed operands and calculate btarget */
2500 /* compact branch */
2503 gen_load_gpr(t0, rs);
2504 gen_load_gpr(t1, rt);
2506 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2510 if (rs == 0 || rs == rt) {
2511 /* OPC_BLEZALC, OPC_BGEZALC */
2512 /* OPC_BGTZALC, OPC_BLTZALC */
2513 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
2515 gen_load_gpr(t0, rs);
2516 gen_load_gpr(t1, rt);
2518 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2521 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2525 /* OPC_BEQZC, OPC_BNEZC */
2526 gen_load_gpr(t0, rs);
2528 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2530 /* OPC_JIC, OPC_JIALC */
2531 TCGv tbase = tcg_temp_new();
2532 TCGv toffset = tcg_temp_new();
2534 gen_load_gpr(tbase, rt);
2535 tcg_gen_movi_tl(toffset, offset);
2536 gen_op_addr_add(ctx, btarget, tbase, toffset);
2537 tcg_temp_free(tbase);
2538 tcg_temp_free(toffset);
2542 MIPS_INVAL("Compact branch/jump");
2543 gen_reserved_instruction(ctx);
2547 if (bcond_compute == 0) {
2548 /* Uncoditional compact branch */
2551 gen_goto_tb(ctx, 0, ctx->btarget);
2554 MIPS_INVAL("Compact branch/jump");
2555 gen_reserved_instruction(ctx);
2559 /* Conditional compact branch */
2560 TCGLabel *fs = gen_new_label();
2564 if (rs == 0 && rt != 0) {
2566 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
2567 } else if (rs != 0 && rt != 0 && rs == rt) {
2569 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
2572 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
2576 if (rs == 0 && rt != 0) {
2578 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
2579 } else if (rs != 0 && rt != 0 && rs == rt) {
2581 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
2584 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
2588 if (rs == 0 && rt != 0) {
2590 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
2591 } else if (rs != 0 && rt != 0 && rs == rt) {
2593 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
2596 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
2600 if (rs == 0 && rt != 0) {
2602 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
2603 } else if (rs != 0 && rt != 0 && rs == rt) {
2605 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
2608 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
2612 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
2615 MIPS_INVAL("Compact conditional branch/jump");
2616 gen_reserved_instruction(ctx);
2620 /* branch completion */
2621 clear_branch_hflags(ctx);
2622 ctx->base.is_jmp = DISAS_NORETURN;
2624 /* Generating branch here as compact branches don't have delay slot */
2625 gen_goto_tb(ctx, 1, ctx->btarget);
2628 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
2637 /* nanoMIPS CP1 Branches */
2638 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
2639 int32_t ft, int32_t offset)
2641 target_ulong btarget;
2642 TCGv_i64 t0 = tcg_temp_new_i64();
2644 gen_load_fpr64(ctx, t0, ft);
2645 tcg_gen_andi_i64(t0, t0, 1);
2647 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
2651 tcg_gen_xori_i64(t0, t0, 1);
2652 ctx->hflags |= MIPS_HFLAG_BC;
2655 /* t0 already set */
2656 ctx->hflags |= MIPS_HFLAG_BC;
2659 MIPS_INVAL("cp1 cond branch");
2660 gen_reserved_instruction(ctx);
2664 tcg_gen_trunc_i64_tl(bcond, t0);
2666 ctx->btarget = btarget;
2669 tcg_temp_free_i64(t0);
2673 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
2676 t0 = tcg_temp_new();
2677 t1 = tcg_temp_new();
2679 gen_load_gpr(t0, rs);
2680 gen_load_gpr(t1, rt);
2682 if ((extract32(ctx->opcode, 6, 1)) == 1) {
2683 /* PP.LSXS instructions require shifting */
2684 switch (extract32(ctx->opcode, 7, 4)) {
2690 tcg_gen_shli_tl(t0, t0, 1);
2698 tcg_gen_shli_tl(t0, t0, 2);
2702 tcg_gen_shli_tl(t0, t0, 3);
2706 gen_op_addr_add(ctx, t0, t0, t1);
2708 switch (extract32(ctx->opcode, 7, 4)) {
2710 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2712 gen_store_gpr(t0, rd);
2716 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2718 gen_store_gpr(t0, rd);
2722 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2724 gen_store_gpr(t0, rd);
2727 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2729 gen_store_gpr(t0, rd);
2733 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
2735 gen_store_gpr(t0, rd);
2739 gen_load_gpr(t1, rd);
2740 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
2746 gen_load_gpr(t1, rd);
2747 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
2753 gen_load_gpr(t1, rd);
2754 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
2765 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2766 check_cp1_enabled(ctx);
2767 switch (extract32(ctx->opcode, 7, 4)) {
2770 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
2774 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
2778 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
2782 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
2786 generate_exception_err(ctx, EXCP_CpU, 1);
2790 gen_reserved_instruction(ctx);
2798 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
2802 rt = extract32(ctx->opcode, 21, 5);
2803 rs = extract32(ctx->opcode, 16, 5);
2804 rd = extract32(ctx->opcode, 11, 5);
2806 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
2807 gen_reserved_instruction(ctx);
2810 check_cp1_enabled(ctx);
2811 switch (extract32(ctx->opcode, 0, 3)) {
2813 switch (extract32(ctx->opcode, 3, 7)) {
2815 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
2818 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
2821 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
2824 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
2827 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
2830 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
2833 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
2836 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
2839 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
2842 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
2845 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
2848 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
2851 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2854 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2857 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2860 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2863 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
2866 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
2869 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
2872 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
2875 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
2878 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
2881 gen_reserved_instruction(ctx);
2886 switch (extract32(ctx->opcode, 3, 3)) {
2888 switch (extract32(ctx->opcode, 9, 1)) {
2890 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
2893 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
2898 switch (extract32(ctx->opcode, 9, 1)) {
2900 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
2903 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
2908 switch (extract32(ctx->opcode, 9, 1)) {
2910 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
2913 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
2918 switch (extract32(ctx->opcode, 9, 1)) {
2920 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
2923 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
2928 switch (extract32(ctx->opcode, 6, 8)) {
2930 gen_cp1(ctx, OPC_CFC1, rt, rs);
2933 gen_cp1(ctx, OPC_CTC1, rt, rs);
2936 gen_cp1(ctx, OPC_MFC1, rt, rs);
2939 gen_cp1(ctx, OPC_MTC1, rt, rs);
2942 gen_cp1(ctx, OPC_MFHC1, rt, rs);
2945 gen_cp1(ctx, OPC_MTHC1, rt, rs);
2948 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
2951 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
2954 switch (extract32(ctx->opcode, 6, 9)) {
2956 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
2959 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
2962 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
2965 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
2968 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
2971 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
2974 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
2977 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
2980 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
2983 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
2986 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
2989 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
2992 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
2995 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
2998 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
3001 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
3004 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
3007 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
3010 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
3013 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
3016 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
3019 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
3022 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
3025 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
3028 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
3031 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
3034 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
3037 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
3040 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
3043 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
3046 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
3049 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
3052 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
3055 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
3058 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
3061 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
3064 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
3067 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
3070 gen_reserved_instruction(ctx);
3079 switch (extract32(ctx->opcode, 3, 3)) {
3080 case NM_CMP_CONDN_S:
3081 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
3083 case NM_CMP_CONDN_D:
3084 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
3087 gen_reserved_instruction(ctx);
3092 gen_reserved_instruction(ctx);
3097 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
3098 int rd, int rs, int rt)
3101 TCGv t0 = tcg_temp_new();
3102 TCGv v1_t = tcg_temp_new();
3103 TCGv v2_t = tcg_temp_new();
3105 gen_load_gpr(v1_t, rs);
3106 gen_load_gpr(v2_t, rt);
3111 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
3115 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
3119 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
3123 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
3127 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
3131 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
3133 case NM_CMPGU_EQ_QB:
3135 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
3136 gen_store_gpr(v1_t, ret);
3138 case NM_CMPGU_LT_QB:
3140 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
3141 gen_store_gpr(v1_t, ret);
3143 case NM_CMPGU_LE_QB:
3145 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
3146 gen_store_gpr(v1_t, ret);
3148 case NM_CMPGDU_EQ_QB:
3150 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
3151 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
3152 gen_store_gpr(v1_t, ret);
3154 case NM_CMPGDU_LT_QB:
3156 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
3157 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
3158 gen_store_gpr(v1_t, ret);
3160 case NM_CMPGDU_LE_QB:
3162 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
3163 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
3164 gen_store_gpr(v1_t, ret);
3168 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
3169 gen_store_gpr(v1_t, ret);
3173 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
3174 gen_store_gpr(v1_t, ret);
3178 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
3179 gen_store_gpr(v1_t, ret);
3183 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
3184 gen_store_gpr(v1_t, ret);
3188 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
3189 gen_store_gpr(v1_t, ret);
3193 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
3194 gen_store_gpr(v1_t, ret);
3198 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
3199 gen_store_gpr(v1_t, ret);
3203 switch (extract32(ctx->opcode, 10, 1)) {
3206 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
3207 gen_store_gpr(v1_t, ret);
3211 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
3212 gen_store_gpr(v1_t, ret);
3218 switch (extract32(ctx->opcode, 10, 1)) {
3221 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
3222 gen_store_gpr(v1_t, ret);
3226 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
3227 gen_store_gpr(v1_t, ret);
3233 switch (extract32(ctx->opcode, 10, 1)) {
3236 gen_helper_addqh_w(v1_t, v1_t, v2_t);
3237 gen_store_gpr(v1_t, ret);
3241 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
3242 gen_store_gpr(v1_t, ret);
3248 switch (extract32(ctx->opcode, 10, 1)) {
3251 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
3252 gen_store_gpr(v1_t, ret);
3256 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
3257 gen_store_gpr(v1_t, ret);
3263 switch (extract32(ctx->opcode, 10, 1)) {
3266 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
3267 gen_store_gpr(v1_t, ret);
3271 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
3272 gen_store_gpr(v1_t, ret);
3278 switch (extract32(ctx->opcode, 10, 1)) {
3281 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
3282 gen_store_gpr(v1_t, ret);
3286 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
3287 gen_store_gpr(v1_t, ret);
3293 switch (extract32(ctx->opcode, 10, 1)) {
3296 gen_helper_shra_ph(v1_t, v1_t, v2_t);
3297 gen_store_gpr(v1_t, ret);
3301 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
3302 gen_store_gpr(v1_t, ret);
3308 switch (extract32(ctx->opcode, 10, 1)) {
3311 gen_helper_shra_qb(v1_t, v1_t, v2_t);
3312 gen_store_gpr(v1_t, ret);
3316 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
3317 gen_store_gpr(v1_t, ret);
3323 switch (extract32(ctx->opcode, 10, 1)) {
3326 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
3327 gen_store_gpr(v1_t, ret);
3331 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
3332 gen_store_gpr(v1_t, ret);
3338 switch (extract32(ctx->opcode, 10, 1)) {
3341 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
3342 gen_store_gpr(v1_t, ret);
3346 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
3347 gen_store_gpr(v1_t, ret);
3353 switch (extract32(ctx->opcode, 10, 1)) {
3356 gen_helper_subqh_w(v1_t, v1_t, v2_t);
3357 gen_store_gpr(v1_t, ret);
3361 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
3362 gen_store_gpr(v1_t, ret);
3368 switch (extract32(ctx->opcode, 10, 1)) {
3371 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
3372 gen_store_gpr(v1_t, ret);
3376 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
3377 gen_store_gpr(v1_t, ret);
3383 switch (extract32(ctx->opcode, 10, 1)) {
3386 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
3387 gen_store_gpr(v1_t, ret);
3391 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
3392 gen_store_gpr(v1_t, ret);
3398 switch (extract32(ctx->opcode, 10, 1)) {
3401 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
3402 gen_store_gpr(v1_t, ret);
3406 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
3407 gen_store_gpr(v1_t, ret);
3413 switch (extract32(ctx->opcode, 10, 1)) {
3416 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
3417 gen_store_gpr(v1_t, ret);
3421 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
3422 gen_store_gpr(v1_t, ret);
3426 case NM_PRECR_SRA_R_PH_W:
3428 switch (extract32(ctx->opcode, 10, 1)) {
3430 /* PRECR_SRA_PH_W */
3432 TCGv_i32 sa_t = tcg_const_i32(rd);
3433 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
3435 gen_store_gpr(v1_t, rt);
3436 tcg_temp_free_i32(sa_t);
3440 /* PRECR_SRA_R_PH_W */
3442 TCGv_i32 sa_t = tcg_const_i32(rd);
3443 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
3445 gen_store_gpr(v1_t, rt);
3446 tcg_temp_free_i32(sa_t);
3451 case NM_MULEU_S_PH_QBL:
3453 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
3454 gen_store_gpr(v1_t, ret);
3456 case NM_MULEU_S_PH_QBR:
3458 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
3459 gen_store_gpr(v1_t, ret);
3463 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
3464 gen_store_gpr(v1_t, ret);
3468 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
3469 gen_store_gpr(v1_t, ret);
3473 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
3474 gen_store_gpr(v1_t, ret);
3478 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
3479 gen_store_gpr(v1_t, ret);
3483 gen_load_gpr(t0, rs);
3485 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
3487 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3491 gen_helper_modsub(v1_t, v1_t, v2_t);
3492 gen_store_gpr(v1_t, ret);
3496 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
3497 gen_store_gpr(v1_t, ret);
3501 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
3502 gen_store_gpr(v1_t, ret);
3506 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
3507 gen_store_gpr(v1_t, ret);
3511 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
3512 gen_store_gpr(v1_t, ret);
3516 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
3517 gen_store_gpr(v1_t, ret);
3522 TCGv tv0 = tcg_temp_new();
3523 TCGv tv1 = tcg_temp_new();
3524 int16_t imm = extract32(ctx->opcode, 16, 7);
3526 tcg_gen_movi_tl(tv0, rd >> 3);
3527 tcg_gen_movi_tl(tv1, imm);
3528 gen_helper_shilo(tv0, tv1, cpu_env);
3533 case NM_MULEQ_S_W_PHL:
3535 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
3536 gen_store_gpr(v1_t, ret);
3538 case NM_MULEQ_S_W_PHR:
3540 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
3541 gen_store_gpr(v1_t, ret);
3545 switch (extract32(ctx->opcode, 10, 1)) {
3548 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
3549 gen_store_gpr(v1_t, ret);
3553 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
3554 gen_store_gpr(v1_t, ret);
3558 case NM_PRECR_QB_PH:
3560 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
3561 gen_store_gpr(v1_t, ret);
3563 case NM_PRECRQ_QB_PH:
3565 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
3566 gen_store_gpr(v1_t, ret);
3568 case NM_PRECRQ_PH_W:
3570 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
3571 gen_store_gpr(v1_t, ret);
3573 case NM_PRECRQ_RS_PH_W:
3575 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
3576 gen_store_gpr(v1_t, ret);
3578 case NM_PRECRQU_S_QB_PH:
3580 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
3581 gen_store_gpr(v1_t, ret);
3585 tcg_gen_movi_tl(t0, rd);
3586 gen_helper_shra_r_w(v1_t, t0, v1_t);
3587 gen_store_gpr(v1_t, rt);
3591 tcg_gen_movi_tl(t0, rd >> 1);
3592 switch (extract32(ctx->opcode, 10, 1)) {
3595 gen_helper_shra_ph(v1_t, t0, v1_t);
3596 gen_store_gpr(v1_t, rt);
3600 gen_helper_shra_r_ph(v1_t, t0, v1_t);
3601 gen_store_gpr(v1_t, rt);
3607 tcg_gen_movi_tl(t0, rd >> 1);
3608 switch (extract32(ctx->opcode, 10, 2)) {
3611 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
3612 gen_store_gpr(v1_t, rt);
3616 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
3617 gen_store_gpr(v1_t, rt);
3620 gen_reserved_instruction(ctx);
3626 tcg_gen_movi_tl(t0, rd);
3627 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
3628 gen_store_gpr(v1_t, rt);
3634 imm = sextract32(ctx->opcode, 11, 11);
3635 imm = (int16_t)(imm << 6) >> 6;
3637 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
3642 gen_reserved_instruction(ctx);
3646 tcg_temp_free(v2_t);
3647 tcg_temp_free(v1_t);
3651 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
3659 insn = translator_lduw(env, ctx->base.pc_next + 2);
3660 ctx->opcode = (ctx->opcode << 16) | insn;
3662 rt = extract32(ctx->opcode, 21, 5);
3663 rs = extract32(ctx->opcode, 16, 5);
3664 rd = extract32(ctx->opcode, 11, 5);
3666 op = extract32(ctx->opcode, 26, 6);
3671 switch (extract32(ctx->opcode, 19, 2)) {
3674 gen_reserved_instruction(ctx);
3677 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
3678 generate_exception_end(ctx, EXCP_SYSCALL);
3680 gen_reserved_instruction(ctx);
3684 generate_exception_end(ctx, EXCP_BREAK);
3687 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
3688 gen_helper_do_semihosting(cpu_env);
3690 if (ctx->hflags & MIPS_HFLAG_SBRI) {
3691 gen_reserved_instruction(ctx);
3693 generate_exception_end(ctx, EXCP_DBp);
3700 imm = extract32(ctx->opcode, 0, 16);
3702 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
3704 tcg_gen_movi_tl(cpu_gpr[rt], imm);
3706 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3711 offset = sextract32(ctx->opcode, 0, 1) << 21 |
3712 extract32(ctx->opcode, 1, 20) << 1;
3713 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
3714 tcg_gen_movi_tl(cpu_gpr[rt], addr);
3718 switch (ctx->opcode & 0x07) {
3720 gen_pool32a0_nanomips_insn(env, ctx);
3724 int32_t op1 = extract32(ctx->opcode, 3, 7);
3725 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
3729 switch (extract32(ctx->opcode, 3, 3)) {
3731 gen_p_lsx(ctx, rd, rs, rt);
3735 * In nanoMIPS, the shift field directly encodes the shift
3736 * amount, meaning that the supported shift values are in
3737 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
3739 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) - 1);
3742 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
3745 gen_pool32axf_nanomips_insn(env, ctx);
3748 gen_reserved_instruction(ctx);
3753 gen_reserved_instruction(ctx);
3758 switch (ctx->opcode & 0x03) {
3761 offset = extract32(ctx->opcode, 0, 21);
3762 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
3766 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
3769 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
3772 gen_reserved_instruction(ctx);
3778 insn = translator_lduw(env, ctx->base.pc_next + 4);
3779 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
3780 switch (extract32(ctx->opcode, 16, 5)) {
3784 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
3790 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
3791 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3797 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
3803 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
3806 tcg_gen_movi_tl(cpu_gpr[rt], addr);
3813 t0 = tcg_temp_new();
3815 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
3818 tcg_gen_movi_tl(t0, addr);
3819 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
3827 t0 = tcg_temp_new();
3828 t1 = tcg_temp_new();
3830 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
3833 tcg_gen_movi_tl(t0, addr);
3834 gen_load_gpr(t1, rt);
3836 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3843 gen_reserved_instruction(ctx);
3849 switch (extract32(ctx->opcode, 12, 4)) {
3851 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
3854 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
3857 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
3860 switch (extract32(ctx->opcode, 20, 1)) {
3862 switch (ctx->opcode & 3) {
3864 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
3865 extract32(ctx->opcode, 2, 1),
3866 extract32(ctx->opcode, 3, 9) << 3);
3869 case NM_RESTORE_JRC:
3870 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
3871 extract32(ctx->opcode, 2, 1),
3872 extract32(ctx->opcode, 3, 9) << 3);
3873 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
3874 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
3878 gen_reserved_instruction(ctx);
3883 gen_reserved_instruction(ctx);
3888 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
3891 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
3895 TCGv t0 = tcg_temp_new();
3897 imm = extract32(ctx->opcode, 0, 12);
3898 gen_load_gpr(t0, rs);
3899 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
3900 gen_store_gpr(t0, rt);
3906 imm = (int16_t) extract32(ctx->opcode, 0, 12);
3907 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
3911 int shift = extract32(ctx->opcode, 0, 5);
3912 switch (extract32(ctx->opcode, 5, 4)) {
3914 if (rt == 0 && shift == 0) {
3916 } else if (rt == 0 && shift == 3) {
3917 /* EHB - treat as NOP */
3918 } else if (rt == 0 && shift == 5) {
3919 /* PAUSE - treat as NOP */
3920 } else if (rt == 0 && shift == 6) {
3922 gen_sync(extract32(ctx->opcode, 16, 5));
3925 gen_shift_imm(ctx, OPC_SLL, rt, rs,
3926 extract32(ctx->opcode, 0, 5));
3930 gen_shift_imm(ctx, OPC_SRL, rt, rs,
3931 extract32(ctx->opcode, 0, 5));
3934 gen_shift_imm(ctx, OPC_SRA, rt, rs,
3935 extract32(ctx->opcode, 0, 5));
3938 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
3939 extract32(ctx->opcode, 0, 5));
3947 TCGv t0 = tcg_temp_new();
3948 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
3949 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
3951 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
3953 gen_load_gpr(t0, rs);
3954 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
3957 tcg_temp_free_i32(shift);
3958 tcg_temp_free_i32(shiftx);
3959 tcg_temp_free_i32(stripe);
3963 switch (((ctx->opcode >> 10) & 2) |
3964 (extract32(ctx->opcode, 5, 1))) {
3967 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
3968 extract32(ctx->opcode, 6, 5));
3971 gen_reserved_instruction(ctx);
3976 switch (((ctx->opcode >> 10) & 2) |
3977 (extract32(ctx->opcode, 5, 1))) {
3980 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
3981 extract32(ctx->opcode, 6, 5));
3984 gen_reserved_instruction(ctx);
3989 gen_reserved_instruction(ctx);
3994 gen_pool32f_nanomips_insn(ctx);
3999 switch (extract32(ctx->opcode, 1, 1)) {
4002 tcg_gen_movi_tl(cpu_gpr[rt],
4003 sextract32(ctx->opcode, 0, 1) << 31 |
4004 extract32(ctx->opcode, 2, 10) << 21 |
4005 extract32(ctx->opcode, 12, 9) << 12);
4010 offset = sextract32(ctx->opcode, 0, 1) << 31 |
4011 extract32(ctx->opcode, 2, 10) << 21 |
4012 extract32(ctx->opcode, 12, 9) << 12;
4014 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
4015 tcg_gen_movi_tl(cpu_gpr[rt], addr);
4022 uint32_t u = extract32(ctx->opcode, 0, 18);
4024 switch (extract32(ctx->opcode, 18, 3)) {
4026 gen_ld(ctx, OPC_LB, rt, 28, u);
4029 gen_st(ctx, OPC_SB, rt, 28, u);
4032 gen_ld(ctx, OPC_LBU, rt, 28, u);
4036 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
4041 switch (ctx->opcode & 1) {
4043 gen_ld(ctx, OPC_LH, rt, 28, u);
4046 gen_ld(ctx, OPC_LHU, rt, 28, u);
4052 switch (ctx->opcode & 1) {
4054 gen_st(ctx, OPC_SH, rt, 28, u);
4057 gen_reserved_instruction(ctx);
4063 switch (ctx->opcode & 0x3) {
4065 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
4068 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
4071 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
4074 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
4079 gen_reserved_instruction(ctx);
4086 uint32_t u = extract32(ctx->opcode, 0, 12);
4088 switch (extract32(ctx->opcode, 12, 4)) {
4093 * Break the TB to be able to sync copied instructions
4096 ctx->base.is_jmp = DISAS_STOP;
4103 gen_ld(ctx, OPC_LB, rt, rs, u);
4106 gen_ld(ctx, OPC_LH, rt, rs, u);
4109 gen_ld(ctx, OPC_LW, rt, rs, u);
4112 gen_ld(ctx, OPC_LBU, rt, rs, u);
4115 gen_ld(ctx, OPC_LHU, rt, rs, u);
4118 gen_st(ctx, OPC_SB, rt, rs, u);
4121 gen_st(ctx, OPC_SH, rt, rs, u);
4124 gen_st(ctx, OPC_SW, rt, rs, u);
4127 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
4130 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
4133 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
4136 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
4139 gen_reserved_instruction(ctx);
4146 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
4147 extract32(ctx->opcode, 0, 8);
4149 switch (extract32(ctx->opcode, 8, 3)) {
4151 switch (extract32(ctx->opcode, 11, 4)) {
4153 gen_ld(ctx, OPC_LB, rt, rs, s);
4156 gen_ld(ctx, OPC_LH, rt, rs, s);
4159 gen_ld(ctx, OPC_LW, rt, rs, s);
4162 gen_ld(ctx, OPC_LBU, rt, rs, s);
4165 gen_ld(ctx, OPC_LHU, rt, rs, s);
4168 gen_st(ctx, OPC_SB, rt, rs, s);
4171 gen_st(ctx, OPC_SH, rt, rs, s);
4174 gen_st(ctx, OPC_SW, rt, rs, s);
4177 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
4180 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
4183 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
4186 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
4192 * Break the TB to be able to sync copied instructions
4195 ctx->base.is_jmp = DISAS_STOP;
4202 gen_reserved_instruction(ctx);
4207 switch (extract32(ctx->opcode, 11, 4)) {
4212 TCGv t0 = tcg_temp_new();
4213 TCGv t1 = tcg_temp_new();
4215 gen_base_offset_addr(ctx, t0, rs, s);
4217 switch (extract32(ctx->opcode, 11, 4)) {
4219 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4221 gen_store_gpr(t0, rt);
4224 gen_load_gpr(t1, rt);
4225 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4234 switch (ctx->opcode & 0x03) {
4236 gen_ld(ctx, OPC_LL, rt, rs, s);
4240 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
4245 switch (ctx->opcode & 0x03) {
4247 gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
4251 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
4257 check_cp0_enabled(ctx);
4258 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
4259 gen_cache_operation(ctx, rt, rs, s);
4265 switch (extract32(ctx->opcode, 11, 4)) {
4268 check_cp0_enabled(ctx);
4269 gen_ld(ctx, OPC_LBE, rt, rs, s);
4273 check_cp0_enabled(ctx);
4274 gen_st(ctx, OPC_SBE, rt, rs, s);
4278 check_cp0_enabled(ctx);
4279 gen_ld(ctx, OPC_LBUE, rt, rs, s);
4283 /* case NM_SYNCIE */
4285 check_cp0_enabled(ctx);
4287 * Break the TB to be able to sync copied instructions
4290 ctx->base.is_jmp = DISAS_STOP;
4294 check_cp0_enabled(ctx);
4300 check_cp0_enabled(ctx);
4301 gen_ld(ctx, OPC_LHE, rt, rs, s);
4305 check_cp0_enabled(ctx);
4306 gen_st(ctx, OPC_SHE, rt, rs, s);
4310 check_cp0_enabled(ctx);
4311 gen_ld(ctx, OPC_LHUE, rt, rs, s);
4315 check_cp0_enabled(ctx);
4316 check_nms_dl_il_sl_tl_l2c(ctx);
4317 gen_cache_operation(ctx, rt, rs, s);
4321 check_cp0_enabled(ctx);
4322 gen_ld(ctx, OPC_LWE, rt, rs, s);
4326 check_cp0_enabled(ctx);
4327 gen_st(ctx, OPC_SWE, rt, rs, s);
4330 switch (extract32(ctx->opcode, 2, 2)) {
4334 check_cp0_enabled(ctx);
4335 gen_ld(ctx, OPC_LLE, rt, rs, s);
4340 check_cp0_enabled(ctx);
4341 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
4344 gen_reserved_instruction(ctx);
4349 switch (extract32(ctx->opcode, 2, 2)) {
4353 check_cp0_enabled(ctx);
4354 gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
4359 check_cp0_enabled(ctx);
4360 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
4364 gen_reserved_instruction(ctx);
4374 int count = extract32(ctx->opcode, 12, 3);
4377 offset = sextract32(ctx->opcode, 15, 1) << 8 |
4378 extract32(ctx->opcode, 0, 8);
4379 TCGv va = tcg_temp_new();
4380 TCGv t1 = tcg_temp_new();
4381 MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
4382 NM_P_LS_UAWM ? MO_UNALN : 0;
4384 count = (count == 0) ? 8 : count;
4385 while (counter != count) {
4386 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
4387 int this_offset = offset + (counter << 2);
4389 gen_base_offset_addr(ctx, va, rs, this_offset);
4391 switch (extract32(ctx->opcode, 11, 1)) {
4393 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
4395 gen_store_gpr(t1, this_rt);
4396 if ((this_rt == rs) &&
4397 (counter != (count - 1))) {
4402 this_rt = (rt == 0) ? 0 : this_rt;
4403 gen_load_gpr(t1, this_rt);
4404 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
4415 gen_reserved_instruction(ctx);
4423 TCGv t0 = tcg_temp_new();
4424 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
4425 extract32(ctx->opcode, 1, 20) << 1;
4426 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
4427 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
4428 extract32(ctx->opcode, 21, 3));
4429 gen_load_gpr(t0, rt);
4430 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4431 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
4437 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
4438 extract32(ctx->opcode, 1, 24) << 1;
4440 if ((extract32(ctx->opcode, 25, 1)) == 0) {
4442 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
4445 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
4450 switch (extract32(ctx->opcode, 12, 4)) {
4453 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
4456 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
4459 gen_reserved_instruction(ctx);
4465 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
4466 extract32(ctx->opcode, 1, 13) << 1;
4467 switch (extract32(ctx->opcode, 14, 2)) {
4470 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
4473 s = sextract32(ctx->opcode, 0, 1) << 14 |
4474 extract32(ctx->opcode, 1, 13) << 1;
4475 check_cp1_enabled(ctx);
4476 switch (extract32(ctx->opcode, 16, 5)) {
4478 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
4481 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
4486 int32_t imm = extract32(ctx->opcode, 1, 13) |
4487 extract32(ctx->opcode, 0, 1) << 13;
4489 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
4494 gen_reserved_instruction(ctx);
4500 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
4502 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
4506 if (rs == rt || rt == 0) {
4507 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
4508 } else if (rs == 0) {
4509 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
4511 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
4519 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
4520 extract32(ctx->opcode, 1, 13) << 1;
4521 switch (extract32(ctx->opcode, 14, 2)) {
4524 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
4527 if (rs != 0 && rt != 0 && rs == rt) {
4529 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
4531 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
4535 if (rs == 0 || rs == rt) {
4537 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
4539 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
4543 gen_reserved_instruction(ctx);
4550 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
4551 extract32(ctx->opcode, 1, 10) << 1;
4552 uint32_t u = extract32(ctx->opcode, 11, 7);
4554 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
4559 gen_reserved_instruction(ctx);
4565 static int decode_isa_nanomips(CPUMIPSState *env, DisasContext *ctx)
4568 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
4569 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
4570 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
4574 /* make sure instructions are on a halfword boundary */
4575 if (ctx->base.pc_next & 0x1) {
4576 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
4577 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4579 generate_exception_end(ctx, EXCP_AdEL);
4583 op = extract32(ctx->opcode, 10, 6);
4586 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
4589 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
4590 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
4593 switch (extract32(ctx->opcode, 3, 2)) {
4594 case NM_P16_SYSCALL:
4595 if (extract32(ctx->opcode, 2, 1) == 0) {
4596 generate_exception_end(ctx, EXCP_SYSCALL);
4598 gen_reserved_instruction(ctx);
4602 generate_exception_end(ctx, EXCP_BREAK);
4605 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
4606 gen_helper_do_semihosting(cpu_env);
4608 if (ctx->hflags & MIPS_HFLAG_SBRI) {
4609 gen_reserved_instruction(ctx);
4611 generate_exception_end(ctx, EXCP_DBp);
4616 gen_reserved_instruction(ctx);
4623 int shift = extract32(ctx->opcode, 0, 3);
4625 shift = (shift == 0) ? 8 : shift;
4627 switch (extract32(ctx->opcode, 3, 1)) {
4635 gen_shift_imm(ctx, opc, rt, rs, shift);
4639 switch (ctx->opcode & 1) {
4641 gen_pool16c_nanomips_insn(ctx);
4644 gen_ldxs(ctx, rt, rs, rd);
4649 switch (extract32(ctx->opcode, 6, 1)) {
4651 imm = extract32(ctx->opcode, 0, 6) << 2;
4652 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
4655 gen_reserved_instruction(ctx);
4660 switch (extract32(ctx->opcode, 3, 1)) {
4662 imm = extract32(ctx->opcode, 0, 3) << 2;
4663 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
4666 rt = extract32(ctx->opcode, 5, 5);
4668 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
4669 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
4670 (extract32(ctx->opcode, 0, 3));
4671 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
4677 switch (ctx->opcode & 0x1) {
4679 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
4682 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
4687 rt = (extract32(ctx->opcode, 9, 1) << 3) |
4688 extract32(ctx->opcode, 5, 3);
4689 rs = (extract32(ctx->opcode, 4, 1) << 3) |
4690 extract32(ctx->opcode, 0, 3);
4691 rt = decode_gpr_gpr4(rt);
4692 rs = decode_gpr_gpr4(rs);
4693 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
4694 (extract32(ctx->opcode, 3, 1))) {
4697 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
4701 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
4704 gen_reserved_instruction(ctx);
4710 int imm = extract32(ctx->opcode, 0, 7);
4711 imm = (imm == 0x7f ? -1 : imm);
4713 tcg_gen_movi_tl(cpu_gpr[rt], imm);
4719 uint32_t u = extract32(ctx->opcode, 0, 4);
4720 u = (u == 12) ? 0xff :
4721 (u == 13) ? 0xffff : u;
4722 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
4726 offset = extract32(ctx->opcode, 0, 2);
4727 switch (extract32(ctx->opcode, 2, 2)) {
4729 gen_ld(ctx, OPC_LB, rt, rs, offset);
4732 rt = decode_gpr_gpr3_src_store(
4733 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4734 gen_st(ctx, OPC_SB, rt, rs, offset);
4737 gen_ld(ctx, OPC_LBU, rt, rs, offset);
4740 gen_reserved_instruction(ctx);
4745 offset = extract32(ctx->opcode, 1, 2) << 1;
4746 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
4748 gen_ld(ctx, OPC_LH, rt, rs, offset);
4751 rt = decode_gpr_gpr3_src_store(
4752 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4753 gen_st(ctx, OPC_SH, rt, rs, offset);
4756 gen_ld(ctx, OPC_LHU, rt, rs, offset);
4759 gen_reserved_instruction(ctx);
4764 offset = extract32(ctx->opcode, 0, 4) << 2;
4765 gen_ld(ctx, OPC_LW, rt, rs, offset);
4768 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
4769 offset = extract32(ctx->opcode, 0, 5) << 2;
4770 gen_ld(ctx, OPC_LW, rt, 29, offset);
4774 rt = (extract32(ctx->opcode, 9, 1) << 3) |
4775 extract32(ctx->opcode, 5, 3);
4776 rs = (extract32(ctx->opcode, 4, 1) << 3) |
4777 extract32(ctx->opcode, 0, 3);
4778 offset = (extract32(ctx->opcode, 3, 1) << 3) |
4779 (extract32(ctx->opcode, 8, 1) << 2);
4780 rt = decode_gpr_gpr4(rt);
4781 rs = decode_gpr_gpr4(rs);
4782 gen_ld(ctx, OPC_LW, rt, rs, offset);
4786 rt = (extract32(ctx->opcode, 9, 1) << 3) |
4787 extract32(ctx->opcode, 5, 3);
4788 rs = (extract32(ctx->opcode, 4, 1) << 3) |
4789 extract32(ctx->opcode, 0, 3);
4790 offset = (extract32(ctx->opcode, 3, 1) << 3) |
4791 (extract32(ctx->opcode, 8, 1) << 2);
4792 rt = decode_gpr_gpr4_zero(rt);
4793 rs = decode_gpr_gpr4(rs);
4794 gen_st(ctx, OPC_SW, rt, rs, offset);
4797 offset = extract32(ctx->opcode, 0, 7) << 2;
4798 gen_ld(ctx, OPC_LW, rt, 28, offset);
4801 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
4802 offset = extract32(ctx->opcode, 0, 5) << 2;
4803 gen_st(ctx, OPC_SW, rt, 29, offset);
4806 rt = decode_gpr_gpr3_src_store(
4807 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4808 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
4809 offset = extract32(ctx->opcode, 0, 4) << 2;
4810 gen_st(ctx, OPC_SW, rt, rs, offset);
4813 rt = decode_gpr_gpr3_src_store(
4814 NANOMIPS_EXTRACT_RT3(ctx->opcode));
4815 offset = extract32(ctx->opcode, 0, 7) << 2;
4816 gen_st(ctx, OPC_SW, rt, 28, offset);
4819 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
4820 (sextract32(ctx->opcode, 0, 1) << 10) |
4821 (extract32(ctx->opcode, 1, 9) << 1));
4824 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
4825 (sextract32(ctx->opcode, 0, 1) << 10) |
4826 (extract32(ctx->opcode, 1, 9) << 1));
4829 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
4830 (sextract32(ctx->opcode, 0, 1) << 7) |
4831 (extract32(ctx->opcode, 1, 6) << 1));
4834 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
4835 (sextract32(ctx->opcode, 0, 1) << 7) |
4836 (extract32(ctx->opcode, 1, 6) << 1));
4839 switch (ctx->opcode & 0xf) {
4842 switch (extract32(ctx->opcode, 4, 1)) {
4844 gen_compute_branch_nm(ctx, OPC_JR, 2,
4845 extract32(ctx->opcode, 5, 5), 0, 0);
4848 gen_compute_branch_nm(ctx, OPC_JALR, 2,
4849 extract32(ctx->opcode, 5, 5), 31, 0);
4856 uint32_t opc = extract32(ctx->opcode, 4, 3) <
4857 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
4858 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
4859 extract32(ctx->opcode, 0, 4) << 1);
4866 int count = extract32(ctx->opcode, 0, 4);
4867 int u = extract32(ctx->opcode, 4, 4) << 4;
4869 rt = 30 + extract32(ctx->opcode, 9, 1);
4870 switch (extract32(ctx->opcode, 8, 1)) {
4872 gen_save(ctx, rt, count, 0, u);
4874 case NM_RESTORE_JRC16:
4875 gen_restore(ctx, rt, count, 0, u);
4876 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
4885 static const int gpr2reg1[] = {4, 5, 6, 7};
4886 static const int gpr2reg2[] = {5, 6, 7, 8};
4888 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
4889 extract32(ctx->opcode, 8, 1);
4890 int r1 = gpr2reg1[rd2];
4891 int r2 = gpr2reg2[rd2];
4892 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
4893 extract32(ctx->opcode, 0, 3);
4894 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
4895 extract32(ctx->opcode, 5, 3);
4896 TCGv t0 = tcg_temp_new();
4897 TCGv t1 = tcg_temp_new();
4898 if (op == NM_MOVEP) {
4901 rs = decode_gpr_gpr4_zero(r3);
4902 rt = decode_gpr_gpr4_zero(r4);
4904 rd = decode_gpr_gpr4(r3);
4905 re = decode_gpr_gpr4(r4);
4909 gen_load_gpr(t0, rs);
4910 gen_load_gpr(t1, rt);
4911 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4912 tcg_gen_mov_tl(cpu_gpr[re], t1);
4918 return decode_nanomips_32_48_opc(env, ctx);