qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [QEMU-PPC] [PATCH] target/ppc: tcg: Implement addex ins


From: David Gibson
Subject: Re: [Qemu-devel] [QEMU-PPC] [PATCH] target/ppc: tcg: Implement addex instruction
Date: Thu, 15 Nov 2018 20:40:36 +1100
User-agent: Mutt/1.10.1 (2018-07-13)

On Thu, Nov 15, 2018 at 02:22:59PM +1100, Suraj Jitindar Singh wrote:
> Implement the addex instruction introduced in ISA V3.00 in qemu tcg.
> 
> The add extended using alternate carry bit (addex) instruction performs
> the same operation as the add extended (adde) instruction, but using the
> overflow (ov) field in the fixed point exception register (xer) as the
> carry in and out instead of the carry (ca) field.
> 
> The instruction has a Z23-form, not an XO form, as follows:
> 
>     ------------------------------------------------------------------
>     |   31   |   RT   |   RA   |   RB   |   CY   |     170     |  0  |
>     ------------------------------------------------------------------
>     0        6        11       16       21       23            31    32
> 
> However since the only valid form of the instruction defined so far is
> CY = 0, we can treat this like an XO form instruction.
> 
> There is no dot form (addex.) of the instruction and the summary overflow
> (so) bit in the xer is not modified by this instruction.
> 
> For simplicity we reuse the gen_op_arith_add function and add a function
> argument to specify where the carry in input should come from and the
> carry out output be stored (note must be the same location).
> 
> Signed-off-by: Suraj Jitindar Singh <address@hidden>

Applied, thanks.

> ---
>  disas/ppc.c            |  2 ++
>  target/ppc/translate.c | 60 
> +++++++++++++++++++++++++++-----------------------
>  2 files changed, 35 insertions(+), 27 deletions(-)
> 
> diff --git a/disas/ppc.c b/disas/ppc.c
> index 5ab9c35a84..da1140ba2b 100644
> --- a/disas/ppc.c
> +++ b/disas/ppc.c
> @@ -3734,6 +3734,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
>  { "addmeo.", XO(31,234,1,1), XORB_MASK, PPCCOM,              { RT, RA } },
>  { "ameo.",   XO(31,234,1,1), XORB_MASK, PWRCOM,              { RT, RA } },
>  
> +{ "addex",   XO(31,170,0,0), XO_MASK,   POWER9,         { RT, RA, RB } },
> +
>  { "mullw",   XO(31,235,0,0), XO_MASK,        PPCCOM,         { RT, RA, RB } 
> },
>  { "muls",    XO(31,235,0,0), XO_MASK,        PWRCOM,         { RT, RA, RB } 
> },
>  { "mullw.",  XO(31,235,0,1), XO_MASK,        PPCCOM,         { RT, RA, RB } 
> },
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 2b37910248..96894ab9a8 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -849,7 +849,7 @@ static inline void gen_op_arith_compute_ov(DisasContext 
> *ctx, TCGv arg0,
>  
>  static inline void gen_op_arith_compute_ca32(DisasContext *ctx,
>                                               TCGv res, TCGv arg0, TCGv arg1,
> -                                             int sub)
> +                                             TCGv ca32, int sub)
>  {
>      TCGv t0;
>  
> @@ -864,13 +864,14 @@ static inline void 
> gen_op_arith_compute_ca32(DisasContext *ctx,
>          tcg_gen_xor_tl(t0, arg0, arg1);
>      }
>      tcg_gen_xor_tl(t0, t0, res);
> -    tcg_gen_extract_tl(cpu_ca32, t0, 32, 1);
> +    tcg_gen_extract_tl(ca32, t0, 32, 1);
>      tcg_temp_free(t0);
>  }
>  
>  /* Common add function */
>  static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
> -                                    TCGv arg2, bool add_ca, bool compute_ca,
> +                                    TCGv arg2, TCGv ca, TCGv ca32,
> +                                    bool add_ca, bool compute_ca,
>                                      bool compute_ov, bool compute_rc0)
>  {
>      TCGv t0 = ret;
> @@ -888,29 +889,29 @@ static inline void gen_op_arith_add(DisasContext *ctx, 
> TCGv ret, TCGv arg1,
>              tcg_gen_xor_tl(t1, arg1, arg2);        /* add without carry */
>              tcg_gen_add_tl(t0, arg1, arg2);
>              if (add_ca) {
> -                tcg_gen_add_tl(t0, t0, cpu_ca);
> +                tcg_gen_add_tl(t0, t0, ca);
>              }
> -            tcg_gen_xor_tl(cpu_ca, t0, t1);        /* bits changed w/ carry 
> */
> +            tcg_gen_xor_tl(ca, t0, t1);        /* bits changed w/ carry */
>              tcg_temp_free(t1);
> -            tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1);
> +            tcg_gen_extract_tl(ca, ca, 32, 1);
>              if (is_isa300(ctx)) {
> -                tcg_gen_mov_tl(cpu_ca32, cpu_ca);
> +                tcg_gen_mov_tl(ca32, ca);
>              }
>          } else {
>              TCGv zero = tcg_const_tl(0);
>              if (add_ca) {
> -                tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
> -                tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
> +                tcg_gen_add2_tl(t0, ca, arg1, zero, ca, zero);
> +                tcg_gen_add2_tl(t0, ca, t0, ca, arg2, zero);
>              } else {
> -                tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
> +                tcg_gen_add2_tl(t0, ca, arg1, zero, arg2, zero);
>              }
> -            gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, 0);
> +            gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, ca32, 0);
>              tcg_temp_free(zero);
>          }
>      } else {
>          tcg_gen_add_tl(t0, arg1, arg2);
>          if (add_ca) {
> -            tcg_gen_add_tl(t0, t0, cpu_ca);
> +            tcg_gen_add_tl(t0, t0, ca);
>          }
>      }
>  
> @@ -927,40 +928,44 @@ static inline void gen_op_arith_add(DisasContext *ctx, 
> TCGv ret, TCGv arg1,
>      }
>  }
>  /* Add functions with two operands */
> -#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)        
>  \
> +#define GEN_INT_ARITH_ADD(name, opc3, ca, add_ca, compute_ca, compute_ov)    
>  \
>  static void glue(gen_, name)(DisasContext *ctx)                              
>  \
>  {                                                                            
>  \
>      gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                          
>  \
>                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     
>  \
> +                     ca, glue(ca, 32),                                       
>  \
>                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       
>  \
>  }
>  /* Add functions with one operand and one immediate */
> -#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                       
>  \
> +#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, ca,                   
>  \
>                                  add_ca, compute_ca, compute_ov)              
>  \
>  static void glue(gen_, name)(DisasContext *ctx)                              
>  \
>  {                                                                            
>  \
>      TCGv t0 = tcg_const_tl(const_val);                                       
>  \
>      gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                          
>  \
>                       cpu_gpr[rA(ctx->opcode)], t0,                           
>  \
> +                     ca, glue(ca, 32),                                       
>  \
>                       add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       
>  \
>      tcg_temp_free(t0);                                                       
>  \
>  }
>  
>  /* add  add.  addo  addo. */
> -GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
> -GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
> +GEN_INT_ARITH_ADD(add, 0x08, cpu_ca, 0, 0, 0)
> +GEN_INT_ARITH_ADD(addo, 0x18, cpu_ca, 0, 0, 1)
>  /* addc  addc.  addco  addco. */
> -GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
> -GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
> +GEN_INT_ARITH_ADD(addc, 0x00, cpu_ca, 0, 1, 0)
> +GEN_INT_ARITH_ADD(addco, 0x10, cpu_ca, 0, 1, 1)
>  /* adde  adde.  addeo  addeo. */
> -GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
> -GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
> +GEN_INT_ARITH_ADD(adde, 0x04, cpu_ca, 1, 1, 0)
> +GEN_INT_ARITH_ADD(addeo, 0x14, cpu_ca, 1, 1, 1)
>  /* addme  addme.  addmeo  addmeo.  */
> -GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
> -GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
> +GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, cpu_ca, 1, 1, 0)
> +GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, cpu_ca, 1, 1, 1)
> +/* addex */
> +GEN_INT_ARITH_ADD(addex, 0x05, cpu_ov, 1, 1, 0);
>  /* addze  addze.  addzeo  addzeo.*/
> -GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
> -GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
> +GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, cpu_ca, 1, 1, 0)
> +GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, cpu_ca, 1, 1, 1)
>  /* addi */
>  static void gen_addi(DisasContext *ctx)
>  {
> @@ -979,7 +984,7 @@ static inline void gen_op_addic(DisasContext *ctx, bool 
> compute_rc0)
>  {
>      TCGv c = tcg_const_tl(SIMM(ctx->opcode));
>      gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
> -                     c, 0, 1, 0, compute_rc0);
> +                     c, cpu_ca, cpu_ca32, 0, 1, 0, compute_rc0);
>      tcg_temp_free(c);
>  }
>  
> @@ -1432,13 +1437,13 @@ static inline void gen_op_arith_subf(DisasContext 
> *ctx, TCGv ret, TCGv arg1,
>              zero = tcg_const_tl(0);
>              tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
>              tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
> -            gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, 0);
> +            gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, cpu_ca32, 0);
>              tcg_temp_free(zero);
>              tcg_temp_free(inv1);
>          } else {
>              tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
>              tcg_gen_sub_tl(t0, arg2, arg1);
> -            gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, 1);
> +            gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, cpu_ca32, 1);
>          }
>      } else if (add_ca) {
>          /* Since we're ignoring carry-out, we can simplify the
> @@ -7087,6 +7092,7 @@ GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
>  GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
>  GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
>  GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
> +GEN_HANDLER_E(addex, 0x1F, 0x0A, 0x05, 0x00000000, PPC_NONE, PPC2_ISA300),
>  GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
>  GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
>  

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

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