https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105817

--- Comment #1 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
The GCC manual says
<quote>
register int *p1 asm ("r0") = …;
register int *p2 asm ("r1") = …;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));

Warning: In the above example, be aware that a register (for example r0) can be
call-clobbered by subsequent code, including function calls and library calls
for arithmetic operators on other variables (for example the initialization of
p2). In this case, use temporary variables for expressions between the register
assignments:

int t1 = …;
register int *p1 asm ("r0") = …;
register int *p2 asm ("r1") = t1;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));
</quote>

So I think by that statement this testcase is invalid.  You need to write
something like:

extern __thread uint64_t p;
int foo(unsigned int *result)
{
        register uint64_t r0 asm("x0");
        register uint64_t r1 asm("x1");
        uint64_t real_r0;
        uint64_t real_r1;
        asm("hvc %2"
                : "=r"(r0), "=r"(r1)
                : "i"(0)
                : "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11",
"x12", "x13", "x14", "x15", "x16", "x17");
        real_r0 = r0;
        real_r1 = r1;

        *result = real_r1;
        return (int)real_r0;
}

It's unfortunate that this type of testcase just fails silently with no
diagnostic from the compiler.

Reply via email to