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)