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 v11 09/14] target-mips: Add ASE DSP bit/manipulation instructions
Date: Wed, 17 Oct 2012 01:23:24 +0200	[thread overview]
Message-ID: <20121016232324.GA20326@ohm.aurel32.net> (raw)
In-Reply-To: <1350319158-7263-10-git-send-email-proljc@gmail.com>

On Tue, Oct 16, 2012 at 12:39:13AM +0800, Jia Liu wrote:
> Add MIPS ASE DSP Bit/Manipulation instructions.
> 
> Signed-off-by: Jia Liu <proljc@gmail.com>
> ---
>  target-mips/dsp_helper.c |   55 +++++++++++
>  target-mips/helper.h     |    7 ++
>  target-mips/translate.c  |  231 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 293 insertions(+)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 1778470..79612ee 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -3148,6 +3148,61 @@ DM_OPERATE(dmsubu, mul_u32_u32, 0, 0);
>  #undef DM_OPERATE
>  #endif
>  
> +/** DSP Bit/Manipulation Sub-class insns **/
> +target_ulong helper_bitrev(target_ulong rt)
> +{
> +    int32_t temp;
> +    uint32_t rd;
> +    int i;
> +
> +    temp = rt & MIPSDSP_LO;
> +    rd = 0;
> +    for (i = 0; i < 16; i++) {
> +        rd = (rd << 1) | (temp & 1);
> +        temp = temp >> 1;
> +    }
> +
> +    return (target_ulong)rd;
> +}
> +
> +#define BIT_INSV(name, posfilter, sizefilter, ret_type)         \
> +target_ulong helper_##name(CPUMIPSState *env, target_ulong rs,  \
> +                           target_ulong rt)                     \
> +{                                                               \
> +    uint32_t pos, size, msb, lsb;                               \
> +    target_ulong filter;                                        \
> +    target_ulong temp, temprs, temprt;                          \
> +    target_ulong dspc;                                          \
> +                                                                \
> +    dspc = env->active_tc.DSPControl;                           \
> +                                                                \
> +    pos  = dspc & posfilter;                                    \
> +    size = (dspc >> 7) & sizefilter;                            \
> +                                                                \
> +    msb  = pos + size - 1;                                      \
> +    lsb  = pos;                                                 \
> +                                                                \
> +    if (lsb > msb || (msb > TARGET_LONG_BITS)) {                \
> +        return rt;                                              \
> +    }                                                           \
> +                                                                \
> +    filter = ((int32_t)0x01 << size) - 1;                       \
> +    filter = filter << pos;                                     \
> +    temprs = rs & filter;                                       \
> +    temprt = rt & ~filter;                                      \
> +    temp = temprs | temprt;                                     \
> +                                                                \
> +    return (target_long)(ret_type)temp;                         \
> +}
> +
> +BIT_INSV(insv, 0x1F, 0x1F, int32_t);
> +#ifdef TARGET_MIPS64
> +BIT_INSV(dinsv, 0x7F, 0x3F, target_long);
> +#endif
> +
> +#undef BIT_INSV
> +
> +
>  #undef MIPSDSP_LHI
>  #undef MIPSDSP_LLO
>  #undef MIPSDSP_HI
> diff --git a/target-mips/helper.h b/target-mips/helper.h
> index 6a6ca99..31475a2 100644
> --- a/target-mips/helper.h
> +++ b/target-mips/helper.h
> @@ -617,4 +617,11 @@ DEF_HELPER_FLAGS_4(dmsub, 0, void, tl, tl, i32, env)
>  DEF_HELPER_FLAGS_4(dmsubu, 0, void, tl, tl, i32, env)
>  #endif
>  
> +/* DSP Bit/Manipulation Sub-class insns */
> +DEF_HELPER_FLAGS_1(bitrev, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
> +DEF_HELPER_FLAGS_3(insv, 0, tl, env, tl, tl)
> +#if defined(TARGET_MIPS64)
> +DEF_HELPER_FLAGS_3(dinsv, 0, tl, env, tl, tl);
> +#endif
> +
>  #include "def-helper.h"
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index f084ab1..f8c7f19 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -343,6 +343,11 @@ enum {
>  #if defined(TARGET_MIPS64)
>      OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
>  #endif
> +    /* DSP Bit/Manipulation Sub-class */
> +    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
> +#if defined(TARGET_MIPS64)
> +    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
> +#endif
>  };
>  
>  /* BSHFL opcodes */
> @@ -450,6 +455,12 @@ enum {
>      OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
>      OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
>      OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
> +    /* DSP Bit/Manipulation Sub-class */
> +    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
> +    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
> +    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
> +    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
> +    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
>  };
>  
>  #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
> @@ -518,6 +529,12 @@ enum {
>      OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
>  };
>  
> +#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
> +enum {
> +    /* DSP Bit/Manipulation Sub-class */
> +    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
> +};
> +
>  #if defined(TARGET_MIPS64)
>  #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
>  enum {
> @@ -539,6 +556,13 @@ enum {
>      OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
>      OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
>      OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
> +    /* DSP Bit/Manipulation Sub-class */
> +    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
> +    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
> +    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
> +    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
> +    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
> +    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
>  };
>  #endif
>  
> @@ -592,6 +616,14 @@ enum {
>  #endif
>  
>  #if defined(TARGET_MIPS64)
> +#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
> +enum {
> +    /* DSP Bit/Manipulation Sub-class */
> +    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
> +};
> +#endif
> +
> +#if defined(TARGET_MIPS64)
>  #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
>  enum {
>      /* MIPS DSP Multiply Sub-class insns */
> @@ -13719,6 +13751,152 @@ static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
>  
>  }
>  
> +static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
> +                                uint32_t op1, uint32_t op2,
> +                                int ret, int val)
> +{
> +    const char *opn = "mipsdsp Bit/ Manipulation";
> +    TCGv t0 = tcg_temp_new();
> +    TCGv val_t = tcg_temp_new();
> +    int16_t imm;
> +
> +    if (ret == 0) {
> +        /* Treat as NOP. */
> +        MIPS_DEBUG("NOP");
> +        return;
> +    }
> +
> +    if (val == 0) {
> +        tcg_gen_movi_tl(val_t, 0);
> +    } else {
> +        gen_load_gpr(val_t, val);
> +    }
> +

Same comments as for the previous patches.

> +    switch (op1) {
> +    case OPC_ABSQ_S_PH_DSP:
> +        switch (op2) {
> +        case OPC_BITREV:
> +            check_dsp(ctx);
> +            gen_helper_bitrev(cpu_gpr[ret], val_t);
> +            break;
> +        case OPC_REPL_QB:
> +            check_dsp(ctx);
> +            {
> +                target_long result;
> +                imm = (ctx->opcode >> 16) & 0xFF;
> +                result = (uint32_t)imm << 24 | \
> +                         (uint32_t)imm << 16 | \
> +                         (uint32_t)imm << 8  | \

It's C, you don't need \ at the end of the line.

> +                         (uint32_t)imm;
> +                result = (int32_t)result;
> +                tcg_gen_movi_tl(cpu_gpr[ret], result);
> +            }
> +            break;
> +        case OPC_REPLV_QB:
> +            check_dsp(ctx);
> +            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
> +            break;
> +        case OPC_REPL_PH:
> +            check_dsp(ctx);
> +            {
> +                imm = (ctx->opcode >> 16) & 0x03FF;
> +                tcg_gen_movi_tl(cpu_gpr[ret], \
> +                                (target_long)((int32_t)imm << 16 | \
> +                                (uint32_t)(uint16_t)imm));
> +            }
> +            break;
> +        case OPC_REPLV_PH:
> +            check_dsp(ctx);
> +            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
> +            break;
> +        }
> +        break;
> +#ifdef TARGET_MIPS64
> +    case OPC_ABSQ_S_QH_DSP:
> +        switch (op2) {
> +        case OPC_REPL_OB:
> +            check_dsp(ctx);
> +            {
> +                target_long temp;
> +
> +                imm = (ctx->opcode >> 16) & 0xFF;
> +                temp = imm;
> +                temp = (temp << 8) | temp;
> +                temp = (temp << 16) | temp;
> +                temp = (temp << 32) | temp;
> +                tcg_gen_movi_tl(cpu_gpr[ret], temp);
> +                break;
> +            }

This hasn't been fixed, and thus is still wrong.

> +        case OPC_REPL_PW:
> +            check_dsp(ctx);
> +            {
> +                target_long temp;
> +
> +                imm = (ctx->opcode >> 16) & 0x03FF;
> +                imm = (int16_t)(imm << 6) >> 6;
> +                temp = ((target_long)imm << 32) \
> +                       | ((target_long)imm & 0xFFFFFFFF);
> +                tcg_gen_movi_tl(cpu_gpr[ret], temp);
> +                break;
> +            }
> +        case OPC_REPL_QH:
> +            check_dsp(ctx);
> +            {
> +                target_long temp;
> +
> +                imm = (ctx->opcode >> 16) & 0x03FF;
> +                imm = (int16_t)(imm << 6) >> 6;
> +
> +                temp = ((uint64_t)(uint16_t)imm << 48) | \
> +                       ((uint64_t)(uint16_t)imm << 32) | \
> +                       ((uint64_t)(uint16_t)imm << 16) | \

Same here.

> +                       (uint64_t)(uint16_t)imm;
> +                tcg_gen_movi_tl(cpu_gpr[ret], temp);
> +                break;
> +            }
> +        case OPC_REPLV_OB:
> +            check_dsp(ctx);
> +            tcg_gen_ext8u_tl(cpu_gpr[ret], cpu_gpr[ret]);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            break;
> +        case OPC_REPLV_PW:
> +            check_dsp(ctx);
> +            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
> +            tcg_gen_and_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            break;
> +        case OPC_REPLV_QH:
> +            check_dsp(ctx);
> +            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
> +            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
> +            break;
> +        }
> +        break;
> +#endif
> +    }
> +    tcg_temp_free(t0);
> +    tcg_temp_free(val_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)
> @@ -14145,6 +14323,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
>              case OPC_PRECEU_PH_QBRA:
>                  gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
>                  break;
> +            case OPC_BITREV:
> +            case OPC_REPL_QB:
> +            case OPC_REPLV_QB:
> +            case OPC_REPL_PH:
> +            case OPC_REPLV_PH:
> +                gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
> +                break;
>              default:
>                  MIPS_INVAL("MASK ABSQ_S.PH");
>                  generate_exception(ctx, EXCP_RI);
> @@ -14245,6 +14430,26 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
>                  break;
>              }
>              break;
> +        case OPC_INSV_DSP:
> +            op2 = MASK_INSV(ctx->opcode);
> +            switch (op2) {
> +            case OPC_INSV:
> +                check_dsp(ctx);
> +                {
> +                    if (rt == 0) {
> +                        MIPS_DEBUG("NOP");
> +                        break;
> +                    }
> +                    gen_helper_insv(cpu_gpr[rt], cpu_env,
> +                                    cpu_gpr[rs], cpu_gpr[rt]);
> +                    break;

This won't work if rs or rt are 0.

> +                }
> +            default:            /* Invalid */
> +                MIPS_INVAL("MASK INSV");
> +                generate_exception(ctx, EXCP_RI);
> +                break;
> +            }
> +            break;
>  #if defined(TARGET_MIPS64)
>          case OPC_DEXTM ... OPC_DEXT:
>          case OPC_DINSM ... OPC_DINS:
> @@ -14286,6 +14491,14 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
>              case OPC_ABSQ_S_QH:
>                  gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
>                  break;
> +            case OPC_REPL_OB:
> +            case OPC_REPL_PW:
> +            case OPC_REPL_QH:
> +            case OPC_REPLV_OB:
> +            case OPC_REPLV_PW:
> +            case OPC_REPLV_QH:
> +                gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
> +                break;
>              default:            /* Invalid */
>                  MIPS_INVAL("MASK ABSQ_S.QH");
>                  generate_exception(ctx, EXCP_RI);
> @@ -14392,6 +14605,24 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
>                  break;
>              }
>              break;
> +        case OPC_DINSV_DSP:
> +            op2 = MASK_INSV(ctx->opcode);
> +            switch (op2) {
> +            case OPC_DINSV:
> +                check_dsp(ctx);
> +                if (rt == 0) {
> +                    MIPS_DEBUG("NOP");
> +                    break;
> +                }
> +                gen_helper_dinsv(cpu_gpr[rt], cpu_env,
> +                                 cpu_gpr[rs], cpu_gpr[rt]);

This won't work if rs or rt are 0.

> +                break;
> +            default:            /* Invalid */
> +                MIPS_INVAL("MASK DINSV");
> +                generate_exception(ctx, EXCP_RI);
> +                break;
> +            }
> +            break;
>          case OPC_SHLL_OB_DSP:
>              gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
>              break;
> -- 
> 1.7.10.2 (Apple Git-33)
> 
> 

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

  reply	other threads:[~2012-10-16 23:23 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-15 16:39 [Qemu-devel] [PATCH v11 00/14] QEMU MIPS ASE DSP support Jia Liu
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 01/14] target-mips: Add ASE DSP internal functions Jia Liu
2012-10-16 23:20   ` Aurelien Jarno
2012-10-17  3:39     ` Jia Liu
2012-10-17 15:15       ` Aurelien Jarno
2012-10-18  1:53         ` Jia Liu
2012-10-18  6:05           ` Aurelien Jarno
2012-10-18 11:18             ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 02/14] target-mips: Add ASE DSP resources access check Jia Liu
2012-10-16 23:21   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 03/14] target-mips: Use correct acc value to index cpu_HI/cpu_LO rather than using a fix number Jia Liu
2012-10-16 23:21   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 04/14] target-mips: Add ASE DSP branch instructions Jia Liu
2012-10-16 23:21   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 05/14] target-mips: Add ASE DSP load instructions Jia Liu
2012-10-16 23:21   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 06/14] target-mips: Add ASE DSP arithmetic instructions Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-17  4:05     ` Jia Liu
2012-10-17  4:54       ` Jia Liu
2012-10-17  6:05         ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 07/14] target-mips: Add ASE DSP GPR based shift instructions Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-30 14:47     ` Jia Liu
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 08/14] target-mips: Add ASE DSP multiply instructions Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 09/14] target-mips: Add ASE DSP bit/manipulation instructions Jia Liu
2012-10-16 23:23   ` Aurelien Jarno [this message]
2012-10-17  3:44     ` Jia Liu
2012-10-17  6:05       ` Aurelien Jarno
2012-10-17  7:16         ` Richard Henderson
2012-10-17 20:07           ` Aurelien Jarno
2012-10-18  0:09             ` Jia Liu
2012-10-17  7:41         ` Jia Liu
2012-10-17 15:15           ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 10/14] target-mips: Add ASE DSP compare-pick instructions Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 11/14] target-mips: Add ASE DSP accumulator instructions Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 12/14] target-mips: Add ASE DSP processors Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 13/14] target-mips: Add ASE DSP testcases Jia Liu
2012-10-16 23:23   ` Aurelien Jarno
2012-10-15 16:39 ` [Qemu-devel] [PATCH v11 14/14] target-mips: Change TODO file Jia Liu
2012-10-16 23:23   ` 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=20121016232324.GA20326@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.