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/
#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;
}
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel