Add MIPS DSP Accumulator and DSPControl Access instructions Support. Signed-off-by: Jia Liu <pro...@gmail.com> --- target-mips/dsp_helper.c | 465 ++++++++++++++++++++++++++++++++++++++++++++++ target-mips/helper.h | 19 ++ target-mips/translate.c | 175 +++++++++++++++++ 3 files changed, 659 insertions(+), 0 deletions(-)
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c index 27949ab..c1ccddc 100644 --- a/target-mips/dsp_helper.c +++ b/target-mips/dsp_helper.c @@ -3362,6 +3362,471 @@ uint32_t helper_packrl_ph(uint32_t rs, uint32_t rt) return rd; } +/** DSP Accumulator and DSPControl Access Sub-class insns **/ +uint32_t helper_extr_w(CPUMIPSState *env, int ac, int shift) +{ + int32_t tempI; + int64_t tempDL[2]; + + mipsdsp__rashift_short_acc(env, tempDL, ac, shift); + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + tempI = (tempDL[0] >> 1) & MIPSDSP_LLO; + + tempDL[0] += 1; + if (tempDL[0] == 0) { + tempDL[1] += 1; + } + + if ((!(tempDL[1] == 0 && (tempDL[0] & MIPSDSP_LHI) == 0x00)) && \ + (!(tempDL[1] == 1 && (tempDL[0] & MIPSDSP_LHI) == MIPSDSP_LHI))) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + return tempI; +} + +uint32_t helper_extr_r_w(CPUMIPSState *env, int ac, int shift) +{ + int32_t tempI; + int64_t tempDL[2]; + + mipsdsp__rashift_short_acc(env, tempDL, ac, shift); + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + tempDL[0] += 1; + if (tempDL[0] == 0) { + tempDL[1] += 1; + } + + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 && (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + tempI = tempDL[0] >> 1; + + return tempI; +} + +uint32_t helper_extr_rs_w(CPUMIPSState *env, int ac, int shift) +{ + int32_t tempI, temp64; + int64_t tempDL[2]; + + mipsdsp__rashift_short_acc(env, tempDL, ac, shift); + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + tempDL[0] += 1; + if (tempDL[0] == 0) { + tempDL[1] += 1; + } + tempI = tempDL[0] >> 1; + + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + temp64 = tempDL[1]; + if (temp64 == 0) { + tempI = 0x7FFFFFFF; + } else { + tempI = 0x80000000; + } + set_DSPControl_overflow_flag(env, 1, 23); + } + + return tempI; +} + +uint32_t helper_extr_s_h(CPUMIPSState *env, int ac, int shift) +{ + int64_t temp; + uint32_t tempI; + + temp = mipsdsp_rashift_short_acc(env, ac, shift); + if (temp > 0x0000000000007FFFull) { + temp &= MIPSDSP_LHI; + temp |= 0x00007FFF; + set_DSPControl_overflow_flag(env, 1, 23); + } else if (temp < 0xFFFFFFFFFFFF8000ull) { + temp &= MIPSDSP_LHI; + temp |= 0xFFFF8000; + set_DSPControl_overflow_flag(env, 1, 23); + } + + tempI = temp & 0xFFFFFFFF; + return tempI; +} + +uint32_t helper_extrv_s_h(CPUMIPSState *env, int ac, uint32_t rs) +{ + uint32_t rd; + int32_t shift, tempI; + int64_t tempL; + + shift = rs & 0x0F; + tempL = mipsdsp_rashift_short_acc(env, ac, shift); + if (tempL > 0x000000000007FFFull) { + tempI = 0x00007FFF; + set_DSPControl_overflow_flag(env, 1, 23); + } else if (tempL < 0xFFFFFFFFFFF8000ull) { + tempI = 0xFFFF8000; + set_DSPControl_overflow_flag(env, 1, 23); + } + rd = tempI; + + return rd; +} + +uint32_t helper_extrv_w(CPUMIPSState *env, int ac, uint32_t rs) +{ + int32_t shift, tempI; + int64_t tempDL[2]; + + shift = rs & 0x0F; + mipsdsp__rashift_short_acc(env, tempDL, ac, shift); + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + tempI = tempDL[0] >> 1; + + tempDL[0] += 1; + if (tempDL[0] == 0) { + tempDL[1] += 1; + } + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + return tempI; +} + +uint32_t helper_extrv_r_w(CPUMIPSState *env, int ac, uint32_t rs) +{ + int32_t shift, tempI; + int64_t tempDL[2]; + + shift = rs & 0x0F; + mipsdsp__rashift_short_acc(env, tempDL, ac, shift); + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + tempDL[0] += 1; + if (tempDL[0] == 0) { + tempDL[1] += 1; + } + + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + tempI = tempDL[0] >> 1; + + return tempI; +} + +uint32_t helper_extrv_rs_w(CPUMIPSState *env, int ac, uint32_t rs) +{ + int32_t shift, tempI; + int64_t tempDL[2]; + + shift = rs & 0x0F; + mipsdsp__rashift_short_acc(env, tempDL, ac, shift); + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + set_DSPControl_overflow_flag(env, 1, 23); + } + + tempDL[0] += 1; + if (tempDL[0] == 0) { + tempDL[1] += 1; + } + tempI = tempDL[0] >> 1; + + if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) && \ + (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) { + if (tempDL[1] == 0) { + tempI = 0x7FFFFFFF; + } else { + tempI = 0x80000000; + } + set_DSPControl_overflow_flag(env, 1, 23); + } + + return tempI; +} + +uint32_t helper_extp(CPUMIPSState *env, int ac, int size) +{ + int32_t start_pos; + uint32_t temp; + uint64_t acc; + + temp = 0; + start_pos = get_DSPControl_pos(env); + if (start_pos - (size + 1) >= -1) { + acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); + temp = (acc >> (start_pos - size)) & \ + (((uint32_t)0x01 << (size + 1)) - 1); + set_DSPControl_efi(env, 0); + } else { + set_DSPControl_efi(env, 1); + } + + return temp; +} + +uint32_t helper_extpv(CPUMIPSState *env, int ac, uint32_t rs) +{ + int32_t start_pos, size; + uint32_t temp; + uint64_t acc; + + temp = 0; + start_pos = get_DSPControl_pos(env); + size = rs & 0x1F; + + if (start_pos - (size + 1) >= -1) { + acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); + temp = (acc >> (start_pos - size)) & \ + (((uint32_t)0x01 << (size + 1)) - 1); + set_DSPControl_efi(env, 0); + } else { + set_DSPControl_efi(env, 1); + } + + return temp; +} + +uint32_t helper_extpdp(CPUMIPSState *env, int ac, int size) +{ + int32_t start_pos; + uint32_t temp; + uint64_t acc; + + temp = 0; + start_pos = get_DSPControl_pos(env); + if (start_pos - (size + 1) >= -1) { + acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); + temp = (acc >> (start_pos - size)) & \ + (((uint32_t)0x01 << (size + 1)) - 1); + + set_DSPControl_pos(env, start_pos - (size + 1)); + set_DSPControl_efi(env, 0); + } else { + set_DSPControl_efi(env, 1); + } + + return temp; +} + +uint32_t helper_extpdpv(CPUMIPSState *env, int ac, uint32_t rs) +{ + int32_t start_pos, size; + uint32_t temp; + uint64_t acc; + + temp = 0; + start_pos = get_DSPControl_pos(env); + size = rs & 0x1F; + + if (start_pos - (size + 1) >= -1) { + acc = ((uint64_t)env->active_tc.HI[ac] << 32) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); + temp = (acc >> (start_pos - size)) & (((int)0x01 << (size + 1)) - 1); + set_DSPControl_pos(env, start_pos - (size + 1)); + set_DSPControl_efi(env, 0); + } else { + set_DSPControl_efi(env, 1); + } + + return temp; +} + +void helper_shilo(CPUMIPSState *env, int ac, int shift) +{ + uint8_t sign; + uint64_t temp, acc; + + shift = (shift << 26) >> 26; + sign = (shift >> 5) & 0x01; + shift = (sign == 0) ? shift : -shift; + acc = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); + + if (shift == 0) { + temp = acc; + } else { + if (sign == 0) { + temp = acc >> shift; + } else { + temp = acc << shift; + } + } + + env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32; + env->active_tc.LO[ac] = temp & MIPSDSP_LLO; +} + +void helper_shilov(CPUMIPSState *env, int ac, uint32_t rs) +{ + uint8_t sign; + int8_t rs5_0; + uint64_t temp, acc; + + rs5_0 = rs & 0x3F; + rs = (rs5_0 << 2) >> 2; + sign = (rs5_0 >> 5) & 0x01; + rs5_0 = (sign == 0) ? rs : -rs; + acc = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) | \ + ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO); + if (rs5_0 == 0) { + temp = acc; + } else { + if (sign == 0) { + temp = acc >> rs5_0; + } else { + temp = acc << rs5_0; + } + } + + env->active_tc.HI[ac] = (temp & MIPSDSP_LHI) >> 32; + env->active_tc.LO[ac] = temp & MIPSDSP_LLO; +} + +void helper_mthlip(CPUMIPSState *env, int ac, uint32_t rs) +{ + int32_t tempA, tempB, pos; + + tempA = rs; + tempB = env->active_tc.LO[ac]; + env->active_tc.HI[ac] = tempB; + env->active_tc.LO[ac] = tempA; + pos = get_DSPControl_pos(env); + + if (pos > 32) { + return; + } else { + set_DSPControl_pos(env, pos + 32); + } +} + +void helper_wrdsp(CPUMIPSState *env, uint32_t rs, int mask_num) +{ + uint8_t mask[6]; + uint8_t i; + uint32_t newbits, overwrite; + target_ulong dsp; + + newbits = 0x00; + overwrite = 0xFFFFFFFF; + dsp = env->active_tc.DSPControl; + + for (i = 0; i < 6; i++) { + mask[i] = (mask_num >> i) & 0x01; + } + + if (mask[0] == 1) { + overwrite &= 0xFFFFFFC0; + newbits &= 0xFFFFFFC0; + newbits |= 0x0000003F & rs; + } + + if (mask[1] == 1) { + overwrite &= 0xFFFFE07F; + newbits &= 0xFFFFE07F; + newbits |= 0x00001F80 & rs; + } + + if (mask[2] == 1) { + overwrite &= 0xFFFFDFFF; + newbits &= 0xFFFFDFFF; + newbits |= 0x00002000 & rs; + } + + if (mask[3] == 1) { + overwrite &= 0xFF00FFFF; + newbits &= 0xFF00FFFF; + newbits |= 0x00FF0000 & rs; + } + + if (mask[4] == 1) { + overwrite &= 0x00FFFFFF; + newbits &= 0x00FFFFFF; + newbits |= 0xFF000000 & rs; + } + + if (mask[5] == 1) { + overwrite &= 0xFFFFBFFF; + newbits &= 0xFFFFBFFF; + newbits |= 0x00004000 & rs; + } + + dsp = dsp & overwrite; + dsp = dsp | newbits; + env->active_tc.DSPControl = dsp; +} + +uint32_t helper_rddsp(CPUMIPSState *env, uint32_t masknum) +{ + uint8_t mask[6]; + uint32_t ruler, i; + uint32_t temp; + uint32_t rd; + target_ulong dsp; + + ruler = 0x01; + for (i = 0; i < 6; i++) { + mask[i] = (masknum & ruler) >> i ; + ruler = ruler << 1; + } + + temp = 0x00; + dsp = env->active_tc.DSPControl; + + if (mask[0] == 1) { + temp |= dsp & 0x3F; + } + + if (mask[1] == 1) { + temp |= dsp & 0x1F80; + } + + if (mask[2] == 1) { + temp |= dsp & 0x2000; + } + + if (mask[3] == 1) { + temp |= dsp & 0x00FF0000; + } + + if (mask[4] == 1) { + temp |= dsp & 0xFF000000; + } + + if (mask[5] == 1) { + temp |= dsp & 0x4000; + } + + rd = temp; + + return rd; +} + #undef MIPSDSP_LHI #undef MIPSDSP_LLO #undef MIPSDSP_HI diff --git a/target-mips/helper.h b/target-mips/helper.h index 7737a22..446e66a 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -431,4 +431,23 @@ DEF_HELPER_FLAGS_3(prepend, TCG_CALL_CONST | TCG_CALL_PURE, i32, int, i32, i32) DEF_HELPER_FLAGS_3(balign, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32, i32) DEF_HELPER_FLAGS_2(packrl_ph, TCG_CALL_CONST | TCG_CALL_PURE, i32, i32, i32) +/* DSP Accumulator and DSPControl Access Sub-class insns */ +DEF_HELPER_FLAGS_3(extr_w, 0, i32, env, int, int) +DEF_HELPER_FLAGS_3(extr_r_w, 0, i32, env, int, int) +DEF_HELPER_FLAGS_3(extr_rs_w, 0, i32, env, int, int) +DEF_HELPER_FLAGS_3(extr_s_h, 0, i32, env, int, int) +DEF_HELPER_FLAGS_3(extrv_s_h, 0, i32, env, int, i32) +DEF_HELPER_FLAGS_3(extrv_w, 0, i32, env, int, i32) +DEF_HELPER_FLAGS_3(extrv_r_w, 0, i32, env, int, i32) +DEF_HELPER_FLAGS_3(extrv_rs_w, 0, i32, env, int, i32) +DEF_HELPER_FLAGS_3(extp, 0, i32, env, int, int) +DEF_HELPER_FLAGS_3(extpv, 0, i32, env, int, i32) +DEF_HELPER_FLAGS_3(extpdp, 0, i32, env, int, int) +DEF_HELPER_FLAGS_3(extpdpv, 0, i32, env, int, i32) +DEF_HELPER_FLAGS_3(shilo, 0, void, env, int, int) +DEF_HELPER_FLAGS_3(shilov, 0, void, env, int, i32) +DEF_HELPER_FLAGS_3(mthlip, 0, void, env, int, i32) +DEF_HELPER_FLAGS_3(wrdsp, 0, void, env, i32, int) +DEF_HELPER_FLAGS_2(rddsp, 0, i32, env, i32) + #include "def-helper.h" diff --git a/target-mips/translate.c b/target-mips/translate.c index f5d3859..d6561c2 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -331,6 +331,8 @@ enum { OPC_INSV_DSP = 0x0C | OPC_SPECIAL3, /* MIPS DSP Compare-Pick Sub-class */ OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3, + /* MIPS DSP Accumulator and DSPControl Access Sub-class */ + OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, }; /* BSHFL opcodes */ @@ -536,6 +538,28 @@ enum { OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP, }; +#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6))) +enum { + /* MIPS DSP Accumulator and DSPControl Access Sub-class */ + OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP, + OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP, + OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP, + OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP, + OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP, + OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP, + OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP, + OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP, + OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP, + OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP, + OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP, + OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP, + OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP, + OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP, +}; + /* Coprocessor 0 (rs field) */ #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21)) @@ -13011,6 +13035,157 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) } } break; + case OPC_EXTR_W_DSP: + op2 = MASK_EXTR_W(ctx->opcode); + switch (op2) { + case OPC_EXTR_W: + { + TCGv temp_rd = tcg_const_i32(rd); + TCGv temp_rs = tcg_const_i32(rs); + gen_helper_extr_w(cpu_gpr[rt], cpu_env, temp_rd, temp_rs); + tcg_temp_free(temp_rd); + tcg_temp_free(temp_rs); + break; + } + case OPC_EXTR_R_W: + { + TCGv temp_rd = tcg_const_i32(rd); + TCGv temp_rs = tcg_const_i32(rs); + gen_helper_extr_r_w(cpu_gpr[rt], cpu_env, temp_rd, temp_rs); + tcg_temp_free(temp_rd); + tcg_temp_free(temp_rs); + break; + } + case OPC_EXTR_RS_W: + { + TCGv temp_rd = tcg_const_i32(rd); + TCGv temp_rs = tcg_const_i32(rs); + gen_helper_extr_rs_w(cpu_gpr[rt], cpu_env, + temp_rd, temp_rs); + tcg_temp_free(temp_rd); + tcg_temp_free(temp_rs); + break; + } + case OPC_EXTR_S_H: + { + TCGv temp_rd = tcg_const_i32(rd); + TCGv temp_rs = tcg_const_i32(rs); + gen_helper_extr_s_h(cpu_gpr[rt], cpu_env, temp_rd, temp_rs); + tcg_temp_free(temp_rd); + tcg_temp_free(temp_rs); + break; + } + case OPC_EXTRV_S_H: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_extrv_s_h(cpu_gpr[rt], cpu_env, + temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_EXTRV_W: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_extrv_w(cpu_gpr[rt], cpu_env, + temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_EXTRV_R_W: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_extrv_r_w(cpu_gpr[rt], cpu_env, + temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_EXTRV_RS_W: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_extrv_rs_w(cpu_gpr[rt], cpu_env, + temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_EXTP: + { + TCGv temp_rd = tcg_const_i32(rd); + TCGv temp_rs = tcg_const_i32(rs); + gen_helper_extp(cpu_gpr[rt], cpu_env, temp_rd, temp_rs); + tcg_temp_free(temp_rd); + tcg_temp_free(temp_rs); + break; + } + case OPC_EXTPV: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_extpv(cpu_gpr[rt], cpu_env, + temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_EXTPDP: + { + TCGv temp_rd = tcg_const_i32(rd); + TCGv temp_rs = tcg_const_i32(rs); + gen_helper_extpdp(cpu_gpr[rt], cpu_env, temp_rd, temp_rs); + tcg_temp_free(temp_rd); + tcg_temp_free(temp_rs); + break; + } + case OPC_EXTPDPV: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_extpdpv(cpu_gpr[rt], cpu_env, + temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_SHILO: + { + TCGv temp_imm; + TCGv temp_rd = tcg_const_i32(rd); + imm = (ctx->opcode >> 20) & 0x3F; + temp_imm = tcg_const_i32(imm); + gen_helper_shilo(cpu_env, temp_rd, temp_imm); + tcg_temp_free(temp_imm); + tcg_temp_free(temp_rd); + break; + } + case OPC_SHILOV: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_shilov(cpu_env, temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_MTHLIP: + { + TCGv temp_rd = tcg_const_i32(rd); + gen_helper_mthlip(cpu_env, temp_rd, cpu_gpr[rs]); + tcg_temp_free(temp_rd); + break; + } + case OPC_WRDSP: + { + TCGv temp_imm; + imm = (ctx->opcode >> 11) & 0x3FF; + temp_imm = tcg_const_i32(imm); + gen_helper_wrdsp(cpu_env, cpu_gpr[rs], temp_imm); + tcg_temp_free(temp_imm); + break; + } + case OPC_RDDSP: + { + TCGv temp_imm; + imm = (ctx->opcode >> 16) & 0x03FF; + temp_imm = tcg_const_i32(imm); + gen_helper_rddsp(cpu_gpr[rd], cpu_env, temp_imm); + tcg_temp_free(temp_imm); + break; + } + } + break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: case OPC_DINSM ... OPC_DINS: -- 1.7.5.4