2 // revisions: riscv64 riscv32
3 // assembly-output: emit-asm
4 //[riscv64] compile-flags: --target riscv64imac-unknown-none-elf
5 //[riscv32] compile-flags: --target riscv32imac-unknown-none-elf
6 // compile-flags: -C target-feature=+d
7 // needs-llvm-components: riscv
9 #![feature(no_core, lang_items, rustc_attrs)]
10 #![crate_type = "rlib"]
12 #![allow(asm_sub_register)]
14 #[rustc_builtin_macro]
18 #[rustc_builtin_macro]
22 #[rustc_builtin_macro]
23 macro_rules! stringify {
44 static extern_static: u8;
47 // CHECK-LABEL: sym_fn:
49 // CHECK: call extern_func
52 pub unsafe fn sym_fn() {
53 asm!("call {}", sym extern_func);
56 // CHECK-LABEL: sym_static:
58 // CHECK: lb t0, extern_static
61 pub unsafe fn sym_static() {
62 asm!("lb t0, {}", sym extern_static);
66 ($func:ident $ty:ident $class:ident $mov:literal) => {
68 pub unsafe fn $func(x: $ty) -> $ty {
69 // Hack to avoid function merging
71 fn dont_merge(s: &str);
73 dont_merge(stringify!($func));
76 asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
82 macro_rules! check_reg {
83 ($func:ident $ty:ident $reg:tt $mov:literal) => {
85 pub unsafe fn $func(x: $ty) -> $ty {
86 // Hack to avoid function merging
88 fn dont_merge(s: &str);
90 dont_merge(stringify!($func));
93 asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
99 // CHECK-LABEL: reg_i8:
101 // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
103 check!(reg_i8 i8 reg "mv");
105 // CHECK-LABEL: reg_i16:
107 // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
109 check!(reg_i16 i16 reg "mv");
111 // CHECK-LABEL: reg_i32:
113 // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
115 check!(reg_i32 i32 reg "mv");
117 // CHECK-LABEL: reg_f32:
119 // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
121 check!(reg_f32 f32 reg "mv");
123 // riscv64-LABEL: reg_i64:
125 // riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
128 check!(reg_i64 i64 reg "mv");
130 // riscv64-LABEL: reg_f64:
132 // riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
135 check!(reg_f64 f64 reg "mv");
137 // CHECK-LABEL: reg_ptr:
139 // CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
141 check!(reg_ptr ptr reg "mv");
143 // CHECK-LABEL: freg_f32:
145 // CHECK: fmv.s f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
147 check!(freg_f32 f32 freg "fmv.s");
149 // CHECK-LABEL: freg_f64:
151 // CHECK: fmv.d f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
153 check!(freg_f64 f64 freg "fmv.d");
155 // CHECK-LABEL: a0_i8:
159 check_reg!(a0_i8 i8 "a0" "mv");
161 // CHECK-LABEL: a0_i16:
165 check_reg!(a0_i16 i16 "a0" "mv");
167 // CHECK-LABEL: a0_i32:
171 check_reg!(a0_i32 i32 "a0" "mv");
173 // CHECK-LABEL: a0_f32:
177 check_reg!(a0_f32 f32 "a0" "mv");
179 // riscv64-LABEL: a0_i64:
181 // riscv64: mv a0, a0
184 check_reg!(a0_i64 i64 "a0" "mv");
186 // riscv64-LABEL: a0_f64:
188 // riscv64: mv a0, a0
191 check_reg!(a0_f64 f64 "a0" "mv");
193 // CHECK-LABEL: a0_ptr:
197 check_reg!(a0_ptr ptr "a0" "mv");
199 // CHECK-LABEL: fa0_f32:
201 // CHECK: fmv.s fa0, fa0
203 check_reg!(fa0_f32 f32 "fa0" "fmv.s");
205 // CHECK-LABEL: fa0_f64:
207 // CHECK: fmv.d fa0, fa0
209 check_reg!(fa0_f64 f64 "fa0" "fmv.d");