Implement inline asm! for AVR platform
This commit is contained in:
parent
09d8a50ea2
commit
c6e8ae1a6c
8 changed files with 549 additions and 1 deletions
60
src/test/assembly/asm/avr-modifiers.rs
Normal file
60
src/test/assembly/asm/avr-modifiers.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
// min-llvm-version: 13.0
|
||||
// assembly-output: emit-asm
|
||||
// compile-flags: --target avr-unknown-gnu-atmega328
|
||||
// needs-llvm-components: avr
|
||||
|
||||
#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
|
||||
#![crate_type = "rlib"]
|
||||
#![no_core]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! asm {
|
||||
() => {};
|
||||
}
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! concat {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
type ptr = *const u64;
|
||||
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i16 {}
|
||||
impl Copy for i32 {}
|
||||
impl Copy for i64 {}
|
||||
impl Copy for ptr {}
|
||||
|
||||
macro_rules! check {
|
||||
($func:ident $hi:literal $lo:literal $reg:tt) => {
|
||||
#[no_mangle]
|
||||
unsafe fn $func() -> i16 {
|
||||
let y;
|
||||
asm!(concat!("mov {0:", $hi, "}, {0:", $lo, "}"), out($reg) y);
|
||||
y
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// CHECK-LABEL: reg_pair_modifiers:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r{{[1-9]?[13579]}}, r{{[1-9]?[24680]}}
|
||||
// CHECK: ;NO_APP
|
||||
check!(reg_pair_modifiers "h" "l" reg_pair);
|
||||
|
||||
// CHECK-LABEL: reg_iw_modifiers:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r{{[1-9]?[13579]}}, r{{[1-9]?[24680]}}
|
||||
// CHECK: ;NO_APP
|
||||
check!(reg_iw_modifiers "h" "l" reg_iw);
|
||||
|
||||
// CHECK-LABEL: reg_ptr_modifiers:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r{{[1-9]?[13579]}}, r{{[1-9]?[24680]}}
|
||||
// CHECK: ;NO_APP
|
||||
check!(reg_ptr_modifiers "h" "l" reg_ptr);
|
||||
222
src/test/assembly/asm/avr-types.rs
Normal file
222
src/test/assembly/asm/avr-types.rs
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
// min-llvm-version: 13.0
|
||||
// assembly-output: emit-asm
|
||||
// compile-flags: --target avr-unknown-gnu-atmega328
|
||||
// needs-llvm-components: avr
|
||||
|
||||
#![feature(no_core, lang_items, rustc_attrs, asm_sym, asm_experimental_arch)]
|
||||
#![crate_type = "rlib"]
|
||||
#![no_core]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! asm {
|
||||
() => {};
|
||||
}
|
||||
#[rustc_builtin_macro]
|
||||
macro_rules! concat {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
type ptr = *const u64;
|
||||
|
||||
impl Copy for i8 {}
|
||||
impl Copy for i16 {}
|
||||
impl Copy for i32 {}
|
||||
impl Copy for i64 {}
|
||||
impl Copy for ptr {}
|
||||
|
||||
macro_rules! check {
|
||||
($func:ident $ty:ident $class:ident) => {
|
||||
#[no_mangle]
|
||||
pub unsafe fn $func(x: $ty) -> $ty {
|
||||
let y;
|
||||
asm!("mov {}, {}", lateout($class) y, in($class) x);
|
||||
y
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! checkw {
|
||||
($func:ident $ty:ident $class:ident) => {
|
||||
#[no_mangle]
|
||||
pub unsafe fn $func(x: $ty) -> $ty {
|
||||
let y;
|
||||
asm!("movw {}, {}", lateout($class) y, in($class) x);
|
||||
y
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! check_reg {
|
||||
($func:ident $ty:ident $reg:tt) => {
|
||||
#[no_mangle]
|
||||
pub unsafe fn $func(x: $ty) -> $ty {
|
||||
let y;
|
||||
asm!(concat!("mov ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
|
||||
y
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! check_regw {
|
||||
($func:ident $ty:ident $reg:tt $reg_lit:tt) => {
|
||||
#[no_mangle]
|
||||
pub unsafe fn $func(x: $ty) -> $ty {
|
||||
let y;
|
||||
asm!(concat!("movw ", $reg_lit, ", ", $reg_lit), lateout($reg) y, in($reg) x);
|
||||
y
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn extern_func();
|
||||
static extern_static: i8;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sym_fn
|
||||
// CHECK: ;APP
|
||||
// CHECK: call extern_func
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn sym_fn() {
|
||||
asm!("call {}", sym extern_func);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sym_static
|
||||
// CHECK: ;APP
|
||||
// CHECK: lds r{{[0-9]+}}, extern_static
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn sym_static() -> i8 {
|
||||
let y;
|
||||
asm!("lds {}, {}", lateout(reg) y, sym extern_static);
|
||||
y
|
||||
}
|
||||
|
||||
// CHECK-LABEL: ld_z:
|
||||
// CHECK: ;APP
|
||||
// CHECK: ld r{{[0-9]+}}, Z
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn ld_z(x: i16) -> i8 {
|
||||
let y;
|
||||
asm!("ld {}, Z", out(reg) y, in("Z") x);
|
||||
y
|
||||
}
|
||||
|
||||
// CHECK-LABEL: ldd_z:
|
||||
// CHECK: ;APP
|
||||
// CHECK: ldd r{{[0-9]+}}, Z+4
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn ldd_z(x: i16) -> i8 {
|
||||
let y;
|
||||
asm!("ldd {}, Z+4", out(reg) y, in("Z") x);
|
||||
y
|
||||
}
|
||||
|
||||
// CHECK-LABEL: ld_predecrement:
|
||||
// CHECK: ;APP
|
||||
// CHECK: ld r{{[0-9]+}}, -Z
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn ld_predecrement(x: i16) -> i8 {
|
||||
let y;
|
||||
asm!("ld {}, -Z", out(reg) y, in("Z") x);
|
||||
y
|
||||
}
|
||||
|
||||
// CHECK-LABEL: ld_postincrement:
|
||||
// CHECK: ;APP
|
||||
// CHECK: ld r{{[0-9]+}}, Z+
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn ld_postincrement(x: i16) -> i8 {
|
||||
let y;
|
||||
asm!("ld {}, Z+", out(reg) y, in("Z") x);
|
||||
y
|
||||
}
|
||||
|
||||
// CHECK-LABEL: muls_clobber:
|
||||
// CHECK: ;APP
|
||||
// CHECK: muls r{{[0-9]+}}, r{{[0-9]+}}
|
||||
// CHECK: movw r{{[0-9]+}}, r0
|
||||
// CHECK: ;NO_APP
|
||||
#[no_mangle]
|
||||
pub unsafe fn muls_clobber(x: i8, y: i8) -> i16 {
|
||||
let z;
|
||||
asm!(
|
||||
"muls {}, {}",
|
||||
"movw {}, r1:r0",
|
||||
out(reg_iw) z,
|
||||
in(reg) x,
|
||||
in(reg) y,
|
||||
);
|
||||
z
|
||||
}
|
||||
|
||||
// CHECK-LABEL: reg_i8:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
|
||||
// CHECK: ;NO_APP
|
||||
check!(reg_i8 i8 reg);
|
||||
|
||||
// CHECK-LABEL: reg_upper_i8:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r{{[1-3][0-9]}}, r{{[1-3][0-9]}}
|
||||
// CHECK: ;NO_APP
|
||||
check!(reg_upper_i8 i8 reg_upper);
|
||||
|
||||
// CHECK-LABEL: reg_pair_i16:
|
||||
// CHECK: ;APP
|
||||
// CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
|
||||
// CHECK: ;NO_APP
|
||||
checkw!(reg_pair_i16 i16 reg_pair);
|
||||
|
||||
// CHECK-LABEL: reg_iw_i16:
|
||||
// CHECK: ;APP
|
||||
// CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
|
||||
// CHECK: ;NO_APP
|
||||
checkw!(reg_iw_i16 i16 reg_iw);
|
||||
|
||||
// CHECK-LABEL: reg_ptr_i16:
|
||||
// CHECK: ;APP
|
||||
// CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
|
||||
// CHECK: ;NO_APP
|
||||
checkw!(reg_ptr_i16 i16 reg_ptr);
|
||||
|
||||
// CHECK-LABEL: r2_i8:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r2, r2
|
||||
// CHECK: ;NO_APP
|
||||
check_reg!(r2_i8 i8 "r2");
|
||||
|
||||
// CHECK-LABEL: xl_i8:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r26, r26
|
||||
// CHECK: ;NO_APP
|
||||
check_reg!(xl_i8 i8 "XL");
|
||||
|
||||
// CHECK-LABEL: xh_i8:
|
||||
// CHECK: ;APP
|
||||
// CHECK: mov r27, r27
|
||||
// CHECK: ;NO_APP
|
||||
check_reg!(xh_i8 i8 "XH");
|
||||
|
||||
// CHECK-LABEL: x_i16:
|
||||
// CHECK: ;APP
|
||||
// CHECK: movw r26, r26
|
||||
// CHECK: ;NO_APP
|
||||
check_regw!(x_i16 i16 "X" "X");
|
||||
|
||||
// CHECK-LABEL: r25r24_i16:
|
||||
// CHECK: ;APP
|
||||
// CHECK: movw r24, r24
|
||||
// CHECK: ;NO_APP
|
||||
check_regw!(r25r24_i16 i16 "r25r24" "r24");
|
||||
Loading…
Add table
Add a link
Reference in a new issue