From patchwork Tue Sep 18 19:52:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: malc X-Patchwork-Id: 184818 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id F0A9A2C0091 for ; Wed, 19 Sep 2012 05:52:42 +1000 (EST) Received: from localhost ([::1]:59604 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TE3qb-00089R-3F for incoming@patchwork.ozlabs.org; Tue, 18 Sep 2012 15:52:41 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37700) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TE3qT-00088l-Ns for qemu-devel@nongnu.org; Tue, 18 Sep 2012 15:52:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TE3qS-0000kc-GI for qemu-devel@nongnu.org; Tue, 18 Sep 2012 15:52:33 -0400 Received: from fe02x03-cgp.akado.ru ([77.232.31.165]:62897 helo=akado.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TE3qR-0000jj-W8 for qemu-devel@nongnu.org; Tue, 18 Sep 2012 15:52:32 -0400 Received: from [10.0.66.9] ([10.0.66.9] verified) by fe02-cgp.akado.ru (CommuniGate Pro SMTP 5.2.13) with ESMTPS id 286923558; Tue, 18 Sep 2012 23:52:28 +0400 Date: Tue, 18 Sep 2012 23:52:21 +0400 (MSK) From: malc X-X-Sender: malc@linmac To: qemu-devel@nongnu.org Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 77.232.31.165 Cc: Max Filippov , Richard Henderson Subject: [Qemu-devel] Shifts, ppc[64], xtensa X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Looks like PPC/PPC64 is also hit by shift issues, on top of that xtensa exposed another bug in power's tcg - gototb's target was expected to be always filled via tb_set_jmp_target (even though it's clearly not what tcg/README prescribes, sorry about that). Thanks to Max Filippov for pointing to xtensa test suite that helped to narrow the search to gototb. Testing of the following with other targets on ppc flavours is welcome.. P.S. Xtensa does mighty weird things with shifts i must say... diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 26c4b33..08f62fa 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -409,6 +409,7 @@ static int tcg_target_const_match(tcg_target_long val, #define TW XO31(4) #define TRAP (TW | TO (31)) +#define NOP 0x60000000 #define RT(r) ((r)<<21) #define RS(r) ((r)<<21) @@ -1306,10 +1307,10 @@ void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr) *ptr = 0x48000000 | (disp & 0x03fffffc); /* b disp */ patch_size = 4; } else { - ptr[0] = 0x60000000; /* nop */ - ptr[1] = 0x60000000; - ptr[2] = 0x60000000; - ptr[3] = 0x60000000; + ptr[0] = NOP; + ptr[1] = NOP; + ptr[2] = NOP; + ptr[3] = NOP; patch_size = 16; } } @@ -1330,7 +1331,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, /* direct jump method */ s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; - s->code_ptr += 16; + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); } else { tcg_abort (); @@ -1565,12 +1569,16 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, case INDEX_op_shl_i32: if (const_args[2]) { + if (args[2] > 31) { + tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); + tcg_out32 (s, SLW | SAB (args[1], args[0], 0)); + } tcg_out32 (s, (RLWINM | RA (args[0]) | RS (args[1]) - | SH (args[2]) + | SH (args[2] & 31) | MB (0) - | ME (31 - args[2]) + | ME (31 - (args[2] & 31)) ) ); } @@ -1579,21 +1587,35 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, break; case INDEX_op_shr_i32: if (const_args[2]) { - tcg_out32 (s, (RLWINM - | RA (args[0]) - | RS (args[1]) - | SH (32 - args[2]) - | MB (args[2]) - | ME (31) - ) - ); + if (args[2] > 31) { + tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); + tcg_out32 (s, SRW | SAB (args[1], args[0], 0)); + } + else { + tcg_out32 (s, (RLWINM + | RA (args[0]) + | RS (args[1]) + | SH (32 - args[2]) + | MB (args[2]) + | ME (31) + ) + ); + } } - else + else { tcg_out32 (s, SRW | SAB (args[1], args[0], args[2])); + } break; case INDEX_op_sar_i32: - if (const_args[2]) - tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2])); + if (const_args[2]) { + if (args[2] > 31) { + tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); + tcg_out32 (s, SRAW | SAB (args[1], args[0], 0)); + } + else { + tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2])); + } + } else tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2])); break; @@ -1604,7 +1626,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, | RS (args[1]) | MB (0) | ME (31) - | (const_args[2] ? RLWINM | SH (args[2]) + | (const_args[2] ? RLWINM | SH (args[2] & 31) : RLWNM | RB (args[2])) ; tcg_out32 (s, op); @@ -1619,7 +1641,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, tcg_out32 (s, RLWINM | RA (args[0]) | RS (args[1]) - | SH (32 - args[2]) + | SH (32 - (args[2] & 31)) | MB (0) | ME (31) ); diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index 337cd41..5da7dc4 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -390,6 +390,7 @@ static int tcg_target_const_match (tcg_target_long val, #define TW XO31( 4) #define TRAP (TW | TO (31)) +#define NOP 0x60000000 #define RT(r) ((r)<<21) #define RS(r) ((r)<<21) @@ -1225,7 +1226,13 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, /* direct jump method */ s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; - s->code_ptr += 28; + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); + tcg_out32 (s, NOP); } else { tcg_abort (); @@ -1430,21 +1437,36 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args, break; case INDEX_op_shr_i32: if (const_args[2]) { - tcg_out32 (s, (RLWINM - | RA (args[0]) - | RS (args[1]) - | SH (32 - args[2]) - | MB (args[2]) - | ME (31) - ) - ); + if (args[2] > 31) { + tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); + tcg_out32 (s, SRW | SAB (args[1], args[0], 0)); + } + else { + tcg_out32 (s, (RLWINM + | RA (args[0]) + | RS (args[1]) + | SH (32 - args[2]) + | MB (args[2]) + | ME (31) + ) + ); + } } - else + else { tcg_out32 (s, SRW | SAB (args[1], args[0], args[2])); + } + break; break; case INDEX_op_sar_i32: - if (const_args[2]) - tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2])); + if (const_args[2]) { + if (args[2] > 31) { + tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]); + tcg_out32 (s, SRAW | SAB (args[1], args[0], 0)); + } + else { + tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2])); + } + } else tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2])); break;