|
|
|
# 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)
|