From b2dd13aa3ab5de0c74a2b51c076f6f51304b339f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Sun, 8 Feb 2026 00:31:59 +0900 Subject: [PATCH] Support AVRTiny devices in AVR inline assembly --- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/asm/avr.rs | 72 ++++++--- compiler/rustc_target/src/asm/mod.rs | 14 +- tests/codegen-llvm/asm/avr-clobbers.rs | 14 +- tests/ui/asm/avr/bad-reg.avr.stderr | 56 +++++++ tests/ui/asm/avr/bad-reg.avrtiny.stderr | 200 ++++++++++++++++++++++++ tests/ui/asm/avr/bad-reg.rs | 88 +++++++++++ 7 files changed, 415 insertions(+), 30 deletions(-) create mode 100644 tests/ui/asm/avr/bad-reg.avr.stderr create mode 100644 tests/ui/asm/avr/bad-reg.avrtiny.stderr create mode 100644 tests/ui/asm/avr/bad-reg.rs diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 1915ff0380fda..845e8dda15361 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2291,6 +2291,7 @@ symbols! { three_way_compare, thumb2, thumb_mode: "thumb-mode", + tinyencoding, tmm_reg, to_owned_method, to_string, diff --git a/compiler/rustc_target/src/asm/avr.rs b/compiler/rustc_target/src/asm/avr.rs index 55d393c81d3ec..3d20734553a15 100644 --- a/compiler/rustc_target/src/asm/avr.rs +++ b/compiler/rustc_target/src/asm/avr.rs @@ -1,8 +1,10 @@ use std::fmt; -use rustc_span::Symbol; +use rustc_data_structures::fx::FxIndexSet; +use rustc_span::{Symbol, sym}; use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; +use crate::spec::{RelocModel, Target}; def_reg_class! { Avr AvrInlineAsmRegClass { @@ -52,24 +54,44 @@ impl AvrInlineAsmRegClass { } } +pub(crate) fn is_tiny(target_features: &FxIndexSet) -> bool { + target_features.contains(&sym::tinyencoding) +} + +fn not_tiny( + _arch: InlineAsmArch, + _reloc_model: RelocModel, + target_features: &FxIndexSet, + _target: &Target, + _is_clobber: bool, +) -> Result<(), &'static str> { + if is_tiny(target_features) { + Err( + "on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM", + ) + } else { + Ok(()) + } +} + def_regs! { Avr AvrInlineAsmReg AvrInlineAsmRegClass { - r2: reg = ["r2"], - r3: reg = ["r3"], - r4: reg = ["r4"], - r5: reg = ["r5"], - r6: reg = ["r6"], - r7: reg = ["r7"], - r8: reg = ["r8"], - r9: reg = ["r9"], - r10: reg = ["r10"], - r11: reg = ["r11"], - r12: reg = ["r12"], - r13: reg = ["r13"], - r14: reg = ["r14"], - r15: reg = ["r15"], - r16: reg, reg_upper = ["r16"], - r17: reg, reg_upper = ["r17"], + r2: reg = ["r2"] % not_tiny, + r3: reg = ["r3"] % not_tiny, + r4: reg = ["r4"] % not_tiny, + r5: reg = ["r5"] % not_tiny, + r6: reg = ["r6"] % not_tiny, + r7: reg = ["r7"] % not_tiny, + r8: reg = ["r8"] % not_tiny, + r9: reg = ["r9"] % not_tiny, + r10: reg = ["r10"] % not_tiny, + r11: reg = ["r11"] % not_tiny, + r12: reg = ["r12"] % not_tiny, + r13: reg = ["r13"] % not_tiny, + r14: reg = ["r14"] % not_tiny, + r15: reg = ["r15"] % not_tiny, + r16: reg, reg_upper = ["r16"] % not_tiny, + r17: reg, reg_upper = ["r17"] % not_tiny, r18: reg, reg_upper = ["r18"], r19: reg, reg_upper = ["r19"], r20: reg, reg_upper = ["r20"], @@ -83,14 +105,14 @@ def_regs! { r30: reg, reg_upper = ["r30", "ZL"], r31: reg, reg_upper = ["r31", "ZH"], - r3r2: reg_pair = ["r3r2"], - r5r4: reg_pair = ["r5r4"], - r7r6: reg_pair = ["r7r6"], - r9r8: reg_pair = ["r9r8"], - r11r10: reg_pair = ["r11r10"], - r13r12: reg_pair = ["r13r12"], - r15r14: reg_pair = ["r15r14"], - r17r16: reg_pair = ["r17r16"], + r3r2: reg_pair = ["r3r2"] % not_tiny, + r5r4: reg_pair = ["r5r4"] % not_tiny, + r7r6: reg_pair = ["r7r6"] % not_tiny, + r9r8: reg_pair = ["r9r8"] % not_tiny, + r11r10: reg_pair = ["r11r10"] % not_tiny, + r13r12: reg_pair = ["r13r12"] % not_tiny, + r15r14: reg_pair = ["r15r14"] % not_tiny, + r17r16: reg_pair = ["r17r16"] % not_tiny, r19r18: reg_pair = ["r19r18"], r21r20: reg_pair = ["r21r20"], r23r22: reg_pair = ["r23r22"], diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index a10699bbce884..d465973766095 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -932,6 +932,7 @@ pub enum InlineAsmClobberAbi { AArch64NoX18, Arm64EC, Avr, + AvrTiny, RiscV, RiscVE, LoongArch, @@ -993,7 +994,11 @@ impl InlineAsmClobberAbi { _ => Err(&["C", "system", "efiapi"]), }, InlineAsmArch::Avr => match name { - "C" | "system" => Ok(InlineAsmClobberAbi::Avr), + "C" | "system" => Ok(if avr::is_tiny(target_features) { + InlineAsmClobberAbi::AvrTiny + } else { + InlineAsmClobberAbi::Avr + }), _ => Err(&["C", "system"]), }, InlineAsmArch::LoongArch32 | InlineAsmArch::LoongArch64 => match name { @@ -1168,6 +1173,13 @@ impl InlineAsmClobberAbi { // is used. } }, + InlineAsmClobberAbi::AvrTiny => clobbered_regs! { + Avr AvrInlineAsmReg { + // Refs: https://gcc.gnu.org/wiki/avr-gcc#Reduced_Tiny + + r20, r21, r22, r23, r24, r25, r26, r27, r30, r31, + } + }, InlineAsmClobberAbi::RiscV => clobbered_regs! { RiscV RiscVInlineAsmReg { // ra diff --git a/tests/codegen-llvm/asm/avr-clobbers.rs b/tests/codegen-llvm/asm/avr-clobbers.rs index 472ee328465b6..d881f88b0b3ca 100644 --- a/tests/codegen-llvm/asm/avr-clobbers.rs +++ b/tests/codegen-llvm/asm/avr-clobbers.rs @@ -1,7 +1,11 @@ //@ add-minicore //@ assembly-output: emit-asm -//@ compile-flags: --target avr-none -C target-cpu=atmega328p -//@ needs-llvm-components: avr +//@ revisions: avr avrtiny +//@[avr] compile-flags: --target avr-none -C target-cpu=atmega328p +//@[avr] needs-llvm-components: avr +//@[avrtiny] compile-flags: --target avr-none -C target-cpu=attiny104 +//@[avrtiny] needs-llvm-components: avr +// ignore-tidy-linelength #![crate_type = "rlib"] #![feature(no_core, asm_experimental_arch)] @@ -25,14 +29,16 @@ pub unsafe fn sreg_is_not_clobbered_if_preserve_flags_is_used() { } // CHECK-LABEL: @clobber_abi -// CHECK: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31},~{sreg}"() +// avr: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31},~{sreg}"() +// avrtiny: asm sideeffect "", "={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31},~{sreg}"() #[no_mangle] pub unsafe fn clobber_abi() { asm!("", clobber_abi("C"), options(nostack, nomem)); } // CHECK-LABEL: @clobber_abi_with_preserved_flags -// CHECK: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31}"() +// avr: asm sideeffect "", "={r18},={r19},={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31}"() +// avrtiny: asm sideeffect "", "={r20},={r21},={r22},={r23},={r24},={r25},={r26},={r27},={r30},={r31}"() #[no_mangle] pub unsafe fn clobber_abi_with_preserved_flags() { asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); diff --git a/tests/ui/asm/avr/bad-reg.avr.stderr b/tests/ui/asm/avr/bad-reg.avr.stderr new file mode 100644 index 0000000000000..4d65560b5342d --- /dev/null +++ b/tests/ui/asm/avr/bad-reg.avr.stderr @@ -0,0 +1,56 @@ +error: invalid register `Y`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:19:18 + | +LL | asm!("", out("Y") _); + | ^^^^^^^^^^ + +error: invalid register `YL`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:21:18 + | +LL | asm!("", out("YL") _); + | ^^^^^^^^^^^ + +error: invalid register `YH`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:23:18 + | +LL | asm!("", out("YH") _); + | ^^^^^^^^^^^ + +error: invalid register `SP`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:25:18 + | +LL | asm!("", out("SP") _); + | ^^^^^^^^^^^ + +error: invalid register `SPL`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:27:18 + | +LL | asm!("", out("SPL") _); + | ^^^^^^^^^^^^ + +error: invalid register `SPH`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:29:18 + | +LL | asm!("", out("SPH") _); + | ^^^^^^^^^^^^ + +error: invalid register `r0`: LLVM reserves r0 (scratch register) and r1 (zero register) + --> $DIR/bad-reg.rs:31:18 + | +LL | asm!("", out("r0") _); + | ^^^^^^^^^^^ + +error: invalid register `r1`: LLVM reserves r0 (scratch register) and r1 (zero register) + --> $DIR/bad-reg.rs:33:18 + | +LL | asm!("", out("r1") _); + | ^^^^^^^^^^^ + +error: invalid register `r1r0`: LLVM reserves r0 (scratch register) and r1 (zero register) + --> $DIR/bad-reg.rs:35:18 + | +LL | asm!("", out("r1r0") _); + | ^^^^^^^^^^^^^ + +error: aborting due to 9 previous errors + diff --git a/tests/ui/asm/avr/bad-reg.avrtiny.stderr b/tests/ui/asm/avr/bad-reg.avrtiny.stderr new file mode 100644 index 0000000000000..6f0ecdb6e4348 --- /dev/null +++ b/tests/ui/asm/avr/bad-reg.avrtiny.stderr @@ -0,0 +1,200 @@ +error: invalid register `Y`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:19:18 + | +LL | asm!("", out("Y") _); + | ^^^^^^^^^^ + +error: invalid register `YL`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:21:18 + | +LL | asm!("", out("YL") _); + | ^^^^^^^^^^^ + +error: invalid register `YH`: the frame pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:23:18 + | +LL | asm!("", out("YH") _); + | ^^^^^^^^^^^ + +error: invalid register `SP`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:25:18 + | +LL | asm!("", out("SP") _); + | ^^^^^^^^^^^ + +error: invalid register `SPL`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:27:18 + | +LL | asm!("", out("SPL") _); + | ^^^^^^^^^^^^ + +error: invalid register `SPH`: the stack pointer cannot be used as an operand for inline asm + --> $DIR/bad-reg.rs:29:18 + | +LL | asm!("", out("SPH") _); + | ^^^^^^^^^^^^ + +error: invalid register `r0`: LLVM reserves r0 (scratch register) and r1 (zero register) + --> $DIR/bad-reg.rs:31:18 + | +LL | asm!("", out("r0") _); + | ^^^^^^^^^^^ + +error: invalid register `r1`: LLVM reserves r0 (scratch register) and r1 (zero register) + --> $DIR/bad-reg.rs:33:18 + | +LL | asm!("", out("r1") _); + | ^^^^^^^^^^^ + +error: invalid register `r1r0`: LLVM reserves r0 (scratch register) and r1 (zero register) + --> $DIR/bad-reg.rs:35:18 + | +LL | asm!("", out("r1r0") _); + | ^^^^^^^^^^^^^ + +error: cannot use register `r2`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:39:18 + | +LL | asm!("", out("r2") _); + | ^^^^^^^^^^^ + +error: cannot use register `r3`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:41:18 + | +LL | asm!("", out("r3") _); + | ^^^^^^^^^^^ + +error: cannot use register `r4`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:43:18 + | +LL | asm!("", out("r4") _); + | ^^^^^^^^^^^ + +error: cannot use register `r5`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:45:18 + | +LL | asm!("", out("r5") _); + | ^^^^^^^^^^^ + +error: cannot use register `r6`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:47:18 + | +LL | asm!("", out("r6") _); + | ^^^^^^^^^^^ + +error: cannot use register `r7`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:49:18 + | +LL | asm!("", out("r7") _); + | ^^^^^^^^^^^ + +error: cannot use register `r8`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:51:18 + | +LL | asm!("", out("r8") _); + | ^^^^^^^^^^^ + +error: cannot use register `r9`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:53:18 + | +LL | asm!("", out("r9") _); + | ^^^^^^^^^^^ + +error: cannot use register `r10`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:55:18 + | +LL | asm!("", out("r10") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r11`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:57:18 + | +LL | asm!("", out("r11") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r12`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:59:18 + | +LL | asm!("", out("r12") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r13`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:61:18 + | +LL | asm!("", out("r13") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r14`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:63:18 + | +LL | asm!("", out("r14") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r15`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:65:18 + | +LL | asm!("", out("r15") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r16`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:67:18 + | +LL | asm!("", out("r16") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r17`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:69:18 + | +LL | asm!("", out("r17") _); + | ^^^^^^^^^^^^ + +error: cannot use register `r3r2`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:71:18 + | +LL | asm!("", out("r3r2") _); + | ^^^^^^^^^^^^^ + +error: cannot use register `r5r4`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:73:18 + | +LL | asm!("", out("r5r4") _); + | ^^^^^^^^^^^^^ + +error: cannot use register `r7r6`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:75:18 + | +LL | asm!("", out("r7r6") _); + | ^^^^^^^^^^^^^ + +error: cannot use register `r9r8`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:77:18 + | +LL | asm!("", out("r9r8") _); + | ^^^^^^^^^^^^^ + +error: cannot use register `r11r10`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:79:18 + | +LL | asm!("", out("r11r10") _); + | ^^^^^^^^^^^^^^^ + +error: cannot use register `r13r12`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:81:18 + | +LL | asm!("", out("r13r12") _); + | ^^^^^^^^^^^^^^^ + +error: cannot use register `r15r14`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:83:18 + | +LL | asm!("", out("r15r14") _); + | ^^^^^^^^^^^^^^^ + +error: cannot use register `r17r16`: on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + --> $DIR/bad-reg.rs:85:18 + | +LL | asm!("", out("r17r16") _); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 33 previous errors + diff --git a/tests/ui/asm/avr/bad-reg.rs b/tests/ui/asm/avr/bad-reg.rs new file mode 100644 index 0000000000000..82b9ccf69cfc1 --- /dev/null +++ b/tests/ui/asm/avr/bad-reg.rs @@ -0,0 +1,88 @@ +//@ add-minicore +//@ revisions: avr avrtiny +//@[avr] compile-flags: --target avr-none -C target-cpu=atmega328p +//@[avr] needs-llvm-components: avr +//@[avrtiny] compile-flags: --target avr-none -C target-cpu=attiny104 +//@[avrtiny] needs-llvm-components: avr +//@ ignore-backends: gcc + +#![crate_type = "rlib"] +#![feature(no_core, asm_experimental_arch)] +#![no_core] + +extern crate minicore; +use minicore::*; + +fn f() { + unsafe { + // Unsupported registers + asm!("", out("Y") _); + //~^ ERROR the frame pointer cannot be used as an operand for inline asm + asm!("", out("YL") _); + //~^ ERROR the frame pointer cannot be used as an operand for inline asm + asm!("", out("YH") _); + //~^ ERROR the frame pointer cannot be used as an operand for inline asm + asm!("", out("SP") _); + //~^ ERROR the stack pointer cannot be used as an operand for inline asm + asm!("", out("SPL") _); + //~^ ERROR the stack pointer cannot be used as an operand for inline asm + asm!("", out("SPH") _); + //~^ ERROR the stack pointer cannot be used as an operand for inline asm + asm!("", out("r0") _); + //~^ ERROR LLVM reserves r0 (scratch register) and r1 (zero register) + asm!("", out("r1") _); + //~^ ERROR LLVM reserves r0 (scratch register) and r1 (zero register) + asm!("", out("r1r0") _); + //~^ ERROR LLVM reserves r0 (scratch register) and r1 (zero register) + + // Unsupported only on AVRTiny + asm!("", out("r2") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r3") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r4") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r5") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r6") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r7") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r8") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r9") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r10") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r11") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r12") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r13") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r14") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r15") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r16") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r17") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r3r2") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r5r4") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r7r6") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r9r8") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r11r10") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + asm!("", out("r13r12") _); + //[avrtiny]~^ ERROR on AVRTiny, r[2-15] are unavailable, r16 (scratch register) and r17 (zero register) are reserved by LLVM + 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 + } +}