summaryrefslogtreecommitdiffstats
path: root/build/moz.configure/arm.configure
diff options
context:
space:
mode:
Diffstat (limited to 'build/moz.configure/arm.configure')
-rw-r--r--build/moz.configure/arm.configure305
1 files changed, 305 insertions, 0 deletions
diff --git a/build/moz.configure/arm.configure b/build/moz.configure/arm.configure
new file mode 100644
index 0000000000..5d26f4d732
--- /dev/null
+++ b/build/moz.configure/arm.configure
@@ -0,0 +1,305 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+@depends(target.os)
+def arm_option_defaults(os):
+ if os == "Android":
+ arch = "armv7-a"
+ thumb = "yes"
+ fpu = "neon"
+ float_abi = "softfp"
+ else:
+ arch = thumb = fpu = float_abi = "toolchain-default"
+ return namespace(
+ arch=arch,
+ thumb=thumb,
+ fpu=fpu,
+ float_abi=float_abi,
+ )
+
+
+# Note: '{...|}' in the help of all options with a non-constant default to
+# make the lint happy. The first arm is always going to be used, because a
+# default is always returned. The lint is fooled by this file being
+# conditional. If it weren't conditional, the lint wouldn't ask for '{|}' to
+# be there.
+option(
+ "--with-arch",
+ nargs=1,
+ default=arm_option_defaults.arch,
+ help="{Use specific CPU features (-march=type). Resets thumb, fpu, "
+ "float-abi, etc. defaults when set|}",
+)
+
+
+@depends("--with-arch")
+def arch_option(value):
+ if value:
+ if value[0] != "toolchain-default":
+ return ["-march={}".format(value[0])]
+ return []
+
+
+option(
+ "--with-thumb",
+ choices=("yes", "no", "toolchain-default"),
+ default=arm_option_defaults.thumb,
+ nargs="?",
+ help="{Use Thumb instruction set (-mthumb)|}",
+)
+
+
+def normalize_arm_option(value):
+ if value:
+ if len(value):
+ if value[0] == "yes":
+ return True
+ elif value[0] == "no":
+ return False
+ else:
+ return value[0]
+ return True
+ return False
+
+
+@depends("--with-thumb")
+def thumb_option(value):
+ value = normalize_arm_option(value)
+ if value is True:
+ return ["-mthumb"]
+ if value is False:
+ return ["-marm"]
+ return []
+
+
+option(
+ "--with-thumb-interwork",
+ choices=("yes", "no", "toolchain-default"),
+ default="toolchain-default",
+ nargs="?",
+ help="Use Thumb/ARM instuctions interwork (-mthumb-interwork)",
+)
+
+
+@depends("--with-thumb-interwork")
+def thumb_interwork_option(value):
+ value = normalize_arm_option(value)
+ if value is True:
+ return ["-mthumb-interwork"]
+ if value is False:
+ return ["-mno-thumb-interwork"]
+ return []
+
+
+option(
+ "--with-fpu",
+ nargs=1,
+ default=arm_option_defaults.fpu,
+ help="{Use specific FPU type (-mfpu=type)|}",
+)
+
+
+@depends("--with-fpu")
+def fpu_option(value):
+ if value:
+ if value[0] != "toolchain-default":
+ return ["-mfpu={}".format(value[0])]
+ return []
+
+
+option(
+ "--with-float-abi",
+ nargs=1,
+ default=arm_option_defaults.float_abi,
+ help="{Use specific arm float ABI (-mfloat-abi=type)|}",
+)
+
+
+@depends("--with-float-abi")
+def float_abi_option(value):
+ if value:
+ if value[0] != "toolchain-default":
+ return ["-mfloat-abi={}".format(value[0])]
+ return []
+
+
+option(
+ "--with-soft-float",
+ choices=("yes", "no", "toolchain-default"),
+ default="toolchain-default",
+ nargs="?",
+ help="Use soft float library (-msoft-float)",
+)
+
+
+@depends("--with-soft-float")
+def soft_float_option(value):
+ value = normalize_arm_option(value)
+ if value is True:
+ return ["-msoft-float"]
+ if value is False:
+ return ["-mno-soft-float"]
+ return []
+
+
+check_and_add_flag(
+ "-mno-unaligned-access", when=depends(target.os)(lambda os: os == "Android")
+)
+
+
+# The set of flags that clang understands
+@depends(
+ arch_option,
+ thumb_option,
+ fpu_option,
+ float_abi_option,
+ soft_float_option,
+)
+def all_clang_arm_flags(arch, thumb, fpu, float_abi, soft_float):
+ return arch + thumb + fpu + float_abi + soft_float
+
+
+# All the flags the compiler understands. When the compiler is clang, this
+# still includes unsupported flags, but we live it to configure to fail
+# during a compiler check. These checks aren't available for clang as used
+# by bindgen, so we keep the separate set of flags for clang for bindgen.
+@depends(all_clang_arm_flags, thumb_interwork_option)
+def all_arm_flags(flags, interwork):
+ return flags + interwork
+
+
+add_old_configure_assignment("_ARM_FLAGS", all_arm_flags)
+add_old_configure_assignment("_THUMB_FLAGS", thumb_option)
+
+
+@depends(configure_cache, c_compiler, all_arm_flags)
+@checking("ARM version support in compiler", lambda x: x.arm_arch)
+@imports(_from="textwrap", _import="dedent")
+def arm_target(configure_cache, compiler, all_arm_flags):
+ # We're going to preprocess the following source to figure out some details
+ # about the arm target options we have enabled.
+ source = dedent(
+ """\
+ %ARM_ARCH __ARM_ARCH
+ #if __thumb2__
+ %THUMB2 yes
+ #else
+ %THUMB2 no
+ #endif
+ // Confusingly, the __SOFTFP__ preprocessor variable indicates the
+ // "softfloat" ABI, not the "softfp" ABI.
+ #if __SOFTFP__
+ %FLOAT_ABI soft
+ #elif __ARM_PCS_VFP
+ %FLOAT_ABI hard
+ #else
+ %FLOAT_ABI softfp
+ #endif
+ // There is more subtlety to it than this preprocessor test, but MOZ_FPU doesn't
+ // need to be too fine-grained.
+ #if __ARM_NEON
+ %FPU neon
+ #elif __ARM_VFPV2__ || __ARM_FP == 12
+ %FPU vfpv2
+ #elif __ARM_VFPV3__
+ %FPU vfpv3
+ #elif __ARM_VFPV4__ || __ARM_FP == 14
+ %FPU vfpv4
+ #elif __ARM_FPV5__
+ %FPU fp-armv8
+ #endif
+ """
+ )
+ result = try_invoke_compiler(
+ configure_cache,
+ [compiler.compiler] + compiler.flags,
+ compiler.language,
+ source,
+ ["-E"] + all_arm_flags,
+ wrapper=compiler.wrapper,
+ )
+ # Metadata emitted by preprocessors such as GCC with LANG=ja_JP.utf-8 may
+ # have non-ASCII characters. Treat the output as bytearray.
+ data = {"fpu": None} # fpu may not get a value from the preprocessor.
+ for line in result.splitlines():
+ if line.startswith("%"):
+ k, _, v = line.partition(" ")
+ k = k.lstrip("%").lower()
+ if k == "arm_arch":
+ data[k] = int(v)
+ else:
+ data[k] = {
+ "yes": True,
+ "no": False,
+ }.get(v, v)
+ log.debug("%s = %s", k, data[k])
+
+ return namespace(**data)
+
+
+@depends(arm_target.arm_arch, when=depends(target.os)(lambda os: os == "Android"))
+def armv7(arch):
+ if arch < 7:
+ die("Android/armv6 and earlier are not supported")
+
+
+set_config("MOZ_THUMB2", True, when=arm_target.thumb2)
+set_define("MOZ_THUMB2", True, when=arm_target.thumb2)
+
+
+have_arm_simd = c_compiler.try_compile(
+ body='asm("uqadd8 r1, r1, r2");', check_msg="for ARM SIMD support in compiler"
+)
+
+set_config("HAVE_ARM_SIMD", have_arm_simd)
+set_define("HAVE_ARM_SIMD", have_arm_simd)
+
+have_arm_neon = c_compiler.try_compile(
+ body='asm(".fpu neon\\n vadd.i8 d0, d0, d0");',
+ check_msg="for ARM NEON support in compiler",
+)
+
+set_config("HAVE_ARM_NEON", have_arm_neon)
+set_define("HAVE_ARM_NEON", have_arm_neon)
+
+
+# We don't need to build NEON support if we're targetting a non-NEON device.
+# This matches media/webrtc/trunk/webrtc/build/common.gypi.
+@depends(arm_target.arm_arch, when=have_arm_neon)
+def build_arm_neon(arm_arch):
+ return arm_arch >= 7
+
+
+set_config("BUILD_ARM_NEON", True, when=build_arm_neon)
+set_define("BUILD_ARM_NEON", True, when=build_arm_neon)
+
+
+set_config("ARM_ARCH", depends(arm_target.arm_arch)(lambda x: str(x)))
+set_config("MOZ_FPU", arm_target.fpu)
+
+
+@depends(arm_target)
+def neon_flags(arm_target):
+ # Building with -mfpu=neon requires either the "softfp" or the
+ # "hardfp" ABI. Depending on the compiler's default target, and the
+ # CFLAGS, the default ABI might be neither, in which case it is the
+ # "softfloat" ABI.
+ # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
+ # we can safely mix code built with both ABIs. So, if we detect
+ # that compiling uses the "softfloat" ABI, force the use of the
+ # "softfp" ABI instead.
+ flags = ["-mfpu=neon"]
+ if arm_target.float_abi == "soft":
+ flags.append("-mfloat-abi=softfp")
+ if arm_target.arm_arch < 7:
+ # clang needs to be forced to at least armv7 for -mfpu=neon to do
+ # something.
+ flags.append("-march=armv7-a")
+ return tuple(flags)
+
+
+set_config("NEON_FLAGS", neon_flags)