Skip to content

Commit ba73166

Browse files
committed
Support clobber_abi for AVR inline assembly
This commit adds the relevant registers to the list of clobbered regis- ters (part of rust-lang#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
1 parent 9b4d7c6 commit ba73166

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

compiler/rustc_target/src/asm/avr.rs

+5
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ def_regs! {
106106
"the stack pointer cannot be used as an operand for inline asm",
107107
#error = ["r0", "r1", "r1r0"] =>
108108
"r0 and r1 are not available due to an issue in LLVM",
109+
// If this changes within LLVM, the compiler might use the registers
110+
// in the future. This must be reflected in the set of clobbered
111+
// registers, else the clobber ABI implementation is *unsound*, as
112+
// this generates invalid code (register is not marked as clobbered
113+
// but may change the register content).
109114
}
110115
}
111116

compiler/rustc_target/src/asm/mod.rs

+22
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ pub enum InlineAsmClobberAbi {
928928
AArch64,
929929
AArch64NoX18,
930930
Arm64EC,
931+
Avr,
931932
RiscV,
932933
RiscVE,
933934
LoongArch,
@@ -986,6 +987,10 @@ impl InlineAsmClobberAbi {
986987
}),
987988
_ => Err(&["C", "system", "efiapi"]),
988989
},
990+
InlineAsmArch::Avr => match name {
991+
"C" | "system" => Ok(InlineAsmClobberAbi::Avr),
992+
_ => Err(&["C", "system"]),
993+
},
989994
InlineAsmArch::LoongArch64 => match name {
990995
"C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
991996
_ => Err(&["C", "system"]),
@@ -1133,6 +1138,23 @@ impl InlineAsmClobberAbi {
11331138
d24, d25, d26, d27, d28, d29, d30, d31,
11341139
}
11351140
},
1141+
InlineAsmClobberAbi::Avr => clobbered_regs! {
1142+
Avr AvrInlineAsmReg {
1143+
// The list of "Call-Used Registers" according to
1144+
// https://gcc.gnu.org/wiki/avr-gcc#Call-Used_Registers
1145+
1146+
// Clobbered registers available in inline assembly
1147+
r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r30, r31,
1148+
// As per the AVR-GCC-ABI documentation linked above, the R0
1149+
// register is a clobbered register as well. Since we don't
1150+
// allow the usage of R0 in inline assembly, nothing has to
1151+
// be done here.
1152+
// Likewise, the T-flag in the SREG should be clobbered, but
1153+
// this is not necessary to be listed here, since the SREG
1154+
// is considered clobbered anyways unless `preserve_flags`
1155+
// is used.
1156+
}
1157+
},
11361158
InlineAsmClobberAbi::RiscV => clobbered_regs! {
11371159
RiscV RiscVInlineAsmReg {
11381160
// ra

0 commit comments

Comments
 (0)