qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH V9 3/6] target/mips: Add loongson-ext lswc2 group of instruct


From: Philippe Mathieu-Daudé
Subject: Re: [PATCH V9 3/6] target/mips: Add loongson-ext lswc2 group of instructions (Part 1)
Date: Wed, 16 Sep 2020 09:46:37 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0

On 9/16/20 4:12 AM, Huacai Chen wrote:
> From: Jiaxun Yang <jiaxun.yang@flygoat.com>
> 
> LWC2 & SWC2 have been rewritten by Loongson EXT vendor ASE
> as "load/store quad word" and "shifted load/store" groups of
> instructions.
> 
> This patch add implementation of these instructions:
> gslq: load 16 bytes to GPR
> gssq: store 16 bytes from GPR
> gslqc1: load 16 bytes to FPR
> gssqc1: store 16 bytes from FPR
> 
> Details of Loongson-EXT is here:
> https://github.com/FlyGoat/loongson-insn/blob/master/loongson-ext.md
> 
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>  target/mips/translate.c | 81 
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 81 insertions(+)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 398edf7..08d51e1 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -460,6 +460,17 @@ enum {
>      R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
>  };
>  
> +/* Loongson EXT load/store quad word opcodes */
> +#define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
> +enum {
> +    OPC_GSLQ        = 0x0020 | OPC_LWC2,
> +    OPC_GSLQC1      = 0x8020 | OPC_LWC2,
> +    OPC_GSSHFL      = OPC_LWC2,
> +    OPC_GSSQ        = 0x0020 | OPC_SWC2,
> +    OPC_GSSQC1      = 0x8020 | OPC_SWC2,
> +    OPC_GSSHFS      = OPC_SWC2,
> +};
> +
>  /* BSHFL opcodes */
>  #define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
>  
> @@ -5910,6 +5921,74 @@ no_rd:
>      tcg_temp_free_i64(t1);
>  }
>  
> +static void gen_loongson_lswc2(DisasContext *ctx, int rt,
> +                                int rs, int rd)
> +{
> +    TCGv t0, t1, t2;
> +    TCGv_i32 fp0;
> +    int lsq_offset = ((int)((ctx->opcode >> 6) & 0x1ff) << 23) >> 19;
> +    int lsq_rt1 = ctx->opcode & 0x1f;
> +    int shf_offset = (int8_t)(ctx->opcode >> 6);
> +
> +    t0 = tcg_temp_new();
> +
> +    switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
> +#if defined(TARGET_MIPS64)

Build failure (is this code tested?):

target/mips/translate.c: In function ‘gen_loongson_lswc2’:
target/mips/translate.c:5961:9: error: unused variable ‘lsq_rt1’
[-Werror=unused-variable]
     int lsq_rt1 = ctx->opcode & 0x1f;
         ^
target/mips/translate.c:5960:9: error: unused variable ‘lsq_offset’
[-Werror=unused-variable]
     int lsq_offset = ((int)((ctx->opcode >> 6) & 0x1ff) << 23) >> 19;
         ^
cc1: all warnings being treated as errors

> +    case OPC_GSLQ:
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
> +        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        gen_store_gpr(t0, rt);
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
> +        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        gen_store_gpr(t0, lsq_rt1);
> +        break;
> +    case OPC_GSLQC1:
> +        check_cp1_enabled(ctx);
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
> +        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        gen_store_fpr64(ctx, t0, rt);
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
> +        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        gen_store_fpr64(ctx, t0, lsq_rt1);
> +        break;
> +    case OPC_GSSQ:
> +        t1 = tcg_temp_new();
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
> +        gen_load_gpr(t1, rt);
> +        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
> +        gen_load_gpr(t1, lsq_rt1);
> +        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        tcg_temp_free(t1);
> +        break;
> +    case OPC_GSSQC1:
> +        check_cp1_enabled(ctx);
> +        t1 = tcg_temp_new();
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
> +        gen_load_fpr64(ctx, t1, rt);
> +        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
> +        gen_load_fpr64(ctx, t1, lsq_rt1);
> +        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
> +                            ctx->default_tcg_memop_mask);
> +        tcg_temp_free(t1);
> +        break;
> +#endif
> +    default:
> +        MIPS_INVAL("loongson_gslsq");
> +        generate_exception_end(ctx, EXCP_RI);
> +        break;
> +    }
> +    tcg_temp_free(t0);
> +}
> +
>  /* Traps */
>  static void gen_trap(DisasContext *ctx, uint32_t opc,
>                       int rs, int rt, int16_t imm)
> @@ -30774,6 +30853,8 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>              /* OPC_BC, OPC_BALC */
>              gen_compute_compact_branch(ctx, op, 0, 0,
>                                         sextract32(ctx->opcode << 2, 0, 28));
> +        } else if (ctx->insn_flags & ASE_LEXT) {
> +            gen_loongson_lswc2(ctx, rt, rs, rd);
>          } else {
>              /* OPC_LWC2, OPC_SWC2 */
>              /* COP2: Not implemented. */
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]