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

https://gitlab.com/rust-lang/rust · Rust · 210 lines · 90 code · 30 blank · 90 comment · 7 complexity · c2bc646eb27ff34026d9bfac0072b429 MD5 · raw file

  1. // revisions: riscv64 riscv32
  2. // assembly-output: emit-asm
  3. //[riscv64] compile-flags: --target riscv64imac-unknown-none-elf
  4. //[riscv64] needs-llvm-components: riscv
  5. //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf
  6. //[riscv32] needs-llvm-components: riscv
  7. // compile-flags: -C target-feature=+d
  8. #![feature(no_core, lang_items, rustc_attrs, asm_sym)]
  9. #![crate_type = "rlib"]
  10. #![no_core]
  11. #![allow(asm_sub_register)]
  12. #[rustc_builtin_macro]
  13. macro_rules! asm {
  14. () => {};
  15. }
  16. #[rustc_builtin_macro]
  17. macro_rules! concat {
  18. () => {};
  19. }
  20. #[rustc_builtin_macro]
  21. macro_rules! stringify {
  22. () => {};
  23. }
  24. #[lang = "sized"]
  25. trait Sized {}
  26. #[lang = "copy"]
  27. trait Copy {}
  28. type ptr = *mut u8;
  29. impl Copy for i8 {}
  30. impl Copy for i16 {}
  31. impl Copy for i32 {}
  32. impl Copy for f32 {}
  33. impl Copy for i64 {}
  34. impl Copy for f64 {}
  35. impl Copy for ptr {}
  36. extern "C" {
  37. fn extern_func();
  38. static extern_static: u8;
  39. }
  40. // CHECK-LABEL: sym_fn:
  41. // CHECK: #APP
  42. // CHECK: call extern_func
  43. // CHECK: #NO_APP
  44. #[no_mangle]
  45. pub unsafe fn sym_fn() {
  46. asm!("call {}", sym extern_func);
  47. }
  48. // CHECK-LABEL: sym_static:
  49. // CHECK: #APP
  50. // CHECK: auipc t0, %pcrel_hi(extern_static)
  51. // CHECK: lb t0, %pcrel_lo(.Lpcrel_hi0)(t0)
  52. // CHECK: #NO_APP
  53. #[no_mangle]
  54. pub unsafe fn sym_static() {
  55. asm!("lb t0, {}", sym extern_static);
  56. }
  57. macro_rules! check {
  58. ($func:ident $ty:ident $class:ident $mov:literal) => {
  59. #[no_mangle]
  60. pub unsafe fn $func(x: $ty) -> $ty {
  61. // Hack to avoid function merging
  62. extern "Rust" {
  63. fn dont_merge(s: &str);
  64. }
  65. dont_merge(stringify!($func));
  66. let y;
  67. asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
  68. y
  69. }
  70. };
  71. }
  72. macro_rules! check_reg {
  73. ($func:ident $ty:ident $reg:tt $mov:literal) => {
  74. #[no_mangle]
  75. pub unsafe fn $func(x: $ty) -> $ty {
  76. // Hack to avoid function merging
  77. extern "Rust" {
  78. fn dont_merge(s: &str);
  79. }
  80. dont_merge(stringify!($func));
  81. let y;
  82. asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
  83. y
  84. }
  85. };
  86. }
  87. // CHECK-LABEL: reg_i8:
  88. // CHECK: #APP
  89. // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  90. // CHECK: #NO_APP
  91. check!(reg_i8 i8 reg "mv");
  92. // CHECK-LABEL: reg_i16:
  93. // CHECK: #APP
  94. // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  95. // CHECK: #NO_APP
  96. check!(reg_i16 i16 reg "mv");
  97. // CHECK-LABEL: reg_i32:
  98. // CHECK: #APP
  99. // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  100. // CHECK: #NO_APP
  101. check!(reg_i32 i32 reg "mv");
  102. // CHECK-LABEL: reg_f32:
  103. // CHECK: #APP
  104. // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  105. // CHECK: #NO_APP
  106. check!(reg_f32 f32 reg "mv");
  107. // riscv64-LABEL: reg_i64:
  108. // riscv64: #APP
  109. // riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  110. // riscv64: #NO_APP
  111. #[cfg(riscv64)]
  112. check!(reg_i64 i64 reg "mv");
  113. // riscv64-LABEL: reg_f64:
  114. // riscv64: #APP
  115. // riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  116. // riscv64: #NO_APP
  117. #[cfg(riscv64)]
  118. check!(reg_f64 f64 reg "mv");
  119. // CHECK-LABEL: reg_ptr:
  120. // CHECK: #APP
  121. // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
  122. // CHECK: #NO_APP
  123. check!(reg_ptr ptr reg "mv");
  124. // CHECK-LABEL: freg_f32:
  125. // CHECK: #APP
  126. // CHECK: fmv.s f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
  127. // CHECK: #NO_APP
  128. check!(freg_f32 f32 freg "fmv.s");
  129. // CHECK-LABEL: freg_f64:
  130. // CHECK: #APP
  131. // CHECK: fmv.d f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
  132. // CHECK: #NO_APP
  133. check!(freg_f64 f64 freg "fmv.d");
  134. // CHECK-LABEL: a0_i8:
  135. // CHECK: #APP
  136. // CHECK: mv a0, a0
  137. // CHECK: #NO_APP
  138. check_reg!(a0_i8 i8 "a0" "mv");
  139. // CHECK-LABEL: a0_i16:
  140. // CHECK: #APP
  141. // CHECK: mv a0, a0
  142. // CHECK: #NO_APP
  143. check_reg!(a0_i16 i16 "a0" "mv");
  144. // CHECK-LABEL: a0_i32:
  145. // CHECK: #APP
  146. // CHECK: mv a0, a0
  147. // CHECK: #NO_APP
  148. check_reg!(a0_i32 i32 "a0" "mv");
  149. // CHECK-LABEL: a0_f32:
  150. // CHECK: #APP
  151. // CHECK: mv a0, a0
  152. // CHECK: #NO_APP
  153. check_reg!(a0_f32 f32 "a0" "mv");
  154. // riscv64-LABEL: a0_i64:
  155. // riscv64: #APP
  156. // riscv64: mv a0, a0
  157. // riscv64: #NO_APP
  158. #[cfg(riscv64)]
  159. check_reg!(a0_i64 i64 "a0" "mv");
  160. // riscv64-LABEL: a0_f64:
  161. // riscv64: #APP
  162. // riscv64: mv a0, a0
  163. // riscv64: #NO_APP
  164. #[cfg(riscv64)]
  165. check_reg!(a0_f64 f64 "a0" "mv");
  166. // CHECK-LABEL: a0_ptr:
  167. // CHECK: #APP
  168. // CHECK: mv a0, a0
  169. // CHECK: #NO_APP
  170. check_reg!(a0_ptr ptr "a0" "mv");
  171. // CHECK-LABEL: fa0_f32:
  172. // CHECK: #APP
  173. // CHECK: fmv.s fa0, fa0
  174. // CHECK: #NO_APP
  175. check_reg!(fa0_f32 f32 "fa0" "fmv.s");
  176. // CHECK-LABEL: fa0_f64:
  177. // CHECK: #APP
  178. // CHECK: fmv.d fa0, fa0
  179. // CHECK: #NO_APP
  180. check_reg!(fa0_f64 f64 "fa0" "fmv.d");