Add an instruction_set property to Arch

Used to allow switching between thumb and arm ISAs

Change-Id: I94aa83cee7179e83c97eedc32fd216965b626d33
diff --git a/cc/arm_device.go b/cc/arm_device.go
index e33bd01..8cd33e3 100644
--- a/cc/arm_device.go
+++ b/cc/arm_device.go
@@ -149,7 +149,7 @@
 
 	// Extended cflags
 
-	// ARM mode vs. Thumb mode
+	// ARM vs. Thumb instruction set flags
 	pctx.StaticVariable("armArmCflags", strings.Join(armArmCflags, " "))
 	pctx.StaticVariable("armThumbCflags", strings.Join(armThumbCflags, " "))
 
@@ -256,6 +256,17 @@
 	return "${armIncludeFlags}"
 }
 
+func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
+	switch isa {
+	case "arm":
+		return "${armArmCflags}", nil
+	case "thumb", "":
+		return "${armThumbCflags}", nil
+	default:
+		return t.toolchainBase.InstructionSetFlags(isa)
+	}
+}
+
 func (t *toolchainArm) ClangTriple() string {
 	return "${armGccTriple}"
 }
@@ -277,7 +288,6 @@
 		cflags: strings.Join([]string{
 			"${armCflags}",
 			"${armIncludeFlags}",
-			"${armThumbCflags}",
 			armArchVariantCflagsVar[archVariant],
 			armCpuVariantCflagsVar[cpuVariant],
 		}, " "),
@@ -288,7 +298,6 @@
 		clangCflags: strings.Join([]string{
 			"${armClangCflags}",
 			"${armIncludeFlags}",
-			"${armThumbCflags}",
 			armClangArchVariantCflagsVar[archVariant],
 			armClangCpuVariantCflagsVar[cpuVariant],
 		}, " "),
diff --git a/cc/cc.go b/cc/cc.go
index df3ba8c..1ebd762 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -126,6 +126,10 @@
 	// ldflags: list of module-specific flags that will be used for all link steps
 	Ldflags []string `android:"arch_variant"`
 
+	// instruction_set: the instruction set architecture to use to compile the C/C++
+	// module.
+	Instruction_set string `android:"arch_variant"`
+
 	// include_dirs: list of directories relative to the root of the source tree that will
 	// be added to the include path using -I.
 	// If possible, don't use this.  If adding paths from the current directory use
@@ -353,6 +357,11 @@
 		toolchain:  toolchain,
 		clang:      c.properties.Clang,
 	}
+	instructionSet := c.properties.Instruction_set
+	instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet)
+	if err != nil {
+		ctx.ModuleErrorf("%s", err)
+	}
 
 	if arch.HostOrDevice.Host() {
 		// TODO: allow per-module clang disable for host
@@ -411,6 +420,7 @@
 			flags.globalFlags = []string{
 				"${commonGlobalIncludes}",
 				toolchain.IncludeFlags(),
+				instructionSetFlags,
 				toolchain.ClangCflags(),
 				"${commonClangGlobalCflags}",
 				fmt.Sprintf("${%sClangGlobalCflags}", arch.HostOrDevice),
@@ -420,6 +430,7 @@
 			flags.globalFlags = []string{
 				"${commonGlobalIncludes}",
 				toolchain.IncludeFlags(),
+				instructionSetFlags,
 				toolchain.Cflags(),
 				"${commonGlobalCflags}",
 				fmt.Sprintf("${%sGlobalCflags}", arch.HostOrDevice),
diff --git a/cc/toolchain.go b/cc/toolchain.go
index d79f23c..291821b 100644
--- a/cc/toolchain.go
+++ b/cc/toolchain.go
@@ -15,6 +15,8 @@
 package cc
 
 import (
+	"fmt"
+
 	"android/soong/common"
 )
 
@@ -38,6 +40,7 @@
 	Cppflags() string
 	Ldflags() string
 	IncludeFlags() string
+	InstructionSetFlags(string) (string, error)
 
 	ClangTriple() string
 	ClangCflags() string
@@ -47,7 +50,18 @@
 	Is64Bit() bool
 }
 
+type toolchainBase struct {
+}
+
+func (toolchainBase) InstructionSetFlags(s string) (string, error) {
+	if s != "" {
+		return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
+	}
+	return "", nil
+}
+
 type toolchain64Bit struct {
+	toolchainBase
 }
 
 func (toolchain64Bit) Is64Bit() bool {
@@ -55,6 +69,7 @@
 }
 
 type toolchain32Bit struct {
+	toolchainBase
 }
 
 func (toolchain32Bit) Is64Bit() bool {