Support clobber_abi for AVR inline assembly
This commit adds the relevant registers to the list of clobbered regis- ters (part of #93335). This follows the [ABI documentation] of AVR-GCC: > The [...] call-clobbered general purpose registers (GPRs) are > registers that might be destroyed (clobbered) by a function call. > > - **R18–R27, R30, R31** > > These GPRs are call clobbered. An ordinary function may use them > without restoring the contents. [...] > > - **R0, T-Flag** > > The temporary register and the T-flag in SREG are also call- > clobbered, but this knowledge is not exposed explicitly to the > compiler (R0 is a fixed register). Therefore this commit lists the aforementioned registers `r18–r27`, `r30` and `r31` as clobbered registers. Since the `r0` register (listed above as well) is not available in inline assembly at all (potentially because the AVR-GCC considers it a fixed register causing the register to never be used in register allocation and LLVM adopting this), there is no need to list it in the clobber list (the `r0`-variant is not even available). A comment was added to ensure, that the `r0` gets added to the clobber-list once the register gets usable in inline ASM. Since the SREG is normally considered clobbered anyways (unless the user supplies the `preserve_flags`-option), there is no need to explicitly list a bit in this register (which is not possible to list anyways). Note, that this commit completely ignores the case of interrupts (that are described in the ABI-specification), since every register touched in an ISR need to be saved anyways. [ABI documentation]: https://gcc.gnu.org/wiki/avr-gcc#Call-Used_Registers
This commit is contained in:
@@ -106,6 +106,11 @@ def_regs! {
|
||||
"the stack pointer cannot be used as an operand for inline asm",
|
||||
#error = ["r0", "r1", "r1r0"] =>
|
||||
"r0 and r1 are not available due to an issue in LLVM",
|
||||
// If this changes within LLVM, the compiler might use the registers
|
||||
// in the future. This must be reflected in the set of clobbered
|
||||
// registers, else the clobber ABI implementation is *unsound*, as
|
||||
// this generates invalid code (register is not marked as clobbered
|
||||
// but may change the register content).
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user