qemu-e2k/tests/tcg/x86_64/adox.c
Richard Henderson 6fbef9426b target/i386: Fix 32-bit AD[CO]X insns in 64-bit mode
Failure to truncate the inputs results in garbage for the carry-out.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1373
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20230115012103.3131796-1-richard.henderson@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2023-02-16 16:57:34 +01:00

70 lines
1.3 KiB
C

/* See if ADOX give expected results */
#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
static uint64_t adoxq(bool *c_out, uint64_t a, uint64_t b, bool c)
{
asm ("addl $0x7fffffff, %k1\n\t"
"adoxq %2, %0\n\t"
"seto %b1"
: "+r"(a), "=&r"(c) : "r"(b), "1"((int)c));
*c_out = c;
return a;
}
static uint64_t adoxl(bool *c_out, uint64_t a, uint64_t b, bool c)
{
asm ("addl $0x7fffffff, %k1\n\t"
"adoxl %k2, %k0\n\t"
"seto %b1"
: "+r"(a), "=&r"(c) : "r"(b), "1"((int)c));
*c_out = c;
return a;
}
int main()
{
uint64_t r;
bool c;
r = adoxq(&c, 0, 0, 0);
assert(r == 0);
assert(c == 0);
r = adoxl(&c, 0, 0, 0);
assert(r == 0);
assert(c == 0);
r = adoxl(&c, 0x100000000, 0, 0);
assert(r == 0);
assert(c == 0);
r = adoxq(&c, 0, 0, 1);
assert(r == 1);
assert(c == 0);
r = adoxl(&c, 0, 0, 1);
assert(r == 1);
assert(c == 0);
r = adoxq(&c, -1, -1, 0);
assert(r == -2);
assert(c == 1);
r = adoxl(&c, -1, -1, 0);
assert(r == 0xfffffffe);
assert(c == 1);
r = adoxq(&c, -1, -1, 1);
assert(r == -1);
assert(c == 1);
r = adoxl(&c, -1, -1, 1);
assert(r == 0xffffffff);
assert(c == 1);
return 0;
}