qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Cc: qemu-ppc@nongnu.org, rth@twiddle.net, qemu-devel@nongnu.org,
	bharata@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com
Subject: Re: [Qemu-devel] [PATCH v4 15/15] target-ppc: introduce opc4 for Expanded Opcode
Date: Wed, 27 Jul 2016 15:31:02 +1000	[thread overview]
Message-ID: <20160727053102.GF17429@voom.fritz.box> (raw)
In-Reply-To: <1469534318-5549-16-git-send-email-nikunj@linux.vnet.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 22164 bytes --]

On Tue, Jul 26, 2016 at 05:28:38PM +0530, Nikunj A Dadhania wrote:
> ISA 3.0 has introduced EO - Expanded Opcode. Introduce third level
> indirect opcode table and corresponding parsing routines.
> 
> EO (11:12) Expanded opcode field
> Formats: XX1
> 
> EO (11:15) Expanded opcode field
> Formats: VX, X, XX2
> 
> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  target-ppc/translate.c      |  82 ++++++++++++++++++++--------
>  target-ppc/translate_init.c | 126 ++++++++++++++++++++++++++++++++------------
>  2 files changed, 154 insertions(+), 54 deletions(-)
> 
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index ec7064f..d522566 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -367,12 +367,13 @@ GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
>  #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
>  GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
>  
> +#define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2)     \
> +GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2)
> +
>  typedef struct opcode_t {
> -    unsigned char opc1, opc2, opc3;
> +    unsigned char opc1, opc2, opc3, opc4;
>  #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
> -    unsigned char pad[5];
> -#else
> -    unsigned char pad[1];
> +    unsigned char pad[4];
>  #endif
>      opc_handler_t handler;
>      const char *oname;
> @@ -452,6 +453,8 @@ EXTRACT_HELPER(opc1, 26, 6);
>  EXTRACT_HELPER(opc2, 1, 5);
>  /* Opcode part 3 */
>  EXTRACT_HELPER(opc3, 6, 5);
> +/* Opcode part 4 */
> +EXTRACT_HELPER(opc4, 16, 5);
>  /* Update Cr0 flags */
>  EXTRACT_HELPER(Rc, 0, 1);
>  /* Update Cr6 flags (Altivec) */
> @@ -589,7 +592,7 @@ EXTRACT_HELPER(SP, 19, 2);
>      .opc1 = op1,                                                              \
>      .opc2 = op2,                                                              \
>      .opc3 = op3,                                                              \
> -    .pad  = { 0, },                                                           \
> +    .opc4 = 0xff,                                                             \
>      .handler = {                                                              \
>          .inval1  = invl,                                                      \
>          .type = _typ,                                                         \
> @@ -604,7 +607,7 @@ EXTRACT_HELPER(SP, 19, 2);
>      .opc1 = op1,                                                              \
>      .opc2 = op2,                                                              \
>      .opc3 = op3,                                                              \
> -    .pad  = { 0, },                                                           \
> +    .opc4 = 0xff,                                                             \
>      .handler = {                                                              \
>          .inval1  = invl1,                                                     \
>          .inval2  = invl2,                                                     \
> @@ -620,7 +623,7 @@ EXTRACT_HELPER(SP, 19, 2);
>      .opc1 = op1,                                                              \
>      .opc2 = op2,                                                              \
>      .opc3 = op3,                                                              \
> -    .pad  = { 0, },                                                           \
> +    .opc4 = 0xff,                                                             \
>      .handler = {                                                              \
>          .inval1  = invl,                                                      \
>          .type = _typ,                                                         \
> @@ -630,13 +633,28 @@ EXTRACT_HELPER(SP, 19, 2);
>      },                                                                        \
>      .oname = onam,                                                            \
>  }
> +#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2)              \
> +{                                                                             \
> +    .opc1 = op1,                                                              \
> +    .opc2 = op2,                                                              \
> +    .opc3 = op3,                                                              \
> +    .opc4 = op4,                                                              \
> +    .handler = {                                                              \
> +        .inval1  = invl,                                                      \
> +        .type = _typ,                                                         \
> +        .type2 = _typ2,                                                       \
> +        .handler = &gen_##name,                                               \
> +        .oname = stringify(name),                                             \
> +    },                                                                        \
> +    .oname = stringify(name),                                                 \
> +}
>  #else
>  #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
>  {                                                                             \
>      .opc1 = op1,                                                              \
>      .opc2 = op2,                                                              \
>      .opc3 = op3,                                                              \
> -    .pad  = { 0, },                                                           \
> +    .opc4 = 0xff,                                                             \
>      .handler = {                                                              \
>          .inval1  = invl,                                                      \
>          .type = _typ,                                                         \
> @@ -650,7 +668,7 @@ EXTRACT_HELPER(SP, 19, 2);
>      .opc1 = op1,                                                              \
>      .opc2 = op2,                                                              \
>      .opc3 = op3,                                                              \
> -    .pad  = { 0, },                                                           \
> +    .opc4 = 0xff,                                                             \
>      .handler = {                                                              \
>          .inval1  = invl1,                                                     \
>          .inval2  = invl2,                                                     \
> @@ -665,7 +683,7 @@ EXTRACT_HELPER(SP, 19, 2);
>      .opc1 = op1,                                                              \
>      .opc2 = op2,                                                              \
>      .opc3 = op3,                                                              \
> -    .pad  = { 0, },                                                           \
> +    .opc4 = 0xff,                                                             \
>      .handler = {                                                              \
>          .inval1  = invl,                                                      \
>          .type = _typ,                                                         \
> @@ -674,6 +692,20 @@ EXTRACT_HELPER(SP, 19, 2);
>      },                                                                        \
>      .oname = onam,                                                            \
>  }
> +#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2)              \
> +{                                                                             \
> +    .opc1 = op1,                                                              \
> +    .opc2 = op2,                                                              \
> +    .opc3 = op3,                                                              \
> +    .opc4 = op4,                                                              \
> +    .handler = {                                                              \
> +        .inval1  = invl,                                                      \
> +        .type = _typ,                                                         \
> +        .type2 = _typ2,                                                       \
> +        .handler = &gen_##name,                                               \
> +    },                                                                        \
> +    .oname = stringify(name),                                                 \
> +}
>  #endif
>  
>  /* SPR load/store helpers */
> @@ -11906,9 +11938,10 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>          } else {
>              ctx.opcode = cpu_ldl_code(env, ctx.nip);
>          }
> -        LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
> -                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
> -                    opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
> +        LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
> +                  ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
> +                  opc3(ctx.opcode), opc4(ctx.opcode),
> +                  ctx.le_mode ? "little" : "big");
>          ctx.nip += 4;
>          table = env->opcodes;
>          handler = table[opc1(ctx.opcode)];
> @@ -11918,14 +11951,20 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>              if (is_indirect_opcode(handler)) {
>                  table = ind_table(handler);
>                  handler = table[opc3(ctx.opcode)];
> +                if (is_indirect_opcode(handler)) {
> +                    table = ind_table(handler);
> +                    handler = table[opc4(ctx.opcode)];
> +                }
>              }
>          }
>          /* Is opcode *REALLY* valid ? */
>          if (unlikely(handler->handler == &gen_invalid)) {
>              qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
> -                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
> +                          "%02x - %02x - %02x - %02x (%08x) "
> +                          TARGET_FMT_lx " %d\n",
>                            opc1(ctx.opcode), opc2(ctx.opcode),
> -                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
> +                          opc3(ctx.opcode), opc4(ctx.opcode),
> +                          ctx.opcode, ctx.nip - 4, (int)msr_ir);
>          } else {
>              uint32_t inval;
>  
> @@ -11937,9 +11976,10 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>  
>              if (unlikely((ctx.opcode & inval) != 0)) {
>                  qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
> -                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
> -                              ctx.opcode & inval, opc1(ctx.opcode),
> -                              opc2(ctx.opcode), opc3(ctx.opcode),
> +                              "%02x - %02x - %02x - %02x (%08x) "
> +                              TARGET_FMT_lx "\n", ctx.opcode & inval,
> +                              opc1(ctx.opcode), opc2(ctx.opcode),
> +                              opc3(ctx.opcode), opc4(ctx.opcode),
>                                ctx.opcode, ctx.nip - 4);
>                  gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
>                  break;
> @@ -11966,9 +12006,9 @@ void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
>              break;
>          }
>          if (tcg_check_temp_count()) {
> -            fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n",
> -                    opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),
> -                    ctx.opcode);
> +            fprintf(stderr, "Opcode %02x %02x %02x %02x (%08x) leaked "
> +                    "temporaries\n", opc1(ctx.opcode), opc2(ctx.opcode),
> +                    opc3(ctx.opcode), opc4(ctx.opcode), ctx.opcode);
>              exit(1);
>          }
>      }
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 0d8cff1..f627cfe 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -9253,13 +9253,47 @@ static int register_dblind_insn (opc_handler_t **ppc_opcodes,
>      return 0;
>  }
>  
> +static int register_trplind_insn(opc_handler_t **ppc_opcodes,
> +                                 unsigned char idx1, unsigned char idx2,
> +                                 unsigned char idx3, unsigned char idx4,
> +                                 opc_handler_t *handler)
> +{
> +    opc_handler_t **table;
> +
> +    if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
> +        printf("*** ERROR: unable to join indirect table idx "
> +               "[%02x-%02x]\n", idx1, idx2);
> +        return -1;
> +    }
> +    table = ind_table(ppc_opcodes[idx1]);
> +    if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
> +        printf("*** ERROR: unable to join 2nd-level indirect table idx "
> +               "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
> +        return -1;
> +    }
> +    table = ind_table(table[idx2]);
> +    if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
> +        printf("*** ERROR: unable to insert opcode "
> +               "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
> +        return -1;
> +    }
> +    return 0;
> +}
>  static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
>  {
>      if (insn->opc2 != 0xFF) {
>          if (insn->opc3 != 0xFF) {
> -            if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
> -                                     insn->opc3, &insn->handler) < 0)
> -                return -1;
> +            if (insn->opc4 != 0xFF) {
> +                if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
> +                                          insn->opc3, insn->opc4,
> +                                          &insn->handler) < 0) {
> +                    return -1;
> +                }
> +            } else {
> +                if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
> +                                         insn->opc3, &insn->handler) < 0)
> +                    return -1;
> +            }
>          } else {
>              if (register_ind_insn(ppc_opcodes, insn->opc1,
>                                    insn->opc2, &insn->handler) < 0)
> @@ -9335,7 +9369,7 @@ static void dump_ppc_insns (CPUPPCState *env)
>  {
>      opc_handler_t **table, *handler;
>      const char *p, *q;
> -    uint8_t opc1, opc2, opc3;
> +    uint8_t opc1, opc2, opc3, opc4;
>  
>      printf("Instructions set:\n");
>      /* opc1 is 6 bits long */
> @@ -9355,34 +9389,50 @@ static void dump_ppc_insns (CPUPPCState *env)
>                      for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
>                              opc3++) {
>                          handler = table[opc3];
> -                        if (handler->handler != &gen_invalid) {
> -                            /* Special hack to properly dump SPE insns */
> -                            p = strchr(handler->oname, '_');
> -                            if (p == NULL) {
> -                                printf("INSN: %02x %02x %02x (%02d %04d) : "
> -                                       "%s\n",
> -                                       opc1, opc2, opc3, opc1,
> -                                       (opc3 << 5) | opc2,
> -                                       handler->oname);
> -                            } else {
> -                                q = "speundef";
> -                                if ((p - handler->oname) != strlen(q) ||
> -                                    memcmp(handler->oname, q, strlen(q)) != 0) {
> -                                    /* First instruction */
> -                                    printf("INSN: %02x %02x %02x (%02d %04d) : "
> -                                           "%.*s\n",
> -                                           opc1, opc2 << 1, opc3, opc1,
> -                                           (opc3 << 6) | (opc2 << 1),
> -                                           (int)(p - handler->oname),
> +                        if (is_indirect_opcode(handler)) {
> +                            table = ind_table(handler);
> +                            /* opc4 is 5 bits long */
> +                            for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
> +                                 opc4++) {
> +                                handler = table[opc4];
> +                                if (handler->handler != &gen_invalid) {
> +                                    printf("INSN: %02x %02x %02x %02x -- "
> +                                           "(%02d %04d %02d) : %s\n",
> +                                           opc1, opc2, opc3, opc4,
> +                                           opc1, (opc3 << 5) | opc2, opc4,
>                                             handler->oname);
>                                  }
> -                                if (strcmp(p + 1, q) != 0) {
> -                                    /* Second instruction */
> +                            }
> +                        } else {
> +                            if (handler->handler != &gen_invalid) {
> +                                /* Special hack to properly dump SPE insns */
> +                                p = strchr(handler->oname, '_');
> +                                if (p == NULL) {
>                                      printf("INSN: %02x %02x %02x (%02d %04d) : "
>                                             "%s\n",
> -                                           opc1, (opc2 << 1) | 1, opc3, opc1,
> -                                           (opc3 << 6) | (opc2 << 1) | 1,
> -                                           p + 1);
> +                                           opc1, opc2, opc3, opc1,
> +                                           (opc3 << 5) | opc2,
> +                                           handler->oname);
> +                                } else {
> +                                    q = "speundef";
> +                                    if ((p - handler->oname) != strlen(q) ||
> +                                        memcmp(handler->oname, q, strlen(q)) != 0) {
> +                                        /* First instruction */
> +                                        printf("INSN: %02x %02x %02x"
> +                                               "(%02d %04d) : %.*s\n",
> +                                               opc1, opc2 << 1, opc3, opc1,
> +                                               (opc3 << 6) | (opc2 << 1),
> +                                               (int)(p - handler->oname),
> +                                               handler->oname);
> +                                    }
> +                                    if (strcmp(p + 1, q) != 0) {
> +                                        /* Second instruction */
> +                                        printf("INSN: %02x %02x %02x "
> +                                               "(%02d %04d) : %s\n", opc1,
> +                                               (opc2 << 1) | 1, opc3, opc1,
> +                                               (opc3 << 6) | (opc2 << 1) | 1,
> +                                               p + 1);
> +                                    }
>                                  }
>                              }
>                          }
> @@ -9858,8 +9908,8 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
>  {
>      PowerPCCPU *cpu = POWERPC_CPU(dev);
>      CPUPPCState *env = &cpu->env;
> -    opc_handler_t **table;
> -    int i, j;
> +    opc_handler_t **table, **table_2;
> +    int i, j, k;
>  
>      cpu_exec_exit(CPU(dev));
>  
> @@ -9870,10 +9920,20 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
>          if (is_indirect_opcode(env->opcodes[i])) {
>              table = ind_table(env->opcodes[i]);
>              for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
> -                if (table[j] != &invalid_handler &&
> -                        is_indirect_opcode(table[j])) {
> +                if (table[j] == &invalid_handler) {
> +                    continue;
> +                }
> +                if (is_indirect_opcode(table[j])) {
> +                    table_2 = ind_table(table[j]);
> +                    for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
> +                        if (table_2[k] != &invalid_handler &&
> +                            is_indirect_opcode(table_2[k])) {
> +                            g_free((opc_handler_t *)((uintptr_t)table_2[k] &
> +                                                     ~PPC_INDIRECT));
> +                        }
> +                    }
>                      g_free((opc_handler_t *)((uintptr_t)table[j] &
> -                        ~PPC_INDIRECT));
> +                                             ~PPC_INDIRECT));
>                  }
>              }
>              g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] &

-- 
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 #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2016-07-27  6:07 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1469534318-5549-1-git-send-email-nikunj@linux.vnet.ibm.com>
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 01/15] target-ppc: Introduce Power9 family Nikunj A Dadhania
2016-07-27  6:17   ` David Gibson
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 02/15] target-ppc: Introduce POWER ISA 3.0 flag Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 03/15] target-ppc: adding addpcis instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 04/15] target-ppc: add cmprb instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 05/15] target-ppc: add modulo word operations Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 06/15] target-ppc: add modulo dword operations Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 07/15] target-ppc: implement branch-less divw[o][.] Nikunj A Dadhania
2016-07-27  5:19   ` David Gibson
2016-07-27  6:17     ` Nikunj A Dadhania
2016-07-27  6:29       ` David Gibson
2016-07-27  6:41         ` Nikunj A Dadhania
2016-07-27  6:56           ` David Gibson
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 08/15] target-ppc: implement branch-less divd[o][.] Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 09/15] target-ppc: add cnttzd[.] instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 10/15] target-ppc: add cnttzw[.] instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 11/15] target-ppc: add cmpeqb instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 12/15] target-ppc: add setb instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 13/15] target-ppc: add maddld instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 14/15] target-ppc: add maddhd and maddhdu instruction Nikunj A Dadhania
2016-07-26 11:58 ` [Qemu-devel] [PATCH v4 15/15] target-ppc: introduce opc4 for Expanded Opcode Nikunj A Dadhania
2016-07-27  5:31   ` David Gibson [this message]
2016-07-27  6:23 ` [Qemu-devel] [PATCH v4 00/15] POWER9 TCG enablements - part1 David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160727053102.GF17429@voom.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=bharata@linux.vnet.ibm.com \
    --cc=nikunj@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).