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