Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -5438,6 +5438,13 @@ if (Feature[0] == '+') Features[Feature.drop_front(1)] = true; + // Enable or disable thumb-mode explicitly per function to enable mixed + // ARM and Thumb code generation. + if (isThumb()) + Features["thumb-mode"] = true; + else + Features["thumb-mode"] = false; + // Convert user-provided arm and thumb GNU target attributes to // [-|+]thumb-mode target features respectively. std::vector UpdatedFeaturesVec(FeaturesVec); Index: test/CodeGen/arm-long-calls.c =================================================================== --- test/CodeGen/arm-long-calls.c +++ test/CodeGen/arm-long-calls.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple thumbv7-apple-ios5 -target-feature +long-calls -emit-llvm -o - %s | FileCheck -check-prefix=LONGCALL %s // RUN: %clang_cc1 -triple thumbv7-apple-ios5 -emit-llvm -o - %s | FileCheck -check-prefix=NOLONGCALL %s -// LONGCALL: attributes #0 = { {{.*}} "target-features"="+long-calls" -// NOLONGCALL-NOT: attributes #0 = { {{.*}} "target-features"="+long-calls" +// LONGCALL: attributes #0 = { {{.*}} "target-features"="+long-calls,+thumb-mode" +// NOLONGCALL-NOT: attributes #0 = { {{.*}} "target-features"="+long-calls,+thumb-mode" int foo1(int a) { return a; } Index: test/CodeGen/arm-no-movt.c =================================================================== --- test/CodeGen/arm-no-movt.c +++ test/CodeGen/arm-no-movt.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple thumbv7-apple-ios5 -target-feature +no-movt -emit-llvm -o - %s | FileCheck -check-prefix=NO-MOVT %s // RUN: %clang_cc1 -triple thumbv7-apple-ios5 -emit-llvm -o - %s | FileCheck -check-prefix=MOVT %s -// NO-MOVT: attributes #0 = { {{.*}} "target-features"="+no-movt" -// MOVT-NOT: attributes #0 = { {{.*}} "target-features"="+no-movt" +// NO-MOVT: attributes #0 = { {{.*}} "target-features"="+no-movt,+thumb-mode" +// MOVT-NOT: attributes #0 = { {{.*}} "target-features"="+no-movt,+thumb-mode" int foo1(int a) { return a; } Index: test/CodeGen/arm-target-features.c =================================================================== --- test/CodeGen/arm-target-features.c +++ test/CodeGen/arm-target-features.c @@ -1,65 +1,63 @@ // REQUIRES: arm-registered-target // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu cortex-a8 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3 -// CHECK-VFP3: "target-features"="+dsp,+neon,+vfp3" - - -// RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-a9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-FP16 -// CHECK-VFP3-FP16: "target-features"="+dsp,+fp16,+neon,+vfp3" +// CHECK-VFP3: "target-features"="+dsp,+neon,+thumb-mode // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu cortex-a5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4 -// CHECK-VFP4: "target-features"="+dsp,+neon,+vfp4" +// CHECK-VFP4: "target-features"="+dsp,+neon,+thumb-mode,+vfp4" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu cortex-a7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-a12 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV -// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a15 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV -// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a17 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV // RUN: %clang_cc1 -triple thumbv7s-linux-gnueabi -target-cpu swift -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV // RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -target-cpu krait -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV -// CHECK-VFP4-DIV: "target-features"="+dsp,+hwdiv,+hwdiv-arm,+neon,+vfp4" +// CHECK-VFP4-DIV: "target-features"="+dsp,+hwdiv,+hwdiv-arm,+neon,+thumb-mode,+vfp4" +// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a15 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV-ARM +// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -target-cpu cortex-a17 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-DIV-ARM +// CHECK-VFP4-DIV-ARM: "target-features"="+dsp,+hwdiv,+hwdiv-arm,+neon,+vfp4,-thumb-mode" // RUN: %clang_cc1 -triple thumbv7s-apple-ios7.0 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a32 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a35 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 -// RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a72 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a73 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m1 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 // RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu exynos-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8 -// CHECK-BASIC-V8: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon" +// CHECK-BASIC-V8: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,+thumb-mode" +// RUN: %clang_cc1 -triple armv8-linux-gnueabi -target-cpu cortex-a53 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-BASIC-V8-ARM +// CHECK-BASIC-V8-ARM: "target-features"="+crc,+crypto,+dsp,+fp-armv8,+hwdiv,+hwdiv-arm,+neon,-thumb-mode" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r5 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-DIV -// CHECK-VFP3-D16-DIV: "target-features"="+d16,+dsp,+hwdiv,+hwdiv-arm,+vfp3" +// CHECK-VFP3-D16-DIV: "target-features"="+d16,+dsp,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp3" // RUN: %clang_cc1 -triple armv7-linux-gnueabi -target-cpu cortex-r4f -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-THUMB-DIV -// CHECK-VFP3-D16-THUMB-DIV: "target-features"="+d16,+dsp,+hwdiv,+vfp3" +// CHECK-VFP3-D16-THUMB-DIV: "target-features"="+d16,+dsp,+hwdiv,+vfp3,-thumb-mode" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-FP16-DIV // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-r8 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP3-D16-FP16-DIV -// CHECK-VFP3-D16-FP16-DIV: "target-features"="+d16,+dsp,+fp16,+hwdiv,+hwdiv-arm,+vfp3" +// CHECK-VFP3-D16-FP16-DIV: "target-features"="+d16,+dsp,+fp16,+hwdiv,+hwdiv-arm,+thumb-mode,+vfp3" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP4-D16-SP-THUMB-DIV -// CHECK-VFP4-D16-SP-THUMB-DIV: "target-features"="+d16,+dsp,+fp-only-sp,+hwdiv,+vfp4" +// CHECK-VFP4-D16-SP-THUMB-DIV: "target-features"="+d16,+dsp,+fp-only-sp,+hwdiv,+thumb-mode,+vfp4" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m7 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-VFP5-D16-THUMB-DIV -// CHECK-VFP5-D16-THUMB-DIV: "target-features"="+d16,+dsp,+fp-armv8,+hwdiv" +// CHECK-VFP5-D16-THUMB-DIV: "target-features"="+d16,+dsp,+fp-armv8,+hwdiv,+thumb-mode" // RUN: %clang_cc1 -triple armv7-linux-gnueabi -target-cpu cortex-r4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-DIV -// CHECK-THUMB-DIV: "target-features"="+dsp,+hwdiv" +// CHECK-THUMB-DIV: "target-features"="+dsp,+hwdiv,-thumb-mode" // RUN: %clang_cc1 -triple thumbv7-linux-gnueabi -target-cpu cortex-m3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-THUMB-DIV-M3 -// CHECK-THUMB-DIV-M3: "target-features"="+hwdiv" +// CHECK-THUMB-DIV-M3: "target-features"="+hwdiv,+thumb-mode" void foo() {} Index: test/CodeGen/arm-thumb-mode-target-feature.c =================================================================== --- /dev/null +++ test/CodeGen/arm-thumb-mode-target-feature.c @@ -0,0 +1,33 @@ +// REQUIRES: arm-registered-target + +// RUN: %clang_cc1 -triple thumbv7-linux-gnueabihf -emit-llvm -o - %s | FileCheck --check-prefix THUMB %s +// RUN: %clang_cc1 -triple thumbv7eb-linux-gnueabihf -emit-llvm -o - %s | FileCheck --check-prefix THUMB %s +// RUN: %clang -target armv7-linux-gnueabihf -mthumb -S -emit-llvm -o - %s | FileCheck --check-prefix THUMB-CLANG %s +// RUN: %clang_cc1 -triple armv7-linux-gnueabihf -emit-llvm -o - %s | FileCheck --check-prefix ARM %s +// RUN: %clang_cc1 -triple armv7eb-linux-gnueabihf -emit-llvm -o - %s | FileCheck --check-prefix ARM %s + +void t1() {} + + __attribute__((target("no-thumb-mode"))) +void t2() {} + + __attribute__((target("thumb-mode"))) +void t3() {} + +// THUMB: void @t1() [[ThumbAttr:#[0-7]]] +// THUMB: void @t2() [[NoThumbAttr:#[0-7]]] +// THUMB: void @t3() [[ThumbAttr:#[0-7]]] +// THUMB: attributes [[ThumbAttr]] = { {{.*}} "target-features"="+thumb-mode" +// THUMB: attributes [[NoThumbAttr]] = { {{.*}} "target-features"="-thumb-mode" +// +// THUMB-CLANG: void @t1() [[ThumbAttr:#[0-7]]] +// THUMB-CLANG: void @t2() [[NoThumbAttr:#[0-7]]] +// THUMB-CLANG: void @t3() [[ThumbAttr:#[0-7]]] +// THUMB-CLANG: attributes [[ThumbAttr]] = { {{.*}} "target-features"="{{.*}}+thumb-mode +// THUMB-CLANG: attributes [[NoThumbAttr]] = { {{.*}} "target-features"="{{.*}}-thumb-mode + +// ARM: void @t1() [[NoThumbAtr:#[0-7]]] +// ARM: void @t2() [[NoThumbAttr:#[0-7]]] +// ARM: void @t3() [[ThumbAttr:#[0-7]]] +// ARM: attributes [[NoThumbAttr]] = { {{.*}} "target-features"="-thumb-mode" +// ARM: attributes [[ThumbAttr]] = { {{.*}} "target-features"="+thumb-mode"