qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Talha Imran <talha_imran@mentor.com>
Cc: agraf@suse.de, qemu-trivial@nongnu.org, qemu-ppc@nongnu.org,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [Qemu-ppc] [PATCH] target-ppc/fpu_helper: Fix efscmp* instructions handling
Date: Fri, 27 May 2016 11:37:14 +1000	[thread overview]
Message-ID: <20160527013714.GP17226@voom.fritz.box> (raw)
In-Reply-To: <1463659895-16281-1-git-send-email-talha_imran@mentor.com>

[-- Attachment #1: Type: text/plain, Size: 3437 bytes --]

On Thu, May 19, 2016 at 05:11:35PM +0500, Talha Imran wrote:
> 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 <bar+60>  //jump to abort() call
> 100004a8:   lwz r10,12(r31)
> 100004ac:   lis r9,16512
> 100004b0:   efscmpeq cr7,r10,r9
> 100004b4:   bgt- cr7,0x100004bc <bar+64>  //skip abort() call
> 28            abort ();
> 100004b8:   bl 0x10000808 <abort>
> 
> Signed-off-by: Talha Imran <talha_imran@mentor.com>

Does this patch supersede the earlier patch you posted for efcmp
instructions on e500v1?  Or is it in addition to that patch?

> ---
>  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);

-- 
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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2016-05-27  1:39 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-19 12:11 [Qemu-devel] [PATCH] target-ppc/fpu_helper: Fix efscmp* instructions handling Talha Imran
2016-05-27  1:37 ` David Gibson [this message]
2016-05-27  7:43   ` [Qemu-devel] [Qemu-ppc] " Imran, Talha
2016-06-01  6:24     ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160527013714.GP17226@voom.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=agraf@suse.de \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=qemu-trivial@nongnu.org \
    --cc=talha_imran@mentor.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).