From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K6lzU-0005rK-1x for qemu-devel@nongnu.org; Thu, 12 Jun 2008 08:33:20 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K6lzS-0005q0-OS for qemu-devel@nongnu.org; Thu, 12 Jun 2008 08:33:19 -0400 Received: from [199.232.76.173] (port=56256 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K6lzS-0005pq-Ja for qemu-devel@nongnu.org; Thu, 12 Jun 2008 08:33:18 -0400 Received: from savannah.gnu.org ([199.232.41.3]:34605 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1K6lzS-0005yN-0B for qemu-devel@nongnu.org; Thu, 12 Jun 2008 08:33:18 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1K6lzL-0007dJ-Rz for qemu-devel@nongnu.org; Thu, 12 Jun 2008 12:33:12 +0000 Received: from malc by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1K6lzL-0007dF-AT for qemu-devel@nongnu.org; Thu, 12 Jun 2008 12:33:11 +0000 MIME-Version: 1.0 Errors-To: malc Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: malc Message-Id: Date: Thu, 12 Jun 2008 12:33:11 +0000 Subject: [Qemu-devel] [4738] Reimplement brcond2 and refactor brcond Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 4738 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4738 Author: malc Date: 2008-06-12 12:33:10 +0000 (Thu, 12 Jun 2008) Log Message: ----------- Reimplement brcond2 and refactor brcond Modified Paths: -------------- trunk/tcg/ppc/tcg-target.c Modified: trunk/tcg/ppc/tcg-target.c =================================================================== --- trunk/tcg/ppc/tcg-target.c 2008-06-12 03:17:06 UTC (rev 4737) +++ trunk/tcg/ppc/tcg-target.c 2008-06-12 12:33:10 UTC (rev 4738) @@ -282,9 +282,12 @@ #define RLWINM OPCD(21) -#define BCLR XO19(16) +#define BCLR XO19( 16) #define BCCTR XO19(528) #define CRAND XO19(257) +#define CRANDC XO19(129) +#define CRNAND XO19(225) +#define CROR XO19(449) #define EXTSB XO31(954) #define EXTSH XO31(922) @@ -870,11 +873,9 @@ ppc_addi (s, reg, reg, val); } -static void tcg_out_brcond(TCGContext *s, int cond, - TCGArg arg1, TCGArg arg2, int const_arg2, - int label_index) +static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2, + int const_arg2, int cr) { - TCGLabel *l = &s->labels[label_index]; int imm; uint32_t op; @@ -930,7 +931,7 @@ default: tcg_abort (); } - op |= BF (7); + op |= BF (cr); if (imm) tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff)); @@ -943,79 +944,79 @@ tcg_out32 (s, op | RA (arg1) | RB (arg2)); } +} + +static void tcg_out_bc (TCGContext *s, int bc, int label_index) +{ + TCGLabel *l = &s->labels[label_index]; + if (l->has_value) - tcg_out32 (s, tcg_to_bc[cond] | reloc_pc14_val (s->code_ptr, - l->u.value)); + tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value)); else { uint16_t val = *(uint16_t *) &s->code_ptr[2]; /* Thanks to Andrzej Zaborowski */ - tcg_out32 (s, tcg_to_bc[cond] | (val & 0xfffc)); + tcg_out32 (s, bc | (val & 0xfffc)); tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0); } } -/* brcond2 is taken verbatim from i386 tcg-target */ +static void tcg_out_brcond (TCGContext *s, int cond, + TCGArg arg1, TCGArg arg2, int const_arg2, + int label_index) +{ + tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7); + tcg_out_bc (s, tcg_to_bc[cond], label_index); +} + /* XXX: we implement it at the target level to avoid having to handle cross basic blocks temporaries */ -static void tcg_out_brcond2(TCGContext *s, - const TCGArg *args, const int *const_args) +static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args, + const int *const_args) { - int label_next; - label_next = gen_new_label(); - switch(args[4]) { + int cond = args[4], label_index = args[5], op; + struct { int bit1; int bit2; int cond2; } bits[] = { + [TCG_COND_LT ] = { CR_LT, CR_LT, TCG_COND_LT }, + [TCG_COND_LE ] = { CR_LT, CR_GT, TCG_COND_LT }, + [TCG_COND_GT ] = { CR_GT, CR_GT, TCG_COND_GT }, + [TCG_COND_GE ] = { CR_GT, CR_LT, TCG_COND_GT }, + [TCG_COND_LTU] = { CR_LT, CR_LT, TCG_COND_LTU }, + [TCG_COND_LEU] = { CR_LT, CR_GT, TCG_COND_LTU }, + [TCG_COND_GTU] = { CR_GT, CR_GT, TCG_COND_GTU }, + [TCG_COND_GEU] = { CR_GT, CR_LT, TCG_COND_GTU }, + }, *b = &bits[cond]; + + switch (cond) { case TCG_COND_EQ: - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], label_next); - tcg_out_brcond(s, TCG_COND_EQ, args[1], args[3], const_args[3], args[5]); + tcg_out_cmp (s, TCG_COND_EQ, args[0], args[2], const_args[2], 6); + tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 7); + tcg_out32 (s, CRAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); break; case TCG_COND_NE: - tcg_out_brcond(s, TCG_COND_NE, args[0], args[2], const_args[2], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], args[5]); + tcg_out_cmp (s, TCG_COND_NE, args[0], args[2], const_args[2], 6); + tcg_out_cmp (s, TCG_COND_NE, args[1], args[3], const_args[3], 7); + tcg_out32 (s, CRNAND | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, CR_EQ)); break; case TCG_COND_LT: - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LT, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_LE: - tcg_out_brcond(s, TCG_COND_LT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LE, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GT: - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GT, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GE: - tcg_out_brcond(s, TCG_COND_GT, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GE, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_LTU: - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LTU, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_LEU: - tcg_out_brcond(s, TCG_COND_LTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_LEU, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GTU: - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GTU, args[0], args[2], const_args[2], args[5]); - break; case TCG_COND_GEU: - tcg_out_brcond(s, TCG_COND_GTU, args[1], args[3], const_args[3], args[5]); - tcg_out_brcond(s, TCG_COND_NE, args[1], args[3], const_args[3], label_next); - tcg_out_brcond(s, TCG_COND_GEU, args[0], args[2], const_args[2], args[5]); + op = (b->bit1 != b->bit2) ? CRANDC : CRAND; + tcg_out_cmp (s, b->cond2, args[1], args[3], const_args[3], 5); + tcg_out_cmp (s, TCG_COND_EQ, args[1], args[3], const_args[3], 6); + tcg_out_cmp (s, cond, args[0], args[2], const_args[2], 7); + tcg_out32 (s, op | BT (7, CR_EQ) | BA (6, CR_EQ) | BB (7, b->bit2)); + tcg_out32 (s, CROR | BT (7, CR_EQ) | BA (5, b->bit1) | BB (7, CR_EQ)); break; default: tcg_abort(); } - tcg_out_label(s, label_next, (tcg_target_long)s->code_ptr); + + tcg_out_bc (s, (BC | BI (7, CR_EQ) | BO_COND_TRUE), label_index); } static void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,