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) 9def 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. 30option( 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") 40def arch_option(value): 41 if value: 42 if value[0] != "toolchain-default": 43 return ["-march={}".format(value[0])] 44 return [] 45 46 47option( 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 56def 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") 70def 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 79option( 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") 89def 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 98option( 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") 107def fpu_option(value): 108 if value: 109 if value[0] != "toolchain-default": 110 return ["-mfpu={}".format(value[0])] 111 return [] 112 113 114option( 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") 123def float_abi_option(value): 124 if value: 125 if value[0] != "toolchain-default": 126 return ["-mfloat-abi={}".format(value[0])] 127 return [] 128 129 130option( 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") 140def 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 149check_and_add_gcc_flag( 150 "-mno-unaligned-access", when=depends(target.os)(lambda os: os == "Android") 151) 152 153 154@depends( 155 arch_option, 156 thumb_option, 157 thumb_interwork_option, 158 fpu_option, 159 float_abi_option, 160 soft_float_option, 161) 162def all_flags(arch, thumb, interwork, fpu, float_abi, soft_float): 163 return arch + thumb + interwork + fpu + float_abi + soft_float 164 165 166add_old_configure_assignment("_ARM_FLAGS", all_flags) 167add_old_configure_assignment("_THUMB_FLAGS", thumb_option) 168 169 170@depends(c_compiler, all_flags) 171@checking("ARM version support in compiler", lambda x: x.arm_arch) 172@imports(_from="textwrap", _import="dedent") 173def arm_target(compiler, all_flags): 174 # We're going to preprocess the following source to figure out some details 175 # about the arm target options we have enabled. 176 source = dedent( 177 """\ 178 %ARM_ARCH __ARM_ARCH 179 #if __thumb2__ 180 %THUMB2 yes 181 #else 182 %THUMB2 no 183 #endif 184 // Confusingly, the __SOFTFP__ preprocessor variable indicates the 185 // "softfloat" ABI, not the "softfp" ABI. 186 #if __SOFTFP__ 187 %FLOAT_ABI soft 188 #elif __ARM_PCS_VFP 189 %FLOAT_ABI hard 190 #else 191 %FLOAT_ABI softfp 192 #endif 193 // There is more subtlety to it than this preprocessor test, but MOZ_FPU doesn't 194 // need to be too fine-grained. 195 #if __ARM_NEON 196 %FPU neon 197 #elif __ARM_VFPV2__ || __ARM_FP == 12 198 %FPU vfpv2 199 #elif __ARM_VFPV3__ 200 %FPU vfpv3 201 #elif __ARM_VFPV4__ || __ARM_FP == 14 202 %FPU vfpv4 203 #elif __ARM_FPV5__ 204 %FPU fp-armv8 205 #endif 206 """ 207 ) 208 result = try_invoke_compiler( 209 compiler.wrapper + [compiler.compiler] + compiler.flags, 210 compiler.language, 211 source, 212 ["-E"] + all_flags, 213 ) 214 # Metadata emitted by preprocessors such as GCC with LANG=ja_JP.utf-8 may 215 # have non-ASCII characters. Treat the output as bytearray. 216 data = {"fpu": None} # fpu may not get a value from the preprocessor. 217 for line in result.splitlines(): 218 if line.startswith("%"): 219 k, _, v = line.partition(" ") 220 k = k.lstrip("%").lower() 221 if k == "arm_arch": 222 data[k] = int(v) 223 else: 224 data[k] = { 225 "yes": True, 226 "no": False, 227 }.get(v, v) 228 log.debug("%s = %s", k, data[k]) 229 230 return namespace(**data) 231 232 233@depends(arm_target.arm_arch, when=depends(target.os)(lambda os: os == "Android")) 234def armv7(arch): 235 if arch < 7: 236 die("Android/armv6 and earlier are not supported") 237 238 239set_config("MOZ_THUMB2", True, when=arm_target.thumb2) 240set_define("MOZ_THUMB2", True, when=arm_target.thumb2) 241add_old_configure_assignment("MOZ_THUMB2", True, when=arm_target.thumb2) 242 243 244have_arm_simd = c_compiler.try_compile( 245 body='asm("uqadd8 r1, r1, r2");', check_msg="for ARM SIMD support in compiler" 246) 247 248set_config("HAVE_ARM_SIMD", have_arm_simd) 249set_define("HAVE_ARM_SIMD", have_arm_simd) 250 251have_arm_neon = c_compiler.try_compile( 252 body='asm(".fpu neon\\n vadd.i8 d0, d0, d0");', 253 check_msg="for ARM NEON support in compiler", 254) 255 256set_config("HAVE_ARM_NEON", have_arm_neon) 257set_define("HAVE_ARM_NEON", have_arm_neon) 258 259 260# We don't need to build NEON support if we're targetting a non-NEON device. 261# This matches media/webrtc/trunk/webrtc/build/common.gypi. 262@depends(arm_target.arm_arch, when=have_arm_neon) 263def build_arm_neon(arm_arch): 264 return arm_arch >= 7 265 266 267set_config("BUILD_ARM_NEON", build_arm_neon) 268set_define("BUILD_ARM_NEON", build_arm_neon) 269 270 271set_config("ARM_ARCH", depends(arm_target.arm_arch)(lambda x: str(x))) 272add_old_configure_assignment("ARM_ARCH", depends(arm_target.arm_arch)(lambda x: str(x))) 273set_config("MOZ_FPU", arm_target.fpu) 274 275 276@depends(arm_target.float_abi) 277def neon_flags(float_abi): 278 # Building with -mfpu=neon requires either the "softfp" or the 279 # "hardfp" ABI. Depending on the compiler's default target, and the 280 # CFLAGS, the default ABI might be neither, in which case it is the 281 # "softfloat" ABI. 282 # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so 283 # we can safely mix code built with both ABIs. So, if we detect 284 # that compiling uses the "softfloat" ABI, force the use of the 285 # "softfp" ABI instead. 286 flags = ["-mfpu=neon"] 287 if float_abi == "soft": 288 flags.append("-mfloat-abi=softfp") 289 return tuple(flags) 290 291 292set_config("NEON_FLAGS", neon_flags) 293