From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bSI0M-0004El-Qi for qemu-devel@nongnu.org; Wed, 27 Jul 2016 02:07:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bSI0J-0001eT-B5 for qemu-devel@nongnu.org; Wed, 27 Jul 2016 02:07:41 -0400 Date: Wed, 27 Jul 2016 15:31:02 +1000 From: David Gibson Message-ID: <20160727053102.GF17429@voom.fritz.box> References: <1469534318-5549-1-git-send-email-nikunj@linux.vnet.ibm.com> <1469534318-5549-16-git-send-email-nikunj@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="4fo3mGi7Q6pk/+I3" Content-Disposition: inline In-Reply-To: <1469534318-5549-16-git-send-email-nikunj@linux.vnet.ibm.com> Subject: Re: [Qemu-devel] [PATCH v4 15/15] target-ppc: introduce opc4 for Expanded Opcode List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Nikunj A Dadhania Cc: qemu-ppc@nongnu.org, rth@twiddle.net, qemu-devel@nongnu.org, bharata@linux.vnet.ibm.com, aneesh.kumar@linux.vnet.ibm.com --4fo3mGi7Q6pk/+I3 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable 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. >=20 > EO (11:12) Expanded opcode field > Formats: XX1 >=20 > EO (11:15) Expanded opcode field > Formats: VX, X, XX2 >=20 > Signed-off-by: Nikunj A Dadhania Reviewed-by: David Gibson > --- > target-ppc/translate.c | 82 ++++++++++++++++++++-------- > target-ppc/translate_init.c | 126 ++++++++++++++++++++++++++++++++------= ------ > 2 files changed, 154 insertions(+), 54 deletions(-) >=20 > 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, ty= pe, PPC_NONE) > #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)= \ > GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2) > =20 > +#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 =3D=3D 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 =3D op1, = \ > .opc2 =3D op2, = \ > .opc3 =3D op3, = \ > - .pad =3D { 0, }, = \ > + .opc4 =3D 0xff, = \ > .handler =3D { = \ > .inval1 =3D invl, = \ > .type =3D _typ, = \ > @@ -604,7 +607,7 @@ EXTRACT_HELPER(SP, 19, 2); > .opc1 =3D op1, = \ > .opc2 =3D op2, = \ > .opc3 =3D op3, = \ > - .pad =3D { 0, }, = \ > + .opc4 =3D 0xff, = \ > .handler =3D { = \ > .inval1 =3D invl1, = \ > .inval2 =3D invl2, = \ > @@ -620,7 +623,7 @@ EXTRACT_HELPER(SP, 19, 2); > .opc1 =3D op1, = \ > .opc2 =3D op2, = \ > .opc3 =3D op3, = \ > - .pad =3D { 0, }, = \ > + .opc4 =3D 0xff, = \ > .handler =3D { = \ > .inval1 =3D invl, = \ > .type =3D _typ, = \ > @@ -630,13 +633,28 @@ EXTRACT_HELPER(SP, 19, 2); > }, = \ > .oname =3D onam, = \ > } > +#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) = \ > +{ = \ > + .opc1 =3D op1, = \ > + .opc2 =3D op2, = \ > + .opc3 =3D op3, = \ > + .opc4 =3D op4, = \ > + .handler =3D { = \ > + .inval1 =3D invl, = \ > + .type =3D _typ, = \ > + .type2 =3D _typ2, = \ > + .handler =3D &gen_##name, = \ > + .oname =3D stringify(name), = \ > + }, = \ > + .oname =3D stringify(name), = \ > +} > #else > #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) = \ > { = \ > .opc1 =3D op1, = \ > .opc2 =3D op2, = \ > .opc3 =3D op3, = \ > - .pad =3D { 0, }, = \ > + .opc4 =3D 0xff, = \ > .handler =3D { = \ > .inval1 =3D invl, = \ > .type =3D _typ, = \ > @@ -650,7 +668,7 @@ EXTRACT_HELPER(SP, 19, 2); > .opc1 =3D op1, = \ > .opc2 =3D op2, = \ > .opc3 =3D op3, = \ > - .pad =3D { 0, }, = \ > + .opc4 =3D 0xff, = \ > .handler =3D { = \ > .inval1 =3D invl1, = \ > .inval2 =3D invl2, = \ > @@ -665,7 +683,7 @@ EXTRACT_HELPER(SP, 19, 2); > .opc1 =3D op1, = \ > .opc2 =3D op2, = \ > .opc3 =3D op3, = \ > - .pad =3D { 0, }, = \ > + .opc4 =3D 0xff, = \ > .handler =3D { = \ > .inval1 =3D invl, = \ > .type =3D _typ, = \ > @@ -674,6 +692,20 @@ EXTRACT_HELPER(SP, 19, 2); > }, = \ > .oname =3D onam, = \ > } > +#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) = \ > +{ = \ > + .opc1 =3D op1, = \ > + .opc2 =3D op2, = \ > + .opc3 =3D op3, = \ > + .opc4 =3D op4, = \ > + .handler =3D { = \ > + .inval1 =3D invl, = \ > + .type =3D _typ, = \ > + .type2 =3D _typ2, = \ > + .handler =3D &gen_##name, = \ > + }, = \ > + .oname =3D stringify(name), = \ > +} > #endif > =20 > /* SPR load/store helpers */ > @@ -11906,9 +11938,10 @@ void gen_intermediate_code(CPUPPCState *env, str= uct TranslationBlock *tb) > } else { > ctx.opcode =3D 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 +=3D 4; > table =3D env->opcodes; > handler =3D table[opc1(ctx.opcode)]; > @@ -11918,14 +11951,20 @@ void gen_intermediate_code(CPUPPCState *env, st= ruct TranslationBlock *tb) > if (is_indirect_opcode(handler)) { > table =3D ind_table(handler); > handler =3D table[opc3(ctx.opcode)]; > + if (is_indirect_opcode(handler)) { > + table =3D ind_table(handler); > + handler =3D table[opc4(ctx.opcode)]; > + } > } > } > /* Is opcode *REALLY* valid ? */ > if (unlikely(handler->handler =3D=3D &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, (in= t)msr_ir); > + opc3(ctx.opcode), opc4(ctx.opcode), > + ctx.opcode, ctx.nip - 4, (int)msr_ir); > } else { > uint32_t inval; > =20 > @@ -11937,9 +11976,10 @@ void gen_intermediate_code(CPUPPCState *env, str= uct TranslationBlock *tb) > =20 > if (unlikely((ctx.opcode & inval) !=3D 0)) { > qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for o= pcode: " > - "%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, stru= ct TranslationBlock *tb) > break; > } > if (tcg_check_temp_count()) { > - fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked tempora= ries\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; > } > =20 > +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 =3D 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 =3D 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 !=3D 0xFF) { > if (insn->opc3 !=3D 0xFF) { > - if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, > - insn->opc3, &insn->handler) < 0) > - return -1; > + if (insn->opc4 !=3D 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; > =20 > printf("Instructions set:\n"); > /* opc1 is 6 bits long */ > @@ -9355,34 +9389,50 @@ static void dump_ppc_insns (CPUPPCState *env) > for (opc3 =3D 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN; > opc3++) { > handler =3D table[opc3]; > - if (handler->handler !=3D &gen_invalid) { > - /* Special hack to properly dump SPE insns */ > - p =3D strchr(handler->oname, '_'); > - if (p =3D=3D NULL) { > - printf("INSN: %02x %02x %02x (%02d %04d)= : " > - "%s\n", > - opc1, opc2, opc3, opc1, > - (opc3 << 5) | opc2, > - handler->oname); > - } else { > - q =3D "speundef"; > - if ((p - handler->oname) !=3D strlen(q) = || > - memcmp(handler->oname, q, strlen(q))= !=3D 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 =3D ind_table(handler); > + /* opc4 is 5 bits long */ > + for (opc4 =3D 0; opc4 < PPC_CPU_INDIRECT_OPC= ODES_LEN; > + opc4++) { > + handler =3D table[opc4]; > + if (handler->handler !=3D &gen_invalid) { > + printf("INSN: %02x %02x %02x %02x --= " > + "(%02d %04d %02d) : %s\n", > + opc1, opc2, opc3, opc4, > + opc1, (opc3 << 5) | opc2, opc= 4, > handler->oname); > } > - if (strcmp(p + 1, q) !=3D 0) { > - /* Second instruction */ > + } > + } else { > + if (handler->handler !=3D &gen_invalid) { > + /* Special hack to properly dump SPE ins= ns */ > + p =3D strchr(handler->oname, '_'); > + if (p =3D=3D 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 =3D "speundef"; > + if ((p - handler->oname) !=3D strlen= (q) || > + memcmp(handler->oname, q, strlen= (q)) !=3D 0) { > + /* First instruction */ > + printf("INSN: %02x %02x %02x" > + "(%02d %04d) : %.*s\n", > + opc1, opc2 << 1, opc3, op= c1, > + (opc3 << 6) | (opc2 << 1), > + (int)(p - handler->oname), > + handler->oname); > + } > + if (strcmp(p + 1, q) !=3D 0) { > + /* Second instruction */ > + printf("INSN: %02x %02x %02x " > + "(%02d %04d) : %s\n", opc= 1, > + (opc2 << 1) | 1, opc3, op= c1, > + (opc3 << 6) | (opc2 << 1)= | 1, > + p + 1); > + } > } > } > } > @@ -9858,8 +9908,8 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, E= rror **errp) > { > PowerPCCPU *cpu =3D POWERPC_CPU(dev); > CPUPPCState *env =3D &cpu->env; > - opc_handler_t **table; > - int i, j; > + opc_handler_t **table, **table_2; > + int i, j, k; > =20 > cpu_exec_exit(CPU(dev)); > =20 > @@ -9870,10 +9920,20 @@ static void ppc_cpu_unrealizefn(DeviceState *dev,= Error **errp) > if (is_indirect_opcode(env->opcodes[i])) { > table =3D ind_table(env->opcodes[i]); > for (j =3D 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { > - if (table[j] !=3D &invalid_handler && > - is_indirect_opcode(table[j])) { > + if (table[j] =3D=3D &invalid_handler) { > + continue; > + } > + if (is_indirect_opcode(table[j])) { > + table_2 =3D ind_table(table[j]); > + for (k =3D 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++)= { > + if (table_2[k] !=3D &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] & --=20 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 --4fo3mGi7Q6pk/+I3 Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJXmEcWAAoJEGw4ysog2bOS9hcQAKDgv5o1zbuytw4wiM8XLFXF F+Iv+z3U9kvYL51y87N9amtjNhEBJQK3O1UMrLdw7GeQWZsTYEwZlidlSex9RWro Z4LJpT16fWlxdzTYQXDmiFlovM7f4AdlZ3eFQZETQA2nvXNXp2rhIWMC8m7KtOKV jPnbOMI1Ml7Fcp502Xo/9+yb5TrBFIyzMjBFQg+jaXeikewTqGkKtWxx/bBcU5/Y i9xggEuSgjOTO80CR6Ou4oBVdaB8bB+C/UZzlbDvkjCuSROMm2sDalPwmMdEt7M6 zyScg3EkA79Cn+jHllSgI4NLx78BZ4s03o8SHo9UsjHdEaFnCI4H4ub5OJqcUoHd O6eFXeOquIfNdazwedkiIUiKyd3B+y6+aNstS5+2uwzr2BHJP1kO+Eh7Xe0VxIxR wu8rbggk9sPMvEF7Jg5jUPAuIBpzNcCNSO7+SmRday1l4ZV3CBnWN62fYJ1xc3uQ IUw5IfaZahWjzOXfbdwkpS9Q47yecOV2mlafgHNrmGPP/0Xsralu06k3xtvRHjer YWnATNQsjuROyUnVaZdwGI0Qz/WQOYnLmZ+i9L8VYSwt73CgINI8zxsueKQPnLod ZLj1saEmV8ZcOSWdVAsu5ipeeXGw6ewA7BNnVQr8e2kzL3zzrOORpDm2WWo5lwrO 8U3Fk18cZKPt5b4TZZZU =lpkT -----END PGP SIGNATURE----- --4fo3mGi7Q6pk/+I3--