| # SPDX-License-Identifier: Apache-2.0 |
| # Copyright 2017 The Meson development team |
| |
| from __future__ import annotations |
| |
| import typing as T |
| |
| from .. import mesonlib, mlog |
| from .. import build |
| from ..compilers import Compiler |
| from ..interpreter.type_checking import BT_SOURCES_KW, STATIC_LIB_KWS |
| from ..interpreterbase.decorators import KwargInfo, permittedKwargs, typed_pos_args, typed_kwargs |
| |
| from . import ExtensionModule, ModuleInfo |
| |
| if T.TYPE_CHECKING: |
| from . import ModuleState |
| from ..interpreter import Interpreter, kwargs as kwtypes |
| from ..interpreter.type_checking import SourcesVarargsType |
| |
| class CheckKw(kwtypes.StaticLibrary): |
| |
| compiler: Compiler |
| mmx: SourcesVarargsType |
| sse: SourcesVarargsType |
| sse2: SourcesVarargsType |
| sse3: SourcesVarargsType |
| ssse3: SourcesVarargsType |
| sse41: SourcesVarargsType |
| sse42: SourcesVarargsType |
| avx: SourcesVarargsType |
| avx2: SourcesVarargsType |
| neon: SourcesVarargsType |
| |
| |
| # FIXME add Altivec and AVX512. |
| ISETS = ( |
| 'mmx', |
| 'sse', |
| 'sse2', |
| 'sse3', |
| 'ssse3', |
| 'sse41', |
| 'sse42', |
| 'avx', |
| 'avx2', |
| 'neon', |
| ) |
| |
| |
| class SimdModule(ExtensionModule): |
| |
| INFO = ModuleInfo('SIMD', '0.42.0', unstable=True) |
| |
| def __init__(self, interpreter: Interpreter): |
| super().__init__(interpreter) |
| self.methods.update({ |
| 'check': self.check, |
| }) |
| |
| @typed_pos_args('simd.check', str) |
| @typed_kwargs('simd.check', |
| KwargInfo('compiler', Compiler, required=True), |
| *[BT_SOURCES_KW.evolve(name=iset, default=None) for iset in ISETS], |
| *[a for a in STATIC_LIB_KWS if a.name != 'sources'], |
| allow_unknown=True) # Because we also accept STATIC_LIB_KWS, but build targets have not been completely ported to typed_pos_args/typed_kwargs. |
| @permittedKwargs({'compiler', *ISETS, *build.known_stlib_kwargs}) # Also remove this, per above comment |
| def check(self, state: ModuleState, args: T.Tuple[str], kwargs: CheckKw) -> T.List[T.Union[T.List[build.StaticLibrary], build.ConfigurationData]]: |
| result: T.List[build.StaticLibrary] = [] |
| |
| if 'sources' in kwargs: |
| raise mesonlib.MesonException('SIMD module does not support the "sources" keyword') |
| |
| local_kwargs = set((*ISETS, 'compiler')) |
| static_lib_kwargs = T.cast('kwtypes.StaticLibrary', {k: v for k, v in kwargs.items() if k not in local_kwargs}) |
| |
| prefix = args[0] |
| compiler = kwargs['compiler'] |
| conf = build.ConfigurationData() |
| |
| for iset in ISETS: |
| sources = kwargs[iset] |
| if sources is None: |
| continue |
| |
| compile_args = compiler.get_instruction_set_args(iset) |
| if compile_args is None: |
| mlog.log(f'Compiler supports {iset}:', mlog.red('NO')) |
| continue |
| |
| if not compiler.has_multi_arguments(compile_args, state.environment)[0]: |
| mlog.log(f'Compiler supports {iset}:', mlog.red('NO')) |
| continue |
| mlog.log(f'Compiler supports {iset}:', mlog.green('YES')) |
| conf.values['HAVE_' + iset.upper()] = ('1', f'Compiler supports {iset}.') |
| |
| libname = prefix + '_' + iset |
| lib_kwargs = static_lib_kwargs.copy() |
| lib_kwargs['sources'] = sources |
| |
| # Add compile args we derived above to those the user provided us |
| langarg_key = compiler.get_language() + '_args' |
| old_lang_args = mesonlib.extract_as_list(lib_kwargs, langarg_key) |
| all_lang_args = old_lang_args + compile_args |
| lib_kwargs[langarg_key] = all_lang_args |
| |
| lib = self.interpreter.build_target(state.current_node, (libname, []), lib_kwargs, build.StaticLibrary) |
| |
| result.append(lib) |
| |
| return [result, conf] |
| |
| def initialize(interp: Interpreter) -> SimdModule: |
| return SimdModule(interp) |