[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [Qemu-devel] [RFC v1 13/13] target-ppc: introduce opc4 fo
From: |
Bharata B Rao |
Subject: |
Re: [Qemu-ppc] [Qemu-devel] [RFC v1 13/13] target-ppc: introduce opc4 for Expanded Opcode |
Date: |
Fri, 22 Jul 2016 15:19:13 +0530 |
On Mon, Jul 18, 2016 at 10:35 PM, Nikunj A Dadhania
<address@hidden> 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 <address@hidden>
> ---
> target-ppc/translate.c | 73 +++++++++++++++++++++++++------
> target-ppc/translate_init.c | 103
> ++++++++++++++++++++++++++++++++------------
> 2 files changed, 136 insertions(+), 40 deletions(-)
>
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 6c5a4a6..733d68d 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -40,6 +40,7 @@
> /* Include definitions for instructions classes and implementations flags */
> //#define PPC_DEBUG_DISAS
> //#define DO_PPC_STATISTICS
> +//#define PPC_DUMP_CPU
>
> #ifdef PPC_DEBUG_DISAS
> # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
> @@ -367,12 +368,15 @@ 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];
> + unsigned char pad[4];
> #else
> - unsigned char pad[1];
> + unsigned char pad[4]; /* 4-byte pad to maintain pad in opcode table */
> #endif
> opc_handler_t handler;
> const char *oname;
> @@ -452,6 +456,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,6 +595,7 @@ EXTRACT_HELPER(SP, 19, 2);
> .opc1 = op1,
> \
> .opc2 = op2,
> \
> .opc3 = op3,
> \
> + .opc4 = 0xff,
> \
> .pad = { 0, },
> \
> .handler = {
> \
> .inval1 = invl,
> \
> @@ -604,6 +611,7 @@ EXTRACT_HELPER(SP, 19, 2);
> .opc1 = op1,
> \
> .opc2 = op2,
> \
> .opc3 = op3,
> \
> + .opc4 = 0xff,
> \
> .pad = { 0, },
> \
> .handler = {
> \
> .inval1 = invl1,
> \
> @@ -620,6 +628,7 @@ EXTRACT_HELPER(SP, 19, 2);
> .opc1 = op1,
> \
> .opc2 = op2,
> \
> .opc3 = op3,
> \
> + .opc4 = 0xff,
> \
> .pad = { 0, },
> \
> .handler = {
> \
> .inval1 = invl,
> \
> @@ -630,12 +639,29 @@ 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,
> \
> + .pad = { 0, },
> \
> + .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,
> \
> + .opc4 = 0xff,
> \
> .pad = { 0, },
> \
> .handler = {
> \
> .inval1 = invl,
> \
> @@ -650,6 +676,7 @@ EXTRACT_HELPER(SP, 19, 2);
> .opc1 = op1,
> \
> .opc2 = op2,
> \
> .opc3 = op3,
> \
> + .opc4 = 0xff,
> \
> .pad = { 0, },
> \
> .handler = {
> \
> .inval1 = invl1,
> \
> @@ -665,6 +692,7 @@ EXTRACT_HELPER(SP, 19, 2);
> .opc1 = op1,
> \
> .opc2 = op2,
> \
> .opc3 = op3,
> \
> + .opc4 = 0xff,
> \
> .pad = { 0, },
> \
> .handler = {
> \
> .inval1 = invl,
> \
> @@ -674,6 +702,21 @@ 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,
> \
> + .pad = { 0, },
> \
> + .handler = {
> \
> + .inval1 = invl,
> \
> + .type = _typ,
> \
> + .type2 = _typ2,
> \
> + .handler = &gen_##name,
> \
> + },
> \
> + .oname = stringify(name),
> \
> +}
> #endif
>
> /* SPR load/store helpers */
> @@ -11946,9 +11989,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)];
> @@ -11958,14 +12002,19 @@ 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;
>
> @@ -11977,10 +12026,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",
> + "%02x - %02x - %02x - %02x (%08x) "
> TARGET_FMT_lx "\n",
> ctx.opcode & inval, opc1(ctx.opcode),
> opc2(ctx.opcode), opc3(ctx.opcode),
> - ctx.opcode, ctx.nip - 4);
> + opc4(ctx.opcode), ctx.opcode, ctx.nip - 4);
> gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
> break;
> }
> @@ -12006,9 +12055,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",
> + fprintf(stderr, "Opcode %02x %02x %02x %02x (%08x) leaked
> temporaries\n",
> opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),
> - ctx.opcode);
> + opc4(ctx.opcode), ctx.opcode);
> exit(1);
> }
> }
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index d207f68..7c723e9 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -9252,13 +9252,45 @@ 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;
> +}
If you are adding a 3rd level opcode table, explicit freeing of the
same from ppc_cpu_unrealizefn() is necessary right ?
Regards,
Bharata.
- Re: [Qemu-ppc] [Qemu-devel] [RFC v1 09/13] target-ppc: add cmpeqb instruction, (continued)
Re: [Qemu-ppc] [RFC v1 09/13] target-ppc: add cmpeqb instruction, David Gibson, 2016/07/22
[Qemu-ppc] [RFC v1 12/13] target-ppc: add maddhd and maddhdu instruction, Nikunj A Dadhania, 2016/07/18
[Qemu-ppc] [RFC v1 13/13] target-ppc: introduce opc4 for Expanded Opcode, Nikunj A Dadhania, 2016/07/18
Re: [Qemu-ppc] [Qemu-devel] [RFC v1 13/13] target-ppc: introduce opc4 for Expanded Opcode,
Bharata B Rao <=