qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* Re: [Qemu-devel] [PATCH] SPARC target : Fix carry flagupdate inaddxcc and subxc
@ 2006-04-13 18:39 Blue Swirl
  2006-04-13 21:14 ` Even Rouault
  0 siblings, 1 reply; 3+ messages in thread
From: Blue Swirl @ 2006-04-13 18:39 UTC (permalink / raw)
  To: even.rouault, qemu-devel

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

>As far as the V flag is concerned, mmm, I'm not really sure whether we 
>should
>change something in the sparc code. If we compare to the arm code, we don't
>take into account the fact that the carry flag is set before.
>
>We'd probably need some extensive tests and their associated expected 
>results.

I made a small test program (attached) to test the addx instruction. The 
program calculates the sum of two 64-bit values, given on the command line 
as 32-bit lower and upper parts.  Native system produces following:
$ ./addx -1 -1 0x80000000 -1
ffffffffffffffff + ffffffff80000000 = ffffffff7fffffff, NZVC: 9
while unpatched Qemu the following:
$ qemu-sparc ./addx -1 -1 0x80000000 -1
ffffffffffffffff + ffffffff80000000 = ffffffff7fffffff, NZVC: 8

So the carry flag not set. When your patch is applied, the output is 
identical:
ffffffffffffffff + ffffffff80000000 = ffffffff7fffffff, NZVC: 9

I couldn't think of a combination of values that would set the V flag when 
there is also a carry from the 32-bit addition, any suggestions?

_________________________________________________________________
FREE pop-up blocking with the new MSN Toolbar - get it now! 
http://toolbar.msn.click-url.com/go/onm00200415ave/direct/01/

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: addx.c --]
[-- Type: text/x-csrc; name="addx.c", Size: 1195 bytes --]

#include <stdlib.h>
#include <stdio.h>

void addx_test(unsigned int a, unsigned int b, unsigned int c, unsigned int d)
{
    int flags, result1, result2;

    asm ("addcc %3,%5,%1\n\t"
         "addxcc %4,%6,%2\n\t"
         "mov 0, %0\n\t"
         "bcc 1f\n\t"
         " nop\n\t"
         "mov 1, %0\n\t"
         "1: \n\t"
         "bvc 1f\n\t"
         " nop\n\t"
         "or %0, 2, %0\n\t"
         "1: \n\t"
         "bnz 1f\n\t"
         " nop\n\t"
         "or %0, 4, %0\n\t"
         "1: \n\t"
         "bpos 1f\n\t"
         " nop\n\t"
         "or %0, 8, %0\n\t"
         "1: \n\t"
         : "=r" (flags), "=r" (result1), "=r" (result2) : "r" (a), "r" (b), "r" (c), "r" (d));
    printf("%llx + %llx = %llx, NZVC: %d\n", ((long long)b << 32) | (long long)a, 
           ((long long)d << 32) | (long long)c,
           ((long long)result2 << 32) | (long long)result1,
           flags);
}

int main(int argc, const char **argv)
{
    unsigned int a, b, c, d;

    if (argc != 5)
        return 1;
    a = strtoul(argv[1], NULL, 0);
    b = strtoul(argv[2], NULL, 0);
    c = strtoul(argv[3], NULL, 0);
    d = strtoul(argv[4], NULL, 0);
    addx_test(a, b, c, d);

    return 0;
}


^ permalink raw reply	[flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH] SPARC target : Fix carry flagupdate inaddxcc and subxc
@ 2006-04-14  7:01 Blue Swirl
  0 siblings, 0 replies; 3+ messages in thread
From: Blue Swirl @ 2006-04-14  7:01 UTC (permalink / raw)
  To: even.rouault, qemu-devel

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

>Conclusion : the computation of the V flag in qemu is correct, and their is 
>no special case to consider if the C flag is set or not  :-)
>For tomorrow, the formal proof of the correctness of the whole qemu code 
>;-)

Thanks for the superb analysis!

Now it's time to check if real hardware works according to theory.

In this addition, there is a carry from lower 32 bits as well as sign 
change:
./addx -1 0x7fffffff 1 0
7fffffffffffffff + 1 = 8000000000000000, NZVC: 10
qemu-sparc ./addx  -1 0x7fffffff  1 0
7fffffffffffffff + 1 = 8000000000000000, NZVC: 10

Here, no carry:
./addx -1 0x7fffffff 0 1
7fffffffffffffff + 100000000 = 80000000ffffffff, NZVC: 10
qemu-sparc ./addx  -1 0x7fffffff 0 1
7fffffffffffffff + 100000000 = 80000000ffffffff, NZVC: 10

Another case:
./addx 0 0x80000000 0 0x80000000
8000000000000000 + 8000000000000000 = 0, NZVC: 7
qemu-sparc ./addx 0 0x80000000 0 0x80000000
8000000000000000 + 8000000000000000 = 0, NZVC: 7

Looks fine to me. There was a sign extension problem in the test program, 
fixed version attached.

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! 
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: addx.c --]
[-- Type: text/x-csrc; name="addx.c", Size: 1258 bytes --]

#include <stdlib.h>
#include <stdio.h>

void addx_test(unsigned int a, unsigned int b, unsigned int c, unsigned int d)
{
    unsigned int flags, result1, result2;

    asm ("addcc %3,%5,%1\n\t"
         "addxcc %4,%6,%2\n\t"
         "mov 0, %0\n\t"
         "bcc 1f\n\t"
         " nop\n\t"
         "mov 1, %0\n\t"
         "1: \n\t"
         "bvc 1f\n\t"
         " nop\n\t"
         "or %0, 2, %0\n\t"
         "1: \n\t"
         "bnz 1f\n\t"
         " nop\n\t"
         "or %0, 4, %0\n\t"
         "1: \n\t"
         "bpos 1f\n\t"
         " nop\n\t"
         "or %0, 8, %0\n\t"
         "1: \n\t"
         : "=r" (flags), "=r" (result1), "=r" (result2) : "r" (a), "r" (b), "r" (c), "r" (d));
    printf("%llx + %llx = %llx, NZVC: %d\n", ((unsigned long long)b << 32) | (unsigned long long)a, 
           ((unsigned long long)d << 32) | (unsigned long long)c,
           ((unsigned long long)result2 << 32) | (unsigned long long)result1,
           flags);
}

int main(int argc, const char **argv)
{
    unsigned int a, b, c, d;

    if (argc != 5)
        return 1;
    a = strtoul(argv[1], NULL, 0);
    b = strtoul(argv[2], NULL, 0);
    c = strtoul(argv[3], NULL, 0);
    d = strtoul(argv[4], NULL, 0);
    addx_test(a, b, c, d);

    return 0;
}


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-04-14  7:01 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-13 18:39 [Qemu-devel] [PATCH] SPARC target : Fix carry flagupdate inaddxcc and subxc Blue Swirl
2006-04-13 21:14 ` Even Rouault
  -- strict thread matches above, loose matches on Subject: below --
2006-04-14  7:01 Blue Swirl

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