1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package config 16 17import ( 18 "fmt" 19 "strings" 20 21 "android/soong/android" 22) 23 24var ( 25 armToolchainCflags = []string{ 26 "-mthumb-interwork", 27 "-msoft-float", 28 } 29 30 armCflags = []string{ 31 "-fomit-frame-pointer", 32 } 33 34 armCppflags = []string{} 35 36 armLdflags = []string{ 37 "-Wl,--hash-style=gnu", 38 "-Wl,-m,armelf", 39 } 40 41 armLldflags = ClangFilterUnknownLldflags(armLdflags) 42 43 armArmCflags = []string{ 44 "-fstrict-aliasing", 45 } 46 47 armThumbCflags = []string{ 48 "-mthumb", 49 "-Os", 50 } 51 52 armClangArchVariantCflags = map[string][]string{ 53 "armv7-a": []string{ 54 "-march=armv7-a", 55 "-mfloat-abi=softfp", 56 "-mfpu=vfpv3-d16", 57 }, 58 "armv7-a-neon": []string{ 59 "-march=armv7-a", 60 "-mfloat-abi=softfp", 61 "-mfpu=neon", 62 }, 63 "armv8-a": []string{ 64 "-march=armv8-a", 65 "-mfloat-abi=softfp", 66 "-mfpu=neon-fp-armv8", 67 }, 68 "armv8-2a": []string{ 69 "-march=armv8.2-a", 70 "-mfloat-abi=softfp", 71 "-mfpu=neon-fp-armv8", 72 }, 73 } 74 75 armClangCpuVariantCflags = map[string][]string{ 76 "cortex-a7": []string{ 77 "-mcpu=cortex-a7", 78 "-mfpu=neon-vfpv4", 79 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 80 // don't advertise. 81 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 82 // better solution comes around. See Bug 27340895 83 "-D__ARM_FEATURE_LPAE=1", 84 }, 85 "cortex-a8": []string{ 86 "-mcpu=cortex-a8", 87 }, 88 "cortex-a15": []string{ 89 "-mcpu=cortex-a15", 90 "-mfpu=neon-vfpv4", 91 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 92 // don't advertise. 93 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 94 // better solution comes around. See Bug 27340895 95 "-D__ARM_FEATURE_LPAE=1", 96 }, 97 "cortex-a53": []string{ 98 "-mcpu=cortex-a53", 99 "-mfpu=neon-fp-armv8", 100 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 101 // don't advertise. 102 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 103 // better solution comes around. See Bug 27340895 104 "-D__ARM_FEATURE_LPAE=1", 105 }, 106 "cortex-a55": []string{ 107 "-mcpu=cortex-a55", 108 "-mfpu=neon-fp-armv8", 109 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 110 // don't advertise. 111 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 112 // better solution comes around. See Bug 27340895 113 "-D__ARM_FEATURE_LPAE=1", 114 }, 115 "cortex-a75": []string{ 116 "-mcpu=cortex-a55", 117 "-mfpu=neon-fp-armv8", 118 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 119 // don't advertise. 120 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 121 // better solution comes around. See Bug 27340895 122 "-D__ARM_FEATURE_LPAE=1", 123 }, 124 "cortex-a76": []string{ 125 "-mcpu=cortex-a55", 126 "-mfpu=neon-fp-armv8", 127 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 128 // don't advertise. 129 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 130 // better solution comes around. See Bug 27340895 131 "-D__ARM_FEATURE_LPAE=1", 132 }, 133 "krait": []string{ 134 "-mcpu=krait", 135 "-mfpu=neon-vfpv4", 136 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 137 // don't advertise. 138 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 139 // better solution comes around. See Bug 27340895 140 "-D__ARM_FEATURE_LPAE=1", 141 }, 142 "kryo": []string{ 143 // Use cortex-a53 because the GNU assembler doesn't recognize -mcpu=kryo 144 // even though clang does. 145 "-mcpu=cortex-a53", 146 "-mfpu=neon-fp-armv8", 147 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 148 // don't advertise. 149 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 150 // better solution comes around. See Bug 27340895 151 "-D__ARM_FEATURE_LPAE=1", 152 }, 153 "kryo385": []string{ 154 // Use cortex-a53 because kryo385 is not supported in GCC/clang. 155 "-mcpu=cortex-a53", 156 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 157 // don't advertise. 158 // TODO This is a hack and we need to add it for each processor that supports LPAE until some 159 // better solution comes around. See Bug 27340895 160 "-D__ARM_FEATURE_LPAE=1", 161 }, 162 } 163) 164 165const ( 166 armGccVersion = "4.9" 167) 168 169func init() { 170 pctx.StaticVariable("armGccVersion", armGccVersion) 171 172 pctx.SourcePathVariable("ArmGccRoot", 173 "prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}") 174 175 pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " ")) 176 pctx.StaticVariable("ArmLldflags", strings.Join(armLldflags, " ")) 177 178 // Clang cflags 179 pctx.StaticVariable("ArmToolchainClangCflags", strings.Join(ClangFilterUnknownCflags(armToolchainCflags), " ")) 180 pctx.StaticVariable("ArmClangCflags", strings.Join(ClangFilterUnknownCflags(armCflags), " ")) 181 pctx.StaticVariable("ArmClangLdflags", strings.Join(ClangFilterUnknownCflags(armLdflags), " ")) 182 pctx.StaticVariable("ArmClangLldflags", strings.Join(ClangFilterUnknownCflags(armLldflags), " ")) 183 pctx.StaticVariable("ArmClangCppflags", strings.Join(ClangFilterUnknownCflags(armCppflags), " ")) 184 185 // Clang ARM vs. Thumb instruction set cflags 186 pctx.StaticVariable("ArmClangArmCflags", strings.Join(ClangFilterUnknownCflags(armArmCflags), " ")) 187 pctx.StaticVariable("ArmClangThumbCflags", strings.Join(ClangFilterUnknownCflags(armThumbCflags), " ")) 188 189 // Clang arch variant cflags 190 pctx.StaticVariable("ArmClangArmv7ACflags", 191 strings.Join(armClangArchVariantCflags["armv7-a"], " ")) 192 pctx.StaticVariable("ArmClangArmv7ANeonCflags", 193 strings.Join(armClangArchVariantCflags["armv7-a-neon"], " ")) 194 pctx.StaticVariable("ArmClangArmv8ACflags", 195 strings.Join(armClangArchVariantCflags["armv8-a"], " ")) 196 pctx.StaticVariable("ArmClangArmv82ACflags", 197 strings.Join(armClangArchVariantCflags["armv8-2a"], " ")) 198 199 // Clang cpu variant cflags 200 pctx.StaticVariable("ArmClangGenericCflags", 201 strings.Join(armClangCpuVariantCflags[""], " ")) 202 pctx.StaticVariable("ArmClangCortexA7Cflags", 203 strings.Join(armClangCpuVariantCflags["cortex-a7"], " ")) 204 pctx.StaticVariable("ArmClangCortexA8Cflags", 205 strings.Join(armClangCpuVariantCflags["cortex-a8"], " ")) 206 pctx.StaticVariable("ArmClangCortexA15Cflags", 207 strings.Join(armClangCpuVariantCflags["cortex-a15"], " ")) 208 pctx.StaticVariable("ArmClangCortexA53Cflags", 209 strings.Join(armClangCpuVariantCflags["cortex-a53"], " ")) 210 pctx.StaticVariable("ArmClangCortexA55Cflags", 211 strings.Join(armClangCpuVariantCflags["cortex-a55"], " ")) 212 pctx.StaticVariable("ArmClangKraitCflags", 213 strings.Join(armClangCpuVariantCflags["krait"], " ")) 214 pctx.StaticVariable("ArmClangKryoCflags", 215 strings.Join(armClangCpuVariantCflags["kryo"], " ")) 216} 217 218var ( 219 armClangArchVariantCflagsVar = map[string]string{ 220 "armv7-a": "${config.ArmClangArmv7ACflags}", 221 "armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}", 222 "armv8-a": "${config.ArmClangArmv8ACflags}", 223 "armv8-2a": "${config.ArmClangArmv82ACflags}", 224 } 225 226 armClangCpuVariantCflagsVar = map[string]string{ 227 "": "${config.ArmClangGenericCflags}", 228 "cortex-a7": "${config.ArmClangCortexA7Cflags}", 229 "cortex-a8": "${config.ArmClangCortexA8Cflags}", 230 "cortex-a15": "${config.ArmClangCortexA15Cflags}", 231 "cortex-a53": "${config.ArmClangCortexA53Cflags}", 232 "cortex-a53.a57": "${config.ArmClangCortexA53Cflags}", 233 "cortex-a55": "${config.ArmClangCortexA55Cflags}", 234 "cortex-a72": "${config.ArmClangCortexA53Cflags}", 235 "cortex-a73": "${config.ArmClangCortexA53Cflags}", 236 "cortex-a75": "${config.ArmClangCortexA55Cflags}", 237 "cortex-a76": "${config.ArmClangCortexA55Cflags}", 238 "krait": "${config.ArmClangKraitCflags}", 239 "kryo": "${config.ArmClangKryoCflags}", 240 "kryo385": "${config.ArmClangCortexA53Cflags}", 241 "exynos-m1": "${config.ArmClangCortexA53Cflags}", 242 "exynos-m2": "${config.ArmClangCortexA53Cflags}", 243 } 244) 245 246type toolchainArm struct { 247 toolchain32Bit 248 ldflags string 249 lldflags string 250 toolchainClangCflags string 251} 252 253func (t *toolchainArm) Name() string { 254 return "arm" 255} 256 257func (t *toolchainArm) GccRoot() string { 258 return "${config.ArmGccRoot}" 259} 260 261func (t *toolchainArm) GccTriple() string { 262 return "arm-linux-androideabi" 263} 264 265func (t *toolchainArm) GccVersion() string { 266 return armGccVersion 267} 268 269func (t *toolchainArm) IncludeFlags() string { 270 return "" 271} 272 273func (t *toolchainArm) ClangTriple() string { 274 // http://b/72619014 work around llvm LTO bug. 275 return "armv7a-linux-androideabi" 276} 277 278func (t *toolchainArm) ndkTriple() string { 279 // Use current NDK include path, while ClangTriple is changed. 280 return t.GccTriple() 281} 282 283func (t *toolchainArm) ToolchainClangCflags() string { 284 return t.toolchainClangCflags 285} 286 287func (t *toolchainArm) ClangCflags() string { 288 return "${config.ArmClangCflags}" 289} 290 291func (t *toolchainArm) ClangCppflags() string { 292 return "${config.ArmClangCppflags}" 293} 294 295func (t *toolchainArm) ClangLdflags() string { 296 return t.ldflags 297} 298 299func (t *toolchainArm) ClangLldflags() string { 300 return t.lldflags // TODO: handle V8 cases 301} 302 303func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) { 304 switch isa { 305 case "arm": 306 return "${config.ArmClangArmCflags}", nil 307 case "thumb", "": 308 return "${config.ArmClangThumbCflags}", nil 309 default: 310 return t.toolchainBase.ClangInstructionSetFlags(isa) 311 } 312} 313 314func (toolchainArm) LibclangRuntimeLibraryArch() string { 315 return "arm" 316} 317 318func armToolchainFactory(arch android.Arch) Toolchain { 319 var fixCortexA8 string 320 toolchainClangCflags := make([]string, 2, 3) 321 322 toolchainClangCflags[0] = "${config.ArmToolchainClangCflags}" 323 toolchainClangCflags[1] = armClangArchVariantCflagsVar[arch.ArchVariant] 324 325 toolchainClangCflags = append(toolchainClangCflags, 326 variantOrDefault(armClangCpuVariantCflagsVar, arch.CpuVariant)) 327 328 switch arch.ArchVariant { 329 case "armv7-a-neon": 330 switch arch.CpuVariant { 331 case "cortex-a8", "": 332 // Generic ARM might be a Cortex A8 -- better safe than sorry 333 fixCortexA8 = "-Wl,--fix-cortex-a8" 334 default: 335 fixCortexA8 = "-Wl,--no-fix-cortex-a8" 336 } 337 case "armv7-a": 338 fixCortexA8 = "-Wl,--fix-cortex-a8" 339 case "armv8-a", "armv8-2a": 340 // Nothing extra for armv8-a/armv8-2a 341 default: 342 panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant)) 343 } 344 345 return &toolchainArm{ 346 ldflags: strings.Join([]string{ 347 "${config.ArmLdflags}", 348 fixCortexA8, 349 }, " "), 350 lldflags: "${config.ArmLldflags}", 351 toolchainClangCflags: strings.Join(toolchainClangCflags, " "), 352 } 353} 354 355func init() { 356 registerToolchainFactory(android.Android, android.Arm, armToolchainFactory) 357} 358