qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH v3 06/15] target-mips: raise RI exceptions when FIR.PS = 0
Date: Wed, 24 Jun 2015 14:28:50 +0200
User-agent: Mutt/1.5.23 (2014-03-12)

On 2015-06-23 16:38, Yongbok Kim wrote:
> 64-bit paired-single (PS) floating point data type is optional in the
> pre-Release 6.
> It has to raise RI exception when PS type is not implemented. (FIR.PS = 0)
> (The PS data type is removed in the Release 6.)
> 
> Signed-off-by: Yongbok Kim <address@hidden>
> Reviewed-by: Leon Alrae <address@hidden>
> ---
>  target-mips/translate.c |   77 
> +++++++++++++++++++++++++++--------------------
>  1 files changed, 44 insertions(+), 33 deletions(-)
> 
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index dc9aae6..1688bd5 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -1429,6 +1429,7 @@ typedef struct DisasContext {
>      uint64_t PAMask;
>      bool mvh;
>      int CP0_LLAddr_shift;
> +    bool ps;
>  } DisasContext;
>  
>  enum {
> @@ -1825,6 +1826,16 @@ static inline void check_insn_opc_removed(DisasContext 
> *ctx, int flags)
>      }
>  }
>  
> +/* This code generates a "reserved instruction" exception if the
> +   CPU does not support 64-bit paired-single (PS) floating point data type */
> +static inline void check_ps(DisasContext *ctx)
> +{
> +    if (unlikely(!ctx->ps)) {
> +        generate_exception(ctx, EXCP_RI);
> +    }
> +    check_cp1_64bitmode(ctx);
> +}
> +
>  #ifdef TARGET_MIPS64
>  /* This code generates a "reserved instruction" exception if 64-bit
>     instructions are not enabled. */
> @@ -1858,7 +1869,7 @@ static inline void gen_cmp ## type ## _ ## 
> fmt(DisasContext *ctx, int n,      \
>      TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                              
>  \
>      switch (ifmt) {                                                          
>  \
>      case FMT_PS:                                                             
>  \
> -        check_cp1_64bitmode(ctx);                                            
>  \
> +        check_ps(ctx);                                                       
>  \
>          break;                                                               
>  \
>      case FMT_D:                                                              
>  \
>          if (abs) {                                                           
>  \
> @@ -8998,7 +9009,6 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
> op1,
>      };
>      enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
>      uint32_t func = ctx->opcode & 0x3f;
> -
>      switch (op1) {
>      case OPC_ADD_S:
>          {
> @@ -9491,8 +9501,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode 
> op1,
>          opn = "cvt.l.s";
>          break;
>      case OPC_CVT_PS_S:
> -        check_insn_opc_removed(ctx, ISA_MIPS32R6);
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp64 = tcg_temp_new_i64();
>              TCGv_i32 fp32_0 = tcg_temp_new_i32();
> @@ -10109,8 +10118,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "cvt.d.l";
>          break;
>      case OPC_CVT_PS_PW:
> -        check_insn_opc_removed(ctx, ISA_MIPS32R6);
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10122,7 +10130,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "cvt.ps.pw";
>          break;
>      case OPC_ADD_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10137,7 +10145,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "add.ps";
>          break;
>      case OPC_SUB_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10152,7 +10160,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "sub.ps";
>          break;
>      case OPC_MUL_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10167,7 +10175,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "mul.ps";
>          break;
>      case OPC_ABS_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10179,7 +10187,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "abs.ps";
>          break;
>      case OPC_MOV_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10190,7 +10198,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "mov.ps";
>          break;
>      case OPC_NEG_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10202,12 +10210,12 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "neg.ps";
>          break;
>      case OPC_MOVCF_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
>          opn = "movcf.ps";
>          break;
>      case OPC_MOVZ_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGLabel *l1 = gen_new_label();
>              TCGv_i64 fp0;
> @@ -10223,7 +10231,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "movz.ps";
>          break;
>      case OPC_MOVN_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGLabel *l1 = gen_new_label();
>              TCGv_i64 fp0;
> @@ -10240,7 +10248,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "movn.ps";
>          break;
>      case OPC_ADDR_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10255,7 +10263,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "addr.ps";
>          break;
>      case OPC_MULR_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10270,7 +10278,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "mulr.ps";
>          break;
>      case OPC_RECIP2_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10285,7 +10293,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "recip2.ps";
>          break;
>      case OPC_RECIP1_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10297,7 +10305,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "recip1.ps";
>          break;
>      case OPC_RSQRT1_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10309,7 +10317,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "rsqrt1.ps";
>          break;
>      case OPC_RSQRT2_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10336,7 +10344,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "cvt.s.pu";
>          break;
>      case OPC_CVT_PW_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>  
> @@ -10360,7 +10368,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "cvt.s.pl";
>          break;
>      case OPC_PLL_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10375,7 +10383,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "pll.ps";
>          break;
>      case OPC_PLU_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10390,7 +10398,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "plu.ps";
>          break;
>      case OPC_PUL_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10405,7 +10413,7 @@ static void gen_farith (DisasContext *ctx, enum 
> fopcode op1,
>          opn = "pul.ps";
>          break;
>      case OPC_PUU_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i32 fp0 = tcg_temp_new_i32();
>              TCGv_i32 fp1 = tcg_temp_new_i32();
> @@ -10564,7 +10572,7 @@ static void gen_flt3_arith (DisasContext *ctx, 
> uint32_t opc,
>  
>      switch (opc) {
>      case OPC_ALNV_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv t0 = tcg_temp_local_new();
>              TCGv_i32 fp = tcg_temp_new_i32();
> @@ -10639,7 +10647,7 @@ static void gen_flt3_arith (DisasContext *ctx, 
> uint32_t opc,
>          opn = "madd.d";
>          break;
>      case OPC_MADD_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10694,7 +10702,7 @@ static void gen_flt3_arith (DisasContext *ctx, 
> uint32_t opc,
>          opn = "msub.d";
>          break;
>      case OPC_MSUB_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10749,7 +10757,7 @@ static void gen_flt3_arith (DisasContext *ctx, 
> uint32_t opc,
>          opn = "nmadd.d";
>          break;
>      case OPC_NMADD_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -10804,7 +10812,7 @@ static void gen_flt3_arith (DisasContext *ctx, 
> uint32_t opc,
>          opn = "nmsub.d";
>          break;
>      case OPC_NMSUB_PS:
> -        check_cp1_64bitmode(ctx);
> +        check_ps(ctx);
>          {
>              TCGv_i64 fp0 = tcg_temp_new_i64();
>              TCGv_i64 fp1 = tcg_temp_new_i64();
> @@ -14108,6 +14116,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                          gen_movcf_d(ctx, rs, rt, cc, 0);
>                          break;
>                      case FMT_SDPS_PS:
> +                        check_ps(ctx);
>                          gen_movcf_ps(ctx, rs, rt, cc, 0);
>                          break;
>                      default:
> @@ -14123,6 +14132,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                          gen_movcf_d(ctx, rs, rt, cc, 1);
>                          break;
>                      case FMT_SDPS_PS:
> +                        check_ps(ctx);
>                          gen_movcf_ps(ctx, rs, rt, cc, 1);
>                          break;
>                      default:
> @@ -14144,6 +14154,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                      mips32_op = OPC_##prfx##_D;         \
>                      goto do_fpop;                       \
>                  case FMT_SDPS_PS:                       \
> +                    check_ps(ctx);                      \
>                      mips32_op = OPC_##prfx##_PS;        \
>                      goto do_fpop;                       \
>                  default:                                \
> @@ -19149,8 +19160,7 @@ static void decode_opc(CPUMIPSState *env, 
> DisasContext *ctx)
>                                  (rt >> 2) & 0x7, imm << 2);
>              break;
>          case OPC_PS_FMT:
> -            check_cp1_enabled(ctx);
> -            check_insn_opc_removed(ctx, ISA_MIPS32R6);
> +            check_ps(ctx);
>              /* fall through */
>          case OPC_S_FMT:
>          case OPC_D_FMT:
> @@ -19459,6 +19469,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
> TranslationBlock *tb,
>      /* Restore delay slot state from the tb context.  */
>      ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
>      ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
> +    ctx.ps = (env->active_fpu.fcr0 >> FCR0_PS) & 1;
>      restore_cpu_state(env, &ctx);
>  #ifdef CONFIG_USER_ONLY
>          ctx.mem_idx = MIPS_HFLAG_UM;

This change means that the PS instructions are now enabled only when
FCR0_PS is set, instead of being enabled when the FPU in 64-bit mode.
Have you checked if we need to update a few CPU definitions for it to
work? I am thinking for example about all the CPU with FCR0_F64, but
without FCR0_PS.

Otherwise the patch looks fine to me.

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
address@hidden                 http://www.aurel32.net



reply via email to

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