/src/test/assembly/asm/avr-types.rs

https://gitlab.com/rust-lang/rust · Rust · 222 lines · 122 code · 27 blank · 73 comment · 5 complexity · ca22a00acc37844a65daa93a74deaddb MD5 · raw file

  1. // min-llvm-version: 13.0
  2. // assembly-output: emit-asm
  3. // compile-flags: --target avr-unknown-gnu-atmega328
  4. // needs-llvm-components: avr
  5. #![feature(no_core, lang_items, rustc_attrs, asm_sym, asm_experimental_arch)]
  6. #![crate_type = "rlib"]
  7. #![no_core]
  8. #![allow(non_camel_case_types)]
  9. #[rustc_builtin_macro]
  10. macro_rules! asm {
  11. () => {};
  12. }
  13. #[rustc_builtin_macro]
  14. macro_rules! concat {
  15. () => {};
  16. }
  17. #[lang = "sized"]
  18. trait Sized {}
  19. #[lang = "copy"]
  20. trait Copy {}
  21. type ptr = *const u64;
  22. impl Copy for i8 {}
  23. impl Copy for i16 {}
  24. impl Copy for i32 {}
  25. impl Copy for i64 {}
  26. impl Copy for ptr {}
  27. macro_rules! check {
  28. ($func:ident $ty:ident $class:ident) => {
  29. #[no_mangle]
  30. pub unsafe fn $func(x: $ty) -> $ty {
  31. let y;
  32. asm!("mov {}, {}", lateout($class) y, in($class) x);
  33. y
  34. }
  35. };
  36. }
  37. macro_rules! checkw {
  38. ($func:ident $ty:ident $class:ident) => {
  39. #[no_mangle]
  40. pub unsafe fn $func(x: $ty) -> $ty {
  41. let y;
  42. asm!("movw {}, {}", lateout($class) y, in($class) x);
  43. y
  44. }
  45. };
  46. }
  47. macro_rules! check_reg {
  48. ($func:ident $ty:ident $reg:tt) => {
  49. #[no_mangle]
  50. pub unsafe fn $func(x: $ty) -> $ty {
  51. let y;
  52. asm!(concat!("mov ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
  53. y
  54. }
  55. };
  56. }
  57. macro_rules! check_regw {
  58. ($func:ident $ty:ident $reg:tt $reg_lit:tt) => {
  59. #[no_mangle]
  60. pub unsafe fn $func(x: $ty) -> $ty {
  61. let y;
  62. asm!(concat!("movw ", $reg_lit, ", ", $reg_lit), lateout($reg) y, in($reg) x);
  63. y
  64. }
  65. };
  66. }
  67. extern "C" {
  68. fn extern_func();
  69. static extern_static: i8;
  70. }
  71. // CHECK-LABEL: sym_fn
  72. // CHECK: ;APP
  73. // CHECK: call extern_func
  74. // CHECK: ;NO_APP
  75. #[no_mangle]
  76. pub unsafe fn sym_fn() {
  77. asm!("call {}", sym extern_func);
  78. }
  79. // CHECK-LABEL: sym_static
  80. // CHECK: ;APP
  81. // CHECK: lds r{{[0-9]+}}, extern_static
  82. // CHECK: ;NO_APP
  83. #[no_mangle]
  84. pub unsafe fn sym_static() -> i8 {
  85. let y;
  86. asm!("lds {}, {}", lateout(reg) y, sym extern_static);
  87. y
  88. }
  89. // CHECK-LABEL: ld_z:
  90. // CHECK: ;APP
  91. // CHECK: ld r{{[0-9]+}}, Z
  92. // CHECK: ;NO_APP
  93. #[no_mangle]
  94. pub unsafe fn ld_z(x: i16) -> i8 {
  95. let y;
  96. asm!("ld {}, Z", out(reg) y, in("Z") x);
  97. y
  98. }
  99. // CHECK-LABEL: ldd_z:
  100. // CHECK: ;APP
  101. // CHECK: ldd r{{[0-9]+}}, Z+4
  102. // CHECK: ;NO_APP
  103. #[no_mangle]
  104. pub unsafe fn ldd_z(x: i16) -> i8 {
  105. let y;
  106. asm!("ldd {}, Z+4", out(reg) y, in("Z") x);
  107. y
  108. }
  109. // CHECK-LABEL: ld_predecrement:
  110. // CHECK: ;APP
  111. // CHECK: ld r{{[0-9]+}}, -Z
  112. // CHECK: ;NO_APP
  113. #[no_mangle]
  114. pub unsafe fn ld_predecrement(x: i16) -> i8 {
  115. let y;
  116. asm!("ld {}, -Z", out(reg) y, in("Z") x);
  117. y
  118. }
  119. // CHECK-LABEL: ld_postincrement:
  120. // CHECK: ;APP
  121. // CHECK: ld r{{[0-9]+}}, Z+
  122. // CHECK: ;NO_APP
  123. #[no_mangle]
  124. pub unsafe fn ld_postincrement(x: i16) -> i8 {
  125. let y;
  126. asm!("ld {}, Z+", out(reg) y, in("Z") x);
  127. y
  128. }
  129. // CHECK-LABEL: muls_clobber:
  130. // CHECK: ;APP
  131. // CHECK: muls r{{[0-9]+}}, r{{[0-9]+}}
  132. // CHECK: movw r{{[0-9]+}}, r0
  133. // CHECK: ;NO_APP
  134. #[no_mangle]
  135. pub unsafe fn muls_clobber(x: i8, y: i8) -> i16 {
  136. let z;
  137. asm!(
  138. "muls {}, {}",
  139. "movw {}, r1:r0",
  140. out(reg_iw) z,
  141. in(reg) x,
  142. in(reg) y,
  143. );
  144. z
  145. }
  146. // CHECK-LABEL: reg_i8:
  147. // CHECK: ;APP
  148. // CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
  149. // CHECK: ;NO_APP
  150. check!(reg_i8 i8 reg);
  151. // CHECK-LABEL: reg_upper_i8:
  152. // CHECK: ;APP
  153. // CHECK: mov r{{[1-3][0-9]}}, r{{[1-3][0-9]}}
  154. // CHECK: ;NO_APP
  155. check!(reg_upper_i8 i8 reg_upper);
  156. // CHECK-LABEL: reg_pair_i16:
  157. // CHECK: ;APP
  158. // CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
  159. // CHECK: ;NO_APP
  160. checkw!(reg_pair_i16 i16 reg_pair);
  161. // CHECK-LABEL: reg_iw_i16:
  162. // CHECK: ;APP
  163. // CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
  164. // CHECK: ;NO_APP
  165. checkw!(reg_iw_i16 i16 reg_iw);
  166. // CHECK-LABEL: reg_ptr_i16:
  167. // CHECK: ;APP
  168. // CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
  169. // CHECK: ;NO_APP
  170. checkw!(reg_ptr_i16 i16 reg_ptr);
  171. // CHECK-LABEL: r2_i8:
  172. // CHECK: ;APP
  173. // CHECK: mov r2, r2
  174. // CHECK: ;NO_APP
  175. check_reg!(r2_i8 i8 "r2");
  176. // CHECK-LABEL: xl_i8:
  177. // CHECK: ;APP
  178. // CHECK: mov r26, r26
  179. // CHECK: ;NO_APP
  180. check_reg!(xl_i8 i8 "XL");
  181. // CHECK-LABEL: xh_i8:
  182. // CHECK: ;APP
  183. // CHECK: mov r27, r27
  184. // CHECK: ;NO_APP
  185. check_reg!(xh_i8 i8 "XH");
  186. // CHECK-LABEL: x_i16:
  187. // CHECK: ;APP
  188. // CHECK: movw r26, r26
  189. // CHECK: ;NO_APP
  190. check_regw!(x_i16 i16 "X" "X");
  191. // CHECK-LABEL: r25r24_i16:
  192. // CHECK: ;APP
  193. // CHECK: movw r24, r24
  194. // CHECK: ;NO_APP
  195. check_regw!(r25r24_i16 i16 "r25r24" "r24");