[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v12 07/14] target-mips: Add ASE DSP GPR-based sh
From: |
Aurelien Jarno |
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 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
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 <address@hidden>
> ---
> 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
address@hidden http://www.aurel32.net
- [Qemu-devel] [PATCH v12 00/14] QEMU MIPS ASE DSP su pport, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 01/14] target-mips: Add A SE DSP internal functions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 02/14] target-mips: Add ASE DSP resources access check, Jia Liu, 2012/10/24
- [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
- [Qemu-devel] [PATCH v12 04/14] target-mips: Add ASE DSP branch instructions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 05/14] target-mips: Add ASE DSP load instructions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 07/14] target-mips: Add ASE DSP GPR-based shift instructions, Jia Liu, 2012/10/24
- Re: [Qemu-devel] [PATCH v12 07/14] target-mips: Add ASE DSP GPR-based shift instructions,
Aurelien Jarno <=
- [Qemu-devel] [PATCH v12 06/14] target-mips: Add ASE DSP arithmetic instructions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 11/14] target-mips: Add ASE DSP accumulator instructions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 14/14] target-mips: Change TODO file, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 13/14] target-mips: Add ASE DSP testcases, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 10/14] target-mips: Add ASE DSP compare-pick instructions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 08/14] target-mips: Add ASE DSP multiply instructions, Jia Liu, 2012/10/24
- [Qemu-devel] [PATCH v12 12/14] target-mips: Add ASE DSP processors, Jia Liu, 2012/10/24