aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/compilers/compilers.py26
-rw-r--r--mesonbuild/modules/simd.py74
-rw-r--r--test cases/common/139 simd/meson.build56
3 files changed, 116 insertions, 40 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index a8ec5e3..0b196d2 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 0000000..3a9fe59
--- /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 4dc352d..c817c2d 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',
-# <etc>
-# 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.
-#<wmmintrin.h> AES
-#<zmmintrin.h> 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)