From patchwork Tue Jun 7 10:47:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 631508 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rP8pt4xZ9z9rxl for ; Tue, 7 Jun 2016 21:43:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b=gX4qZa/x; dkim-atps=neutral Received: from localhost ([::1]:48828 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bAFQC-0004VT-Sj for incoming@patchwork.ozlabs.org; Tue, 07 Jun 2016 07:43:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46451) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bAEZ2-0007Rq-3Y for qemu-devel@nongnu.org; Tue, 07 Jun 2016 06:48:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bAEYx-0005I8-Ix for qemu-devel@nongnu.org; Tue, 07 Jun 2016 06:48:51 -0400 Received: from ozlabs.org ([103.22.144.67]:37278) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bAEYx-0005Hx-7x; Tue, 07 Jun 2016 06:48:47 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3rP7Zm0s3rz9sXR; Tue, 7 Jun 2016 20:48:16 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1465296496; bh=g6Qs8a4dbKR7sMAwsY9xQwQa3ibWNSxccACY4oFjpXU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gX4qZa/xzy2GRCq7Zuki6/wgJNo0pt9CS+izFL3D9r8hPmrKayhOwxbiWLJjXAher hnlK3iBF6X10XVzZ6k0O2g9pY2Spd0VE1+/vxHzBTYlhFAlIcj7w028GEdZxTZxiy3 hOdjs5/P5AqqCLU/Yf6LHhfv1ts7z1LXRTu3FqW0= From: David Gibson To: peter.maydell@linaro.org Date: Tue, 7 Jun 2016 20:47:48 +1000 Message-Id: <1465296493-10851-2-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1465296493-10851-1-git-send-email-david@gibson.dropbear.id.au> References: <1465296493-10851-1-git-send-email-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PULL 01/26] target-ppc/fpu_helper: Fix efscmp* instructions handling 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: , Cc: Talha Imran , David Gibson , qemu-ppc@nongnu.org, agraf@suse.de, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Talha Imran With specification at hand from the reference manual from Freescale http://cache.nxp.com/files/32bit/doc/ref_manual/SPEPEM.pdf , I have found a fix to efscmp* instructions handling in QEMU. efscmp* instructions in QEMU set crD (Condition Register nibble) values as (0b0100 << 2) = 0b10000 (consider the HELPER_SINGLE_SPE_CMP macro which left shifts the value returned by efscmp* handler 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 0bx1xx. Please find attached a patch which disables left shifting in HELPER_SINGLE_SPE_CMP macro. This macro is used by efscmp* and efstst* instructions only. efstst* instruction handlers, in turn, call efscmp* handlers too. *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 Signed-off-by: Talha Imran Signed-off-by: David Gibson --- target-ppc/fpu_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index b67ebca..6fd56a8 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1442,7 +1442,7 @@ static inline uint32_t efststeq(CPUPPCState *env, uint32_t op1, uint32_t op2) #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);