From patchwork Wed May 18 08:04:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Imran, Talha" X-Patchwork-Id: 9116681 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 96431BF29F for ; Wed, 18 May 2016 08:05:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A27E9202EC for ; Wed, 18 May 2016 08:05:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A0222202AE for ; Wed, 18 May 2016 08:05:10 +0000 (UTC) Received: from localhost ([::1]:43519 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2wTd-0005U1-GB for patchwork-qemu-devel@patchwork.kernel.org; Wed, 18 May 2016 04:05:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56384) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2wTG-0005Pp-QH for qemu-devel@nongnu.org; Wed, 18 May 2016 04:04:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b2wTE-0005wE-DS for qemu-devel@nongnu.org; Wed, 18 May 2016 04:04:45 -0400 Received: from relay1.mentorg.com ([192.94.38.131]:48360) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b2wT6-0005sU-Kk; Wed, 18 May 2016 04:04:36 -0400 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1b2wSs-0007hb-MB from Talha_Imran@mentor.com ; Wed, 18 May 2016 01:04:23 -0700 Received: from EU-MBX-02.mgc.mentorg.com ([169.254.3.121]) by SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) with mapi id 14.03.0224.002; Wed, 18 May 2016 09:04:21 +0100 From: "Imran, Talha" To: "qemu-ppc@nongnu.org" , "qemu-devel@nongnu.org" , "qemu-trivial@nongnu.org" Thread-Topic: [PATCH] Fix QEMU PPC e500v1 efscmp* instructions Thread-Index: AQHRqr9BoGiDdbboj0abVCg4qfVMbJ+2Q4r1gADO1wCABQUwMIACSYmg Date: Wed, 18 May 2016 08:04:21 +0000 Message-ID: <3052678E9DA67D4CB879A6625EE42075274B5F9D@EU-MBX-02.mgc.mentorg.com> References: <3052678E9DA67D4CB879A6625EE42075274B5092@EU-MBX-02.mgc.mentorg.com>, <3052678E9DA67D4CB879A6625EE42075274B5912@EU-MBX-02.mgc.mentorg.com>, <3052678E9DA67D4CB879A6625EE42075274B5A3C@EU-MBX-02.mgc.mentorg.com>, <3052678E9DA67D4CB879A6625EE42075274B5D82@EU-MBX-02.mgc.mentorg.com> In-Reply-To: <3052678E9DA67D4CB879A6625EE42075274B5D82@EU-MBX-02.mgc.mentorg.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: x-originating-ip: [137.202.0.69] MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 X-Content-Filtered-By: Mailman/MimeDel 2.1.21 Subject: Re: [Qemu-devel] [PATCH] Fix QEMU PPC e500v1 efscmp* instructions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP With more information at hand with the reference manual from Freescale http://cache.nxp.com/files/32bit/doc/ref_manual/SPEPEM.pdf , I was able to revisit my patch and figure out what is actually going on. Before applying any patch, efscmp* instructions in QEMU set crD values as (0b0100 << 2) = 0b10000 (consider the HELPER_SINGLE_SPE_CMP macro which left shifts the value returned by efscmp* instruction by 2 bits). A value of 0b10000 is not correct according the to the reference manual. The reference manual expects efscmp* instructions to return a value of 0b0100. Please find attached an updated patch qemu-patch-5 which disables left shifting in HELPER_SINGLE_SPE_CMP macro. This macro is used by efscmp* and efstst* instructions only. efstst* instruction handlers call efscmp* handlers. *Explanation:* Traditionally, each crD (condition register nibble) consist of 4 bits, which is set by comparisons as follows: crD = W X Y Z where W = Less than X = Greater than Y = Equal to However, efscmp* instructions being a special case return a binary result. (efscmpeq will set the crD = 0bx1xx iff when op1 == op2 and 0bx0xx otherwise; i.e. there is no notion of different crD values based on Less than, Greater than and Equal to). This effectively means that crD will store a "Greater than" comparison result iff efscmp* instruction comparison is TRUE. Compiler exploits this feature by checking for "Branch if Less than or Equal to" (ble instruction) OR "Branch if Greater than" (bgt instruction) for Branch if FALSE OR Branch if TRUE respectively after an efscmp* instruction. This can be seen in a assembly code snippet below: 27 if (__real__ x != 3.0f || __imag__ x != 4.0f) 10000498: lwz r10,8(r31) 1000049c: lis r9,16448 100004a0: efscmpeq cr7,r10,r9 100004a4: ble- cr7,0x100004b8 //jump to abort() call 100004a8: lwz r10,12(r31) 100004ac: lis r9,16512 100004b0: efscmpeq cr7,r10,r9 100004b4: bgt- cr7,0x100004bc //skip abort() call 28 abort (); 100004b8: bl 0x10000808 Comments and suggestions are welcome. -Talha Index: src/qemu-2.2-2015.17/target-ppc/fpu_helper.c =================================================================== --- src/qemu-2.2-2015.17/target-ppc/fpu_helper.c (revision 463967) +++ src/qemu-2.2-2015.17/target-ppc/fpu_helper.c (working copy) @@ -1437,7 +1437,7 @@ #define HELPER_SINGLE_SPE_CMP(name) \ uint32_t helper_e##name(CPUPPCState *env, uint32_t op1, uint32_t op2) \ { \ - return e##name(env, op1, op2) << 2; \ + return e##name(env, op1, op2); \ } /* efststlt */ HELPER_SINGLE_SPE_CMP(fststlt);