Skip to content

Commit d60e71d

Browse files
committed
Add loop_asm macro
1 parent a36d477 commit d60e71d

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

riscv-rt/macros/src/lib.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ extern crate proc_macro2;
99
extern crate syn;
1010

1111
use proc_macro2::Span;
12-
use syn::{parse, spanned::Spanned, FnArg, ItemFn, PathArguments, ReturnType, Type, Visibility};
12+
use syn::{parse::{self, Parse}, spanned::Spanned, FnArg, ItemFn, PathArguments, ReturnType, Type, Visibility, LitStr, LitInt};
1313

1414
use proc_macro::TokenStream;
1515

@@ -205,3 +205,33 @@ pub fn pre_init(args: TokenStream, input: TokenStream) -> TokenStream {
205205
)
206206
.into()
207207
}
208+
209+
struct AsmLoopArgs {
210+
asm_template: String,
211+
count: usize,
212+
}
213+
214+
impl Parse for AsmLoopArgs {
215+
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
216+
let template: LitStr = input.parse().unwrap();
217+
_ = input.parse::<Token![,]>().unwrap();
218+
let count: LitInt = input.parse().unwrap();
219+
220+
Ok(Self {
221+
asm_template: template.value(),
222+
count: count.base10_parse().unwrap(),
223+
})
224+
}
225+
}
226+
227+
#[proc_macro]
228+
pub fn loop_asm(input: TokenStream) -> TokenStream {
229+
let args = parse_macro_input!(input as AsmLoopArgs);
230+
231+
let tokens = (0..args.count).map(|i| {
232+
let i = i.to_string();
233+
let asm = args.asm_template.replace("{}", &i);
234+
format!("core::arch::asm!(\"{}\");", asm)
235+
}).collect::<Vec<String>>().join("\n");
236+
tokens.parse().unwrap()
237+
}

riscv-rt/src/lib.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -524,17 +524,15 @@ pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! {
524524
core::arch::asm!("fscsr x0"); // Zero out fcsr register csrrw x0, fcsr, x0
525525

526526
// Zero out floating point registers
527-
for i in 0..32 {
528-
if cfg!(all(riscv32, riscvd)) {
529-
// rv32 targets with double precision floating point can use fmvp.d.x
530-
// to combine 2 32 bit registers to fill the 64 bit floating point
531-
// register
532-
core::arch::asm!("fmvp.d.x f{}, x0, x0", i);
533-
} else if cfg!(riscvd) {
534-
core::arch::asm!("fmv.d.x f{}, x0", i);
535-
} else {
536-
core::arch::asm!("fmv.w.x f{}, x0", i);
537-
}
527+
if cfg!(all(target_arch = "riscv32", riscvd)) {
528+
// rv32 targets with double precision floating point can use fmvp.d.x
529+
// to combine 2 32 bit registers to fill the 64 bit floating point
530+
// register
531+
riscv_rt_macros::loop_asm!("fmvp.d.x f{}, x0, x0", 32);
532+
} else if cfg!(riscvd) {
533+
riscv_rt_macros::loop_asm!("fmv.d.x f{}, x0", 32);
534+
} else {
535+
riscv_rt_macros::loop_asm!("fmv.w.x f{}, x0", 32);
538536
}
539537
}
540538

0 commit comments

Comments
 (0)