use std::collections::{HashMap, HashSet};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum LibFunc {
Memcpy,
Memmove,
Memset,
Memcmp,
Memchr,
Memrchr,
Bcopy,
Bzero,
Bcmp,
Memccpy,
Mempcpy,
Strlen,
Strnlen,
Strcpy,
Strncpy,
Stpcpy,
Stpncpy,
Strcat,
Strncat,
Strcmp,
Strncmp,
Strcasecmp,
Strncasecmp,
Strchr,
Strrchr,
Strstr,
Strpbrk,
Strspn,
Strcspn,
Strsep,
Strtok,
Strdup,
Strndup,
Isdigit,
Isalpha,
Isalnum,
Isxdigit,
Islower,
Isupper,
Isspace,
Isprint,
Isgraph,
Ispunct,
Iscntrl,
Isblank,
ToLower,
ToUpper,
Sin,
Cos,
Tan,
Asin,
Acos,
Atan,
Atan2,
Sinh,
Cosh,
Tanh,
Asinh,
Acosh,
Atanh,
Exp,
Exp2,
Exp10,
ExpM1,
Log,
Log2,
Log10,
Log1p,
LogB,
Sqrt,
Cbrt,
Fabs,
Fmod,
Remainder,
Copysign,
Pow,
PowI,
Hypot,
Erf,
Erfc,
Lgamma,
LgammaR,
Tgamma,
Fma,
Fmax,
Fmin,
Fdim,
Ceil,
Floor,
Trunc,
Round,
RoundEven,
Rint,
Nearbyint,
Lrint,
Llrint,
Lround,
Llround,
Ilogb,
Fpclassify,
IsFinite,
IsInf,
IsNan,
IsNormal,
Signbit,
SinF,
CosF,
TanF,
AsinF,
AcosF,
AtanF,
Atan2F,
ExpF,
Exp2F,
LogF,
Log2F,
Log10F,
SqrtF,
FabsF,
FmodF,
PowF,
CeilF,
FloorF,
TruncF,
RoundF,
RintF,
FmaF,
FmaxF,
FminF,
HypotF,
SinL,
CosL,
TanL,
ExpL,
LogL,
SqrtL,
FabsL,
PowL,
CeilL,
FloorL,
TruncL,
Printf,
Fprintf,
Sprintf,
Snprintf,
Puts,
Fputs,
Putchar,
Fputc,
Putc,
Fwrite,
Fread,
Fgets,
Gets,
Scanf,
Fscanf,
Sscanf,
Getchar,
Malloc,
Calloc,
Realloc,
Free,
AlignedAlloc,
PosixMemalign,
Memalign,
Valloc,
Pvalloc,
Exit,
Abort,
Atexit,
Getenv,
System,
Qsort,
Bsearch,
Abs,
Labs,
Llabs,
Rand,
Srand,
Atoi,
Atol,
Atoll,
Atof,
Strtol,
Strtoll,
Strtoul,
Strtoull,
Strtod,
Strtof,
Strtold,
PthreadCreate,
PthreadJoin,
PthreadMutexLock,
PthreadMutexUnlock,
PthreadMutexInit,
PthreadMutexDestroy,
PthreadOnce,
PthreadKeyCreate,
PthreadKeyDelete,
PthreadSetspecific,
PthreadGetspecific,
TlsGetAddr,
Getpid,
Getppid,
Gettid,
Getuid,
Geteuid,
Getgid,
Getegid,
Fork,
Execve,
Execvp,
Wait,
Waitpid,
Kill,
Signal,
Sigaction,
Alarm,
Sleep,
Ualarm,
Nanosleep,
Clock,
Time,
Gettimeofday,
ClockGettime,
Setjmp,
Longjmp,
Sigsetjmp,
Siglongjmp,
UnwindResume,
Setlocale,
Localeconv,
Strcoll,
Strxfrm,
Perror,
Strerror,
StrerrorR,
Ferror,
Feof,
Clearerr,
_Setjmp,
_Longjmp,
__Sigsetjmp,
__SinF16,
__CosF16,
__SinF32,
__CosF32,
__SinF64,
__CosF64,
__PowF32,
__PowF64,
Fesetround,
Fegetround,
Feclearexcept,
Feraiseexcept,
Fetestexcept,
Fegetexceptflag,
Fesetexceptflag,
Feholdexcept,
Feupdateenv,
Fegetenv,
Fesetenv,
}
impl LibFunc {
pub fn c_name(&self) -> &'static str {
match self {
LibFunc::Memcpy => "memcpy",
LibFunc::Memmove => "memmove",
LibFunc::Memset => "memset",
LibFunc::Memcmp => "memcmp",
LibFunc::Memchr => "memchr",
LibFunc::Memrchr => "memrchr",
LibFunc::Bcopy => "bcopy",
LibFunc::Bzero => "bzero",
LibFunc::Bcmp => "bcmp",
LibFunc::Memccpy => "memccpy",
LibFunc::Mempcpy => "mempcpy",
LibFunc::Strlen => "strlen",
LibFunc::Strnlen => "strnlen",
LibFunc::Strcpy => "strcpy",
LibFunc::Strncpy => "strncpy",
LibFunc::Stpcpy => "stpcpy",
LibFunc::Stpncpy => "stpncpy",
LibFunc::Strcat => "strcat",
LibFunc::Strncat => "strncat",
LibFunc::Strcmp => "strcmp",
LibFunc::Strncmp => "strncmp",
LibFunc::Strcasecmp => "strcasecmp",
LibFunc::Strncasecmp => "strncasecmp",
LibFunc::Strchr => "strchr",
LibFunc::Strrchr => "strrchr",
LibFunc::Strstr => "strstr",
LibFunc::Strpbrk => "strpbrk",
LibFunc::Strspn => "strspn",
LibFunc::Strcspn => "strcspn",
LibFunc::Strsep => "strsep",
LibFunc::Strtok => "strtok",
LibFunc::Strdup => "strdup",
LibFunc::Strndup => "strndup",
LibFunc::Isdigit => "isdigit",
LibFunc::Isalpha => "isalpha",
LibFunc::Isalnum => "isalnum",
LibFunc::Isxdigit => "isxdigit",
LibFunc::Islower => "islower",
LibFunc::Isupper => "isupper",
LibFunc::Isspace => "isspace",
LibFunc::Isprint => "isprint",
LibFunc::Isgraph => "isgraph",
LibFunc::Ispunct => "ispunct",
LibFunc::Iscntrl => "iscntrl",
LibFunc::Isblank => "isblank",
LibFunc::ToLower => "tolower",
LibFunc::ToUpper => "toupper",
LibFunc::Sin => "sin",
LibFunc::Cos => "cos",
LibFunc::Tan => "tan",
LibFunc::Asin => "asin",
LibFunc::Acos => "acos",
LibFunc::Atan => "atan",
LibFunc::Atan2 => "atan2",
LibFunc::Sinh => "sinh",
LibFunc::Cosh => "cosh",
LibFunc::Tanh => "tanh",
LibFunc::Asinh => "asinh",
LibFunc::Acosh => "acosh",
LibFunc::Atanh => "atanh",
LibFunc::Exp => "exp",
LibFunc::Exp2 => "exp2",
LibFunc::Exp10 => "exp10",
LibFunc::ExpM1 => "expm1",
LibFunc::Log => "log",
LibFunc::Log2 => "log2",
LibFunc::Log10 => "log10",
LibFunc::Log1p => "log1p",
LibFunc::LogB => "logb",
LibFunc::Sqrt => "sqrt",
LibFunc::Cbrt => "cbrt",
LibFunc::Fabs => "fabs",
LibFunc::Fmod => "fmod",
LibFunc::Remainder => "remainder",
LibFunc::Copysign => "copysign",
LibFunc::Pow => "pow",
LibFunc::PowI => "powi",
LibFunc::Hypot => "hypot",
LibFunc::Erf => "erf",
LibFunc::Erfc => "erfc",
LibFunc::Lgamma => "lgamma",
LibFunc::LgammaR => "lgamma_r",
LibFunc::Tgamma => "tgamma",
LibFunc::Fma => "fma",
LibFunc::Fmax => "fmax",
LibFunc::Fmin => "fmin",
LibFunc::Fdim => "fdim",
LibFunc::Ceil => "ceil",
LibFunc::Floor => "floor",
LibFunc::Trunc => "trunc",
LibFunc::Round => "round",
LibFunc::RoundEven => "roundeven",
LibFunc::Rint => "rint",
LibFunc::Nearbyint => "nearbyint",
LibFunc::Lrint => "lrint",
LibFunc::Llrint => "llrint",
LibFunc::Lround => "lround",
LibFunc::Llround => "llround",
LibFunc::Ilogb => "ilogb",
LibFunc::Fpclassify => "fpclassify",
LibFunc::IsFinite => "isfinite",
LibFunc::IsInf => "isinf",
LibFunc::IsNan => "isnan",
LibFunc::IsNormal => "isnormal",
LibFunc::Signbit => "signbit",
LibFunc::SinF => "sinf",
LibFunc::CosF => "cosf",
LibFunc::TanF => "tanf",
LibFunc::AsinF => "asinf",
LibFunc::AcosF => "acosf",
LibFunc::AtanF => "atanf",
LibFunc::Atan2F => "atan2f",
LibFunc::ExpF => "expf",
LibFunc::Exp2F => "exp2f",
LibFunc::LogF => "logf",
LibFunc::Log2F => "log2f",
LibFunc::Log10F => "log10f",
LibFunc::SqrtF => "sqrtf",
LibFunc::FabsF => "fabsf",
LibFunc::FmodF => "fmodf",
LibFunc::PowF => "powf",
LibFunc::CeilF => "ceilf",
LibFunc::FloorF => "floorf",
LibFunc::TruncF => "truncf",
LibFunc::RoundF => "roundf",
LibFunc::RintF => "rintf",
LibFunc::FmaF => "fmaf",
LibFunc::FmaxF => "fmaxf",
LibFunc::FminF => "fminf",
LibFunc::HypotF => "hypotf",
LibFunc::SinL => "sinl",
LibFunc::CosL => "cosl",
LibFunc::TanL => "tanl",
LibFunc::ExpL => "expl",
LibFunc::LogL => "logl",
LibFunc::SqrtL => "sqrtl",
LibFunc::FabsL => "fabsl",
LibFunc::PowL => "powl",
LibFunc::CeilL => "ceill",
LibFunc::FloorL => "floorl",
LibFunc::TruncL => "truncl",
LibFunc::Printf => "printf",
LibFunc::Fprintf => "fprintf",
LibFunc::Sprintf => "sprintf",
LibFunc::Snprintf => "snprintf",
LibFunc::Puts => "puts",
LibFunc::Fputs => "fputs",
LibFunc::Putchar => "putchar",
LibFunc::Fputc => "fputc",
LibFunc::Putc => "putc",
LibFunc::Fwrite => "fwrite",
LibFunc::Fread => "fread",
LibFunc::Fgets => "fgets",
LibFunc::Gets => "gets",
LibFunc::Scanf => "scanf",
LibFunc::Fscanf => "fscanf",
LibFunc::Sscanf => "sscanf",
LibFunc::Getchar => "getchar",
LibFunc::Malloc => "malloc",
LibFunc::Calloc => "calloc",
LibFunc::Realloc => "realloc",
LibFunc::Free => "free",
LibFunc::AlignedAlloc => "aligned_alloc",
LibFunc::PosixMemalign => "posix_memalign",
LibFunc::Memalign => "memalign",
LibFunc::Valloc => "valloc",
LibFunc::Pvalloc => "pvalloc",
LibFunc::Exit => "exit",
LibFunc::Abort => "abort",
LibFunc::Atexit => "atexit",
LibFunc::Getenv => "getenv",
LibFunc::System => "system",
LibFunc::Qsort => "qsort",
LibFunc::Bsearch => "bsearch",
LibFunc::Abs => "abs",
LibFunc::Labs => "labs",
LibFunc::Llabs => "llabs",
LibFunc::Rand => "rand",
LibFunc::Srand => "srand",
LibFunc::Atoi => "atoi",
LibFunc::Atol => "atol",
LibFunc::Atoll => "atoll",
LibFunc::Atof => "atof",
LibFunc::Strtol => "strtol",
LibFunc::Strtoll => "strtoll",
LibFunc::Strtoul => "strtoul",
LibFunc::Strtoull => "strtoull",
LibFunc::Strtod => "strtod",
LibFunc::Strtof => "strtof",
LibFunc::Strtold => "strtold",
LibFunc::PthreadCreate => "pthread_create",
LibFunc::PthreadJoin => "pthread_join",
LibFunc::PthreadMutexLock => "pthread_mutex_lock",
LibFunc::PthreadMutexUnlock => "pthread_mutex_unlock",
LibFunc::PthreadMutexInit => "pthread_mutex_init",
LibFunc::PthreadMutexDestroy => "pthread_mutex_destroy",
LibFunc::PthreadOnce => "pthread_once",
LibFunc::PthreadKeyCreate => "pthread_key_create",
LibFunc::PthreadKeyDelete => "pthread_key_delete",
LibFunc::PthreadSetspecific => "pthread_setspecific",
LibFunc::PthreadGetspecific => "pthread_getspecific",
LibFunc::TlsGetAddr => "__tls_get_addr",
LibFunc::Getpid => "getpid",
LibFunc::Getppid => "getppid",
LibFunc::Gettid => "gettid",
LibFunc::Getuid => "getuid",
LibFunc::Geteuid => "geteuid",
LibFunc::Getgid => "getgid",
LibFunc::Getegid => "getegid",
LibFunc::Fork => "fork",
LibFunc::Execve => "execve",
LibFunc::Execvp => "execvp",
LibFunc::Wait => "wait",
LibFunc::Waitpid => "waitpid",
LibFunc::Kill => "kill",
LibFunc::Signal => "signal",
LibFunc::Sigaction => "sigaction",
LibFunc::Alarm => "alarm",
LibFunc::Sleep => "sleep",
LibFunc::Ualarm => "ualarm",
LibFunc::Nanosleep => "nanosleep",
LibFunc::Clock => "clock",
LibFunc::Time => "time",
LibFunc::Gettimeofday => "gettimeofday",
LibFunc::ClockGettime => "clock_gettime",
LibFunc::Setjmp => "setjmp",
LibFunc::Longjmp => "longjmp",
LibFunc::Sigsetjmp => "sigsetjmp",
LibFunc::Siglongjmp => "siglongjmp",
LibFunc::UnwindResume => "_Unwind_Resume",
LibFunc::Setlocale => "setlocale",
LibFunc::Localeconv => "localeconv",
LibFunc::Strcoll => "strcoll",
LibFunc::Strxfrm => "strxfrm",
LibFunc::Perror => "perror",
LibFunc::Strerror => "strerror",
LibFunc::StrerrorR => "strerror_r",
LibFunc::Ferror => "ferror",
LibFunc::Feof => "feof",
LibFunc::Clearerr => "clearerr",
LibFunc::_Setjmp => "_setjmp",
LibFunc::_Longjmp => "_longjmp",
LibFunc::__Sigsetjmp => "__sigsetjmp",
LibFunc::__SinF16 => "__sinf16",
LibFunc::__CosF16 => "__cosf16",
LibFunc::__SinF32 => "__sinf32",
LibFunc::__CosF32 => "__cosf32",
LibFunc::__SinF64 => "__sinf64",
LibFunc::__CosF64 => "__cosf64",
LibFunc::__PowF32 => "__powf32",
LibFunc::__PowF64 => "__powf64",
LibFunc::Fesetround => "fesetround",
LibFunc::Fegetround => "fegetround",
LibFunc::Feclearexcept => "feclearexcept",
LibFunc::Feraiseexcept => "feraiseexcept",
LibFunc::Fetestexcept => "fetestexcept",
LibFunc::Fegetexceptflag => "fegetexceptflag",
LibFunc::Fesetexceptflag => "fesetexceptflag",
LibFunc::Feholdexcept => "feholdexcept",
LibFunc::Feupdateenv => "feupdateenv",
LibFunc::Fegetenv => "fegetenv",
LibFunc::Fesetenv => "fesetenv",
}
}
}
#[derive(Debug, Clone)]
pub struct VecFuncMapping {
pub scalar: LibFunc,
pub vector_width: u32,
pub vector_name: String,
pub library: VectorLibrary,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VectorLibrary {
SVML,
Accelerate,
LibMVec,
ArmPL,
AOCL,
SLEEF,
LibSystem,
NoLibrary,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TargetPlatform {
Linux,
MacOS,
Windows,
FreeBSD,
Android,
IOS,
PS4,
PS5,
Haiku,
Solaris,
NetBSD,
OpenBSD,
DragonFly,
Fuchsia,
Emscripten,
Other,
}
impl TargetPlatform {
pub fn from_triple(triple: &str) -> Self {
if triple.contains("linux") {
TargetPlatform::Linux
} else if triple.contains("darwin") || triple.contains("macos") {
TargetPlatform::MacOS
} else if triple.contains("windows") || triple.contains("mingw") {
TargetPlatform::Windows
} else if triple.contains("freebsd") {
TargetPlatform::FreeBSD
} else if triple.contains("android") {
TargetPlatform::Android
} else if triple.contains("ios") {
TargetPlatform::IOS
} else {
TargetPlatform::Other
}
}
}
pub struct TargetLibraryInfo {
pub platform: TargetPlatform,
available: HashSet<LibFunc>,
unavailable: HashSet<LibFunc>,
vector_mappings: Vec<VecFuncMapping>,
pub memset_size_arg: u8,
pub memcpy_size_arg: u8,
pub memmove_size_arg: u8,
}
impl TargetLibraryInfo {
pub fn new(platform: TargetPlatform) -> Self {
let mut tli = Self {
platform,
available: HashSet::new(),
unavailable: HashSet::new(),
vector_mappings: Vec::new(),
memset_size_arg: 2,
memcpy_size_arg: 2,
memmove_size_arg: 2,
};
tli.init_platform_defaults();
tli.init_vector_mappings();
tli
}
fn init_platform_defaults(&mut self) {
let common: &[LibFunc] = &[
LibFunc::Sin,
LibFunc::Cos,
LibFunc::Tan,
LibFunc::Exp,
LibFunc::Log,
LibFunc::Sqrt,
LibFunc::Fabs,
LibFunc::Pow,
LibFunc::Ceil,
LibFunc::Floor,
LibFunc::Trunc,
LibFunc::SinF,
LibFunc::CosF,
LibFunc::ExpF,
LibFunc::LogF,
LibFunc::SqrtF,
LibFunc::FabsF,
LibFunc::PowF,
LibFunc::CeilF,
LibFunc::FloorF,
LibFunc::TruncF,
LibFunc::Memcpy,
LibFunc::Memmove,
LibFunc::Memset,
LibFunc::Memcmp,
LibFunc::Strlen,
LibFunc::Strcpy,
LibFunc::Strncpy,
LibFunc::Strcmp,
LibFunc::Strncmp,
LibFunc::Malloc,
LibFunc::Calloc,
LibFunc::Realloc,
LibFunc::Free,
LibFunc::Exit,
LibFunc::Abort,
];
let linux_extras: &[LibFunc] = &[
LibFunc::Memrchr,
LibFunc::Memccpy,
LibFunc::Mempcpy,
LibFunc::Stpcpy,
LibFunc::Stpncpy,
LibFunc::Strnlen,
LibFunc::Strdup,
LibFunc::Strndup,
LibFunc::Fma,
LibFunc::FmaF,
LibFunc::Remainder,
LibFunc::Copysign,
LibFunc::Lgamma,
LibFunc::LgammaR,
LibFunc::Tgamma,
LibFunc::Erf,
LibFunc::Erfc,
LibFunc::Fmod,
LibFunc::FmodF,
LibFunc::Atan2,
LibFunc::Atan2F,
LibFunc::Hypot,
LibFunc::HypotF,
LibFunc::PosixMemalign,
LibFunc::AlignedAlloc,
LibFunc::Setjmp,
LibFunc::Longjmp,
LibFunc::Getenv,
LibFunc::Gettimeofday,
LibFunc::ClockGettime,
];
let macos_extras: &[LibFunc] = &[
LibFunc::SinL,
LibFunc::CosL,
LibFunc::ExpL,
LibFunc::LogL,
LibFunc::SqrtL,
LibFunc::FabsL,
LibFunc::PowL,
LibFunc::Memchr,
LibFunc::Strdup,
LibFunc::Strndup,
LibFunc::Strnlen,
LibFunc::Strcasecmp,
LibFunc::Strncasecmp,
LibFunc::Fma,
LibFunc::FmaF,
LibFunc::PosixMemalign,
LibFunc::Gettimeofday,
LibFunc::Sigaction,
];
let windows_extras: &[LibFunc] = &[LibFunc::Memchr, LibFunc::Strdup, LibFunc::AlignedAlloc];
for func in common {
self.available.insert(*func);
}
let extras = match self.platform {
TargetPlatform::Linux | TargetPlatform::Android | TargetPlatform::FreeBSD => {
linux_extras
}
TargetPlatform::MacOS | TargetPlatform::IOS => macos_extras,
TargetPlatform::Windows => windows_extras,
_ => linux_extras, };
for func in extras {
self.available.insert(*func);
}
}
fn init_vector_mappings(&mut self) {
match self.platform {
TargetPlatform::Linux => {
self.add_vec_svml();
self.add_vec_libmvec();
}
TargetPlatform::MacOS | TargetPlatform::IOS => {
self.add_vec_accelerate();
}
_ => {
}
}
}
fn add_vec_svml(&mut self) {
let svml_funcs = &[
(LibFunc::Sin, "sin"),
(LibFunc::Cos, "cos"),
(LibFunc::Exp, "exp"),
(LibFunc::Log, "log"),
(LibFunc::Pow, "pow"),
(LibFunc::SinF, "sinf"),
(LibFunc::CosF, "cosf"),
(LibFunc::ExpF, "expf"),
(LibFunc::LogF, "logf"),
(LibFunc::PowF, "powf"),
];
for &(func, name) in svml_funcs {
for &width in &[2u32, 4, 8, 16] {
self.vector_mappings.push(VecFuncMapping {
scalar: func,
vector_width: width,
vector_name: format!("__svml_{}{}", name, width),
library: VectorLibrary::SVML,
});
}
}
}
fn add_vec_libmvec(&mut self) {
let libmvec_funcs = &[
(LibFunc::Sin, "_ZGVbN2v_sin"),
(LibFunc::Cos, "_ZGVbN2v_cos"),
(LibFunc::Exp, "_ZGVbN2v_exp"),
(LibFunc::Log, "_ZGVbN2v_log"),
(LibFunc::SinF, "_ZGVbN4v_sinf"),
(LibFunc::CosF, "_ZGVbN4v_cosf"),
(LibFunc::ExpF, "_ZGVbN4v_expf"),
(LibFunc::LogF, "_ZGVbN4v_logf"),
];
for &(func, name) in libmvec_funcs {
self.vector_mappings.push(VecFuncMapping {
scalar: func,
vector_width: if func as u32 >= LibFunc::SinF as u32 {
4
} else {
2
},
vector_name: name.to_string(),
library: VectorLibrary::LibMVec,
});
}
}
fn add_vec_accelerate(&mut self) {
let accelerate_funcs = &[
(LibFunc::Sin, "vvsincos"),
(LibFunc::Cos, "vvsincos"),
(LibFunc::Exp, "vvexp"),
(LibFunc::Log, "vvlog"),
(LibFunc::SinF, "vvsinf"),
(LibFunc::CosF, "vvcosf"),
(LibFunc::ExpF, "vvexpf"),
(LibFunc::LogF, "vvlogf"),
];
for &(func, name) in accelerate_funcs {
self.vector_mappings.push(VecFuncMapping {
scalar: func,
vector_width: 4,
vector_name: name.to_string(),
library: VectorLibrary::Accelerate,
});
}
}
pub fn has(&self, func: LibFunc) -> bool {
if self.unavailable.contains(&func) {
return false;
}
self.available.contains(&func)
}
pub fn set_unavailable(&mut self, func: LibFunc) {
self.unavailable.insert(func);
}
pub fn set_available(&mut self, func: LibFunc) {
self.available.insert(func);
self.unavailable.remove(&func);
}
pub fn get_lib_func(&self, name: &str) -> Option<LibFunc> {
let all_funcs = Self::all_lib_funcs();
all_funcs.iter().find(|&&f| f.c_name() == name).copied()
}
fn all_lib_funcs() -> Vec<LibFunc> {
vec![
LibFunc::Memcpy,
LibFunc::Memmove,
LibFunc::Memset,
LibFunc::Memcmp,
LibFunc::Memchr,
LibFunc::Memrchr,
LibFunc::Bcopy,
LibFunc::Bzero,
LibFunc::Bcmp,
LibFunc::Memccpy,
LibFunc::Mempcpy,
LibFunc::Strlen,
LibFunc::Strnlen,
LibFunc::Strcpy,
LibFunc::Strncpy,
LibFunc::Stpcpy,
LibFunc::Stpncpy,
LibFunc::Strcat,
LibFunc::Strncat,
LibFunc::Strcmp,
LibFunc::Strncmp,
LibFunc::Strcasecmp,
LibFunc::Strncasecmp,
LibFunc::Strchr,
LibFunc::Strrchr,
LibFunc::Strstr,
LibFunc::Strpbrk,
LibFunc::Strspn,
LibFunc::Strcspn,
LibFunc::Strsep,
LibFunc::Strtok,
LibFunc::Strdup,
LibFunc::Strndup,
LibFunc::Sin,
LibFunc::Cos,
LibFunc::Tan,
LibFunc::Exp,
LibFunc::Log,
LibFunc::Sqrt,
LibFunc::Fabs,
LibFunc::Pow,
LibFunc::Ceil,
LibFunc::Floor,
LibFunc::Trunc,
LibFunc::SinF,
LibFunc::CosF,
LibFunc::ExpF,
LibFunc::LogF,
LibFunc::SqrtF,
LibFunc::FabsF,
LibFunc::PowF,
LibFunc::CeilF,
LibFunc::FloorF,
LibFunc::TruncF,
LibFunc::SinL,
LibFunc::CosL,
LibFunc::ExpL,
LibFunc::LogL,
LibFunc::SqrtL,
LibFunc::FabsL,
LibFunc::PowL,
LibFunc::CeilL,
LibFunc::FloorL,
LibFunc::TruncL,
LibFunc::Malloc,
LibFunc::Calloc,
LibFunc::Realloc,
LibFunc::Free,
LibFunc::Exit,
LibFunc::Abort,
LibFunc::PosixMemalign,
LibFunc::AlignedAlloc,
LibFunc::Gettimeofday,
LibFunc::ClockGettime,
LibFunc::Fma,
LibFunc::FmaF,
LibFunc::Fmod,
LibFunc::FmodF,
]
}
pub fn get_vector_mapping(&self, func: LibFunc, width: u32) -> Option<&VecFuncMapping> {
self.vector_mappings
.iter()
.find(|m| m.scalar == func && m.vector_width == width)
}
pub fn get_vector_mappings_for(&self, func: LibFunc) -> Vec<&VecFuncMapping> {
self.vector_mappings
.iter()
.filter(|m| m.scalar == func)
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_libfunc_cname() {
assert_eq!(LibFunc::Memcpy.c_name(), "memcpy");
assert_eq!(LibFunc::Sin.c_name(), "sin");
assert_eq!(LibFunc::Malloc.c_name(), "malloc");
}
#[test]
fn test_platform_from_triple() {
assert_eq!(
TargetPlatform::from_triple("x86_64-linux-gnu"),
TargetPlatform::Linux
);
assert_eq!(
TargetPlatform::from_triple("x86_64-apple-darwin"),
TargetPlatform::MacOS
);
assert_eq!(
TargetPlatform::from_triple("x86_64-windows-msvc"),
TargetPlatform::Windows
);
}
#[test]
fn test_tli_has_common() {
let tli = TargetLibraryInfo::new(TargetPlatform::Linux);
assert!(tli.has(LibFunc::Memcpy));
assert!(tli.has(LibFunc::Memmove));
assert!(tli.has(LibFunc::Memset));
}
#[test]
fn test_tli_has_linux_extras() {
let tli = TargetLibraryInfo::new(TargetPlatform::Linux);
assert!(tli.has(LibFunc::Memrchr));
assert!(tli.has(LibFunc::Mempcpy));
assert!(tli.has(LibFunc::Fma));
}
#[test]
fn test_tli_has_macos_extras() {
let tli = TargetLibraryInfo::new(TargetPlatform::MacOS);
assert!(tli.has(LibFunc::SinL));
assert!(tli.has(LibFunc::Strcasecmp));
}
#[test]
fn test_tli_set_unavailable() {
let mut tli = TargetLibraryInfo::new(TargetPlatform::Linux);
assert!(tli.has(LibFunc::Memcpy));
tli.set_unavailable(LibFunc::Memcpy);
assert!(!tli.has(LibFunc::Memcpy));
}
#[test]
fn test_tli_get_lib_func() {
let tli = TargetLibraryInfo::new(TargetPlatform::Linux);
assert_eq!(tli.get_lib_func("memcpy"), Some(LibFunc::Memcpy));
assert_eq!(tli.get_lib_func("sin"), Some(LibFunc::Sin));
assert_eq!(tli.get_lib_func("nonexistent"), None);
}
#[test]
fn test_vector_mappings_svml() {
let tli = TargetLibraryInfo::new(TargetPlatform::Linux);
let mapping = tli.get_vector_mapping(LibFunc::Sin, 4);
assert!(mapping.is_some());
let m = mapping.unwrap();
assert_eq!(m.library, VectorLibrary::SVML);
assert_eq!(m.vector_name, "__svml_sin4");
}
#[test]
fn test_vector_mappings_libmvec() {
let tli = TargetLibraryInfo::new(TargetPlatform::Linux);
let mappings = tli.get_vector_mappings_for(LibFunc::Sin);
assert!(!mappings.is_empty());
}
#[test]
fn test_vector_mappings_accelerate() {
let tli = TargetLibraryInfo::new(TargetPlatform::MacOS);
let mapping = tli.get_vector_mapping(LibFunc::Sin, 4);
assert!(mapping.is_some());
let m = mapping.unwrap();
assert_eq!(m.library, VectorLibrary::Accelerate);
}
#[test]
fn test_windows_tli() {
let tli = TargetLibraryInfo::new(TargetPlatform::Windows);
assert!(tli.has(LibFunc::Memcpy));
assert!(!tli.has(LibFunc::Mempcpy)); }
#[test]
fn test_memset_size_arg() {
let tli = TargetLibraryInfo::new(TargetPlatform::Linux);
assert_eq!(tli.memset_size_arg, 2);
assert_eq!(tli.memcpy_size_arg, 2);
assert_eq!(tli.memmove_size_arg, 2);
}
}