macros: Always emit f16_enabled and f128_enabled attributes

Once we start addinf `f16` and `f128` routines, we will need to have
this cfg for almost all uses of `for_each_function`. Rather than needing
to specify this each time, always emit `#[cfg(f16_enabled)]` or
`#[cfg(f128_enabled)]` for each function that uses `f16` or `f128`,
respectively.
This commit is contained in:
Trevor Gross 2025-01-02 21:23:28 +00:00 committed by Trevor Gross
parent d39169556a
commit 3fb16fbdbe
9 changed files with 57 additions and 20 deletions

View file

@ -79,7 +79,7 @@ pub fn base_name_enum(attributes: pm::TokenStream, tokens: pm::TokenStream) -> p
/// // The Rust version's return type (e.g. `(f32, f32)`)
/// RustRet: $RustRet:ty,
/// // Attributes for the current function, if any
/// attrs: [$($meta:meta)*]
/// attrs: [$($attr:meta),*],
/// // Extra tokens passed directly (if any)
/// extra: [$extra:ident],
/// // Extra function-tokens passed directly (if any)
@ -97,6 +97,9 @@ pub fn base_name_enum(attributes: pm::TokenStream, tokens: pm::TokenStream) -> p
/// skip: [sin, cos],
/// // Attributes passed as `attrs` for specific functions. For example, here the invocation
/// // with `sinf` and that with `cosf` will both get `meta1` and `meta2`, but no others will.
/// //
/// // Note that `f16_enabled` and `f128_enabled` will always get emitted regardless of whether
/// // or not this is specified.
/// attributes: [
/// #[meta1]
/// #[meta2]
@ -255,16 +258,28 @@ fn expand(input: StructuredInput, fn_list: &[&MathOpInfo]) -> syn::Result<pm2::T
let fn_name = Ident::new(func.name, Span::call_site());
// Prepare attributes in an `attrs: ...` field
let meta_field = match &input.attributes {
Some(attrs) => {
let meta = attrs
.iter()
.filter(|map| map.names.contains(&fn_name))
.flat_map(|map| &map.meta);
quote! { attrs: [ #( #meta )* ] }
}
None => pm2::TokenStream::new(),
};
let mut meta_fields = Vec::new();
if let Some(attrs) = &input.attributes {
let meta_iter = attrs
.iter()
.filter(|map| map.names.contains(&fn_name))
.flat_map(|map| &map.meta)
.map(|v| v.into_token_stream());
meta_fields.extend(meta_iter);
}
// Always emit f16 and f128 meta so this doesn't need to be repeated everywhere
if func.rust_sig.args.contains(&Ty::F16) || func.rust_sig.returns.contains(&Ty::F16) {
let ts = quote! { cfg(f16_enabled) };
meta_fields.push(ts);
}
if func.rust_sig.args.contains(&Ty::F128) || func.rust_sig.returns.contains(&Ty::F128) {
let ts = quote! { cfg(f128_enabled) };
meta_fields.push(ts);
}
let meta_field = quote! { attrs: [ #( #meta_fields ),* ], };
// Prepare extra in an `extra: ...` field, running the replacer
let extra_field = match input.extra.clone() {

View file

@ -1,3 +1,5 @@
#![feature(f16)]
#![feature(f128)]
// `STATUS_DLL_NOT_FOUND` on i686 MinGW, not worth looking into.
#![cfg(not(all(target_arch = "x86", target_os = "windows", target_env = "gnu")))]
@ -11,11 +13,11 @@ macro_rules! basic {
RustFn: $RustFn:ty,
RustArgs: $RustArgs:ty,
RustRet: $RustRet:ty,
attrs: [$($meta:meta)*]
attrs: [$($attr:meta),*],
extra: [$($extra_tt:tt)*],
fn_extra: $fn_extra:expr,
) => {
$(#[$meta])*
$(#[$attr])*
mod $fn_name {
#[allow(unused)]
type FTy= $FTy;
@ -60,7 +62,9 @@ mod test_basic {
macro_rules! basic_no_extra {
(
fn_name: $fn_name:ident,
attrs: [$($attr:meta),*],
) => {
$(#[$attr])*
mod $fn_name {}
};
}
@ -85,7 +89,9 @@ macro_rules! specified_types {
fn_name: $fn_name:ident,
RustFn: $RustFn:ty,
RustArgs: $RustArgs:ty,
attrs: [$($attr:meta),*],
) => {
$(#[$attr])*
mod $fn_name {
#[allow(unused)]
type RustFnTy = $RustFn;

View file

@ -18,9 +18,11 @@ struct MuslExtra<F> {
macro_rules! musl_rand_benches {
(
fn_name: $fn_name:ident,
attrs: [$($attr:meta),*],
fn_extra: $skip_on_i586:expr,
) => {
paste::paste! {
$(#[$attr])*
fn [< musl_bench_ $fn_name >](c: &mut Criterion) {
type Op = libm_test::op::$fn_name::Routine;
@ -113,9 +115,11 @@ libm_macros::for_each_function! {
macro_rules! run_callback {
(
fn_name: $fn_name:ident,
attrs: [$($attr:meta),*],
extra: [$criterion:ident],
) => {
paste::paste! {
$(#[$attr])*
[< musl_bench_ $fn_name >](&mut $criterion)
}
};

View file

@ -1,3 +1,5 @@
#![cfg_attr(f16_enabled, feature(f16))]
#![cfg_attr(f128_enabled, feature(f128))]
#![allow(clippy::unusual_byte_groupings)] // sometimes we group by sign_exp_sig
pub mod domain;

View file

@ -50,9 +50,11 @@ macro_rules! impl_mp_op {
(
fn_name: $fn_name:ident,
RustFn: fn($_fty:ty,) -> $_ret:ty,
attrs: [$($attr:meta),*],
fn_extra: $fn_name_normalized:expr,
) => {
paste::paste! {
$(#[$attr])*
impl MpOp for crate::op::$fn_name::Routine {
type MpTy = MpFloat;
@ -72,9 +74,11 @@ macro_rules! impl_mp_op {
(
fn_name: $fn_name:ident,
RustFn: fn($_fty:ty, $_fty2:ty,) -> $_ret:ty,
attrs: [$($attr:meta),*],
fn_extra: $fn_name_normalized:expr,
) => {
paste::paste! {
$(#[$attr])*
impl MpOp for crate::op::$fn_name::Routine {
type MpTy = (MpFloat, MpFloat);
@ -95,9 +99,11 @@ macro_rules! impl_mp_op {
(
fn_name: $fn_name:ident,
RustFn: fn($_fty:ty, $_fty2:ty, $_fty3:ty,) -> $_ret:ty,
attrs: [$($attr:meta),*],
fn_extra: $fn_name_normalized:expr,
) => {
paste::paste! {
$(#[$attr])*
impl MpOp for crate::op::$fn_name::Routine {
type MpTy = (MpFloat, MpFloat, MpFloat);

View file

@ -112,8 +112,11 @@ macro_rules! do_thing {
RustFn: $RustFn:ty,
RustArgs: $RustArgs:ty,
RustRet: $RustRet:ty,
attrs: [$($attr:meta),*],
) => {
paste::paste! {
$(#[$attr])*
pub mod $fn_name {
use super::*;
pub struct Routine;

View file

@ -8,6 +8,7 @@ use std::process::Command;
macro_rules! callback {
(
fn_name: $name:ident,
attrs: [$($attr:meta),*],
extra: [$set:ident],
) => {
let name = stringify!($name);

View file

@ -15,11 +15,11 @@ use libm_test::{CheckBasis, CheckCtx, CheckOutput, GenerateInput, MathOp, TupleC
macro_rules! musl_rand_tests {
(
fn_name: $fn_name:ident,
attrs: [$($meta:meta)*]
attrs: [$($attr:meta),*],
) => {
paste::paste! {
#[test]
$(#[$meta])*
$(#[$attr])*
fn [< musl_random_ $fn_name >]() {
test_one::<libm_test::op::$fn_name::Routine>(musl_math_sys::$fn_name);
}

View file

@ -13,11 +13,11 @@ use libm_test::{
macro_rules! mp_rand_tests {
(
fn_name: $fn_name:ident,
attrs: [$($meta:meta)*]
attrs: [$($attr:meta),*],
) => {
paste::paste! {
#[test]
$(#[$meta])*
$(#[$attr])*
fn [< mp_random_ $fn_name >]() {
test_one_random::<libm_test::op::$fn_name::Routine>();
}
@ -76,18 +76,18 @@ libm_macros::for_each_function! {
macro_rules! mp_domain_tests {
(
fn_name: $fn_name:ident,
attrs: [$($meta:meta)*]
attrs: [$($attr:meta),*],
) => {
paste::paste! {
#[test]
$(#[$meta])*
$(#[$attr])*
fn [< mp_edge_case_ $fn_name >]() {
type Op = libm_test::op::$fn_name::Routine;
domain_test_runner::<Op, _>(edge_cases::get_test_cases::<Op, _>);
}
#[test]
$(#[$meta])*
$(#[$attr])*
fn [< mp_logspace_ $fn_name >]() {
type Op = libm_test::op::$fn_name::Routine;
domain_test_runner::<Op, _>(domain_logspace::get_test_cases::<Op>);