2

I have a game engine API that is executed as compiled RISC-V. It has been working well until I tried to pass the address of a local struct. The parameter gets optimized away and I'm not sure why. Compiler is GCC 9.2.

This is the particular function used:

inline long syscall(long n, long arg0)
{
    register long a0 asm("a0") = arg0;
    register long syscall_id asm("a7") = n;

    asm volatile ("scall" : "+r"(a0) : "r"(syscall_id));

    return a0;
}

Which is called by:

inline void player_init(const PlayerInit& pinit)
{
    syscall(ECALL_PLAYER_INIT, (long) &pinit);
}

And the API call itself:

dm::player_init({
    .x = 256, .y = 256, .floor = 0,
    .direction = 1,
    .life = 1,
    .maxlife = 24
});

As you can see everything is in order until we read the assembly.

000100f0 <start>:
start():
   100f0:       fe010113                addi    sp,sp,-32
   100f4:       00810513                addi    a0,sp,8
   100f8:       19500893                li      a7,405
   100fc:       00000073                ecall

Why is the struct itself optimized out? It does set a0 to a seemingly correct location, but it would only contain zeroes. I have also passed other structs like this, which works, but inline assembly can be fickle so I am curious if I'm doing something wrong. It's a very weird problem to have because it does the right thing but the data isn't there!

It's very important that the system calls be inlined.

As a band-aid I have temporarily solved this by making the compiler unaware of what I'm doing with the struct like so:

inline void player_init(const PlayerInit& pinit)
{
    asm ("" ::: "memory");
    syscall(ECALL_PLAYER_INIT, (long) &pinit);
}

Any ideas would be appreciated.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
gonzo
  • 442
  • 4
  • 15
  • 1
    Pointer operands don't imply that the pointed-to memory is also an operand so from what you've told the compiler those stores would be "dead" stores. Use a `"memory"` clobber *on the syscall*, or a dummy memory input operand. (Or output for syscalls that write user-space memory) – Peter Cordes Apr 09 '20 at 11:25

0 Answers0