qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v3 22/31] target-arm: A64: Implement MSR (immedi


From: Peter Crosthwaite
Subject: Re: [Qemu-devel] [PATCH v3 22/31] target-arm: A64: Implement MSR (immediate) instructions
Date: Tue, 25 Feb 2014 18:32:25 +1000

On Sun, Feb 16, 2014 at 2:07 AM, Peter Maydell <address@hidden> wrote:
> Implement the MSR (immediate) instructions, which can update the
> PSTATE SP and DAIF fields.
>
> Signed-off-by: Peter Maydell <address@hidden>

Reviewed-by: Peter Crosthwaite <address@hidden>

> ---
>  target-arm/helper.h        |  2 ++
>  target-arm/op_helper.c     | 25 +++++++++++++++++++++++++
>  target-arm/translate-a64.c | 25 ++++++++++++++++++++++++-
>  3 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/target-arm/helper.h b/target-arm/helper.h
> index 19bd620..4a063c1 100644
> --- a/target-arm/helper.h
> +++ b/target-arm/helper.h
> @@ -63,6 +63,8 @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
>  DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
>  DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
>
> +DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
> +
>  DEF_HELPER_2(get_r13_banked, i32, env, i32)
>  DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
>
> diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
> index eb0fccd..7d06d2f 100644
> --- a/target-arm/op_helper.c
> +++ b/target-arm/op_helper.c
> @@ -319,6 +319,31 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void 
> *rip)
>      return ri->readfn(env, ri);
>  }
>
> +void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
> +{
> +    /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
> +     * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
> +     * to catch that case at translate time.
> +     */
> +    if (arm_current_pl(env) == 0 && !(env->cp15.c1_sys & SCTLR_UMA)) {
> +        raise_exception(env, EXCP_UDEF);
> +    }
> +
> +    switch (op) {
> +    case 0x05: /* SPSel */
> +        env->pstate = deposit32(env->pstate, 0, 1, imm);
> +        break;
> +    case 0x1e: /* DAIFSet */
> +        env->daif |= (imm << 6) & PSTATE_DAIF;
> +        break;
> +    case 0x1f: /* DAIFClear */
> +        env->daif &= ~((imm << 6) & PSTATE_DAIF);
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +}
> +
>  /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
>     The only way to do that in TCG is a conditional branch, which clobbers
>     all our temporaries.  For now implement these as helper functions.  */
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 948470f..1054e38 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1113,7 +1113,30 @@ static void handle_sync(DisasContext *s, uint32_t insn,
>  static void handle_msr_i(DisasContext *s, uint32_t insn,
>                           unsigned int op1, unsigned int op2, unsigned int 
> crm)
>  {
> -    unsupported_encoding(s, insn);
> +    int op = op1 << 3 | op2;
> +    switch (op) {
> +    case 0x05: /* SPSel */
> +        if (s->current_pl == 0) {
> +            unallocated_encoding(s);
> +            return;
> +        }
> +        /* fall through */
> +    case 0x1e: /* DAIFSet */
> +    case 0x1f: /* DAIFClear */
> +    {
> +        TCGv_i32 tcg_imm = tcg_const_i32(crm);
> +        TCGv_i32 tcg_op = tcg_const_i32(op);
> +        gen_a64_set_pc_im(s->pc - 4);
> +        gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
> +        tcg_temp_free_i32(tcg_imm);
> +        tcg_temp_free_i32(tcg_op);
> +        s->is_jmp = DISAS_UPDATE;
> +        break;
> +    }
> +    default:
> +        unallocated_encoding(s);
> +        return;
> +    }
>  }
>
>  static void gen_get_nzcv(TCGv_i64 tcg_rt)
> --
> 1.8.5
>
>



reply via email to

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