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: auipc t0, %pcrel_hi(extern_static)
59 // CHECK: lb t0, %pcrel_lo(.Lpcrel_hi0)(t0)
62 pub unsafe fn sym_static() {
63 asm!("lb t0, {}", sym extern_static);
67 ($func:ident $ty:ident $class:ident $mov:literal) => {
69 pub unsafe fn $func(x: $ty) -> $ty {
70 // Hack to avoid function merging
72 fn dont_merge(s: &str);
74 dont_merge(stringify!($func));
77 asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
83 macro_rules! check_reg {
84 ($func:ident $ty:ident $reg:tt $mov:literal) => {
86 pub unsafe fn $func(x: $ty) -> $ty {
87 // Hack to avoid function merging
89 fn dont_merge(s: &str);
91 dont_merge(stringify!($func));
94 asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
100 // CHECK-LABEL: reg_i8:
102 // CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
104 check!(reg_i8 i8 reg "mv");
106 // CHECK-LABEL: reg_i16:
108 // CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
110 check!(reg_i16 i16 reg "mv");
112 // CHECK-LABEL: reg_i32:
114 // CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
116 check!(reg_i32 i32 reg "mv");
118 // CHECK-LABEL: reg_f32:
120 // CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
122 check!(reg_f32 f32 reg "mv");
124 // riscv64-LABEL: reg_i64:
126 // riscv64: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
129 check!(reg_i64 i64 reg "mv");
131 // riscv64-LABEL: reg_f64:
133 // riscv64: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
136 check!(reg_f64 f64 reg "mv");
138 // CHECK-LABEL: reg_ptr:
140 // CHECK: add {{[a-z0-9]+}}, zero, {{[a-z0-9]+}}
142 check!(reg_ptr ptr reg "mv");
144 // CHECK-LABEL: freg_f32:
146 // CHECK: fmv.s f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
148 check!(freg_f32 f32 freg "fmv.s");
150 // CHECK-LABEL: freg_f64:
152 // CHECK: fmv.d f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
154 check!(freg_f64 f64 freg "fmv.d");
156 // CHECK-LABEL: a0_i8:
158 // CHECK: add a0, zero, a0
160 check_reg!(a0_i8 i8 "a0" "mv");
162 // CHECK-LABEL: a0_i16:
164 // CHECK: add a0, zero, a0
166 check_reg!(a0_i16 i16 "a0" "mv");
168 // CHECK-LABEL: a0_i32:
170 // CHECK: add a0, zero, a0
172 check_reg!(a0_i32 i32 "a0" "mv");
174 // CHECK-LABEL: a0_f32:
176 // CHECK: add a0, zero, a0
178 check_reg!(a0_f32 f32 "a0" "mv");
180 // riscv64-LABEL: a0_i64:
182 // riscv64: add a0, zero, a0
185 check_reg!(a0_i64 i64 "a0" "mv");
187 // riscv64-LABEL: a0_f64:
189 // riscv64: add a0, zero, a0
192 check_reg!(a0_f64 f64 "a0" "mv");
194 // CHECK-LABEL: a0_ptr:
196 // CHECK: add a0, zero, a0
198 check_reg!(a0_ptr ptr "a0" "mv");
200 // CHECK-LABEL: fa0_f32:
202 // CHECK: fmv.s fa0, fa0
204 check_reg!(fa0_f32 f32 "fa0" "fmv.s");
206 // CHECK-LABEL: fa0_f64:
208 // CHECK: fmv.d fa0, fa0
210 check_reg!(fa0_f64 f64 "fa0" "fmv.d");