tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

arm.configure (8442B)


      1 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
      2 # vim: set filetype=python:
      3 # This Source Code Form is subject to the terms of the Mozilla Public
      4 # License, v. 2.0. If a copy of the MPL was not distributed with this
      5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      6 
      7 
      8 @depends(target.os)
      9 def arm_option_defaults(os):
     10     if os == "Android":
     11         arch = "armv7-a"
     12         thumb = "yes"
     13         fpu = "neon"
     14         float_abi = "softfp"
     15     else:
     16         arch = thumb = fpu = float_abi = "toolchain-default"
     17     return namespace(
     18         arch=arch,
     19         thumb=thumb,
     20         fpu=fpu,
     21         float_abi=float_abi,
     22     )
     23 
     24 
     25 # Note: '{...|}' in the help of all options with a non-constant default to
     26 # make the lint happy. The first arm is always going to be used, because a
     27 # default is always returned. The lint is fooled by this file being
     28 # conditional. If it weren't conditional, the lint wouldn't ask for '{|}' to
     29 # be there.
     30 option(
     31     "--with-arch",
     32     nargs=1,
     33     default=arm_option_defaults.arch,
     34     help="{Use specific CPU features (-march=type). Resets thumb, fpu, "
     35     "float-abi, etc. defaults when set|}",
     36 )
     37 
     38 
     39 @depends("--with-arch")
     40 def arch_option(value):
     41     if value:
     42         if value[0] != "toolchain-default":
     43             return ["-march={}".format(value[0])]
     44     return []
     45 
     46 
     47 option(
     48     "--with-thumb",
     49     choices=("yes", "no", "toolchain-default"),
     50     default=arm_option_defaults.thumb,
     51     nargs="?",
     52     help="{Use Thumb instruction set (-mthumb)|}",
     53 )
     54 
     55 
     56 def normalize_arm_option(value):
     57     if value:
     58         if len(value):
     59             if value[0] == "yes":
     60                 return True
     61             elif value[0] == "no":
     62                 return False
     63             else:
     64                 return value[0]
     65         return True
     66     return False
     67 
     68 
     69 @depends("--with-thumb")
     70 def thumb_option(value):
     71     value = normalize_arm_option(value)
     72     if value is True:
     73         return ["-mthumb"]
     74     if value is False:
     75         return ["-marm"]
     76     return []
     77 
     78 
     79 option(
     80     "--with-thumb-interwork",
     81     choices=("yes", "no", "toolchain-default"),
     82     default="toolchain-default",
     83     nargs="?",
     84     help="Use Thumb/ARM instuctions interwork (-mthumb-interwork)",
     85 )
     86 
     87 
     88 @depends("--with-thumb-interwork")
     89 def thumb_interwork_option(value):
     90     value = normalize_arm_option(value)
     91     if value is True:
     92         return ["-mthumb-interwork"]
     93     if value is False:
     94         return ["-mno-thumb-interwork"]
     95     return []
     96 
     97 
     98 option(
     99     "--with-fpu",
    100     nargs=1,
    101     default=arm_option_defaults.fpu,
    102     help="{Use specific FPU type (-mfpu=type)|}",
    103 )
    104 
    105 
    106 @depends("--with-fpu")
    107 def fpu_option(value):
    108     if value:
    109         if value[0] != "toolchain-default":
    110             return ["-mfpu={}".format(value[0])]
    111     return []
    112 
    113 
    114 option(
    115     "--with-float-abi",
    116     nargs=1,
    117     default=arm_option_defaults.float_abi,
    118     help="{Use specific arm float ABI (-mfloat-abi=type)|}",
    119 )
    120 
    121 
    122 @depends("--with-float-abi")
    123 def float_abi_option(value):
    124     if value:
    125         if value[0] != "toolchain-default":
    126             return ["-mfloat-abi={}".format(value[0])]
    127     return []
    128 
    129 
    130 option(
    131     "--with-soft-float",
    132     choices=("yes", "no", "toolchain-default"),
    133     default="toolchain-default",
    134     nargs="?",
    135     help="Use soft float library (-msoft-float)",
    136 )
    137 
    138 
    139 @depends("--with-soft-float")
    140 def soft_float_option(value):
    141     value = normalize_arm_option(value)
    142     if value is True:
    143         return ["-msoft-float"]
    144     if value is False:
    145         return ["-mno-soft-float"]
    146     return []
    147 
    148 
    149 check_and_add_flag(
    150     "-mno-unaligned-access", when=depends(target.os)(lambda os: os == "Android")
    151 )
    152 
    153 
    154 # The set of flags that clang understands
    155 @depends(
    156     arch_option,
    157     thumb_option,
    158     fpu_option,
    159     float_abi_option,
    160     soft_float_option,
    161 )
    162 def all_clang_arm_flags(arch, thumb, fpu, float_abi, soft_float):
    163     return arch + thumb + fpu + float_abi + soft_float
    164 
    165 
    166 # All the flags the compiler understands. When the compiler is clang, this
    167 # still includes unsupported flags, but we live it to configure to fail
    168 # during a compiler check. These checks aren't available for clang as used
    169 # by bindgen, so we keep the separate set of flags for clang for bindgen.
    170 @depends(all_clang_arm_flags, thumb_interwork_option)
    171 def all_arm_flags(flags, interwork):
    172     return flags + interwork
    173 
    174 
    175 @depends(configure_cache, c_compiler, all_arm_flags)
    176 @checking("ARM version support in compiler", lambda x: x.arm_arch)
    177 @imports(_from="textwrap", _import="dedent")
    178 def arm_target(configure_cache, compiler, all_arm_flags):
    179     # We're going to preprocess the following source to figure out some details
    180     # about the arm target options we have enabled.
    181     source = dedent(
    182         """\
    183         %ARM_ARCH __ARM_ARCH
    184         #if __thumb2__
    185         %THUMB2 yes
    186         #else
    187         %THUMB2 no
    188         #endif
    189         // Confusingly, the __SOFTFP__ preprocessor variable indicates the
    190         // "softfloat" ABI, not the "softfp" ABI.
    191         #if __SOFTFP__
    192         %FLOAT_ABI soft
    193         #elif __ARM_PCS_VFP
    194         %FLOAT_ABI hard
    195         #else
    196         %FLOAT_ABI softfp
    197         #endif
    198         // There is more subtlety to it than this preprocessor test, but MOZ_FPU doesn't
    199         // need to be too fine-grained.
    200         #if __ARM_NEON
    201         %FPU neon
    202         #elif __ARM_VFPV2__ || __ARM_FP == 12
    203         %FPU vfpv2
    204         #elif __ARM_VFPV3__
    205         %FPU vfpv3
    206         #elif __ARM_VFPV4__ || __ARM_FP == 14
    207         %FPU vfpv4
    208         #elif __ARM_FPV5__
    209         %FPU fp-armv8
    210         #endif
    211     """
    212     )
    213     result = try_invoke_compiler(
    214         configure_cache,
    215         [compiler.compiler] + compiler.flags,
    216         compiler.language,
    217         source,
    218         ["-E"] + all_arm_flags,
    219         wrapper=compiler.wrapper,
    220     )
    221     # Metadata emitted by preprocessors such as GCC with LANG=ja_JP.utf-8 may
    222     # have non-ASCII characters. Treat the output as bytearray.
    223     data = {"fpu": None}  # fpu may not get a value from the preprocessor.
    224     for line in result.splitlines():
    225         if line.startswith("%"):
    226             k, _, v = line.partition(" ")
    227             k = k.lstrip("%").lower()
    228             if k == "arm_arch":
    229                 data[k] = int(v)
    230             else:
    231                 data[k] = {
    232                     "yes": True,
    233                     "no": False,
    234                 }.get(v, v)
    235             log.debug("%s = %s", k, data[k])
    236 
    237     return namespace(**data)
    238 
    239 
    240 @depends(arm_target.arm_arch, when=depends(target.os)(lambda os: os == "Android"))
    241 def armv7(arch):
    242     if arch < 7:
    243         die("Android/armv6 and earlier are not supported")
    244 
    245 
    246 set_config("MOZ_THUMB2", True, when=arm_target.thumb2)
    247 set_define("MOZ_THUMB2", True, when=arm_target.thumb2)
    248 
    249 
    250 have_arm_simd = c_compiler.try_compile(
    251     body='asm("uqadd8 r1, r1, r2");', check_msg="for ARM SIMD support in compiler"
    252 )
    253 
    254 set_config("HAVE_ARM_SIMD", have_arm_simd)
    255 set_define("HAVE_ARM_SIMD", have_arm_simd)
    256 
    257 have_arm_neon = c_compiler.try_compile(
    258     body='asm(".fpu neon\\n vadd.i8 d0, d0, d0");',
    259     check_msg="for ARM NEON support in compiler",
    260 )
    261 
    262 set_config("HAVE_ARM_NEON", have_arm_neon)
    263 set_define("HAVE_ARM_NEON", have_arm_neon)
    264 
    265 
    266 # We don't need to build NEON support if we're targetting a non-NEON device.
    267 # This matches media/webrtc/trunk/webrtc/build/common.gypi.
    268 @depends(arm_target.arm_arch, when=have_arm_neon)
    269 def build_arm_neon(arm_arch):
    270     return arm_arch >= 7
    271 
    272 
    273 set_config("BUILD_ARM_NEON", True, when=build_arm_neon)
    274 set_define("BUILD_ARM_NEON", True, when=build_arm_neon)
    275 
    276 
    277 set_config("ARM_ARCH", depends(arm_target.arm_arch)(lambda x: str(x)))
    278 set_config("MOZ_FPU", arm_target.fpu)
    279 
    280 
    281 @depends(arm_target)
    282 def neon_flags(arm_target):
    283     # Building with -mfpu=neon requires either the "softfp" or the
    284     # "hardfp" ABI. Depending on the compiler's default target, and the
    285     # CFLAGS, the default ABI might be neither, in which case it is the
    286     # "softfloat" ABI.
    287     # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
    288     # we can safely mix code built with both ABIs. So, if we detect
    289     # that compiling uses the "softfloat" ABI, force the use of the
    290     # "softfp" ABI instead.
    291     flags = ["-mfpu=neon"]
    292     if arm_target.float_abi == "soft":
    293         flags.append("-mfloat-abi=softfp")
    294     if arm_target.arm_arch < 7:
    295         # clang needs to be forced to at least armv7 for -mfpu=neon to do
    296         # something.
    297         flags.append("-march=armv7-a")
    298     return tuple(flags)
    299 
    300 
    301 set_config("NEON_FLAGS", neon_flags)