All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aurelien Jarno <aurelien@aurel32.net>
To: Jia Liu <proljc@gmail.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v12 07/14] target-mips: Add ASE DSP GPR-based shift instructions
Date: Mon, 29 Oct 2012 14:54:30 +0100	[thread overview]
Message-ID: <20121029135430.GA29866@ohm.aurel32.net> (raw)
In-Reply-To: <1351088234-7421-8-git-send-email-proljc@gmail.com>

On Wed, Oct 24, 2012 at 10:17:07PM +0800, Jia Liu wrote:
> Add MIPS ASE DSP GPR-Based Shift instructions.
> 
> Signed-off-by: Jia Liu <proljc@gmail.com>
> ---
>  target-mips/dsp_helper.c |  256 ++++++++++++++++++++++++++++++++++++
>  target-mips/helper.h     |   38 ++++++
>  target-mips/translate.c  |  324 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 618 insertions(+)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 7ddad34..3c79ceb 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -1933,6 +1933,262 @@ PRECEU_QH(obra, 48, 32, 16, 0);
>  
>  #endif
>  
> +/** DSP GPR-Based Shift Sub-class insns **/
> +#define SHIFT_QB(name, func) \
> +target_ulong helper_##name##_qb(target_ulong sa, target_ulong rt) \
> +{                                                                    \
> +    uint8_t rt3, rt2, rt1, rt0;                                      \
> +                                                                     \
> +    sa = sa & 0x07;                                                  \
> +                                                                     \
> +    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                       \
> +                                                                     \
> +    rt3 = mipsdsp_##func(rt3, sa);                                   \
> +    rt2 = mipsdsp_##func(rt2, sa);                                   \
> +    rt1 = mipsdsp_##func(rt1, sa);                                   \
> +    rt0 = mipsdsp_##func(rt0, sa);                                   \
> +                                                                     \
> +    return MIPSDSP_RETURN32_8(rt3, rt2, rt1, rt0);                   \
> +}
> +
> +#define SHIFT_QB_ENV(name, func) \
> +target_ulong helper_##name##_qb(target_ulong sa, target_ulong rt,\
> +                                CPUMIPSState *env) \
> +{                                                                    \
> +    uint8_t rt3, rt2, rt1, rt0;                                      \
> +                                                                     \
> +    sa = sa & 0x07;                                                  \
> +                                                                     \
> +    MIPSDSP_SPLIT32_8(rt, rt3, rt2, rt1, rt0);                       \
> +                                                                     \
> +    rt3 = mipsdsp_##func(rt3, sa, env);                              \
> +    rt2 = mipsdsp_##func(rt2, sa, env);                              \
> +    rt1 = mipsdsp_##func(rt1, sa, env);                              \
> +    rt0 = mipsdsp_##func(rt0, sa, env);                              \
> +                                                                     \
> +    return MIPSDSP_RETURN32_8(rt3, rt2, rt1, rt0);                   \
> +}
> +
> +SHIFT_QB_ENV(shll, lshift8);
> +SHIFT_QB(shrl, rshift_u8);
> +
> +SHIFT_QB(shra, rashift8);
> +SHIFT_QB(shra_r, rnd8_rashift);
> +
> +#undef SHIFT_QB
> +#undef SHIFT_QB_ENV
> +
> +#if defined(TARGET_MIPS64)
> +#define SHIFT_OB(name, func) \
> +target_ulong helper_##name##_ob(target_ulong rt, target_ulong sa) \
> +{                                                                        \
> +    int i;                                                               \
> +    uint8_t rt_t[8];                                                     \
> +    uint64_t temp;                                                       \
> +                                                                         \
> +    sa = sa & 0x07;                                                      \
> +    temp = 0;                                                            \
> +                                                                         \
> +    for (i = 0; i < 8; i++) {                                            \
> +        rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                          \
> +        rt_t[i] = mipsdsp_##func(rt_t[i], sa);                           \
> +        temp |= (uint64_t)rt_t[i] << (8 * i);                            \
> +    }                                                                    \
> +                                                                         \
> +    return temp;                                                         \
> +}
> +
> +#define SHIFT_OB_ENV(name, func) \
> +target_ulong helper_##name##_ob(target_ulong rt, target_ulong sa, \
> +                                CPUMIPSState *env)                       \
> +{                                                                        \
> +    int i;                                                               \
> +    uint8_t rt_t[8];                                                     \
> +    uint64_t temp;                                                       \
> +                                                                         \
> +    sa = sa & 0x07;                                                      \
> +    temp = 0;                                                            \
> +                                                                         \
> +    for (i = 0; i < 8; i++) {                                            \
> +        rt_t[i] = (rt >> (8 * i)) & MIPSDSP_Q0;                          \
> +        rt_t[i] = mipsdsp_##func(rt_t[i], sa, env);                      \
> +        temp |= (uint64_t)rt_t[i] << (8 * i);                            \
> +    }                                                                    \
> +                                                                         \
> +    return temp;                                                         \
> +}
> +
> +SHIFT_OB_ENV(shll, lshift8);
> +SHIFT_OB(shrl, rshift_u8);
> +
> +SHIFT_OB(shra, rashift8);
> +SHIFT_OB(shra_r, rnd8_rashift);
> +
> +#undef SHIFT_OB
> +#undef SHIFT_OB_ENV
> +
> +#endif
> +
> +#define SHIFT_PH(name, func) \
> +target_ulong helper_##name##_ph(target_ulong sa, target_ulong rt, \
> +                                CPUMIPSState *env)                \
> +{                                                                 \
> +    uint16_t rth, rtl;                                            \
> +                                                                  \
> +    sa = sa & 0x0F;                                               \
> +                                                                  \
> +    MIPSDSP_SPLIT32_16(rt, rth, rtl);                             \
> +                                                                  \
> +    rth = mipsdsp_##func(rth, sa, env);                           \
> +    rtl = mipsdsp_##func(rtl, sa, env);                           \
> +                                                                  \
> +    return MIPSDSP_RETURN32_16(rth, rtl);                         \
> +}
> +
> +SHIFT_PH(shll, lshift16);
> +SHIFT_PH(shll_s, sat16_lshift);
> +
> +#undef SHIFT_PH
> +
> +#if defined(TARGET_MIPS64)
> +#define SHIFT_QH(name, func) \
> +target_ulong helper_##name##_qh(target_ulong rt, target_ulong sa) \
> +{                                                                 \
> +    uint16_t rt3, rt2, rt1, rt0;                                  \
> +                                                                  \
> +    sa = sa & 0x0F;                                               \
> +                                                                  \
> +    MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);                   \
> +                                                                  \
> +    rt3 = mipsdsp_##func(rt3, sa);                                \
> +    rt2 = mipsdsp_##func(rt2, sa);                                \
> +    rt1 = mipsdsp_##func(rt1, sa);                                \
> +    rt0 = mipsdsp_##func(rt0, sa);                                \
> +                                                                  \
> +    return MIPSDSP_RETURN64_16(rt3, rt2, rt1, rt0);               \
> +}
> +
> +#define SHIFT_QH_ENV(name, func) \
> +target_ulong helper_##name##_qh(target_ulong rt, target_ulong sa, \
> +                                CPUMIPSState *env)                \
> +{                                                                 \
> +    uint16_t rt3, rt2, rt1, rt0;                                  \
> +                                                                  \
> +    sa = sa & 0x0F;                                               \
> +                                                                  \
> +    MIPSDSP_SPLIT64_16(rt, rt3, rt2, rt1, rt0);                   \
> +                                                                  \
> +    rt3 = mipsdsp_##func(rt3, sa, env);                           \
> +    rt2 = mipsdsp_##func(rt2, sa, env);                           \
> +    rt1 = mipsdsp_##func(rt1, sa, env);                           \
> +    rt0 = mipsdsp_##func(rt0, sa, env);                           \
> +                                                                  \
> +    return MIPSDSP_RETURN64_16(rt3, rt2, rt1, rt0);               \
> +}
> +
> +SHIFT_QH_ENV(shll, lshift16);
> +SHIFT_QH_ENV(shll_s, sat16_lshift);
> +
> +SHIFT_QH(shrl, rshift_u16);
> +SHIFT_QH(shra, rashift16);
> +SHIFT_QH(shra_r, rnd16_rashift);
> +
> +#undef SHIFT_QH
> +#undef SHIFT_QH_ENV
> +
> +#endif
> +
> +#define SHIFT_W(name, func) \
> +target_ulong helper_##name##_w(target_ulong sa, target_ulong rt) \
> +{                                                                       \
> +    uint32_t temp;                                                      \
> +                                                                        \
> +    sa = sa & 0x1F;                                                     \
> +    temp = mipsdsp_##func(rt, sa);                                      \
> +                                                                        \
> +    return (target_long)(int32_t)temp;                                  \
> +}
> +
> +#define SHIFT_W_ENV(name, func) \
> +target_ulong helper_##name##_w(target_ulong sa, target_ulong rt, \
> +                               CPUMIPSState *env) \
> +{                                                                       \
> +    uint32_t temp;                                                      \
> +                                                                        \
> +    sa = sa & 0x1F;                                                     \
> +    temp = mipsdsp_##func(rt, sa, env);                                 \
> +                                                                        \
> +    return (target_long)(int32_t)temp;                                  \
> +}
> +
> +SHIFT_W_ENV(shll_s, sat32_lshift);
> +SHIFT_W(shra_r, rnd32_rashift);
> +
> +#undef SHIFT_W
> +#undef SHIFT_W_ENV
> +
> +#if defined(TARGET_MIPS64)
> +#define SHIFT_PW(name, func) \
> +target_ulong helper_##name##_pw(target_ulong rt, target_ulong sa) \
> +{                                                                 \
> +    uint32_t rt1, rt0;                                            \
> +                                                                  \
> +    sa = sa & 0x1F;                                               \
> +    MIPSDSP_SPLIT64_32(rt, rt1, rt0);                             \
> +                                                                  \
> +    rt1 = mipsdsp_##func(rt1, sa);                                \
> +    rt0 = mipsdsp_##func(rt0, sa);                                \
> +                                                                  \
> +    return MIPSDSP_RETURN64_32(rt1, rt0);                         \
> +}
> +
> +#define SHIFT_PW_ENV(name, func) \
> +target_ulong helper_##name##_pw(target_ulong rt, target_ulong sa, \
> +                                CPUMIPSState *env)                \
> +{                                                                 \
> +    uint32_t rt1, rt0;                                            \
> +                                                                  \
> +    sa = sa & 0x1F;                                               \
> +    MIPSDSP_SPLIT64_32(rt, rt1, rt0);                             \
> +                                                                  \
> +    rt1 = mipsdsp_##func(rt1, sa, env);                           \
> +    rt0 = mipsdsp_##func(rt0, sa, env);                           \
> +                                                                  \
> +    return MIPSDSP_RETURN64_32(rt1, rt0);                         \
> +}
> +
> +SHIFT_PW_ENV(shll, lshift32);
> +SHIFT_PW_ENV(shll_s, sat32_lshift);
> +
> +SHIFT_PW(shra, rashift32);
> +SHIFT_PW(shra_r, rnd32_rashift);
> +
> +#undef SHIFT_PW
> +#undef SHIFT_PW_ENV
> +
> +#endif
> +
> +#define SHIFT_PH(name, func) \
> +target_ulong helper_##name##_ph(target_ulong sa, target_ulong rt) \
> +{                                                                    \
> +    uint16_t rth, rtl;                                               \
> +                                                                     \
> +    sa = sa & 0x0F;                                                  \
> +                                                                     \
> +    MIPSDSP_SPLIT32_16(rt, rth, rtl);                                \
> +                                                                     \
> +    rth = mipsdsp_##func(rth, sa);                                   \
> +    rtl = mipsdsp_##func(rtl, sa);                                   \
> +                                                                     \
> +    return MIPSDSP_RETURN32_16(rth, rtl);                            \
> +}
> +
> +SHIFT_PH(shrl, rshift_u16);
> +SHIFT_PH(shra, rashift16);
> +SHIFT_PH(shra_r, rnd16_rashift);
> +
> +#undef SHIFT_PH
> +
>  #undef MIPSDSP_LHI
>  #undef MIPSDSP_LLO
>  #undef MIPSDSP_HI
> diff --git a/target-mips/helper.h b/target-mips/helper.h
> index 9201aae..5258ef6 100644
> --- a/target-mips/helper.h
> +++ b/target-mips/helper.h
> @@ -488,4 +488,42 @@ 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, tl, tl, env)
> +#if defined(TARGET_MIPS64)
> +DEF_HELPER_FLAGS_3(shll_ob, 0, tl, tl, tl, env)
> +#endif
> +DEF_HELPER_FLAGS_3(shll_ph, 0, tl, tl, tl, env)
> +DEF_HELPER_FLAGS_3(shll_s_ph, 0, tl, tl, tl, env)
> +#if defined(TARGET_MIPS64)
> +DEF_HELPER_FLAGS_3(shll_qh, 0, tl, tl, tl, env)
> +DEF_HELPER_FLAGS_3(shll_s_qh, 0, tl, tl, tl, env)
> +#endif
> +DEF_HELPER_FLAGS_3(shll_s_w, 0, tl, tl, tl, env)
> +#if defined(TARGET_MIPS64)
> +DEF_HELPER_FLAGS_3(shll_pw, 0, tl, tl, tl, env)
> +DEF_HELPER_FLAGS_3(shll_s_pw, 0, tl, tl, tl, env)
> +#endif
> +DEF_HELPER_FLAGS_2(shrl_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
> +DEF_HELPER_FLAGS_2(shrl_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, tl)
> +DEF_HELPER_FLAGS_2(shrl_qh, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
> +#endif
> +DEF_HELPER_FLAGS_2(shra_qb, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl, tl)
> +DEF_HELPER_FLAGS_2(shra_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, tl)
> +DEF_HELPER_FLAGS_2(shra_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, tl, tl)
> +DEF_HELPER_FLAGS_2(shra_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, tl, tl)
> +#if defined(TARGET_MIPS64)
> +DEF_HELPER_FLAGS_2(shra_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, tl)
> +DEF_HELPER_FLAGS_2(shra_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, tl)
> +#endif
> +
>  #include "def-helper.h"
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index c4d4c47..bcfd4b4 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))
>  
> @@ -12888,6 +12959,253 @@ static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
>      MIPS_DEBUG("%s", opn);
>  }
>  
> +static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
> +                              int ret, int v1, int v2)
> +{
> +    uint32_t op2;
> +    const char *opn = "mipsdsp shift";
> +    TCGv t0;
> +    TCGv v1_t;
> +    TCGv v2_t;
> +
> +    if (ret == 0) {
> +        /* Treat as NOP. */
> +        MIPS_DEBUG("NOP");
> +        return;
> +    }
> +
> +    t0 = tcg_temp_new();
> +    v1_t = tcg_temp_new();
> +    v2_t = tcg_temp_new();
> +
> +    tcg_gen_movi_tl(t0, v1);
> +    gen_load_gpr(v1_t, v1);
> +    gen_load_gpr(v2_t, v2);

As previously said, this won't work. When v1 is an immediate value,
gen_load_gpr() might be called with a value <= 0 or > 31. gen_load_gpr()
is defined by:

| static inline void gen_load_gpr (TCGv t, int reg)
| {
|     if (reg == 0)
|         tcg_gen_movi_tl(t, 0);
|     else
|         tcg_gen_mov_tl(t, cpu_gpr[reg]);
| }

In that case, it means the cpu_gpr array will be accessed out of bound.
The best solution for that is to split gen_mipsdsp_shift in two
functions, one for register operations, and one for immediate
operations.

> +    switch (opc) {
> +    case OPC_SHLL_QB_DSP:
> +        {
> +            op2 = MASK_SHLL_QB(ctx->opcode);
> +            switch (op2) {
> +            case OPC_SHLL_QB:
> +                check_dsp(ctx);
> +                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLLV_QB:
> +                check_dsp(ctx);
> +                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLL_PH:
> +                check_dsp(ctx);
> +                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLLV_PH:
> +                check_dsp(ctx);
> +                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLL_S_PH:
> +                check_dsp(ctx);
> +                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLLV_S_PH:
> +                check_dsp(ctx);
> +                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLL_S_W:
> +                check_dsp(ctx);
> +                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
> +                break;
> +            case OPC_SHLLV_S_W:
> +                check_dsp(ctx);
> +                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
> +                break;
> +            case OPC_SHRL_QB:
> +                check_dsp(ctx);
> +                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRLV_QB:
> +                check_dsp(ctx);
> +                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            case OPC_SHRL_PH:
> +                check_dspr2(ctx);
> +                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRLV_PH:
> +                check_dspr2(ctx);
> +                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            case OPC_SHRA_QB:
> +                check_dspr2(ctx);
> +                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRA_R_QB:
> +                check_dspr2(ctx);
> +                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRAV_QB:
> +                check_dspr2(ctx);
> +                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            case OPC_SHRAV_R_QB:
> +                check_dspr2(ctx);
> +                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            case OPC_SHRA_PH:
> +                check_dsp(ctx);
> +                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRA_R_PH:
> +                check_dsp(ctx);
> +                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRAV_PH:
> +                check_dsp(ctx);
> +                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            case OPC_SHRAV_R_PH:
> +                check_dsp(ctx);
> +                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            case OPC_SHRA_R_W:
> +                check_dsp(ctx);
> +                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
> +                break;
> +            case OPC_SHRAV_R_W:
> +                check_dsp(ctx);
> +                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
> +                break;
> +            default:            /* Invalid */
> +                MIPS_INVAL("MASK SHLL.QB");
> +                generate_exception(ctx, EXCP_RI);
> +                break;
> +            }
> +            break;
> +        }
> +#ifdef TARGET_MIPS64
> +    case OPC_SHLL_OB_DSP:
> +        op2 = MASK_SHLL_OB(ctx->opcode);
> +        switch (op2) {
> +        case OPC_SHLL_PW:
> +            check_dsp(ctx);
> +            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
> +            break;
> +        case OPC_SHLLV_PW:
> +            check_dsp(ctx);
> +            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
> +            break;
> +        case OPC_SHLL_S_PW:
> +            check_dsp(ctx);
> +            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
> +            break;
> +        case OPC_SHLLV_S_PW:
> +            check_dsp(ctx);
> +            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
> +            break;
> +        case OPC_SHLL_OB:
> +            check_dsp(ctx);
> +            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
> +            break;
> +        case OPC_SHLLV_OB:
> +            check_dsp(ctx);
> +            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
> +            break;
> +        case OPC_SHLL_QH:
> +            check_dsp(ctx);
> +            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
> +            break;
> +        case OPC_SHLLV_QH:
> +            check_dsp(ctx);
> +            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
> +            break;
> +        case OPC_SHLL_S_QH:
> +            check_dsp(ctx);
> +            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
> +            break;
> +        case OPC_SHLLV_S_QH:
> +            check_dsp(ctx);
> +            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
> +            break;
> +        case OPC_SHRA_OB:
> +            check_dspr2(ctx);
> +            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRAV_OB:
> +            check_dspr2(ctx);
> +            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRA_R_OB:
> +            check_dspr2(ctx);
> +            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRAV_R_OB:
> +            check_dspr2(ctx);
> +            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRA_PW:
> +            check_dsp(ctx);
> +            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRAV_PW:
> +            check_dsp(ctx);
> +            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRA_R_PW:
> +            check_dsp(ctx);
> +            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRAV_R_PW:
> +            check_dsp(ctx);
> +            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRA_QH:
> +            check_dsp(ctx);
> +            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRAV_QH:
> +            check_dsp(ctx);
> +            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRA_R_QH:
> +            check_dsp(ctx);
> +            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRAV_R_QH:
> +            check_dsp(ctx);
> +            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRL_OB:
> +            check_dsp(ctx);
> +            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRLV_OB:
> +            check_dsp(ctx);
> +            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        case OPC_SHRL_QH:
> +            check_dspr2(ctx);
> +            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
> +            break;
> +        case OPC_SHRLV_QH:
> +            check_dspr2(ctx);
> +            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
> +            break;
> +        default:            /* Invalid */
> +            MIPS_INVAL("MASK SHLL.OB");
> +            generate_exception(ctx, EXCP_RI);
> +            break;
> +        }
> +        break;
> +#endif
> +    }
> +
> +    tcg_temp_free(t0);
> +    tcg_temp_free(v1_t);
> +    tcg_temp_free(v2_t);
> +    (void)opn; /* avoid a compiler warning */
> +    MIPS_DEBUG("%s", opn);
> +}
> +
>  /* End MIPSDSP functions. */
>  
>  static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
> @@ -13364,6 +13682,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
>                  break;
>              }
>              break;
> +        case OPC_SHLL_QB_DSP:
> +            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
> +            break;
>  #if defined(TARGET_MIPS64)
>          case OPC_DEXTM ... OPC_DEXT:
>          case OPC_DINSM ... OPC_DINS:
> @@ -13465,6 +13786,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
>                  break;
>              }
>              break;
> +        case OPC_SHLL_OB_DSP:
> +            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
> +            break;
>  #endif
>          default:            /* Invalid */
>              MIPS_INVAL("special3");
> -- 
> 1.7.10.2 (Apple Git-33)
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

  reply	other threads:[~2012-10-29 13:54 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-24 14:17 [Qemu-devel] [PATCH v12 00/14] QEMU MIPS ASE DSP support Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 01/14] target-mips: Add ASE DSP internal functions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 02/14] target-mips: Add ASE DSP resources access check Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 03/14] Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 04/14] target-mips: Add ASE DSP branch instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 05/14] target-mips: Add ASE DSP load instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 06/14] target-mips: Add ASE DSP arithmetic instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 07/14] target-mips: Add ASE DSP GPR-based shift instructions Jia Liu
2012-10-29 13:54   ` Aurelien Jarno [this message]
2012-10-30 15:05     ` Jia Liu
2012-10-31 13:26     ` Jia Liu
2012-10-31 20:29       ` Aurelien Jarno
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 08/14] target-mips: Add ASE DSP multiply instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 09/14] target-mips: Add ASE DSP bit/manipulation instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 10/14] target-mips: Add ASE DSP compare-pick instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 11/14] target-mips: Add ASE DSP accumulator instructions Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 12/14] target-mips: Add ASE DSP processors Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 13/14] target-mips: Add ASE DSP testcases Jia Liu
2012-10-24 14:17 ` [Qemu-devel] [PATCH v12 14/14] target-mips: Change TODO file Jia Liu
2012-10-31 21:46 ` [Qemu-devel] [PATCH v12 00/14] QEMU MIPS ASE DSP support Aurelien Jarno

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=20121029135430.GA29866@ohm.aurel32.net \
    --to=aurelien@aurel32.net \
    --cc=proljc@gmail.com \
    --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.