Home | History | Annotate | Download | only in config
      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 
     15 package config
     16 
     17 import (
     18 	"fmt"
     19 	"strings"
     20 
     21 	"android/soong/android"
     22 )
     23 
     24 var (
     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 	armArmCflags = []string{
     43 		"-fstrict-aliasing",
     44 	}
     45 
     46 	armThumbCflags = []string{
     47 		"-mthumb",
     48 		"-Os",
     49 	}
     50 
     51 	armArchVariantCflags = map[string][]string{
     52 		"armv7-a": []string{
     53 			"-march=armv7-a",
     54 			"-mfloat-abi=softfp",
     55 			"-mfpu=vfpv3-d16",
     56 		},
     57 		"armv7-a-neon": []string{
     58 			"-march=armv7-a",
     59 			"-mfloat-abi=softfp",
     60 			"-mfpu=neon",
     61 		},
     62 		"armv8-a": []string{
     63 			"-march=armv8-a",
     64 			"-mfloat-abi=softfp",
     65 			"-mfpu=neon-fp-armv8",
     66 		},
     67 	}
     68 
     69 	armCpuVariantCflags = map[string][]string{
     70 		"cortex-a7": []string{
     71 			"-mcpu=cortex-a7",
     72 			"-mfpu=neon-vfpv4",
     73 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
     74 			// don't advertise.
     75 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
     76 			// better solution comes around. See Bug 27340895
     77 			"-D__ARM_FEATURE_LPAE=1",
     78 		},
     79 		"cortex-a8": []string{
     80 			"-mcpu=cortex-a8",
     81 		},
     82 		"cortex-a15": []string{
     83 			"-mcpu=cortex-a15",
     84 			"-mfpu=neon-vfpv4",
     85 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
     86 			// don't advertise.
     87 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
     88 			// better solution comes around. See Bug 27340895
     89 			"-D__ARM_FEATURE_LPAE=1",
     90 		},
     91 		"cortex-a53": []string{
     92 			"-mcpu=cortex-a53",
     93 			"-mfpu=neon-fp-armv8",
     94 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
     95 			// don't advertise.
     96 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
     97 			// better solution comes around. See Bug 27340895
     98 			"-D__ARM_FEATURE_LPAE=1",
     99 		},
    100 		"cortex-a55": []string{
    101 			"-mcpu=cortex-a53",
    102 			"-mfpu=neon-fp-armv8",
    103 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
    104 			// don't advertise.
    105 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
    106 			// better solution comes around. See Bug 27340895
    107 			"-D__ARM_FEATURE_LPAE=1",
    108 		},
    109 		"cortex-a75": []string{
    110 			"-mcpu=cortex-a53",
    111 			"-mfpu=neon-fp-armv8",
    112 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
    113 			// don't advertise.
    114 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
    115 			// better solution comes around. See Bug 27340895
    116 			"-D__ARM_FEATURE_LPAE=1",
    117 		},
    118 		"krait": []string{
    119 			"-mcpu=cortex-a15",
    120 			"-mfpu=neon-vfpv4",
    121 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
    122 			// don't advertise.
    123 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
    124 			// better solution comes around. See Bug 27340895
    125 			"-D__ARM_FEATURE_LPAE=1",
    126 		},
    127 		"kryo": []string{
    128 			// Use cortex-a53 because the GNU assembler doesn't recognize -mcpu=kryo
    129 			// even though clang does.
    130 			"-mcpu=cortex-a53",
    131 			"-mfpu=neon-fp-armv8",
    132 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
    133 			// don't advertise.
    134 			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
    135 			// better solution comes around. See Bug 27340895
    136 			"-D__ARM_FEATURE_LPAE=1",
    137 		},
    138 	}
    139 
    140 	armClangCpuVariantCflags  = copyVariantFlags(armCpuVariantCflags)
    141 	armClangArchVariantCflags = copyVariantFlags(armArchVariantCflags)
    142 )
    143 
    144 const (
    145 	armGccVersion = "4.9"
    146 )
    147 
    148 func init() {
    149 	android.RegisterArchFeatures(android.Arm,
    150 		"neon")
    151 
    152 	android.RegisterArchVariants(android.Arm,
    153 		"armv7-a",
    154 		"armv7-a-neon",
    155 		"armv8-a",
    156 		"cortex-a7",
    157 		"cortex-a8",
    158 		"cortex-a9",
    159 		"cortex-a15",
    160 		"cortex-a53",
    161 		"cortex-a53-a57",
    162 		"cortex-a55",
    163 		"cortex-a73",
    164 		"cortex-a75",
    165 		"krait",
    166 		"kryo",
    167 		"exynos-m1",
    168 		"exynos-m2",
    169 		"denver")
    170 
    171 	android.RegisterArchVariantFeatures(android.Arm, "armv7-a-neon", "neon")
    172 	android.RegisterArchVariantFeatures(android.Arm, "armv8-a", "neon")
    173 
    174 	// Krait is not supported by GCC, but is supported by Clang, so
    175 	// override the definitions when building modules with Clang.
    176 	replaceFirst(armClangCpuVariantCflags["krait"], "-mcpu=cortex-a15", "-mcpu=krait")
    177 
    178 	// The reason we use "-march=armv8-a+crc", instead of "-march=armv8-a", for
    179 	// gcc is the latter would conflict with any specified/supported -mcpu!
    180 	// All armv8-a cores supported by gcc 4.9 support crc, so it's safe
    181 	// to add +crc. Besides, the use of gcc is only for legacy code.
    182 	replaceFirst(armArchVariantCflags["armv8-a"], "-march=armv8-a", "-march=armv8-a+crc")
    183 
    184 	pctx.StaticVariable("armGccVersion", armGccVersion)
    185 
    186 	pctx.SourcePathVariable("ArmGccRoot",
    187 		"prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
    188 
    189 	pctx.StaticVariable("ArmToolchainCflags", strings.Join(armToolchainCflags, " "))
    190 	pctx.StaticVariable("ArmCflags", strings.Join(armCflags, " "))
    191 	pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " "))
    192 	pctx.StaticVariable("ArmCppflags", strings.Join(armCppflags, " "))
    193 	pctx.StaticVariable("ArmIncludeFlags", bionicHeaders("arm"))
    194 
    195 	// Extended cflags
    196 
    197 	// ARM vs. Thumb instruction set flags
    198 	pctx.StaticVariable("ArmArmCflags", strings.Join(armArmCflags, " "))
    199 	pctx.StaticVariable("ArmThumbCflags", strings.Join(armThumbCflags, " "))
    200 
    201 	// Architecture variant cflags
    202 	pctx.StaticVariable("ArmArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " "))
    203 	pctx.StaticVariable("ArmArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
    204 	pctx.StaticVariable("ArmArmv8ACflags", strings.Join(armArchVariantCflags["armv8-a"], " "))
    205 
    206 	// Cpu variant cflags
    207 	pctx.StaticVariable("ArmGenericCflags", strings.Join(armCpuVariantCflags[""], " "))
    208 	pctx.StaticVariable("ArmCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
    209 	pctx.StaticVariable("ArmCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
    210 	pctx.StaticVariable("ArmCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
    211 	pctx.StaticVariable("ArmCortexA53Cflags", strings.Join(armCpuVariantCflags["cortex-a53"], " "))
    212 	pctx.StaticVariable("ArmCortexA55Cflags", strings.Join(armCpuVariantCflags["cortex-a55"], " "))
    213 	pctx.StaticVariable("ArmKraitCflags", strings.Join(armCpuVariantCflags["krait"], " "))
    214 	pctx.StaticVariable("ArmKryoCflags", strings.Join(armCpuVariantCflags["kryo"], " "))
    215 
    216 	// Clang cflags
    217 	pctx.StaticVariable("ArmToolchainClangCflags", strings.Join(ClangFilterUnknownCflags(armToolchainCflags), " "))
    218 	pctx.StaticVariable("ArmClangCflags", strings.Join(ClangFilterUnknownCflags(armCflags), " "))
    219 	pctx.StaticVariable("ArmClangLdflags", strings.Join(ClangFilterUnknownCflags(armLdflags), " "))
    220 	pctx.StaticVariable("ArmClangCppflags", strings.Join(ClangFilterUnknownCflags(armCppflags), " "))
    221 
    222 	// Clang ARM vs. Thumb instruction set cflags
    223 	pctx.StaticVariable("ArmClangArmCflags", strings.Join(ClangFilterUnknownCflags(armArmCflags), " "))
    224 	pctx.StaticVariable("ArmClangThumbCflags", strings.Join(ClangFilterUnknownCflags(armThumbCflags), " "))
    225 
    226 	// Clang arch variant cflags
    227 	pctx.StaticVariable("ArmClangArmv7ACflags",
    228 		strings.Join(armClangArchVariantCflags["armv7-a"], " "))
    229 	pctx.StaticVariable("ArmClangArmv7ANeonCflags",
    230 		strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
    231 	pctx.StaticVariable("ArmClangArmv8ACflags",
    232 		strings.Join(armClangArchVariantCflags["armv8-a"], " "))
    233 
    234 	// Clang cpu variant cflags
    235 	pctx.StaticVariable("ArmClangGenericCflags",
    236 		strings.Join(armClangCpuVariantCflags[""], " "))
    237 	pctx.StaticVariable("ArmClangCortexA7Cflags",
    238 		strings.Join(armClangCpuVariantCflags["cortex-a7"], " "))
    239 	pctx.StaticVariable("ArmClangCortexA8Cflags",
    240 		strings.Join(armClangCpuVariantCflags["cortex-a8"], " "))
    241 	pctx.StaticVariable("ArmClangCortexA15Cflags",
    242 		strings.Join(armClangCpuVariantCflags["cortex-a15"], " "))
    243 	pctx.StaticVariable("ArmClangCortexA53Cflags",
    244 		strings.Join(armClangCpuVariantCflags["cortex-a53"], " "))
    245 	pctx.StaticVariable("ArmClangCortexA55Cflags",
    246 		strings.Join(armClangCpuVariantCflags["cortex-a55"], " "))
    247 	pctx.StaticVariable("ArmClangKraitCflags",
    248 		strings.Join(armClangCpuVariantCflags["krait"], " "))
    249 	pctx.StaticVariable("ArmClangKryoCflags",
    250 		strings.Join(armClangCpuVariantCflags["kryo"], " "))
    251 }
    252 
    253 var (
    254 	armArchVariantCflagsVar = map[string]string{
    255 		"armv7-a":      "${config.ArmArmv7ACflags}",
    256 		"armv7-a-neon": "${config.ArmArmv7ANeonCflags}",
    257 		"armv8-a":      "${config.ArmArmv8ACflags}",
    258 	}
    259 
    260 	armCpuVariantCflagsVar = map[string]string{
    261 		"":               "${config.ArmGenericCflags}",
    262 		"cortex-a7":      "${config.ArmCortexA7Cflags}",
    263 		"cortex-a8":      "${config.ArmCortexA8Cflags}",
    264 		"cortex-a15":     "${config.ArmCortexA15Cflags}",
    265 		"cortex-a53":     "${config.ArmCortexA53Cflags}",
    266 		"cortex-a53.a57": "${config.ArmCortexA53Cflags}",
    267 		"cortex-a55":     "${config.ArmCortexA55Cflags}",
    268 		"cortex-a73":     "${config.ArmCortexA53Cflags}",
    269 		"cortex-a75":     "${config.ArmCortexA55Cflags}",
    270 		"krait":          "${config.ArmKraitCflags}",
    271 		"kryo":           "${config.ArmKryoCflags}",
    272 		"exynos-m1":      "${config.ArmCortexA53Cflags}",
    273 		"exynos-m2":      "${config.ArmCortexA53Cflags}",
    274 		"denver":         "${config.ArmCortexA15Cflags}",
    275 	}
    276 
    277 	armClangArchVariantCflagsVar = map[string]string{
    278 		"armv7-a":      "${config.ArmClangArmv7ACflags}",
    279 		"armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
    280 		"armv8-a":      "${config.ArmClangArmv8ACflags}",
    281 	}
    282 
    283 	armClangCpuVariantCflagsVar = map[string]string{
    284 		"":               "${config.ArmClangGenericCflags}",
    285 		"cortex-a7":      "${config.ArmClangCortexA7Cflags}",
    286 		"cortex-a8":      "${config.ArmClangCortexA8Cflags}",
    287 		"cortex-a15":     "${config.ArmClangCortexA15Cflags}",
    288 		"cortex-a53":     "${config.ArmClangCortexA53Cflags}",
    289 		"cortex-a53.a57": "${config.ArmClangCortexA53Cflags}",
    290 		"cortex-a55":     "${config.ArmClangCortexA55Cflags}",
    291 		"cortex-a73":     "${config.ArmClangCortexA53Cflags}",
    292 		"cortex-a75":     "${config.ArmClangCortexA55Cflags}",
    293 		"krait":          "${config.ArmClangKraitCflags}",
    294 		"kryo":           "${config.ArmClangKryoCflags}",
    295 		"exynos-m1":      "${config.ArmClangCortexA53Cflags}",
    296 		"exynos-m2":      "${config.ArmClangCortexA53Cflags}",
    297 		"denver":         "${config.ArmClangCortexA15Cflags}",
    298 	}
    299 )
    300 
    301 type toolchainArm struct {
    302 	toolchain32Bit
    303 	ldflags                               string
    304 	toolchainCflags, toolchainClangCflags string
    305 }
    306 
    307 func (t *toolchainArm) Name() string {
    308 	return "arm"
    309 }
    310 
    311 func (t *toolchainArm) GccRoot() string {
    312 	return "${config.ArmGccRoot}"
    313 }
    314 
    315 func (t *toolchainArm) GccTriple() string {
    316 	return "arm-linux-androideabi"
    317 }
    318 
    319 func (t *toolchainArm) GccVersion() string {
    320 	return armGccVersion
    321 }
    322 
    323 func (t *toolchainArm) ToolchainCflags() string {
    324 	return t.toolchainCflags
    325 }
    326 
    327 func (t *toolchainArm) Cflags() string {
    328 	return "${config.ArmCflags}"
    329 }
    330 
    331 func (t *toolchainArm) Cppflags() string {
    332 	return "${config.ArmCppflags}"
    333 }
    334 
    335 func (t *toolchainArm) Ldflags() string {
    336 	return t.ldflags
    337 }
    338 
    339 func (t *toolchainArm) IncludeFlags() string {
    340 	return "${config.ArmIncludeFlags}"
    341 }
    342 
    343 func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
    344 	switch isa {
    345 	case "arm":
    346 		return "${config.ArmArmCflags}", nil
    347 	case "thumb", "":
    348 		return "${config.ArmThumbCflags}", nil
    349 	default:
    350 		return t.toolchainBase.InstructionSetFlags(isa)
    351 	}
    352 }
    353 
    354 func (t *toolchainArm) ClangTriple() string {
    355 	return t.GccTriple()
    356 }
    357 
    358 func (t *toolchainArm) ToolchainClangCflags() string {
    359 	return t.toolchainClangCflags
    360 }
    361 
    362 func (t *toolchainArm) ClangCflags() string {
    363 	return "${config.ArmClangCflags}"
    364 }
    365 
    366 func (t *toolchainArm) ClangCppflags() string {
    367 	return "${config.ArmClangCppflags}"
    368 }
    369 
    370 func (t *toolchainArm) ClangLdflags() string {
    371 	return t.ldflags
    372 }
    373 
    374 func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) {
    375 	switch isa {
    376 	case "arm":
    377 		return "${config.ArmClangArmCflags}", nil
    378 	case "thumb", "":
    379 		return "${config.ArmClangThumbCflags}", nil
    380 	default:
    381 		return t.toolchainBase.ClangInstructionSetFlags(isa)
    382 	}
    383 }
    384 
    385 func (toolchainArm) SanitizerRuntimeLibraryArch() string {
    386 	return "arm"
    387 }
    388 
    389 func armToolchainFactory(arch android.Arch) Toolchain {
    390 	var fixCortexA8 string
    391 	toolchainCflags := make([]string, 2, 3)
    392 	toolchainClangCflags := make([]string, 2, 3)
    393 
    394 	toolchainCflags[0] = "${config.ArmToolchainCflags}"
    395 	toolchainCflags[1] = armArchVariantCflagsVar[arch.ArchVariant]
    396 	toolchainClangCflags[0] = "${config.ArmToolchainClangCflags}"
    397 	toolchainClangCflags[1] = armClangArchVariantCflagsVar[arch.ArchVariant]
    398 
    399 	toolchainCflags = append(toolchainCflags,
    400 		variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant))
    401 	toolchainClangCflags = append(toolchainClangCflags,
    402 		variantOrDefault(armClangCpuVariantCflagsVar, arch.CpuVariant))
    403 
    404 	switch arch.ArchVariant {
    405 	case "armv7-a-neon":
    406 		switch arch.CpuVariant {
    407 		case "cortex-a8", "":
    408 			// Generic ARM might be a Cortex A8 -- better safe than sorry
    409 			fixCortexA8 = "-Wl,--fix-cortex-a8"
    410 		default:
    411 			fixCortexA8 = "-Wl,--no-fix-cortex-a8"
    412 		}
    413 	case "armv7-a":
    414 		fixCortexA8 = "-Wl,--fix-cortex-a8"
    415 	case "armv8-a":
    416 		// Nothing extra for armv8-a
    417 	default:
    418 		panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
    419 	}
    420 
    421 	return &toolchainArm{
    422 		toolchainCflags: strings.Join(toolchainCflags, " "),
    423 		ldflags: strings.Join([]string{
    424 			"${config.ArmLdflags}",
    425 			fixCortexA8,
    426 		}, " "),
    427 		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
    428 	}
    429 }
    430 
    431 func init() {
    432 	registerToolchainFactory(android.Android, android.Arm, armToolchainFactory)
    433 }
    434