From: Jia Liu <proljc@gmail.com>
To: qemu-devel@nongnu.org
Cc: aurelien@aurel32.net
Subject: [Qemu-devel] [PATCH v6 06/13] target-mips-ase-dsp: Add GPR Based shift instructions
Date: Tue, 21 Aug 2012 14:53:12 +0800 [thread overview]
Message-ID: <1345531999-17872-7-git-send-email-proljc@gmail.com> (raw)
In-Reply-To: <1345531999-17872-1-git-send-email-proljc@gmail.com>
Add MIPS ASE DSP GPR-Based Shift instructions.
Signed-off-by: Jia Liu <proljc@gmail.com>
---
target-mips/dsp_helper.c | 991 ++++++++++++++++++++++++++++++++++++++++++++++
target-mips/helper.h | 62 +++
target-mips/translate.c | 359 +++++++++++++++++
3 files changed, 1412 insertions(+)
diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index 486b22f..8e7bccb 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3196,6 +3196,997 @@ target_ulong helper_preceu_qh_obra(target_ulong rt)
}
#endif
+/** DSP GPR-Based Shift Sub-class insns **/
+target_ulong helper_shll_qb(CPUMIPSState *env, uint32_t sa, target_ulong rt)
+{
+ uint8_t rt3, rt2, rt1, rt0;
+ uint8_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ tempD = mipsdsp_lshift8(env, rt3, sa);
+ tempC = mipsdsp_lshift8(env, rt2, sa);
+ tempB = mipsdsp_lshift8(env, rt1, sa);
+ tempA = mipsdsp_lshift8(env, rt0, sa);
+ rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |
+ ((uint32_t)tempB << 8) | ((uint32_t)tempA);
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shllv_qb(CPUMIPSState *env,
+ target_ulong rs, target_ulong rt)
+{
+ uint8_t rs2_0;
+ uint8_t rt3, rt2, rt1, rt0;
+ uint8_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rs2_0 = rs & 0x07;
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ tempD = mipsdsp_lshift8(env, rt3, rs2_0);
+ tempC = mipsdsp_lshift8(env, rt2, rs2_0);
+ tempB = mipsdsp_lshift8(env, rt1, rs2_0);
+ tempA = mipsdsp_lshift8(env, rt0, rs2_0);
+
+ rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |
+ ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_shll_ob(CPUMIPSState *env, target_ulong rt, uint32_t sa)
+{
+ int i;
+ uint8_t rt_t[8];
+ uint8_t temp_t[8];
+ uint64_t temp;
+
+ sa = sa & 0x07;
+ temp = 0;
+
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ temp_t[i] = mipsdsp_lshift8(env, rt_t[i], sa);
+
+ temp |= (uint64_t)temp_t[i] << (8 * i);
+ }
+
+ return temp;
+}
+
+target_ulong helper_shllv_ob(CPUMIPSState *env,
+ target_ulong rt, target_ulong sa)
+{
+ int i;
+ uint8_t rt_t[8];
+ uint8_t temp_t[8];
+ uint64_t temp;
+
+ sa = sa & 0x07;
+ temp = 0;
+
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ temp_t[i] = mipsdsp_lshift8(env, rt_t[i], sa);
+
+ temp |= (uint64_t)temp_t[i] << (8 * i);
+ }
+
+ return temp;
+}
+#endif
+
+target_ulong helper_shll_ph(CPUMIPSState *env, uint32_t sa, target_ulong rt)
+{
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = mipsdsp_lshift16(env, rth, sa);
+ tempA = mipsdsp_lshift16(env, rtl, sa);
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shllv_ph(CPUMIPSState *env,
+ target_ulong rs, target_ulong rt)
+{
+ uint8_t rs3_0;
+ uint16_t rth, rtl, tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ rs3_0 = rs & 0x0F;
+
+ tempB = mipsdsp_lshift16(env, rth, rs3_0);
+ tempA = mipsdsp_lshift16(env, rtl, rs3_0);
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shll_s_ph(CPUMIPSState *env, uint32_t sa, target_ulong rt)
+{
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = mipsdsp_sat16_lshift(env, rth, sa);
+ tempA = mipsdsp_sat16_lshift(env, rtl, sa);
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shllv_s_ph(CPUMIPSState *env,
+ target_ulong rs, target_ulong rt)
+{
+ uint8_t rs3_0;
+ uint16_t rth, rtl, tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ rs3_0 = rs & 0x0F;
+
+ tempB = mipsdsp_sat16_lshift(env, rth, rs3_0);
+ tempA = mipsdsp_sat16_lshift(env, rtl, rs3_0);
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_shll_qh(CPUMIPSState *env, target_ulong rt, uint32_t sa)
+{
+ uint16_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x0F;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_lshift16(env, rt3, sa);
+ tempC = mipsdsp_lshift16(env, rt2, sa);
+ tempB = mipsdsp_lshift16(env, rt1, sa);
+ tempA = mipsdsp_lshift16(env, rt0, sa);
+
+ temp = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shllv_qh(CPUMIPSState *env,
+ target_ulong rt, target_ulong sa)
+{
+ uint16_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x0F;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_lshift16(env, rt3, sa);
+ tempC = mipsdsp_lshift16(env, rt2, sa);
+ tempB = mipsdsp_lshift16(env, rt1, sa);
+ tempA = mipsdsp_lshift16(env, rt0, sa);
+
+ temp = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shll_s_qh(CPUMIPSState *env, target_ulong rt, uint32_t sa)
+{
+ uint16_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x0F;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_sat16_lshift(env, rt3, sa);
+ tempC = mipsdsp_sat16_lshift(env, rt2, sa);
+ tempB = mipsdsp_sat16_lshift(env, rt1, sa);
+ tempA = mipsdsp_sat16_lshift(env, rt0, sa);
+
+ temp = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shllv_s_qh(CPUMIPSState *env,
+ target_ulong rt, target_ulong sa)
+{
+ uint16_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x0F;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_sat16_lshift(env, rt3, sa);
+ tempC = mipsdsp_sat16_lshift(env, rt2, sa);
+ tempB = mipsdsp_sat16_lshift(env, rt1, sa);
+ tempA = mipsdsp_sat16_lshift(env, rt0, sa);
+
+ temp = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return temp;
+}
+#endif
+
+target_ulong helper_shll_s_w(CPUMIPSState *env, uint32_t sa, target_ulong rt)
+{
+ uint32_t temp, rd;
+
+ temp = mipsdsp_sat32_lshift(env, rt, sa);
+ rd = temp;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shllv_s_w(CPUMIPSState *env,
+ target_ulong rs, target_ulong rt)
+{
+ uint8_t rs4_0;
+ uint32_t rd;
+
+ rs4_0 = rs & 0x1F;
+ rd = mipsdsp_sat32_lshift(env, rt, rs4_0);
+
+ return (target_long)(int32_t)rd;
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_shll_pw(CPUMIPSState *env, target_ulong rt, uint32_t sa)
+{
+ uint32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t temp;
+
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_lshift32(env, rt1, sa);
+ tempA = mipsdsp_lshift32(env, rt0, sa);
+ temp = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shllv_pw(CPUMIPSState *env,
+ target_ulong rt, target_ulong sa)
+{
+ uint32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x1F;
+
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_lshift32(env, rt1, sa);
+ tempA = mipsdsp_lshift32(env, rt0, sa);
+ temp = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shll_s_pw(CPUMIPSState *env, target_ulong rt, uint32_t sa)
+{
+ uint32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t temp;
+
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_sat32_lshift(env, rt1, sa);
+ tempA = mipsdsp_sat32_lshift(env, rt0, sa);
+ temp = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shllv_s_pw(CPUMIPSState *env,
+ target_ulong rt, target_ulong sa)
+{
+ uint32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x1F;
+
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_sat32_lshift(env, rt1, sa);
+ tempA = mipsdsp_sat32_lshift(env, rt0, sa);
+ temp = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return temp;
+}
+#endif
+
+target_ulong helper_shrl_qb(uint32_t sa, target_ulong rt)
+{
+ uint8_t rt3, rt2, rt1, rt0;
+ uint8_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ tempD = mipsdsp_rshift8(rt3, sa);
+ tempC = mipsdsp_rshift8(rt2, sa);
+ tempB = mipsdsp_rshift8(rt1, sa);
+ tempA = mipsdsp_rshift8(rt0, sa);
+
+ rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |
+ ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrlv_qb(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs2_0;
+ uint8_t rt3, rt2, rt1, rt0;
+ uint8_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rs2_0 = rs & 0x07;
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ tempD = mipsdsp_rshift8(rt3, rs2_0);
+ tempC = mipsdsp_rshift8(rt2, rs2_0);
+ tempB = mipsdsp_rshift8(rt1, rs2_0);
+ tempA = mipsdsp_rshift8(rt0, rs2_0);
+ rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |
+ ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrl_ph(uint32_t sa, target_ulong rt)
+{
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = rth >> sa;
+ tempA = rtl >> sa;
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrlv_ph(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs3_0;
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rs3_0 = rs & 0x0F;
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+
+ tempB = rth >> rs3_0;
+ tempA = rtl >> rs3_0;
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_shrl_ob(target_ulong rt, uint32_t sa)
+{
+ int i;
+ uint8_t rt_t[8];
+ uint8_t temp[8];
+ uint64_t result;
+
+ sa = sa & 0x07;
+ result = 0;
+
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ temp[i] = mipsdsp_rshift8(rt_t[i], sa);
+ result |= (uint64_t)temp[i] << (8 * i);
+ }
+
+ return result;
+}
+
+target_ulong helper_shrlv_ob(target_ulong rt, target_ulong sa)
+{
+ int i;
+ uint8_t rt_t[8];
+ uint8_t temp[8];
+ uint64_t result;
+
+ sa = sa & 0x07;
+ result = 0;
+
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ temp[i] = mipsdsp_rshift8(rt_t[i], sa);
+ result |= (uint64_t)temp[i] << (8 * i);
+ }
+
+ return result;
+}
+
+target_ulong helper_shrl_qh(target_ulong rt, uint32_t sa)
+{
+ uint16_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x0F;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = rt3 >> sa;
+ tempC = rt2 >> sa;
+ tempB = rt1 >> sa;
+ tempA = rt0 >> sa;
+
+ temp = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return temp;
+}
+
+target_ulong helper_shrlv_qh(target_ulong rt, target_ulong sa)
+{
+ uint16_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint64_t temp;
+
+ sa = sa & 0x0F;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = rt3 >> sa;
+ tempC = rt2 >> sa;
+ tempB = rt1 >> sa;
+ tempA = rt0 >> sa;
+
+ temp = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return temp;
+}
+#endif
+
+target_ulong helper_shra_qb(uint32_t sa, target_ulong rt)
+{
+ int8_t rt3, rt2, rt1, rt0;
+ uint8_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ tempD = rt3 >> sa;
+ tempC = rt2 >> sa;
+ tempB = rt1 >> sa;
+ tempA = rt0 >> sa;
+
+ rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |
+ ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shra_r_qb(uint32_t sa, target_ulong rt)
+{
+ int8_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ if (sa == 0) {
+ tempD = rt3 & 0x00FF;
+ tempC = rt2 & 0x00FF;
+ tempB = rt1 & 0x00FF;
+ tempA = rt0 & 0x00FF;
+ } else {
+ tempD = ((int16_t)rt3 >> (sa - 1)) + 1;
+ tempC = ((int16_t)rt2 >> (sa - 1)) + 1;
+ tempB = ((int16_t)rt1 >> (sa - 1)) + 1;
+ tempA = ((int16_t)rt0 >> (sa - 1)) + 1;
+ }
+
+ rd = ((uint32_t)((tempD >> 1) & 0x00FF) << 24) |
+ ((uint32_t)((tempC >> 1) & 0x00FF) << 16) |
+ ((uint32_t)((tempB >> 1) & 0x00FF) << 8) |
+ (uint32_t)((tempA >> 1) & 0x00FF) ;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrav_qb(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs2_0;
+ int8_t rt3, rt2, rt1, rt0;
+ uint8_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rs2_0 = rs & 0x07;
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ if (rs2_0 == 0) {
+ tempD = rt3;
+ tempC = rt2;
+ tempB = rt1;
+ tempA = rt0;
+ } else {
+ tempD = rt3 >> rs2_0;
+ tempC = rt2 >> rs2_0;
+ tempB = rt1 >> rs2_0;
+ tempA = rt0 >> rs2_0;
+ }
+
+ rd = ((uint32_t)tempD << 24) | ((uint32_t)tempC << 16) |
+ ((uint32_t)tempB << 8) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrav_r_qb(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs2_0;
+ int8_t rt3, rt2, rt1, rt0;
+ uint16_t tempD, tempC, tempB, tempA;
+ uint32_t rd;
+
+ rs2_0 = rs & 0x07;
+ rt3 = (rt & MIPSDSP_Q3) >> 24;
+ rt2 = (rt & MIPSDSP_Q2) >> 16;
+ rt1 = (rt & MIPSDSP_Q1) >> 8;
+ rt0 = rt & MIPSDSP_Q0;
+
+ if (rs2_0 == 0) {
+ tempD = (int16_t)rt3 << 1;
+ tempC = (int16_t)rt2 << 1;
+ tempB = (int16_t)rt1 << 1;
+ tempA = (int16_t)rt0 << 1;
+ } else {
+ tempD = ((int16_t)rt3 >> (rs2_0 - 1)) + 1;
+ tempC = ((int16_t)rt2 >> (rs2_0 - 1)) + 1;
+ tempB = ((int16_t)rt1 >> (rs2_0 - 1)) + 1;
+ tempA = ((int16_t)rt0 >> (rs2_0 - 1)) + 1;
+ }
+
+ rd = ((uint32_t)((tempD >> 1) & 0x00FF) << 24) |
+ ((uint32_t)((tempC >> 1) & 0x00FF) << 16) |
+ ((uint32_t)((tempB >> 1) & 0x00FF) << 8) |
+ (uint32_t)((tempA >> 1) & 0x00FF) ;
+
+ return (target_long)(int32_t)rd;
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_shra_ob(target_ulong rt, uint32_t sa)
+{
+ int i;
+ int8_t rt_t[8];
+ uint8_t temp[8];
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0x07;
+
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ temp[i] = rt_t[i] >> sa;
+ result |= (uint64_t)temp[i] << (8 * i);
+ }
+
+ return result;
+}
+
+target_ulong helper_shrav_ob(target_ulong rt, target_ulong sa)
+{
+ int i;
+ int8_t rt_t[8];
+ uint8_t temp[8];
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0x07;
+
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ temp[i] = rt_t[i] >> sa;
+ result |= (uint64_t)temp[i] << (8 * i);
+ }
+
+ return result;
+}
+
+target_ulong helper_shra_r_ob(target_ulong rt, uint32_t sa)
+{
+ int i;
+ int8_t rt_t[8];
+ int16_t rt_t_S[8];
+ uint8_t temp[8];
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0x07;
+
+ if (sa == 0) {
+ result = rt;
+ } else {
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ rt_t_S[i] = ((int16_t)rt_t[i] >> (sa - 1)) + 1;
+ temp[i] = (rt_t_S[i] >> 1) & MIPSDSP_Q0;
+ result |= (uint64_t)temp[i] << (8 * i);
+ }
+ }
+
+ return result;
+}
+
+target_ulong helper_shrav_r_ob(target_ulong rt, target_ulong sa)
+{
+ int i;
+ int8_t rt_t[8];
+ int16_t rt_t_S[8];
+ uint8_t temp[8];
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0x07;
+
+ if (sa == 0) {
+ result = rt;
+ } else {
+ for (i = 0; i < 8; i++) {
+ rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;
+ rt_t_S[i] = ((int16_t)rt_t[i] >> (sa - 1)) + 1;
+ temp[i] = (rt_t_S[i] >> 1) & MIPSDSP_Q0;
+ result |= (uint64_t)temp[i] << (8 * i);
+ }
+ }
+
+ return result;
+}
+#endif
+
+target_ulong helper_shra_ph(uint32_t sa, target_ulong rt)
+{
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = mipsdsp_rashift16(rth, sa);
+ tempA = mipsdsp_rashift16(rtl, sa);
+ rd = ((uint32_t)tempB << 16) | (uint32_t) tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrav_ph(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs3_0;
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rs3_0 = rs & 0x0F;
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = mipsdsp_rashift16(rth, rs3_0);
+ tempA = mipsdsp_rashift16(rtl, rs3_0);
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shra_r_ph(uint32_t sa, target_ulong rt)
+{
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = mipsdsp_rnd16_rashift(rth, sa);
+ tempA = mipsdsp_rnd16_rashift(rtl, sa);
+ rd = ((uint32_t)tempB << 16) | (uint32_t) tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrav_r_ph(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs3_0;
+ uint16_t rth, rtl;
+ uint16_t tempB, tempA;
+ uint32_t rd;
+
+ rs3_0 = rs & 0x0F;
+ rth = (rt & MIPSDSP_HI) >> 16;
+ rtl = rt & MIPSDSP_LO;
+ tempB = mipsdsp_rnd16_rashift(rth, rs3_0);
+ tempA = mipsdsp_rnd16_rashift(rtl, rs3_0);
+
+ rd = ((uint32_t)tempB << 16) | (uint32_t)tempA;
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shra_r_w(uint32_t sa, target_ulong rt)
+{
+ uint32_t rd;
+
+ rd = mipsdsp_rnd32_rashift(rt, sa);
+
+ return (target_long)(int32_t)rd;
+}
+
+target_ulong helper_shrav_r_w(target_ulong rs, target_ulong rt)
+{
+ uint8_t rs4_0;
+ uint32_t rd;
+
+ rs4_0 = rs & 0x1F;
+ rd = mipsdsp_rnd32_rashift(rt, rs4_0);
+
+ return (target_long)(int32_t)rd;
+}
+
+#if defined(TARGET_MIPS64)
+target_ulong helper_shra_qh(target_ulong rt, uint32_t sa)
+{
+ int32_t rt3, rt2, rt1, rt0;
+ uint32_t tempD, tempC, tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0xF;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_rashift16(rt3, sa);
+ tempC = mipsdsp_rashift16(rt2, sa);
+ tempB = mipsdsp_rashift16(rt1, sa);
+ tempA = mipsdsp_rashift16(rt0, sa);
+
+ result = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return result;
+}
+
+target_ulong helper_shrav_qh(target_ulong rt, target_ulong sa)
+{
+ int32_t rt3, rt2, rt1, rt0;
+ uint32_t tempD, tempC, tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0xF;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_rashift16(rt3, sa);
+ tempC = mipsdsp_rashift16(rt2, sa);
+ tempB = mipsdsp_rashift16(rt1, sa);
+ tempA = mipsdsp_rashift16(rt0, sa);
+
+ result = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return result;
+}
+
+
+target_ulong helper_shra_r_qh(target_ulong rt, uint32_t sa)
+{
+ int32_t rt3, rt2, rt1, rt0;
+ uint32_t tempD, tempC, tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0xF;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_rnd16_rashift(rt3, sa);
+ tempC = mipsdsp_rnd16_rashift(rt2, sa);
+ tempB = mipsdsp_rnd16_rashift(rt1, sa);
+ tempA = mipsdsp_rnd16_rashift(rt0, sa);
+
+ result = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return result;
+}
+
+target_ulong helper_shrav_r_qh(target_ulong rt, target_ulong sa)
+{
+ int32_t rt3, rt2, rt1, rt0;
+ uint32_t tempD, tempC, tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0xF;
+
+ rt3 = (rt >> 48) & MIPSDSP_LO;
+ rt2 = (rt >> 32) & MIPSDSP_LO;
+ rt1 = (rt >> 16) & MIPSDSP_LO;
+ rt0 = rt & MIPSDSP_LO;
+
+ tempD = mipsdsp_rnd16_rashift(rt3, sa);
+ tempC = mipsdsp_rnd16_rashift(rt2, sa);
+ tempB = mipsdsp_rnd16_rashift(rt1, sa);
+ tempA = mipsdsp_rnd16_rashift(rt0, sa);
+
+ result = ((uint64_t)tempD << 48) | ((uint64_t)tempC << 32) |
+ ((uint64_t)tempB << 16) | (uint64_t)tempA;
+
+ return result;
+}
+
+target_ulong helper_shra_pw(target_ulong rt, uint32_t sa)
+{
+ int32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+
+ /* FIXME, it seems like document error. */
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_rashift32(rt1, sa);
+ tempA = mipsdsp_rashift32(rt0, sa);
+
+ result = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return result;
+}
+
+target_ulong helper_shrav_pw(target_ulong rt, target_ulong sa)
+{
+ int32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0x1F;
+
+ /* FIXME, it seems like document error. */
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_rashift32(rt1, sa);
+ tempA = mipsdsp_rashift32(rt0, sa);
+
+ result = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return result;
+}
+
+target_ulong helper_shra_r_pw(target_ulong rt, uint32_t sa)
+{
+ int32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_rnd32_rashift(rt1, sa);
+ tempA = mipsdsp_rnd32_rashift(rt0, sa);
+
+ result = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return result;
+}
+
+target_ulong helper_shrav_r_pw(target_ulong rt, target_ulong sa)
+{
+ int32_t rt1, rt0;
+ uint32_t tempB, tempA;
+ uint64_t result;
+
+ result = 0;
+ sa = sa & 0x1F;
+
+ rt1 = (rt >> 32) & MIPSDSP_LLO;
+ rt0 = rt & MIPSDSP_LLO;
+
+ tempB = mipsdsp_rnd32_rashift(rt1, sa);
+ tempA = mipsdsp_rnd32_rashift(rt0, sa);
+
+ result = ((uint64_t)tempB << 32) | (uint64_t)tempA;
+
+ return result;
+}
+#endif
+
#undef MIPSDSP_LHI
#undef MIPSDSP_LLO
#undef MIPSDSP_HI
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 0607105..7046380 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -429,4 +429,66 @@ DEF_HELPER_FLAGS_1(preceu_qh_obla, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
DEF_HELPER_FLAGS_1(preceu_qh_obra, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
#endif
+/* DSP GPR-Based Shift Sub-class insns */
+DEF_HELPER_FLAGS_3(shll_qb, 0, tl, env, i32, tl)
+DEF_HELPER_FLAGS_3(shllv_qb, 0, tl, env, tl, tl)
+#if defined(TARGET_MIPS64)
+DEF_HELPER_FLAGS_3(shll_ob, 0, tl, env, tl, i32)
+DEF_HELPER_FLAGS_3(shllv_ob, 0, tl, env, tl, tl)
+#endif
+DEF_HELPER_FLAGS_3(shll_ph, 0, tl, env, i32, tl)
+DEF_HELPER_FLAGS_3(shllv_ph, 0, tl, env, tl, tl)
+DEF_HELPER_FLAGS_3(shll_s_ph, 0, tl, env, i32, tl)
+DEF_HELPER_FLAGS_3(shllv_s_ph, 0, tl, env, tl, tl)
+#if defined(TARGET_MIPS64)
+DEF_HELPER_FLAGS_3(shll_qh, 0, tl, env, tl, i32)
+DEF_HELPER_FLAGS_3(shllv_qh, 0, tl, env, tl, tl)
+DEF_HELPER_FLAGS_3(shll_s_qh, 0, tl, env, tl, i32)
+DEF_HELPER_FLAGS_3(shllv_s_qh, 0, tl, env, tl, tl)
+#endif
+DEF_HELPER_FLAGS_3(shll_s_w, 0, tl, env, i32, tl)
+DEF_HELPER_FLAGS_3(shllv_s_w, 0, tl, env, tl, tl)
+#if defined(TARGET_MIPS64)
+DEF_HELPER_FLAGS_3(shll_pw, 0, tl, env, tl, i32)
+DEF_HELPER_FLAGS_3(shllv_pw, 0, tl, env, tl, tl)
+DEF_HELPER_FLAGS_3(shll_s_pw, 0, tl, env, tl, i32)
+DEF_HELPER_FLAGS_3(shllv_s_pw, 0, tl, env, tl, tl)
+#endif
+DEF_HELPER_FLAGS_2(shrl_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shrlv_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shrl_ph, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shrlv_ph, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+#if defined(TARGET_MIPS64)
+DEF_HELPER_FLAGS_2(shrl_ob, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrlv_ob, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shrl_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrlv_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+#endif
+DEF_HELPER_FLAGS_2(shra_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shra_r_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shrav_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shrav_r_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+#if defined(TARGET_MIPS64)
+DEF_HELPER_FLAGS_2(shra_ob, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrav_ob, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shra_r_ob, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrav_r_ob, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+#endif
+DEF_HELPER_FLAGS_2(shra_ph, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shrav_ph, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shra_r_ph, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shrav_r_ph, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shra_r_w, TCG_CALL_CONST | TCG_CALL_PURE, tl, i32, tl)
+DEF_HELPER_FLAGS_2(shrav_r_w, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+#if defined(TARGET_MIPS64)
+DEF_HELPER_FLAGS_2(shra_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrav_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shra_r_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrav_r_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shra_pw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrav_pw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+DEF_HELPER_FLAGS_2(shra_r_pw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, i32)
+DEF_HELPER_FLAGS_2(shrav_r_pw, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
+#endif
+
#include "def-helper.h"
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0ea9131..fa26bb1 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -331,6 +331,18 @@ enum {
#if defined(TARGET_MIPS64)
OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
#endif
+ /* MIPS DSP GPR-Based Shift Sub-class */
+ OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
+#if defined(TARGET_MIPS64)
+ OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
+#endif
+ /* MIPS DSP Multiply Sub-class insns */
+ /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
+ /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
+ OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
+#if defined(TARGET_MIPS64)
+ OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
+#endif
};
/* BSHFL opcodes */
@@ -439,6 +451,32 @@ enum {
OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
};
+#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
+enum {
+ /* MIPS DSP GPR-Based Shift Sub-class */
+ OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
+ OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
+};
#if defined(TARGET_MIPS64)
#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
@@ -507,6 +545,39 @@ enum {
};
#endif
+#if defined(TARGET_MIPS64)
+#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
+enum {
+ /* MIPS DSP GPR-Based Shift Sub-class */
+ OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
+ OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
+};
+#endif
+
/* Coprocessor 0 (rs field) */
#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
@@ -12619,6 +12690,117 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
break;
}
break;
+ case OPC_SHLL_QB_DSP:
+ {
+ TCGv_i32 temp_rs = tcg_const_i32(rs);
+ op2 = MASK_SHLL_QB(ctx->opcode);
+ switch (op2) {
+ case OPC_SHLL_QB:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shll_qb(cpu_gpr[rd], cpu_env,
+ temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHLLV_QB:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_qb(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHLL_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shll_ph(cpu_gpr[rd], cpu_env,
+ temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHLLV_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_ph(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHLL_S_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shll_s_ph(cpu_gpr[rd], cpu_env,
+ temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHLLV_S_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_s_ph(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHLL_S_W:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shll_s_w(cpu_gpr[rd], cpu_env,
+ temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHLLV_S_W:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_s_w(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHRL_QB:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrl_qb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRLV_QB:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrlv_qb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHRL_PH:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrl_ph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRLV_PH:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrlv_ph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHRA_QB:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shra_qb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRA_R_QB:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shra_r_qb(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRAV_QB:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrav_qb(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHRAV_R_QB:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrav_r_qb(cpu_gpr[rd], cpu_gpr[rs],
+ cpu_gpr[rt]);
+ break;
+ case OPC_SHRA_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shra_ph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRA_R_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shra_r_ph(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRAV_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_ph(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ case OPC_SHRAV_R_PH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_r_ph(cpu_gpr[rd], cpu_gpr[rs],
+ cpu_gpr[rt]);
+ break;
+ case OPC_SHRA_R_W:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shra_r_w(cpu_gpr[rd], temp_rs, cpu_gpr[rt]);
+ break;
+ case OPC_SHRAV_R_W:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_r_w(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
+ break;
+ default: /* Invalid */
+ MIPS_INVAL("MASK SHLL.QB");
+ generate_exception(ctx, EXCP_RI);
+ break;
+ }
+ tcg_temp_free_i32(temp_rs);
+ break;
+ }
#if defined(TARGET_MIPS64)
case OPC_DEXTM ... OPC_DEXT:
case OPC_DINSM ... OPC_DINS:
@@ -12888,6 +13070,183 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
}
break;
#endif
+#if defined(TARGET_MIPS64)
+ case OPC_SHLL_OB_DSP:
+ op2 = MASK_SHLL_OB(ctx->opcode);
+ switch (op2) {
+ case OPC_SHLL_PW:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shll_pw(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHLLV_PW:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_pw(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHLL_S_PW:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shll_s_pw(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHLLV_S_PW:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_s_pw(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHLL_OB:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shll_ob(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHLLV_OB:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_ob(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHLL_QH:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shll_qh(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHLLV_QH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_qh(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHLL_S_QH:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shll_s_qh(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHLLV_S_QH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shllv_s_qh(cpu_gpr[rd], cpu_env,
+ cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRA_OB:
+ check_insn(env, ctx, ASE_DSPR2);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shra_ob(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRAV_OB:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrav_ob(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRA_R_OB:
+ check_insn(env, ctx, ASE_DSPR2);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shra_r_ob(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRAV_R_OB:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrav_r_ob(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRA_PW:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shra_pw(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRAV_PW:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_pw(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRA_R_PW:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shra_r_pw(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRAV_R_PW:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_r_pw(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRA_QH:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shra_qh(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRAV_QH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_qh(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRA_R_QH:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shra_r_qh(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRAV_R_QH:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrav_r_qh(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRL_OB:
+ check_insn(env, ctx, ASE_DSP);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shrl_ob(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRLV_OB:
+ check_insn(env, ctx, ASE_DSP);
+ gen_helper_shrlv_ob(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ case OPC_SHRL_QH:
+ check_insn(env, ctx, ASE_DSPR2);
+ {
+ TCGv_i32 sa_v = tcg_const_i32(rs);
+ gen_helper_shrl_qh(cpu_gpr[rd], cpu_gpr[rt], sa_v);
+ tcg_temp_free_i32(sa_v);
+ break;
+ }
+ case OPC_SHRLV_QH:
+ check_insn(env, ctx, ASE_DSPR2);
+ gen_helper_shrlv_qh(cpu_gpr[rd], cpu_gpr[rt], cpu_gpr[rs]);
+ break;
+ default: /* Invalid */
+ MIPS_INVAL("MASK SHLL.OB");
+ generate_exception(ctx, EXCP_RI);
+ break;
+ }
+ break;
+#endif
default: /* Invalid */
MIPS_INVAL("special3");
generate_exception(ctx, EXCP_RI);
--
1.7.9.5
next prev parent reply other threads:[~2012-08-21 6:55 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-21 6:53 [Qemu-devel] [PATCH v6 00/13] QEMU MIPS ASE DSP support Jia Liu
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 01/13] target-mips-ase-dsp: Add internal functions Jia Liu
2012-08-23 13:31 ` Aurelien Jarno
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 02/13] target-mips-ase-dsp: Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number Jia Liu
2012-08-23 13:33 ` Aurelien Jarno
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 03/13] target-mips-ase-dsp: Add branch instructions Jia Liu
2012-08-23 14:18 ` Aurelien Jarno
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 04/13] target-mips-ase-dsp: Add load instructions Jia Liu
2012-08-23 14:23 ` Aurelien Jarno
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 05/13] target-mips-ase-dsp: Add arithmetic instructions Jia Liu
2012-08-23 14:28 ` Aurelien Jarno
2012-08-21 6:53 ` Jia Liu [this message]
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 07/13] target-mips-ase-dsp: Add multiply instructions Jia Liu
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 08/13] target-mips-ase-dsp: Add bit/manipulation instructions Jia Liu
2012-08-23 14:48 ` Aurelien Jarno
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 09/13] target-mips-ase-dsp: Add compare pick instructions Jia Liu
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 10/13] target-mips-ase-dsp: Add MIPS ASE DSP Accumulator and DSPControl Access instructions Jia Liu
2012-08-21 6:53 ` [Qemu-devel] [PATCH v6 11/13] target-mips-ase-dsp: Add MIPS[32|64] ASE DSP[R1|R2] generic cpu model Jia Liu
2012-08-21 9:32 ` [Qemu-devel] [PATCH v6 12/13] target-mips-ase-dsp: Add testcases Jia Liu
2012-08-21 9:34 ` [Qemu-devel] [PATCH v6 13/13] target-mips-ase-dsp: Change TODO Jia Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345531999-17872-7-git-send-email-proljc@gmail.com \
--to=proljc@gmail.com \
--cc=aurelien@aurel32.net \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.