From: Olivier Danet <odanet@caramail.com>
To: qemu-devel <qemu-devel@nongnu.org>,
Blue Swirl <blauwirbel@gmail.com>,
Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Subject: [Qemu-devel] [PATCH] sparc32 : Signed integer division overflow
Date: Wed, 12 Mar 2014 22:26:55 +0100 [thread overview]
Message-ID: <5320D11F.3060703@caramail.com> (raw)
I wanted to test an integer divider for SPARC32, and tried the stress
test program on QEMU, which choked on the division
-0x8000_0000_0000_0000 / -1 (QEMU compiled on x86_64).
Excerpt from the test program :
-------------------------------------------------------------------
#include <stdio.h>
typedef unsigned uint32;
typedef unsigned long long uint64;
typedef signed int32;
typedef signed long long int64;
void sdiv(int64 x, int32 y, int32 *q, uint32 *ov)
{
uint32 a,b,c,d,e;
a=x>>32;
b=x;
c=y;
__asm__ __volatile__("wr %2,%%y\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"sdivcc %3,%4,%0\n\t"
"or %%r0,0,%1\n\t"
"bvc xxa\n\t"
"nop\n\t"
"add %1,1,%1\n\t"
"xxa:bpos xxb\n\t"
"nop\n\t"
"add %1,2,%1\n\t"
"xxb:bne xxc\n\t"
"nop\n\t"
"add %1,4,%1\n\t"
"xxc:nop\n\t"
: "=r"(d),"=r"(e):"r"(a),"r"(b),"r"(c)
);
*q=d;
*ov=e & 1;
}
void main(void)
{
uint64 x;
uint32 y;
int32 q;
int32 ov;
x = 1LL << 63;
y = -1;
sdiv(x, y, &q, &ov);
}
Here is a patch for handling this corner case on SPARC32.
SPARC64 division already checks this in helper_sdivx(), some other
architectures
seem to do the same (for example, target-arm/helper.c: HELPER(sdiv))
===================================================================
The integer division 0x8000_0000_0000_0000 / -1 must be handled separately
to avoid overflows on the QEMU host.
Signed-off-by: Olivier Danet <odanet@caramail.com>
-------------------------------------------------------------------
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 57c20af..b6b5937 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -116,14 +116,16 @@ static target_ulong
helper_sdiv_common(CPUSPARCState *env, target_ulong a,
if (x1 == 0) {
cpu_restore_state(env, GETPC());
helper_raise_exception(env, TT_DIV_ZERO);
- }
-
- x0 = x0 / x1;
- if ((int32_t) x0 != x0) {
- x0 = x0 < 0 ? 0x80000000 : 0x7fffffff;
+ } else if (x1 == -1 && x0 == 0x8000000000000000) {
+ x0 = 0x7fffffff;
overflow = 1;
+ } else {
+ x0 = x0 / x1;
+ if ((int32_t) x0 != x0) {
+ x0 = x0 < 0 ? 0x80000000 : 0x7fffffff;
+ overflow = 1;
+ }
}
-
if (cc) {
env->cc_dst = x0;
env->cc_src2 = overflow;
-------------------------------------------------------------------
next reply other threads:[~2014-03-12 21:25 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-12 21:26 Olivier Danet [this message]
2014-03-18 0:20 ` [Qemu-devel] [PATCH] sparc32 : Signed integer division overflow Mark Cave-Ayland
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=5320D11F.3060703@caramail.com \
--to=odanet@caramail.com \
--cc=blauwirbel@gmail.com \
--cc=mark.cave-ayland@ilande.co.uk \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.