diff options
| author | Julian Frimmel <julian@fri-me.de> | 2024-10-06 12:33:25 +0200 | 
|---|---|---|
| committer | Julian Frimmel <julian@fri-me.de> | 2024-11-28 16:12:02 +0100 | 
| commit | ba7316655645c020263e207ee9c036131b511d45 (patch) | |
| tree | 779e4c6007505f71c01102664006aedb301e0d4c /compiler/rustc_target/src/asm/avr.rs | |
| parent | 9b4d7c6a40b328d212095c28670c629facf1557d (diff) | |
| download | rust-ba7316655645c020263e207ee9c036131b511d45.tar.gz rust-ba7316655645c020263e207ee9c036131b511d45.zip | |
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
Diffstat (limited to 'compiler/rustc_target/src/asm/avr.rs')
| -rw-r--r-- | compiler/rustc_target/src/asm/avr.rs | 5 | 
1 files changed, 5 insertions, 0 deletions
| diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs index 276f376b297..9adcbecdf3c 100644 --- a/compiler/rustc_target/src/asm/avr.rs +++ b/compiler/rustc_target/src/asm/avr.rs @@ -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). } } | 
