[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [QEMU-PPC] [PATCH] target/ppc: tcg: Implement addex instr
From: |
David Gibson |
Subject: |
Re: [Qemu-ppc] [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
signature.asc
Description: PGP signature