From: Julian Seward <jseward@acm.org>
To: Aurelien Jarno <aurelien@aurel32.net>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] ppc32 guests: fix computation of XER.{CA, OV} in addme, subfme, mullwo
Date: Wed, 18 Jun 2008 00:06:51 +0200 [thread overview]
Message-ID: <200806180006.51954.jseward@acm.org> (raw)
In-Reply-To: <20080617122746.GA23769@volta.aurel32.net>
On Tuesday 17 June 2008 14:27, Aurelien Jarno wrote:
> On Sun, May 11, 2008 at 02:04:47AM +0200, Julian Seward wrote:
> > For ppc32 guests, computation of XER.CA and XER.OV in some obscure
> > cases is incorrect. At least, it doesn't produce the same results
> > as a real MPC7447, and doesn't appear to be in accordance with the
> > instruction set documentation.
> >
> > The attached patch fixes it:
> >
> > * addme{o}{.}, subfme{o}{.}: compute XER.CA correctly
> >
> > * mullwo{.}: sign extend arguments before doing 64-bit
> > multiply, so as to make the XER.OV computation correct
>
> Could you please give us a corner case for at least one of the
> instructions? It would help to clearly understand the problem.
Below is a test case showing the problem with mullwo, addme and
subfme. On a real 7447 it prints
mullwo. 000f423f ffffffff = fff0bdc1 (cr 80000000 xer 00000000)
addme 00000000 XER.CA=1 = 00000000 (cr 00000000 xer 20000000)
subfme 00000000 XER.CA=1 = ffffffff (cr 00000000 xer 20000000)
On QEMU, unpatched, both the result cr and xer are wrong for
mullwo., and the xer values are wrong for addme and subfme.
mullwo. 000f423f ffffffff = fff0bdc1 (cr 90000000 xer c0000000)
addme 00000000 XER.CA=1 = 00000000 (cr 00000000 xer 00000000)
subfme 00000000 XER.CA=1 = ffffffff (cr 00000000 xer 00000000)
On QEMU, with patch applied, result is same as on 7447.
mullwo. 000f423f ffffffff = fff0bdc1 (cr 80000000 xer 00000000)
addme 00000000 XER.CA=1 = 00000000 (cr 00000000 xer 20000000)
subfme 00000000 XER.CA=1 = ffffffff (cr 00000000 xer 20000000)
J
/* Compiled with "gcc -Wall -g -O -o ppcbad ppcbad.c" */
#include <stdio.h>
#include <string.h>
typedef unsigned int UInt;
/* At entry, res[0] and res[1] contain 2 args to "mullwo.". At exit,
res[0] holds result, res[1] holds resulting %cr, and res[2] holds
resulting %xer. */
void do_mullwo_dot ( UInt* res )
{
__asm__ __volatile__(
"\tmr 29,%0\n"
"\tli 25,0\n"
"\tmtxer 25\n"
"\tmtcr 25\n"
"\tlwz 21,0(29)\n"
"\tlwz 22,4(29)\n"
"\tmullwo. 23,21,22\n"
"\tstw 23,0(29)\n"
"\tmfcr 25\n"
"\tstw 25,4(29)\n"
"\tmfxer 25\n"
"\tstw 25,8(29)\n"
: /*OUT*/ : /*IN*/"b"(res) : /*trash*/ "r29","r25","r21","r22","r23",
"memory","cc"
);
}
/* At entry, res[0] contain 1 arg to "addme". Set XER.CA=1. At exit,
res[0] holds result, res[1] holds resulting %cr, and res[2] holds
resulting %xer. */
void do_addme ( UInt* res )
{
__asm__ __volatile__(
"\tmr 29,%0\n"
"\tli 25,0\n"
"\tmtcr 25\n"
"\tlis 25,0x2000\n"
"\tmtxer 25\n" // set XER.CA=1
"\tlwz 21,0(29)\n"
"\taddme 23,21\n"
"\tstw 23,0(29)\n"
"\tmfcr 25\n"
"\tstw 25,4(29)\n"
"\tmfxer 25\n"
"\tstw 25,8(29)\n"
: /*OUT*/ : /*IN*/"b"(res) : /*trash*/ "r29","r25","r21","r22","r23",
"memory","cc"
);
}
/* At entry, res[0] contain 1 arg to "subfme". Set XER.CA=1. At exit,
res[0] holds result, res[1] holds resulting %cr, and res[2] holds
resulting %xer. */
void do_subfme ( UInt* res )
{
__asm__ __volatile__(
"\tmr 29,%0\n"
"\tli 25,0\n"
"\tmtcr 25\n"
"\tlis 25,0x2000\n"
"\tmtxer 25\n" // set XER.CA=1
"\tlwz 21,0(29)\n"
"\tsubfme 23,21\n"
"\tstw 23,0(29)\n"
"\tmfcr 25\n"
"\tstw 25,4(29)\n"
"\tmfxer 25\n"
"\tstw 25,8(29)\n"
: /*OUT*/ : /*IN*/"b"(res) : /*trash*/ "r29","r25","r21","r22","r23",
"memory","cc"
);
}
UInt zzz ( void ) { return 0x20000000; }
int main ( void )
{
UInt arr[3];
/* Try mullwo. */
arr[0] = 0x000f423f;
arr[1] = 0xffffffff;
arr[2] = 0;
do_mullwo_dot(&arr[0]);
printf("mullwo. 000f423f ffffffff = %08x (cr %08x xer %08x)\n",
arr[0],arr[1],arr[2]);
/* Try addme */
arr[0] = 0;
arr[1] = 0;
arr[2] = 0;
do_addme(&arr[0]);
printf("addme 00000000 XER.CA=1 = %08x (cr %08x xer %08x)\n",
arr[0],arr[1],arr[2]);
/* Try subfme */
arr[0] = 0;
arr[1] = 0;
arr[2] = 0;
do_subfme(&arr[0]);
printf("subfme 00000000 XER.CA=1 = %08x (cr %08x xer %08x)\n",
arr[0],arr[1],arr[2]);
return 0;
}
next prev parent reply other threads:[~2008-06-17 22:13 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-11 0:04 [Qemu-devel] [PATCH] ppc32 guests: fix computation of XER.{CA, OV} in addme, subfme, mullwo Julian Seward
2008-06-17 12:27 ` Aurelien Jarno
2008-06-17 22:06 ` Julian Seward [this message]
2008-06-17 22:53 ` J. Mayer
2008-06-17 23:23 ` Julian Seward
2008-06-18 21:32 ` J. Mayer
2008-06-18 21:39 ` Julian Seward
2008-06-18 22:09 ` J. Mayer
2008-06-18 22:13 ` Tristan Gingold
2008-06-19 7:36 ` Julian Seward
2008-06-19 8:36 ` Tristan Gingold
2008-06-19 9:12 ` J. Mayer
2008-10-01 21:47 ` Aurelien Jarno
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=200806180006.51954.jseward@acm.org \
--to=jseward@acm.org \
--cc=aurelien@aurel32.net \
--cc=qemu-devel@nongnu.org \
/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).