Merge "Remove extension from LOCAL_MODULE_STEM"
diff --git a/cc/arm64_device.go b/cc/arm64_device.go
index c861498..284e5bd 100644
--- a/cc/arm64_device.go
+++ b/cc/arm64_device.go
@@ -15,6 +15,7 @@
 package cc
 
 import (
+	"fmt"
 	"strings"
 
 	"android/soong/common"
@@ -72,6 +73,14 @@
 	arm64Cppflags = []string{
 		"-fvisibility-inlines-hidden",
 	}
+
+	arm64CpuVariantCflags = map[string][]string{
+		"cortex-a53": []string{
+			"-mcpu=cortex-a53",
+		},
+	}
+
+	arm64ClangCpuVariantCflags = copyVariantFlags(arm64CpuVariantCflags)
 )
 
 const (
@@ -101,13 +110,31 @@
 	pctx.StaticVariable("arm64ClangCflags", strings.Join(clangFilterUnknownCflags(arm64Cflags), " "))
 	pctx.StaticVariable("arm64ClangLdflags", strings.Join(clangFilterUnknownCflags(arm64Ldflags), " "))
 	pctx.StaticVariable("arm64ClangCppflags", strings.Join(clangFilterUnknownCflags(arm64Cppflags), " "))
+
+	pctx.StaticVariable("arm64CortexA53Cflags",
+		strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
+	pctx.StaticVariable("arm64ClangCortexA53Cflags",
+		strings.Join(arm64ClangCpuVariantCflags["cortex-a53"], " "))
 }
 
+var (
+	arm64CpuVariantCflagsVar = map[string]string{
+		"":           "",
+		"cortex-a53": "${arm64CortexA53Cflags}",
+	}
+
+	arm64ClangCpuVariantCflagsVar = map[string]string{
+		"":           "",
+		"cortex-a53": "${arm64ClangCortexA53Cflags}",
+	}
+)
+
 type toolchainArm64 struct {
 	toolchain64Bit
-}
 
-var toolchainArm64Singleton = &toolchainArm64{}
+	toolchainCflags      string
+	toolchainClangCflags string
+}
 
 func (t *toolchainArm64) Name() string {
 	return "arm64"
@@ -125,6 +152,10 @@
 	return arm64GccVersion
 }
 
+func (t *toolchainArm64) ToolchainCflags() string {
+	return t.toolchainCflags
+}
+
 func (t *toolchainArm64) Cflags() string {
 	return "${arm64Cflags}"
 }
@@ -157,8 +188,19 @@
 	return "${arm64Ldflags}"
 }
 
+func (t *toolchainArm64) ToolchainClangCflags() string {
+	return t.toolchainClangCflags
+}
+
 func arm64ToolchainFactory(arch common.Arch) Toolchain {
-	return toolchainArm64Singleton
+	if arch.ArchVariant != "armv8-a" {
+		panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
+	}
+
+	return &toolchainArm64{
+		toolchainCflags:      variantOrDefault(arm64CpuVariantCflagsVar, arch.CpuVariant),
+		toolchainClangCflags: variantOrDefault(arm64ClangCpuVariantCflagsVar, arch.CpuVariant),
+	}
 }
 
 func init() {
diff --git a/cc/arm_device.go b/cc/arm_device.go
index 7212c4f..c122664 100644
--- a/cc/arm_device.go
+++ b/cc/arm_device.go
@@ -104,8 +104,16 @@
 	}
 
 	armCpuVariantCflags = map[string][]string{
+		"": []string{
+			"-march=armv7-a",
+		},
 		"cortex-a7": []string{
 			"-mcpu=cortex-a7",
+			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
+			// don't advertise.
+			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
+			// better solution comes around. See Bug 27340895
+			"-D__ARM_FEATURE_LPAE=1",
 		},
 		"cortex-a8": []string{
 			"-mcpu=cortex-a8",
@@ -114,6 +122,8 @@
 			"-mcpu=cortex-a15",
 			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
 			// don't advertise.
+			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
+			// better solution comes around. See Bug 27340895
 			"-D__ARM_FEATURE_LPAE=1",
 		},
 	}
@@ -126,18 +136,6 @@
 	armGccVersion = "4.9"
 )
 
-func copyVariantFlags(m map[string][]string) map[string][]string {
-	ret := make(map[string][]string, len(m))
-	for k, v := range m {
-		l := make([]string, len(m[k]))
-		for i := range m[k] {
-			l[i] = v[i]
-		}
-		ret[k] = l
-	}
-	return ret
-}
-
 func init() {
 	replaceFirst := func(slice []string, from, to string) {
 		if slice[0] != from {
@@ -185,6 +183,7 @@
 	pctx.StaticVariable("armArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
 
 	// Cpu variant cflags
+	pctx.StaticVariable("armGenericCflags", strings.Join(armCpuVariantCflags[""], " "))
 	pctx.StaticVariable("armCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
 	pctx.StaticVariable("armCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
 	pctx.StaticVariable("armCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
@@ -199,7 +198,7 @@
 	pctx.StaticVariable("armClangArmCflags", strings.Join(clangFilterUnknownCflags(armArmCflags), " "))
 	pctx.StaticVariable("armClangThumbCflags", strings.Join(clangFilterUnknownCflags(armThumbCflags), " "))
 
-	// Clang cpu variant cflags
+	// Clang arch variant cflags
 	pctx.StaticVariable("armClangArmv5TECflags",
 		strings.Join(armClangArchVariantCflags["armv5te"], " "))
 	pctx.StaticVariable("armClangArmv7ACflags",
@@ -208,6 +207,8 @@
 		strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
 
 	// Clang cpu variant cflags
+	pctx.StaticVariable("armClangGenericCflags",
+		strings.Join(armClangCpuVariantCflags[""], " "))
 	pctx.StaticVariable("armClangCortexA7Cflags",
 		strings.Join(armClangCpuVariantCflags["cortex-a7"], " "))
 	pctx.StaticVariable("armClangCortexA8Cflags",
@@ -226,7 +227,7 @@
 	}
 
 	armCpuVariantCflagsVar = map[string]string{
-		"":               "",
+		"":               "${armGenericCflags}",
 		"cortex-a7":      "${armCortexA7Cflags}",
 		"cortex-a8":      "${armCortexA8Cflags}",
 		"cortex-a15":     "${armCortexA15Cflags}",
@@ -243,7 +244,7 @@
 	}
 
 	armClangCpuVariantCflagsVar = map[string]string{
-		"":               "",
+		"":               "${armClangGenericCflags}",
 		"cortex-a7":      "${armClangCortexA7Cflags}",
 		"cortex-a8":      "${armClangCortexA8Cflags}",
 		"cortex-a15":     "${armClangCortexA15Cflags}",
@@ -340,29 +341,43 @@
 
 func armToolchainFactory(arch common.Arch) Toolchain {
 	var fixCortexA8 string
-	switch arch.CpuVariant {
-	case "cortex-a8", "":
-		// Generic ARM might be a Cortex A8 -- better safe than sorry
+	toolchainCflags := make([]string, 2, 3)
+	toolchainClangCflags := make([]string, 2, 3)
+
+	toolchainCflags[0] = "${armToolchainCflags}"
+	toolchainCflags[1] = armArchVariantCflagsVar[arch.ArchVariant]
+	toolchainClangCflags[0] = "${armToolchainClangCflags}"
+	toolchainClangCflags[1] = armClangArchVariantCflagsVar[arch.ArchVariant]
+
+	switch arch.ArchVariant {
+	case "armv7-a-neon":
+		switch arch.CpuVariant {
+		case "cortex-a8", "":
+			// Generic ARM might be a Cortex A8 -- better safe than sorry
+			fixCortexA8 = "-Wl,--fix-cortex-a8"
+		default:
+			fixCortexA8 = "-Wl,--no-fix-cortex-a8"
+		}
+
+		toolchainCflags = append(toolchainCflags,
+			variantOrDefault(armCpuVariantCflagsVar, arch.CpuVariant))
+		toolchainClangCflags = append(toolchainClangCflags,
+			variantOrDefault(armClangCpuVariantCflagsVar, arch.CpuVariant))
+	case "armv7-a":
 		fixCortexA8 = "-Wl,--fix-cortex-a8"
+	case "armv5te":
+		// Nothing extra for armv5te
 	default:
-		fixCortexA8 = "-Wl,--no-fix-cortex-a8"
+		panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
 	}
 
 	return &toolchainArm{
-		toolchainCflags: strings.Join([]string{
-			"${armToolchainCflags}",
-			armArchVariantCflagsVar[arch.ArchVariant],
-			armCpuVariantCflagsVar[arch.CpuVariant],
-		}, " "),
+		toolchainCflags: strings.Join(toolchainCflags, " "),
 		ldflags: strings.Join([]string{
 			"${armLdflags}",
 			fixCortexA8,
 		}, " "),
-		toolchainClangCflags: strings.Join([]string{
-			"${armToolchainClangCflags}",
-			armClangArchVariantCflagsVar[arch.ArchVariant],
-			armClangCpuVariantCflagsVar[arch.CpuVariant],
-		}, " "),
+		toolchainClangCflags: strings.Join(toolchainClangCflags, " "),
 	}
 }
 
diff --git a/cc/util.go b/cc/util.go
index c083744..1d27f73 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -86,3 +86,22 @@
 		clang:       in.Clang,
 	}
 }
+
+func copyVariantFlags(m map[string][]string) map[string][]string {
+	ret := make(map[string][]string, len(m))
+	for k, v := range m {
+		l := make([]string, len(m[k]))
+		for i := range m[k] {
+			l[i] = v[i]
+		}
+		ret[k] = l
+	}
+	return ret
+}
+
+func variantOrDefault(variants map[string]string, choice string) string {
+	if ret, ok := variants[choice]; ok {
+		return ret
+	}
+	return variants[""]
+}
diff --git a/common/arch.go b/common/arch.go
index 0e9c7fe..8a86c79 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -912,18 +912,20 @@
 		cpuVariant  string
 		abi         []string
 	}{
+		// armv5 is only used for unbundled apps
+		//{"arm", "armv5te", "", []string{"armeabi"}},
+		{"arm", "armv7-a", "generic", []string{"armeabi-v7a"}},
+		{"arm", "armv7-a-neon", "generic", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a7", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a8", []string{"armeabi-v7a"}},
-		// gtest_all_test.cc fails to build:
-		//   error in backend: Unsupported library call operation!
-		//{"arm", "armv7-a-neon", "cortex-a9", []string{"armeabi-v7a"}},
+		{"arm", "armv7-a-neon", "cortex-a9", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a15", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a53", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "cortex-a53.a57", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "denver", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "krait", []string{"armeabi-v7a"}},
-		{"arm64", "", "cortex-a53", []string{"arm64-v8a"}},
-		{"arm64", "", "denver64", []string{"arm64-v8a"}},
+		{"arm64", "armv8-a", "cortex-a53", []string{"arm64-v8a"}},
+		{"arm64", "armv8-a", "denver64", []string{"arm64-v8a"}},
 		{"mips", "mips32-fp", "", []string{"mips"}},
 		{"mips", "mips32r2-fp", "", []string{"mips"}},
 		{"mips", "mips32r2-fp-xburst", "", []string{"mips"}},