diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index a8ec5e362..0b196d212 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -228,6 +228,19 @@ base_options = {'b_pch': coredata.UserBooleanOption('b_pch', 'Use precompiled he True), } +gnulike_instruction_set_args = {'mmx': ['-mmmx'], + 'sse': ['-msse'], + 'sse2': ['-msse2'], + 'sse3': ['-msse3'], + 'ssse3': ['-mssse3'], + 'sse41': ['-msse4.1'], + 'sse42': ['-msse4.2'], + 'avx': ['-mavx'], + 'avx2': ['-mavx2'], + 'neon': ['-mfpu=neon'], + } + + def sanitizer_compile_args(value): if value == 'none': return [] @@ -755,6 +768,12 @@ class Compiler: return [] raise EnvironmentException('Language %s does not support linking whole archives.' % self.get_display_language()) + # Compiler arguments needed to enable the given instruction set. + # May be [] meaning nothing needed or None meaning the given set + # is not supported. + def get_instruction_set_args(self, instruction_set): + return None + def build_unix_rpath_args(self, build_dir, from_dir, rpath_paths, install_rpath): if not rpath_paths and not install_rpath: return [] @@ -933,6 +952,10 @@ class GnuCompiler: return ['-mwindows'] return [] + def get_instruction_set_args(self, instruction_set): + return gnulike_instruction_set_args.get(instruction_set, None) + + class ClangCompiler: def __init__(self, clang_type): self.id = 'clang' @@ -1010,6 +1033,9 @@ class ClangCompiler: return result return ['-Wl,--whole-archive'] + args + ['-Wl,--no-whole-archive'] + def get_instruction_set_args(self, instruction_set): + return gnulike_instruction_set_args.get(instruction_set, None) + # Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1 class IntelCompiler: diff --git a/mesonbuild/modules/simd.py b/mesonbuild/modules/simd.py new file mode 100644 index 000000000..3a9fe59cf --- /dev/null +++ b/mesonbuild/modules/simd.py @@ -0,0 +1,74 @@ +# Copyright 2017 The Meson development team + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from .. import mesonlib, compilers, build, mlog + +from . import ExtensionModule + +class SimdModule(ExtensionModule): + + def __init__(self): + super().__init__() + self.snippets.add('check') + # FIXME add Altivec and AVX512. + self.isets = ('mmx', + 'sse', + 'sse2', + 'sse3', + 'ssse3', + 'sse41', + 'sse42', + 'avx', + 'avx2', + 'neon', + ) + + def check(self, interpreter, state, args, kwargs): + result = [] + if len(args) != 1: + raise mesonlib.MesonException('Check requires one argument, a name prefix for checks.') + prefix = args[0] + if not isinstance(prefix, str): + raise mesonlib.MesonException('Argument must be a string.') + if 'compiler' not in kwargs: + raise mesonlib.MesonException('Must specify compiler keyword') + compiler = kwargs['compiler'].compiler + if not isinstance(compiler, compilers.Compiler): + raise mesonlib.MesonException('Compiler argument must be a compiler object.') + if 'configuration' not in kwargs: + raise mesonlib.MesonException('Must specify configuration object.') + conf = kwargs['configuration'].held_object + if not isinstance(conf, build.ConfigurationData): + raise mesonlib.MesonException('Configuration must be a configuration object.') + for iset in self.isets: + if iset not in kwargs: + continue + iset_fname = kwargs[iset] # Migth also be an array or Files. static_library will validate. + args = compiler.get_instruction_set_args(iset) + if args is None: + continue + if len(args) > 0: + if not compiler.has_multi_arguments(args, state.environment): + mlog.log('Compiler supports %s:' % iset, mlog.red('NO')) + continue + mlog.log('Compiler supports %s:' % iset, mlog.green('YES')) + conf.values['HAVE_' + iset.upper()] = ('1', 'Compiler supports %s.' % iset) + libname = prefix + '_' + iset + lib_kwargs = {'sources': iset_fname, + compiler.get_language() + '_args': args} + result.append(interpreter.func_static_lib(None, [libname], lib_kwargs)) + return result + +def initialize(): + return SimdModule() diff --git a/test cases/common/139 simd/meson.build b/test cases/common/139 simd/meson.build index 4dc352d29..c817c2d00 100644 --- a/test cases/common/139 simd/meson.build +++ b/test cases/common/139 simd/meson.build @@ -1,49 +1,25 @@ project('simd', 'c') +simd = import('simd') + cc = meson.get_compiler('c') cdata = configuration_data() -# The idea is to have a simd module and then do something like: -# -# static_libs = simd.check('mysimdstuff', -# mmx : 'mmx_funcs.c', -# sse : 'sse_funcs.c', -# sse2 : 'sse2_funcs.c', -# -# configuration : cdata, # adds HAVE_XXX -# compiler : cc) -# -# and then have a target that uses the result in links_with. - -# The following headers need to be added. Also Thumb and Altivec. -# AES -# AVX512 - -simdlibs = [] - -simdarr = [['-mmmx', 'HAVE_MMX', 'simd_mmx', 'simd_mmx.c'], - ['-msse', 'HAVE_SSE', 'simd_sse', 'simd_sse.c'], - ['-msse2', 'HAVE_SSE2', 'simd_sse2', 'simd_sse2.c'], - ['-msse3', 'HAVE_SSE3', 'simd_sse3', 'simd_sse3.c'], - ['-mssse3', 'HAVE_SSSE3', 'simd_ssse3', 'simd_ssse3.c'], - ['-msse4.1', 'HAVE_SSE41', 'simd_sse41', 'simd_sse41.c'], - ['-msse4.2', 'HAVE_SSE42', 'simd_sse42', 'simd_sse42.c'], - ['-mavx', 'HAVE_AVX', 'simd_avx', 'simd_avx.c'], - ['-mavx2', 'HAVE_AVX2', 'simd_avx2', 'simd_avx2.c'], - ['-mfpu=neon', 'HAVE_NEON', 'simd_neon', 'simd_neon.c'], -] - -foreach ia : simdarr - arg = ia[0] - def = ia[1] - libname = ia[2] - filename = ia[3] - if cc.has_argument(arg) - cdata.set(def, 1) - simdlibs += static_library(libname, filename, c_args : arg) - endif -endforeach +simdlibs = simd.check('mysimds', + mmx : 'simd_mmx.c', + sse : 'simd_sse.c', + sse2 : 'simd_sse2.c', + sse3 : 'simd_sse3.c', + ssse3 : 'simd_ssse3.c', + sse41 : 'simd_sse41.c', + sse42 : 'simd_sse42.c', + avx : 'simd_avx.c', + avx2 : 'simd_avx2.c', + neon : 'simd_neon.c', + configuration : cdata, + compiler : cc) + configure_file(output : 'simdconfig.h', configuration : cdata)