qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v2 14/33] target/mips: Add emulation of nanoMIPS


From: Aleksandar Markovic
Subject: Re: [Qemu-devel] [PATCH v2 14/33] target/mips: Add emulation of nanoMIPS 32-bit load and store instructions
Date: Tue, 10 Jul 2018 17:52:55 +0000

> Subject: [PATCH v2 14/33] target/mips: Add emulation of nanoMIPS 32-bit load 
> and store > instructions
>
> From: Yongbok Kim <address@hidden>
>
> Add emulation of various nanoMIPS load and store instructions.
>
> Signed-off-by: Yongbok Kim <address@hidden>
> Signed-off-by: Aleksandar Markovic <address@hidden>
> Signed-off-by: Stefan Markovic <address@hidden>
> ---
>  target/mips/translate.c | 271 
> ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 271 insertions(+)
>

Switch-case alignment in this parch doesn't look good. If this is fixed:

Reviewed-by: Aleksandar Markovic <address@hidden>

> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 3160a3f..d48a0cf 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -17527,10 +17527,281 @@ static int decode_nanomips_32_48_opc(CPUMIPSState 
> *env, > DisasContext *ctx)
>          }
>          break;
>      case NM_P_GP_BH:
> +    {
> +        uint32_t u = extract32(ctx->opcode, 0, 18);
> +        switch ((ctx->opcode >> 18) & 0x7) {
> +        case NM_LBGP:
> +            gen_ld(ctx, OPC_LB, rt, 28, u);
> +            break;
> +        case NM_SBGP:
> +            gen_st(ctx, OPC_SB, rt, 28, u);
> +            break;
> +        case NM_LBUGP:
> +            gen_ld(ctx, OPC_LBU, rt, 28, u);
> +            break;
> +        case NM_ADDIUGP_B:
> +            gen_arith_imm(ctx, OPC_ADDIU, rt, 28, u);
> +            break;
> +        case NM_P_GP_LH:
> +            u &= ~1;
> +            switch (ctx->opcode & 1) {
> +            case NM_LHGP:
> +                gen_ld(ctx, OPC_LH, rt, 28, u);
> +                break;
> +            case NM_LHUGP:
> +                gen_ld(ctx, OPC_LHU, rt, 28, u);
> +                break;
> +            }
> +            break;
> +        case NM_P_GP_SH:
> +            u &= ~1;
> +            switch (ctx->opcode & 1) {
> +            case NM_SHGP:
> +                gen_st(ctx, OPC_SH, rt, 28, u);
> +                break;
> +            default:
> +                generate_exception_end(ctx, EXCP_RI);
> +                break;
> +            }
> +            break;
> +        case NM_P_GP_CP1:
> +            u &= ~0x3;
> +            switch ((ctx->opcode & 0x3)) {
> +            case NM_LWC1GP:
> +                gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
> +                break;
> +            case NM_LDC1GP:
> +                gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
> +                break;
> +            case NM_SWC1GP:
> +                gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
> +                break;
> +            case NM_SDC1GP:
> +                gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
> +                break;
> +            }
> +            break;
> +        default:
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
> +        }
> +    }
>          break;
>      case NM_P_LS_U12:
> +    {
> +        uint32_t u = extract32(ctx->opcode, 0, 12);
> +        switch ((ctx->opcode >> 12) & 0x0f) {
> +        case NM_P_PREFU12:
> +            if (rt == 31) {
> +                /* SYNCI */
> +                /* Break the TB to be able to sync copied instructions
> +                   immediately */
> +                ctx->base.is_jmp = DISAS_STOP;
> +            } else {
> +                /* PREF */
> +                /* Treat as NOP. */
> +            }
> +            break;
> +        case NM_LB:
> +            gen_ld(ctx, OPC_LB, rt, rs, u);
> +            break;
> +        case NM_LH:
> +            gen_ld(ctx, OPC_LH, rt, rs, u);
> +            break;
> +        case NM_LW:
> +            gen_ld(ctx, OPC_LW, rt, rs, u);
> +            break;
> +        case NM_LBU:
> +            gen_ld(ctx, OPC_LBU, rt, rs, u);
> +            break;
> +        case NM_LHU:
> +            gen_ld(ctx, OPC_LHU, rt, rs, u);
> +            break;
> +        case NM_SB:
> +            gen_st(ctx, OPC_SB, rt, rs, u);
> +            break;
> +        case NM_SH:
> +            gen_st(ctx, OPC_SH, rt, rs, u);
> +            break;
> +        case NM_SW:
> +            gen_st(ctx, OPC_SW, rt, rs, u);
> +            break;
> +        case NM_LWC1:
> +            gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
> +            break;
> +        case NM_LDC1:
> +            gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
> +            break;
> +        case NM_SWC1:
> +            gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
> +            break;
> +        case NM_SDC1:
> +            gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
> +            break;
> +        default:
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
> +        }
> +    }
>          break;
>      case NM_P_LS_S9:
> +    {
> +        int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
> +                    extract32(ctx->opcode, 0, 8);
> +        switch ((ctx->opcode >> 8) & 0x07) {
> +        case NM_P_LS_S0:
> +            switch ((ctx->opcode >> 11) & 0x0f) {
> +            case NM_LBS9:
> +                gen_ld(ctx, OPC_LB, rt, rs, s);
> +                break;
> +            case NM_LHS9:
> +                gen_ld(ctx, OPC_LH, rt, rs, s);
> +                break;
> +            case NM_LWS9:
> +                gen_ld(ctx, OPC_LW, rt, rs, s);
> +                break;
> +            case NM_LBUS9:
> +                gen_ld(ctx, OPC_LBU, rt, rs, s);
> +                break;
> +            case NM_LHUS9:
> +                gen_ld(ctx, OPC_LHU, rt, rs, s);
> +                break;
> +            case NM_SBS9:
> +                gen_st(ctx, OPC_SB, rt, rs, s);
> +                break;
> +            case NM_SHS9:
> +                gen_st(ctx, OPC_SH, rt, rs, s);
> +                break;
> +            case NM_SWS9:
> +                gen_st(ctx, OPC_SW, rt, rs, s);
> +                break;
> +            case NM_LWC1S9:
> +                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
> +                break;
> +            case NM_LDC1S9:
> +                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
> +                break;
> +            case NM_SWC1S9:
> +                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
> +                break;
> +            case NM_SDC1S9:
> +                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
> +                break;
> +            case NM_P_PREFS9:
> +                if (rt == 31) {
> +                    /* SYNCI */
> +                    /* Break the TB to be able to sync copied instructions
> +                       immediately */
> +                    ctx->base.is_jmp = DISAS_STOP;
> +                } else {
> +                    /* PREF */
> +                    /* Treat as NOP. */
> +                }
> +                break;
> +            default:
> +                generate_exception_end(ctx, EXCP_RI);
> +                break;
> +            }
> +            break;
> +        case NM_P_LS_S1:
> +            switch ((ctx->opcode >> 11) & 0x0f) {
> +            case NM_UALH:
> +            case NM_UASH:
> +            {
> +                TCGv t0 = tcg_temp_new();
> +                TCGv t1 = tcg_temp_new();
> +
> +                gen_base_offset_addr(ctx, t0, rs, s);
> +
> +                switch ((ctx->opcode >> 11) & 0x0f) {
> +                case NM_UALH:
> +                    tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
> +                                       MO_UNALN);
> +                    gen_store_gpr(t0, rt);
> +                    break;
> +                case NM_UASH:
> +                    gen_load_gpr(t1, rt);
> +                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
> +                                       MO_UNALN);
> +                    break;
> +                }
> +                tcg_temp_free(t0);
> +                tcg_temp_free(t1);
> +            }
> +                break;
> +            case NM_P_LL:
> +                switch (ctx->opcode & 0x03) {
> +                case NM_LL:
> +                    gen_ld(ctx, OPC_LL, rt, rs, s);
> +                    break;
> +                case NM_LLWP:
> +                    break;
> +                }
> +                break;
> +            case NM_P_SC:
> +                switch (ctx->opcode & 0x03) {
> +                case NM_SC:
> +                    gen_st_cond(ctx, OPC_SC, rt, rs, s);
> +                    break;
> +                case NM_SCWP:
> +                    break;
> +                }
> +                break;
> +            case NM_CACHE:
> +                check_cp0_enabled(ctx);
> +                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
> +                    gen_cache_operation(ctx, rt, rs, s);
> +                }
> +                break;
> +            }
> +            break;
> +        case NM_P_LS_WM:
> +        case NM_P_LS_UAWM:
> +        {
> +            int32_t offset = sextract32(ctx->opcode, 15, 1) << 8 |
> +                            extract32(ctx->opcode, 0, 8);
> +            int count = extract32(ctx->opcode, 12, 3);
> +            int counter = 0;
> +            TCGv va = tcg_temp_new();
> +            TCGv t1 = tcg_temp_new();
> +            TCGMemOp memop = ((ctx->opcode >> 8) & 0x07) == NM_P_LS_UAWM ?
> +                            MO_UNALN : 0;
> +
> +            count = (count == 0) ? 8 : count;
> +            while (counter != count) {
> +                int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
> +                int32_t this_offset = offset + (counter << 2);
> +
> +                gen_base_offset_addr(ctx, va, rs, this_offset);
> +
> +                switch (extract32(ctx->opcode, 11, 1)) {
> +                case NM_LWM:
> +                    tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
> +                                       memop | MO_TESL);
> +                    gen_store_gpr(t1, this_rt);
> +                    if ((this_rt == rs) &&
> +                        (counter != (count - 1))) {
> +                        /* UNPREDICTABLE */
> +                    }
> +                    break;
> +                case NM_SWM:
> +                    this_rt = (rt == 0) ? 0 : this_rt;
> +                    gen_load_gpr(t1, this_rt);
> +                    tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
> +                                       memop | MO_TEUL);
> +                    break;
> +                }
> +                counter++;
> +            }
> +            tcg_temp_free(va);
> +            tcg_temp_free(t1);
> +        }
> +            break;
> +        default:
> +            generate_exception_end(ctx, EXCP_RI);
> +            break;
> +        }
> +    }
>          break;
>      case NM_MOVE_BALC:
>          break;
> --
> 2.7.4
>
>


reply via email to

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