1

I'm trying to compile seabios in a more debug-able state, and so I want to cancel function inlining.

To do so, I have added -fon-inline to the compilation flag, but then I get compilation error:

 error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'  

Which is complaning on the following code:

asm volatile(
    "calll __call16big_from32"
    : "+a" (callregs), "+m" (*callregs)
    :
    : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");

I've looked this error up and found this means that compiler has ran out of registers so it can't compile that asm statement.

The thing is, the exact same code compile just fine without -fon-inline, why is that?

buc030
  • 425
  • 3
  • 14

1 Answers1

1

Why doesn't compile?

The first argument to the asm may not share a register with the address of the second because the first is modified. If the function is inlined callregs may be a constant or an offset from the stack pointer, and therefore a separate register is not required.

How to fix the program so it compiles

Given the presence of volatile and "memory", and no reference to it the second argument may be removed.

asm volatile(
    "call __call16big_from32"
    : "+a" (callregs)
    :
    : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
Timothy Baldwin
  • 3,551
  • 1
  • 14
  • 23
  • But if callregs was an offset from esp (or a constant, I don't see how it matters) in the parent function, then it needs to be passed to this function too as an argument, and thus it will still be an offset from esp, and still no extra register will be required. – buc030 Mar 25 '14 at 12:18
  • @buc030 when compiling with `-fno-inline`, the compiler attempts to compile the function so it works with all possible callers. I've also clarified my answer. – Timothy Baldwin Feb 05 '23 at 09:09
  • @buc030: The pointed-to memory *is* accessible by the callee, via the pointer in EAX. The `"memory"` clobber makes sure the compiler respects the fact that the pointed-to memory may be an input as well as the pointer itself, and that it may have changed when execution comes out the other side of the asm statement. (See [How can I indicate that the memory \*pointed\* to by an inline ASM argument may be used?](https://stackoverflow.com/q/56432259) - since `volatile` and `"memory"` are necessary anyway, we don't actually need a separate `"+m"(*callregs)` asm operand.) – Peter Cordes Feb 05 '23 at 20:12