Skip to content

Support AVRTiny devices in AVR inline assembly#146901

Draft
taiki-e wants to merge 2 commits intorust-lang:mainfrom
taiki-e:avrtiny
Draft

Support AVRTiny devices in AVR inline assembly#146901
taiki-e wants to merge 2 commits intorust-lang:mainfrom
taiki-e:avrtiny

Conversation

@taiki-e
Copy link
Member

@taiki-e taiki-e commented Sep 22, 2025

Note: This is still draft and this depends on #146900 which adds necessary target feature. (The first commit is from it.)


Follow-up to #131323.

AVR has devices that reduce the number of registers, similar to RISC-V's RV32E, which have different ABI than default. This PR supports such devices in inline assembly.

Refs: AVR-GCC docs https://gcc.gnu.org/wiki/avr-gcc#Reduced_Tiny

On the Reduced Tiny cores (16 GPRs only) several modifications to the ABI above apply:

Call-saved registers are: R18–R19, R28–R29.
Fixed Registers are R16 (tmp_reg) and R17 (zero_reg).

Registers used to pass arguments to functions and return values from functions are R25...R20 (instead of R25...R8).
Values that occupy more than 4 registers are returned in memory (instead of more than 8 registers).
There is only limited library support both from libgcc and AVR-LibC, for example there is no float support and no printf support.

r? @Amanieu

@rustbot label +O-AVR +A-inline-assembly

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-inline-assembly Area: Inline assembly (`asm!(…)`) O-AVR Target: AVR processors (ATtiny, ATmega, etc.) labels Sep 22, 2025
@taiki-e taiki-e changed the title Support AVRTiny devices AVR inline assembly Support AVRTiny devices in AVR inline assembly Sep 22, 2025
@rust-log-analyzer

This comment has been minimized.

@tgross35
Copy link
Contributor

Cc target maintainer @Patryk27

asm!("", out("r15r14") _);
//[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM
asm!("", out("r17r16") _);
//[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM
Copy link
Contributor

@Patryk27 Patryk27 Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would be nice to have a different message for register pairs, otherwise it takes a moment to parse what the compiler is trying to say

@Amanieu
Copy link
Member

Amanieu commented Sep 26, 2025

r=me once the target features land

@bors
Copy link
Collaborator

bors commented Nov 5, 2025

☔ The latest upstream changes (presumably #147645) made this pull request unmergeable. Please resolve the merge conflicts.

Zalathar added a commit to Zalathar/rust that referenced this pull request Feb 5, 2026
…ingjubilee

Add avr_target_feature

This adds the following unstable target features (tracking issue: rust-lang#146889):

- The following two are particularly important for properly supporting inline assembly:
  - `tinyencoding`: AVR has devices that reduce the number of registers, similar to RISC-V's RV32E. This feature is necessary to support inline assembly in such devices. (see also rust-lang#146901)
  - `lowbytefirst`: AVR's memory access is per 8-bit, and when writing 16-bit ports, the bytes must be written in a specific order. This order depends on devices, making this feature necessary to write proper inline assembly for such use cases. (see also llvm/llvm-project@2a52876)
- The followings help recognizing whether specific instructions are available:
  - `addsubiw`
  - `break`
  - `eijmpcall`
  - `elpm`
  - `elpmx`
  - `ijmpcall`
  - `jmpcall`
  - `lpm`
  - `lpmx`
  - `movw`
  - `mul`
  - `rmw`
  - `spm`
  - `spmx`

  Of these, all except `addsubiw`, `break`, `ijmpcall`, `lpm`, `rmw`, `spm`, and `spmx` have [corresponding conditional codes in avr-libc](https://github.com/search?q=repo%3Aavrdudes%2Favr-libc+%2F__AVR_HAVE_%2F&type=code&p=1). LLVM also has `des` feature, but I excluded it from this PR because [DES](https://en.wikipedia.org/wiki/Data_Encryption_Standard) is insecure.

- Report future-incompatible warning (rust-lang#116344) for -C target-feature=-sram and -C target-cpu=<device_without_sram> cases because SRAM is minimum requirement for non-assembly language in both avr-gcc and LLVM.
  - See rust-lang#146900 (comment) for details.

LLVM also has `smallstack`, `wrappingrjmp`, and `memmappedregs` features, but I skipped them because they didn't seem to belong to either of the above categories, but I might have missed something.

(The feature names are match with [definitions in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-21.1.0/llvm/lib/Target/AVR/AVRDevices.td).)

cc @Patryk27 @Rahix
r? workingjubilee

@rustbot label +O-AVR +A-target-feature
Zalathar added a commit to Zalathar/rust that referenced this pull request Feb 5, 2026
…ingjubilee

Add avr_target_feature

This adds the following unstable target features (tracking issue: rust-lang#146889):

- The following two are particularly important for properly supporting inline assembly:
  - `tinyencoding`: AVR has devices that reduce the number of registers, similar to RISC-V's RV32E. This feature is necessary to support inline assembly in such devices. (see also rust-lang#146901)
  - `lowbytefirst`: AVR's memory access is per 8-bit, and when writing 16-bit ports, the bytes must be written in a specific order. This order depends on devices, making this feature necessary to write proper inline assembly for such use cases. (see also llvm/llvm-project@2a52876)
- The followings help recognizing whether specific instructions are available:
  - `addsubiw`
  - `break`
  - `eijmpcall`
  - `elpm`
  - `elpmx`
  - `ijmpcall`
  - `jmpcall`
  - `lpm`
  - `lpmx`
  - `movw`
  - `mul`
  - `rmw`
  - `spm`
  - `spmx`

  Of these, all except `addsubiw`, `break`, `ijmpcall`, `lpm`, `rmw`, `spm`, and `spmx` have [corresponding conditional codes in avr-libc](https://github.com/search?q=repo%3Aavrdudes%2Favr-libc+%2F__AVR_HAVE_%2F&type=code&p=1). LLVM also has `des` feature, but I excluded it from this PR because [DES](https://en.wikipedia.org/wiki/Data_Encryption_Standard) is insecure.

- Report future-incompatible warning (rust-lang#116344) for -C target-feature=-sram and -C target-cpu=<device_without_sram> cases because SRAM is minimum requirement for non-assembly language in both avr-gcc and LLVM.
  - See rust-lang#146900 (comment) for details.

LLVM also has `smallstack`, `wrappingrjmp`, and `memmappedregs` features, but I skipped them because they didn't seem to belong to either of the above categories, but I might have missed something.

(The feature names are match with [definitions in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-21.1.0/llvm/lib/Target/AVR/AVRDevices.td).)

cc @Patryk27 @Rahix
r? workingjubilee

@rustbot label +O-AVR +A-target-feature
Zalathar added a commit to Zalathar/rust that referenced this pull request Feb 5, 2026
…ingjubilee

Add avr_target_feature

This adds the following unstable target features (tracking issue: rust-lang#146889):

- The following two are particularly important for properly supporting inline assembly:
  - `tinyencoding`: AVR has devices that reduce the number of registers, similar to RISC-V's RV32E. This feature is necessary to support inline assembly in such devices. (see also rust-lang#146901)
  - `lowbytefirst`: AVR's memory access is per 8-bit, and when writing 16-bit ports, the bytes must be written in a specific order. This order depends on devices, making this feature necessary to write proper inline assembly for such use cases. (see also llvm/llvm-project@2a52876)
- The followings help recognizing whether specific instructions are available:
  - `addsubiw`
  - `break`
  - `eijmpcall`
  - `elpm`
  - `elpmx`
  - `ijmpcall`
  - `jmpcall`
  - `lpm`
  - `lpmx`
  - `movw`
  - `mul`
  - `rmw`
  - `spm`
  - `spmx`

  Of these, all except `addsubiw`, `break`, `ijmpcall`, `lpm`, `rmw`, `spm`, and `spmx` have [corresponding conditional codes in avr-libc](https://github.com/search?q=repo%3Aavrdudes%2Favr-libc+%2F__AVR_HAVE_%2F&type=code&p=1). LLVM also has `des` feature, but I excluded it from this PR because [DES](https://en.wikipedia.org/wiki/Data_Encryption_Standard) is insecure.

- Report future-incompatible warning (rust-lang#116344) for -C target-feature=-sram and -C target-cpu=<device_without_sram> cases because SRAM is minimum requirement for non-assembly language in both avr-gcc and LLVM.
  - See rust-lang#146900 (comment) for details.

LLVM also has `smallstack`, `wrappingrjmp`, and `memmappedregs` features, but I skipped them because they didn't seem to belong to either of the above categories, but I might have missed something.

(The feature names are match with [definitions in LLVM](https://github.com/llvm/llvm-project/blob/llvmorg-21.1.0/llvm/lib/Target/AVR/AVRDevices.td).)

cc @Patryk27 @Rahix
r? workingjubilee

@rustbot label +O-AVR +A-target-feature
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-inline-assembly Area: Inline assembly (`asm!(…)`) O-AVR Target: AVR processors (ATtiny, ATmega, etc.) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants