[PATCH] D59310: [PowerPC] Fix issue with inline asm - soft float mode
This revision was automatically updated to reflect the committed changes. Closed by commit rC357466: [PowerPC] Fix issue with inline asm - soft float mode (authored by spetrovic, committed by ). Herald added a project: clang. Herald added a subscriber: cfe-commits. Changed prior to commit: https://reviews.llvm.org/D59310?vs=190446=193252#toc Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59310/new/ https://reviews.llvm.org/D59310 Files: lib/Basic/Targets/PPC.cpp lib/Basic/Targets/PPC.h test/Driver/ppc-inlineasm-sf.c Index: test/Driver/ppc-inlineasm-sf.c === --- test/Driver/ppc-inlineasm-sf.c +++ test/Driver/ppc-inlineasm-sf.c @@ -0,0 +1,16 @@ +// RUN: not %clang -target powerpc-unknown-linux -O2 -fPIC -m32 -msoft-float %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s +int foo () +{ + double x,y; + int a; + __asm__ ("fctiw %0,%1" : "=f"(x) : "f"(y)); + // CHECK-ERRMSG: error: invalid output constraint '=f' in asm + // CHECK-ERRMSG-NEXT: __asm__ ("fctiw %0,%1" : "=f"(x) : "f"(y)); + __asm__ ("fctiw %0,%1" : "=d"(x) : "d"(y)); + // CHECK-ERRMSG: error: invalid output constraint '=d' in asm + // CHECK-ERRMSG-NEXT: __asm__ ("fctiw %0,%1" : "=d"(x) : "d"(y)); + __asm__ ("vec_dss %0" : "=v"(a)); + // CHECK-ERRMSG: error: invalid output constraint '=v' in asm + // CHECK-ERRMSG-NEXT: __asm__ ("vec_dss %0" : "=v"(a)); +} + Index: lib/Basic/Targets/PPC.cpp === --- lib/Basic/Targets/PPC.cpp +++ lib/Basic/Targets/PPC.cpp @@ -30,6 +30,7 @@ /// configured set of features. bool PPCTargetInfo::handleTargetFeatures(std::vector , DiagnosticsEngine ) { + FloatABI = HardFloat; for (const auto : Features) { if (Feature == "+altivec") { HasAltivec = true; @@ -53,6 +54,8 @@ HasFloat128 = true; } else if (Feature == "+power9-vector") { HasP9Vector = true; +} else if (Feature == "-hard-float") { + FloatABI = SoftFloat; } // TODO: Finish this list and add an assert that we've handled them // all. Index: lib/Basic/Targets/PPC.h === --- lib/Basic/Targets/PPC.h +++ lib/Basic/Targets/PPC.h @@ -53,6 +53,7 @@ static const char *const GCCRegNames[]; static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; + enum PPCFloatABI { HardFloat, SoftFloat } FloatABI; // Target cpu features. bool HasAltivec = false; @@ -183,8 +184,11 @@ return false; case 'O': // Zero break; -case 'b': // Base register case 'f': // Floating point register + // Don't use floating point registers on soft float ABI. + if (FloatABI == SoftFloat) +return false; +case 'b': // Base register Info.setAllowsRegister(); break; // FIXME: The following are added to allow parsing. @@ -192,6 +196,10 @@ // Also, is more specific checking needed? I.e. specific registers? case 'd': // Floating point register (containing 64-bit value) case 'v': // Altivec vector register + // Don't use floating point and altivec vector registers + // on soft float ABI + if (FloatABI == SoftFloat) +return false; Info.setAllowsRegister(); break; case 'w': Index: test/Driver/ppc-inlineasm-sf.c === --- test/Driver/ppc-inlineasm-sf.c +++ test/Driver/ppc-inlineasm-sf.c @@ -0,0 +1,16 @@ +// RUN: not %clang -target powerpc-unknown-linux -O2 -fPIC -m32 -msoft-float %s -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s +int foo () +{ + double x,y; + int a; + __asm__ ("fctiw %0,%1" : "=f"(x) : "f"(y)); + // CHECK-ERRMSG: error: invalid output constraint '=f' in asm + // CHECK-ERRMSG-NEXT: __asm__ ("fctiw %0,%1" : "=f"(x) : "f"(y)); + __asm__ ("fctiw %0,%1" : "=d"(x) : "d"(y)); + // CHECK-ERRMSG: error: invalid output constraint '=d' in asm + // CHECK-ERRMSG-NEXT: __asm__ ("fctiw %0,%1" : "=d"(x) : "d"(y)); + __asm__ ("vec_dss %0" : "=v"(a)); + // CHECK-ERRMSG: error: invalid output constraint '=v' in asm + // CHECK-ERRMSG-NEXT: __asm__ ("vec_dss %0" : "=v"(a)); +} + Index: lib/Basic/Targets/PPC.cpp === --- lib/Basic/Targets/PPC.cpp +++ lib/Basic/Targets/PPC.cpp @@ -30,6 +30,7 @@ /// configured set of features. bool PPCTargetInfo::handleTargetFeatures(std::vector , DiagnosticsEngine ) { + FloatABI = HardFloat; for (const auto : Features) { if (Feature == "+altivec") { HasAltivec = true; @@ -53,6 +54,8 @@ HasFloat128 = true; } else if (Feature == "+power9-vector") { HasP9Vector = true; +} else if (Feature == "-hard-float") { + FloatABI = SoftFloat; }
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rL331979: This patch provides that bitfields are splitted even in case (authored by spetrovic, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D39053?vs=143918=146117#toc Repository: rL LLVM https://reviews.llvm.org/D39053 Files: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1156,7 +1156,7 @@ def ffine_grained_bitfield_accesses : Flag<["-"], "ffine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, - HelpText<"Use separate accesses for bitfields with legal widths and alignments.">; + HelpText<"Use separate accesses for consecutive bitfield runs with legal widths and alignments.">; def fno_fine_grained_bitfield_accesses : Flag<["-"], "fno-fine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, HelpText<"Use large-integer access for consecutive bitfield runs.">; Index: cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp === --- cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp +++ cfe/trunk/test/CodeGenCXX/finegrain-bitfield-type.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s +struct S4 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:12; +}; +struct S4 a4; + +struct S5 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:28; + unsigned long f4:4; + unsigned long f5:12; +}; +struct S5 a5; + +// CHECK: %struct.S4 = type { i32, i16 } +// CHECK-NOT: %struct.S4 = type { i48 } +// CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] } +// CHECK-NOT: %struct.S5 = type { i80 } \ No newline at end of file Index: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp === --- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -404,19 +404,20 @@ return; } - // Check if current Field is better as a single field run. When current field + // Check if OffsetInRecord is better as a single field run. When OffsetInRecord // has legal integer width, and its bitfield offset is naturally aligned, it // is better to make the bitfield a separate storage component so as it can be // accessed directly with lower cost. - auto IsBetterAsSingleFieldRun = [&](RecordDecl::field_iterator Field) { + auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, + uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; -unsigned Width = Field->getBitWidthValue(Context); -if (!DataLayout.isLegalInteger(Width)) +if (!DataLayout.isLegalInteger(OffsetInRecord)) return false; -// Make sure Field is natually aligned if it is treated as an IType integer. -if (getFieldBitOffset(*Field) % -Context.toBits(getAlignment(getIntNType(Width))) != +// Make sure StartBitOffset is natually aligned if it is treated as an +// IType integer. + if (StartBitOffset % +Context.toBits(getAlignment(getIntNType(OffsetInRecord))) != 0) return false; return true; @@ -435,23 +436,24 @@ Run = Field; StartBitOffset = getFieldBitOffset(*Field); Tail = StartBitOffset + Field->getBitWidthValue(Context); -StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Run); +StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, + StartBitOffset); } ++Field; continue; } // If the start field of a new run is better as a single run, or -// if current field is better as a single run, or +// if current field (or consecutive fields) is better as a single run, or // if current field has zero width bitfield and either // UseZeroLengthBitfieldAlignment or UseBitFieldTypeAlignment is set to // true, or // if the offset of current field is inconsistent with the offset of // previous field plus its offset, // skip the block below and go ahead to emit the storage. // Otherwise, try to add bitfields to the run. if (!StartFieldAsSingleRun && Field != FieldEnd && -!IsBetterAsSingleFieldRun(Field) && +!IsBetterAsSingleFieldRun(Tail - StartBitOffset, StartBitOffset) && (!Field->isZeroLengthBitField(Context) ||
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic updated this revision to Diff 143918. spetrovic added a comment. Comments addressed https://reviews.llvm.org/D39053 Files: include/clang/Driver/Options.td lib/CodeGen/CGRecordLayoutBuilder.cpp test/CodeGenCXX/finegrain-bitfield-type.cpp Index: test/CodeGenCXX/finegrain-bitfield-type.cpp === --- test/CodeGenCXX/finegrain-bitfield-type.cpp +++ test/CodeGenCXX/finegrain-bitfield-type.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s +struct S4 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:12; +}; +struct S4 a4; + +struct S5 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:28; + unsigned long f4:4; + unsigned long f5:12; +}; +struct S5 a5; + +// CHECK: %struct.S4 = type { i32, i16 } +// CHECK-NOT: %struct.S4 = type { i48 } +// CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] } +// CHECK-NOT: %struct.S5 = type { i80 } \ No newline at end of file Index: lib/CodeGen/CGRecordLayoutBuilder.cpp === --- lib/CodeGen/CGRecordLayoutBuilder.cpp +++ lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -404,19 +404,20 @@ return; } - // Check if current Field is better as a single field run. When current field + // Check if OffsetInRecord is better as a single field run. When OffsetInRecord // has legal integer width, and its bitfield offset is naturally aligned, it // is better to make the bitfield a separate storage component so as it can be // accessed directly with lower cost. - auto IsBetterAsSingleFieldRun = [&](RecordDecl::field_iterator Field) { + auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, + uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; -unsigned Width = Field->getBitWidthValue(Context); -if (!DataLayout.isLegalInteger(Width)) +if (!DataLayout.isLegalInteger(OffsetInRecord)) return false; -// Make sure Field is natually aligned if it is treated as an IType integer. -if (getFieldBitOffset(*Field) % -Context.toBits(getAlignment(getIntNType(Width))) != +// Make sure StartBitOffset is natually aligned if it is treated as an +// IType integer. + if (StartBitOffset % +Context.toBits(getAlignment(getIntNType(OffsetInRecord))) != 0) return false; return true; @@ -435,23 +436,24 @@ Run = Field; StartBitOffset = getFieldBitOffset(*Field); Tail = StartBitOffset + Field->getBitWidthValue(Context); -StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Run); +StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, + StartBitOffset); } ++Field; continue; } // If the start field of a new run is better as a single run, or -// if current field is better as a single run, or +// if current field (or consecutive fields) is better as a single run, or // if current field has zero width bitfield and either // UseZeroLengthBitfieldAlignment or UseBitFieldTypeAlignment is set to // true, or // if the offset of current field is inconsistent with the offset of // previous field plus its offset, // skip the block below and go ahead to emit the storage. // Otherwise, try to add bitfields to the run. if (!StartFieldAsSingleRun && Field != FieldEnd && -!IsBetterAsSingleFieldRun(Field) && +!IsBetterAsSingleFieldRun(Tail - StartBitOffset, StartBitOffset) && (!Field->isZeroLengthBitField(Context) || (!Context.getTargetInfo().useZeroLengthBitfieldAlignment() && !Context.getTargetInfo().useBitFieldTypeAlignment())) && Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1138,7 +1138,7 @@ def ffine_grained_bitfield_accesses : Flag<["-"], "ffine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, - HelpText<"Use separate accesses for bitfields with legal widths and alignments.">; + HelpText<"Use separate accesses for consecutive bitfield runs with legal widths and alignments.">; def fno_fine_grained_bitfield_accesses : Flag<["-"], "fno-fine-grained-bitfield-accesses">, Group, Flags<[CC1Option]>, HelpText<"Use large-integer access for consecutive bitfield runs.">; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. ping https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44921: [PowerPC] Option for secure plt mode
This revision was automatically updated to reflect the committed changes. Closed by commit rL329795: [PowerPC] Option for secure plt mode (authored by spetrovic, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D44921?vs=140060=141976#toc Repository: rL LLVM https://reviews.llvm.org/D44921 Files: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Driver/ToolChains/Arch/PPC.cpp cfe/trunk/lib/Driver/ToolChains/Arch/PPC.h cfe/trunk/test/Driver/ppc-features.cpp Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1957,6 +1957,7 @@ def mno_altivec : Flag<["-"], "mno-altivec">, Group; def mvsx : Flag<["-"], "mvsx">, Group; def mno_vsx : Flag<["-"], "mno-vsx">, Group; +def msecure_plt : Flag<["-"], "msecure-plt">, Group; def mpower8_vector : Flag<["-"], "mpower8-vector">, Group; def mno_power8_vector : Flag<["-"], "mno-power8-vector">, Index: cfe/trunk/test/Driver/ppc-features.cpp === --- cfe/trunk/test/Driver/ppc-features.cpp +++ cfe/trunk/test/Driver/ppc-features.cpp @@ -22,6 +22,10 @@ // RUN: %clang -target powerpc-unknown-linux-gnu %s -msoft-float -mhard-float -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SOFTHARD %s // CHECK-SOFTHARD-NOT: "-target-feature" "-hard-float" +// check -msecure-plt option for ppc32 +// RUN: %clang -target powerpc-unknown-linux-gnu -msecure-plt %s -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SECUREPLT %s +// CHECK-SECUREPLT: "-target-feature" "+secure-plt" + // check -mfloat-abi=x option // RUN: %clang -target powerpc-unknown-linux-gnu %s -mfloat-abi=x -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s // CHECK-ERRMSG: error: invalid float ABI '-mfloat-abi=x' Index: cfe/trunk/lib/Driver/ToolChains/Arch/PPC.cpp === --- cfe/trunk/lib/Driver/ToolChains/Arch/PPC.cpp +++ cfe/trunk/lib/Driver/ToolChains/Arch/PPC.cpp @@ -106,6 +106,16 @@ ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); if (FloatABI == ppc::FloatABI::Soft) Features.push_back("-hard-float"); + + ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Args); + if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt) +Features.push_back("+secure-plt"); +} + +ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver , const ArgList ) { + if (Args.getLastArg(options::OPT_msecure_plt)) +return ppc::ReadGOTPtrMode::SecurePlt; + return ppc::ReadGOTPtrMode::Bss; } ppc::FloatABI ppc::getPPCFloatABI(const Driver , const ArgList ) { Index: cfe/trunk/lib/Driver/ToolChains/Arch/PPC.h === --- cfe/trunk/lib/Driver/ToolChains/Arch/PPC.h +++ cfe/trunk/lib/Driver/ToolChains/Arch/PPC.h @@ -29,10 +29,17 @@ Hard, }; +enum class ReadGOTPtrMode { + Bss, + SecurePlt, +}; + FloatABI getPPCFloatABI(const Driver , const llvm::opt::ArgList ); std::string getPPCTargetCPU(const llvm::opt::ArgList ); const char *getPPCAsmModeForCPU(StringRef Name); +ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver , + const llvm::opt::ArgList ); void getPPCTargetFeatures(const Driver , const llvm::Triple , const llvm::opt::ArgList , Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1957,6 +1957,7 @@ def mno_altivec : Flag<["-"], "mno-altivec">, Group; def mvsx : Flag<["-"], "mvsx">, Group; def mno_vsx : Flag<["-"], "mno-vsx">, Group; +def msecure_plt : Flag<["-"], "msecure-plt">, Group; def mpower8_vector : Flag<["-"], "mpower8-vector">, Group; def mno_power8_vector : Flag<["-"], "mno-power8-vector">, Index: cfe/trunk/test/Driver/ppc-features.cpp === --- cfe/trunk/test/Driver/ppc-features.cpp +++ cfe/trunk/test/Driver/ppc-features.cpp @@ -22,6 +22,10 @@ // RUN: %clang -target powerpc-unknown-linux-gnu %s -msoft-float -mhard-float -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SOFTHARD %s // CHECK-SOFTHARD-NOT: "-target-feature" "-hard-float" +// check -msecure-plt option for ppc32 +// RUN: %clang -target powerpc-unknown-linux-gnu -msecure-plt %s -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SECUREPLT %s +// CHECK-SECUREPLT: "-target-feature" "+secure-plt" + // check -mfloat-abi=x option // RUN: %clang -target powerpc-unknown-linux-gnu %s -mfloat-abi=x -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s // CHECK-ERRMSG: error: invalid float ABI '-mfloat-abi=x' Index: cfe/trunk/lib/Driver/ToolChains/Arch/PPC.cpp
[PATCH] D44921: [PowerPC] Option for secure plt mode
spetrovic added a comment. -mbss-plt is currently default in LLVM, once secure plt support is finished we can set secure plt as default in LLVM, but not for now. https://reviews.llvm.org/D44921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. ping https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44921: [PowerPC] Option for secure plt mode
spetrovic added a comment. Yes, secure PLT is PowerPC specific feature. https://reviews.llvm.org/D44921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44921: [PowerPC] Option for secure plt mode
spetrovic added inline comments. Comment at: include/clang/Driver/Options.td:1941 def mno_vsx : Flag<["-"], "mno-vsx">, Group; +def msecure_plt : Flag<["-"], "msecure-plt">, Group; def mpower8_vector : Flag<["-"], "mpower8-vector">, nemanjai wrote: > Do we not want the negated option? Well, I'm not sure if we need negated option. This is just switch from default mode (BSS) to SECURE PLT mode, also I didn't see that gcc has negated option for SECURE-PLT. Comment at: lib/Driver/ToolChains/Arch/PPC.cpp:116 +ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver , const ArgList ) { + ppc::ReadGOTPtrMode ReadGOT = ppc::ReadGOTPtrMode::Bss; + if (Args.getLastArg(options::OPT_msecure_plt)) nemanjai wrote: > Just a style question out of curiosity. Why the temporary? Since there are > just two possible values, why not just return the respective enumerator? You are right, we don't need the temporary. https://reviews.llvm.org/D44921 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D44921: [PowerPC] Option for secure plt mode
spetrovic updated this revision to Diff 140060. https://reviews.llvm.org/D44921 Files: include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/PPC.cpp lib/Driver/ToolChains/Arch/PPC.h test/Driver/ppc-features.cpp Index: test/Driver/ppc-features.cpp === --- test/Driver/ppc-features.cpp +++ test/Driver/ppc-features.cpp @@ -22,6 +22,10 @@ // RUN: %clang -target powerpc-unknown-linux-gnu %s -msoft-float -mhard-float -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SOFTHARD %s // CHECK-SOFTHARD-NOT: "-target-feature" "-hard-float" +// check -msecure-plt option for ppc32 +// RUN: %clang -target powerpc-unknown-linux-gnu -msecure-plt %s -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SECUREPLT %s +// CHECK-SECUREPLT: "-target-feature" "+secure-plt" + // check -mfloat-abi=x option // RUN: %clang -target powerpc-unknown-linux-gnu %s -mfloat-abi=x -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s // CHECK-ERRMSG: error: invalid float ABI '-mfloat-abi=x' Index: lib/Driver/ToolChains/Arch/PPC.h === --- lib/Driver/ToolChains/Arch/PPC.h +++ lib/Driver/ToolChains/Arch/PPC.h @@ -29,10 +29,17 @@ Hard, }; +enum class ReadGOTPtrMode { + Bss, + SecurePlt, +}; + FloatABI getPPCFloatABI(const Driver , const llvm::opt::ArgList ); std::string getPPCTargetCPU(const llvm::opt::ArgList ); const char *getPPCAsmModeForCPU(StringRef Name); +ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver , + const llvm::opt::ArgList ); void getPPCTargetFeatures(const Driver , const llvm::Triple , const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/PPC.cpp === --- lib/Driver/ToolChains/Arch/PPC.cpp +++ lib/Driver/ToolChains/Arch/PPC.cpp @@ -106,6 +106,16 @@ ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); if (FloatABI == ppc::FloatABI::Soft) Features.push_back("-hard-float"); + + ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Args); + if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt) +Features.push_back("+secure-plt"); +} + +ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver , const ArgList ) { + if (Args.getLastArg(options::OPT_msecure_plt)) +return ppc::ReadGOTPtrMode::SecurePlt; + return ppc::ReadGOTPtrMode::Bss; } ppc::FloatABI ppc::getPPCFloatABI(const Driver , const ArgList ) { Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1938,6 +1938,7 @@ def mno_altivec : Flag<["-"], "mno-altivec">, Group; def mvsx : Flag<["-"], "mvsx">, Group; def mno_vsx : Flag<["-"], "mno-vsx">, Group; +def msecure_plt : Flag<["-"], "msecure-plt">, Group; def mpower8_vector : Flag<["-"], "mpower8-vector">, Group; def mno_power8_vector : Flag<["-"], "mno-power8-vector">, Index: test/Driver/ppc-features.cpp === --- test/Driver/ppc-features.cpp +++ test/Driver/ppc-features.cpp @@ -22,6 +22,10 @@ // RUN: %clang -target powerpc-unknown-linux-gnu %s -msoft-float -mhard-float -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SOFTHARD %s // CHECK-SOFTHARD-NOT: "-target-feature" "-hard-float" +// check -msecure-plt option for ppc32 +// RUN: %clang -target powerpc-unknown-linux-gnu -msecure-plt %s -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SECUREPLT %s +// CHECK-SECUREPLT: "-target-feature" "+secure-plt" + // check -mfloat-abi=x option // RUN: %clang -target powerpc-unknown-linux-gnu %s -mfloat-abi=x -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s // CHECK-ERRMSG: error: invalid float ABI '-mfloat-abi=x' Index: lib/Driver/ToolChains/Arch/PPC.h === --- lib/Driver/ToolChains/Arch/PPC.h +++ lib/Driver/ToolChains/Arch/PPC.h @@ -29,10 +29,17 @@ Hard, }; +enum class ReadGOTPtrMode { + Bss, + SecurePlt, +}; + FloatABI getPPCFloatABI(const Driver , const llvm::opt::ArgList ); std::string getPPCTargetCPU(const llvm::opt::ArgList ); const char *getPPCAsmModeForCPU(StringRef Name); +ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver , + const llvm::opt::ArgList ); void getPPCTargetFeatures(const Driver , const llvm::Triple , const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/PPC.cpp === --- lib/Driver/ToolChains/Arch/PPC.cpp +++ lib/Driver/ToolChains/Arch/PPC.cpp @@ -106,6 +106,16 @@ ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); if (FloatABI == ppc::FloatABI::Soft) Features.push_back("-hard-float"); + + ppc::ReadGOTPtrMode ReadGOT =
[PATCH] D44921: [PowerPC] Option for secure plt mode
spetrovic created this revision. spetrovic added reviewers: jhibbits, nemanjai. Herald added a subscriber: kbarton. This patch enables option for secure plt mode in clang (-msecure-plt). This feature is supported in backend also (https://reviews.llvm.org/D42112). https://reviews.llvm.org/D44921 Files: include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/PPC.cpp lib/Driver/ToolChains/Arch/PPC.h test/Driver/ppc-features.cpp Index: test/Driver/ppc-features.cpp === --- test/Driver/ppc-features.cpp +++ test/Driver/ppc-features.cpp @@ -22,6 +22,10 @@ // RUN: %clang -target powerpc-unknown-linux-gnu %s -msoft-float -mhard-float -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SOFTHARD %s // CHECK-SOFTHARD-NOT: "-target-feature" "-hard-float" +// check -msecure-plt option for ppc32 +// RUN: %clang -target powerpc-unknown-linux-gnu -msecure-plt %s -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SECUREPLT %s +// CHECK-SECUREPLT: "-target-feature" "+secure-plt" + // check -mfloat-abi=x option // RUN: %clang -target powerpc-unknown-linux-gnu %s -mfloat-abi=x -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s // CHECK-ERRMSG: error: invalid float ABI '-mfloat-abi=x' Index: lib/Driver/ToolChains/Arch/PPC.h === --- lib/Driver/ToolChains/Arch/PPC.h +++ lib/Driver/ToolChains/Arch/PPC.h @@ -29,10 +29,17 @@ Hard, }; +enum class ReadGOTPtrMode { + Bss, + SecurePlt, +}; + FloatABI getPPCFloatABI(const Driver , const llvm::opt::ArgList ); std::string getPPCTargetCPU(const llvm::opt::ArgList ); const char *getPPCAsmModeForCPU(StringRef Name); +ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver , + const llvm::opt::ArgList ); void getPPCTargetFeatures(const Driver , const llvm::Triple , const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/PPC.cpp === --- lib/Driver/ToolChains/Arch/PPC.cpp +++ lib/Driver/ToolChains/Arch/PPC.cpp @@ -106,6 +106,17 @@ ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args); if (FloatABI == ppc::FloatABI::Soft) Features.push_back("-hard-float"); + + ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Args); + if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt) +Features.push_back("+secure-plt"); +} + +ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver , const ArgList ) { + ppc::ReadGOTPtrMode ReadGOT = ppc::ReadGOTPtrMode::Bss; + if (Args.getLastArg(options::OPT_msecure_plt)) +ReadGOT = ppc::ReadGOTPtrMode::SecurePlt; + return ReadGOT; } ppc::FloatABI ppc::getPPCFloatABI(const Driver , const ArgList ) { Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1938,6 +1938,7 @@ def mno_altivec : Flag<["-"], "mno-altivec">, Group; def mvsx : Flag<["-"], "mvsx">, Group; def mno_vsx : Flag<["-"], "mno-vsx">, Group; +def msecure_plt : Flag<["-"], "msecure-plt">, Group; def mpower8_vector : Flag<["-"], "mpower8-vector">, Group; def mno_power8_vector : Flag<["-"], "mno-power8-vector">, Index: test/Driver/ppc-features.cpp === --- test/Driver/ppc-features.cpp +++ test/Driver/ppc-features.cpp @@ -22,6 +22,10 @@ // RUN: %clang -target powerpc-unknown-linux-gnu %s -msoft-float -mhard-float -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SOFTHARD %s // CHECK-SOFTHARD-NOT: "-target-feature" "-hard-float" +// check -msecure-plt option for ppc32 +// RUN: %clang -target powerpc-unknown-linux-gnu -msecure-plt %s -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-SECUREPLT %s +// CHECK-SECUREPLT: "-target-feature" "+secure-plt" + // check -mfloat-abi=x option // RUN: %clang -target powerpc-unknown-linux-gnu %s -mfloat-abi=x -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-ERRMSG %s // CHECK-ERRMSG: error: invalid float ABI '-mfloat-abi=x' Index: lib/Driver/ToolChains/Arch/PPC.h === --- lib/Driver/ToolChains/Arch/PPC.h +++ lib/Driver/ToolChains/Arch/PPC.h @@ -29,10 +29,17 @@ Hard, }; +enum class ReadGOTPtrMode { + Bss, + SecurePlt, +}; + FloatABI getPPCFloatABI(const Driver , const llvm::opt::ArgList ); std::string getPPCTargetCPU(const llvm::opt::ArgList ); const char *getPPCAsmModeForCPU(StringRef Name); +ReadGOTPtrMode getPPCReadGOTPtrMode(const Driver , + const llvm::opt::ArgList ); void getPPCTargetFeatures(const Driver , const llvm::Triple , const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/PPC.cpp === ---
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. ping https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. ping https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. I tried to compile some important libraries for X86 and MIPS64 within Chromium with clang/llvm. I have compared results between LLVM trunk, and LLVM trunk with my patch. There is code size improvement on many libraries, here are some results: - X86 libframe~1.5% librendering~1.2% liblayout_2 ~0.7% libpaint_1 ~0.65% libglslang ~0.5% libediting_3~0.5% libcore_generated ~0.5% libanimation_1 ~0.5% - Mips64 libglslang ~3.2% libframe~1.5% liblayout_0 ~1.2% libGLESv2 ~1% librendering~0.7% liblayout_1 ~0.5% libcss_9~0.5% Those are just some of libraries where we have code size improvement with this patch, I have also tried to compile LLVM with LLVM (with my patch) for x86 and MIPS64, and there is also code size improvement on both architectures. For example within clang executable for MIPS64 ~350 unaligned loads is removed. So, what do you think about it ? https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. ping https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. I was looking if I can reslove this problem in backend. Example: C code: typedef struct { unsigned int f1 : 28; unsigned int f2 : 4; unsigned int f3 : 12; } S5; void foo(S5 *cmd) { cmd->f3 = 5; } . ll file (without the patch): %struct.S5 = type { i48 } define void @foo(%struct.S5* nocapture %cmd) local_unnamed_addr #0 { entry: %0 = bitcast %struct.S5* %cmd to i64* %bf.load = load i64, i64* %0, align 4 %bf.clear = and i64 %bf.load, -4293918721 %bf.set = or i64 %bf.clear, 5242880 store i64 %bf.set, i64* %0, align 4 ret void } The load (%bf.load = load i64, i64* %0, align 4) is NON_EXTLOAD, and backend handles it later as unaligned load. So, maybe one of possible solutions in backend is for each architecture to try to catch node pattern and replace unaligned loads with normal loads in specific cases, but I'm not sure how feasible that is. At the moment, the solution in frontend seems better to me. What do you think? https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic added a comment. Well, basically I'm just expanding the existing algorithm, why should we split fields just in case when current field is integer, I'm not resolving specific problem with unaligned loads/stores on MIPS. In this example: typedef struct { unsigned int f1 : 28; unsigned int f2 : 4; unsigned int f3 : 12; } S5; S5 *cmd; void foo() { cmd->f3 = 5; } With this patch there is improvement in code size not just on MIPS architecture, on X86 and ARM is also improved code size. If structure S5 is treated as i48 type there are extra instructions for reading it not just on MIPS. We can take results for MIPS just for example: Output without the patch: : 0: 3c01lui at,0x0 4: 0039082ddaddu at,at,t9 8: 6421daddiu at,at,0 c: dc21ld at,0(at) 10: dc21ld at,0(at) 14: 6822ldl v0,0(at) 18: 6c220007ldr v0,7(at) 1c: 64030005daddiu v1,zero,5 20: 7c62fd07dinsv0,v1,0x14,0xc 24: b022sdl v0,0(at) 28: 03e8jr ra 2c: b4220007sdr v0,7(at) Output with the patch: : 0: 3c01lui at,0x0 4: 0039082ddaddu at,at,t9 8: 6421daddiu at,at,0 c: dc21ld at,0(at) 10: dc21ld at,0(at) 14: 94220004lhu v0,4(at) 18: 24030005li v1,5 1c: 7c62f904ins v0,v1,0x4,0x1c 20: 03e8jr ra 24: a4220004sh v0,4(at) This is simple example, in more complicated examples there is more improvement. https://reviews.llvm.org/D39053 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39053: [Bitfield] Add more cases to making the bitfield a separate location
spetrovic created this revision. Herald added subscribers: arichardson, sdardis. This patch provides that bitfields are splitted even in case when current field is not legal integer type. For Example, struct S3 { unsigned long a1:28; unsigned long a2:4; unsigned long a3:12; }; struct S4 { unsigned long long b1:61; unsigned long b2:3; unsigned long b3:3; }; At the moment, S3 is i48 type, and S4 is i72 type, with this change S3 is treated as i32 + 16, and S4 is treated as i32 + i32 + i8. With this patch we avoid unaligned loads and stores, at least on MIPS architecture. https://reviews.llvm.org/D39053 Files: lib/CodeGen/CGRecordLayoutBuilder.cpp test/CodeGenCXX/finegrain-bitfield-type.cpp Index: test/CodeGenCXX/finegrain-bitfield-type.cpp === --- test/CodeGenCXX/finegrain-bitfield-type.cpp +++ test/CodeGenCXX/finegrain-bitfield-type.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s +struct S4 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:12; +}; +struct S4 a4; + +struct S5 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:28; + unsigned long f4:4; + unsigned long f5:12; +}; +struct S5 a5; + + +// CHECK: %struct.S4 = type { i32, i16 } +// CHECK-NOT: %struct.S4 = type { i48 } +// CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] } +// CHECK-NOT: %struct.S5 = type { i80 } \ No newline at end of file Index: lib/CodeGen/CGRecordLayoutBuilder.cpp === --- lib/CodeGen/CGRecordLayoutBuilder.cpp +++ lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -408,15 +408,15 @@ // has legal integer width, and its bitfield offset is naturally aligned, it // is better to make the bitfield a separate storage component so as it can be // accessed directly with lower cost. - auto IsBetterAsSingleFieldRun = [&](RecordDecl::field_iterator Field) { + auto IsBetterAsSingleFieldRun = [&](uint64_t OffsetInRecord, + uint64_t StartBitOffset) { if (!Types.getCodeGenOpts().FineGrainedBitfieldAccesses) return false; -unsigned Width = Field->getBitWidthValue(Context); -if (!DataLayout.isLegalInteger(Width)) +if (!DataLayout.isLegalInteger(OffsetInRecord)) return false; // Make sure Field is natually aligned if it is treated as an IType integer. -if (getFieldBitOffset(*Field) % -Context.toBits(getAlignment(getIntNType(Width))) != +if (StartBitOffset % +Context.toBits(getAlignment(getIntNType(OffsetInRecord))) != 0) return false; return true; @@ -435,7 +435,8 @@ Run = Field; StartBitOffset = getFieldBitOffset(*Field); Tail = StartBitOffset + Field->getBitWidthValue(Context); -StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Run); +StartFieldAsSingleRun = IsBetterAsSingleFieldRun(Tail - StartBitOffset, + StartBitOffset); } ++Field; continue; @@ -449,7 +450,7 @@ // skip the block below and go ahead to emit the storage. // Otherwise, try to add bitfields to the run. if (!StartFieldAsSingleRun && Field != FieldEnd && -!IsBetterAsSingleFieldRun(Field) && +!IsBetterAsSingleFieldRun(Tail - StartBitOffset, StartBitOffset) && Field->getBitWidthValue(Context) != 0 && Tail == getFieldBitOffset(*Field)) { Tail += Field->getBitWidthValue(Context); Index: test/CodeGenCXX/finegrain-bitfield-type.cpp === --- test/CodeGenCXX/finegrain-bitfield-type.cpp +++ test/CodeGenCXX/finegrain-bitfield-type.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffine-grained-bitfield-accesses \ +// RUN: -emit-llvm -o - %s | FileCheck %s +struct S4 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:12; +}; +struct S4 a4; + +struct S5 { + unsigned long f1:28; + unsigned long f2:4; + unsigned long f3:28; + unsigned long f4:4; + unsigned long f5:12; +}; +struct S5 a5; + + +// CHECK: %struct.S4 = type { i32, i16 } +// CHECK-NOT: %struct.S4 = type { i48 } +// CHECK: %struct.S5 = type { i32, i32, i16, [6 x i8] } +// CHECK-NOT: %struct.S5 = type { i80 } \ No newline at end of file Index: lib/CodeGen/CGRecordLayoutBuilder.cpp === --- lib/CodeGen/CGRecordLayoutBuilder.cpp +++ lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -408,15 +408,15 @@ // has legal integer width, and its bitfield offset is naturally aligned, it // is better to make the bitfield a separate storage component so as it can be // accessed directly with lower cost. - auto IsBetterAsSingleFieldRun = [&](RecordDecl::field_iterator Field) { + auto
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
This revision was automatically updated to reflect the committed changes. Closed by commit rL313018: [ARM] Option for reading thread pointer from coprocessor register (authored by spetrovic). Changed prior to commit: https://reviews.llvm.org/D34878?vs=114618=114792#toc Repository: rL LLVM https://reviews.llvm.org/D34878 Files: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td cfe/trunk/include/clang/Driver/CC1Options.td cfe/trunk/include/clang/Driver/Options.td cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h cfe/trunk/test/Driver/clang-translation.c Index: cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h === --- cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h +++ cfe/trunk/lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp === --- cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp +++ cfe/trunk/lib/Driver/ToolChains/Arch/ARM.cpp @@ -131,6 +131,26 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { +const Driver = TC.getDriver(); +arm::ReadTPMode ThreadPointer = +llvm::StringSwitch(A->getValue()) +.Case("cp15", ReadTPMode::Cp15) +.Case("soft", ReadTPMode::Soft) +.Default(ReadTPMode::Invalid); +if (ThreadPointer != ReadTPMode::Invalid) + return ThreadPointer; +if (StringRef(A->getValue()).empty()) + D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); +else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); +return ReadTPMode::Invalid; + } + return ReadTPMode::Soft; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -262,6 +282,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -303,6 +324,9 @@ } } + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: cfe/trunk/include/clang/Driver/Options.td === --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -1689,6 +1689,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; Index: cfe/trunk/include/clang/Driver/CC1Options.td === --- cfe/trunk/include/clang/Driver/CC1Options.td +++ cfe/trunk/include/clang/Driver/CC1Options.td @@ -257,6 +257,8 @@ "precision">; def mfloat_abi : Separate<["-"], "mfloat-abi">, HelpText<"The float ABI to use">; +def mtp : Separate<["-"], "mtp">, + HelpText<"Mode for reading thread pointer">; def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, HelpText<"Limit float precision to the given value">; def split_stacks : Flag<["-"], "split-stacks">, Index: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td === --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td @@ -101,6 +101,10 @@ "failing because %select{environment variable
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic updated this revision to Diff 114618. spetrovic added a comment. Indentations fixed. https://reviews.llvm.org/D34878 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/ARM.cpp lib/Driver/ToolChains/Arch/ARM.h test/Driver/clang-translation.c Index: test/Driver/clang-translation.c === --- test/Driver/clang-translation.c +++ test/Driver/clang-translation.c @@ -87,6 +87,18 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s +// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s +// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s +// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang Index: lib/Driver/ToolChains/Arch/ARM.h === --- lib/Driver/ToolChains/Arch/ARM.h +++ lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -131,6 +131,26 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { +const Driver = TC.getDriver(); +arm::ReadTPMode ThreadPointer = +llvm::StringSwitch(A->getValue()) +.Case("cp15", ReadTPMode::Cp15) +.Case("soft", ReadTPMode::Soft) +.Default(ReadTPMode::Invalid); +if (ThreadPointer != ReadTPMode::Invalid) + return ThreadPointer; +if (StringRef(A->getValue()).empty()) + D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); +else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); +return ReadTPMode::Invalid; + } + return ReadTPMode::Soft; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -262,6 +282,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -303,6 +324,9 @@ } } + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1689,6 +1689,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; Index: include/clang/Driver/CC1Options.td === --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -257,6 +257,8 @@ "precision">; def mfloat_abi : Separate<["-"], "mfloat-abi">,
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. Thanks for the review! I will check indentations with clang format. https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic updated this revision to Diff 114582. https://reviews.llvm.org/D34878 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/ARM.cpp lib/Driver/ToolChains/Arch/ARM.h test/Driver/clang-translation.c Index: test/Driver/clang-translation.c === --- test/Driver/clang-translation.c +++ test/Driver/clang-translation.c @@ -87,6 +87,18 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s +// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s +// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s +// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang Index: lib/Driver/ToolChains/Arch/ARM.h === --- lib/Driver/ToolChains/Arch/ARM.h +++ lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -131,6 +131,27 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + if (Arg *A = + Args.getLastArg(options::OPT_mtp_mode_EQ)) { +const Driver = TC.getDriver(); +arm::ReadTPMode ThreadPointer = + llvm::StringSwitch(A->getValue()) + .Case("cp15", ReadTPMode::Cp15) + .Case("soft", ReadTPMode::Soft) + .Default(ReadTPMode::Invalid); +if (ThreadPointer != ReadTPMode::Invalid) + return ThreadPointer; +if (StringRef(A->getValue()).empty()) + D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); +else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); +return ReadTPMode::Invalid; + } + return ReadTPMode::Soft; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -262,6 +283,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -303,6 +325,10 @@ } } + + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1689,6 +1689,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; Index: include/clang/Driver/CC1Options.td === --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -257,6 +257,8 @@ "precision">; def mfloat_abi : Separate<["-"], "mfloat-abi">,
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added inline comments. Comment at: lib/Driver/ToolChains/Arch/ARM.cpp:149-150 +else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); + } + return ReadTPMode::Soft; kristof.beyls wrote: > a return ReadTPMode::Invalid is missing here. Yes, my mistake, I will fix that. https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. Comments addressed. https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic updated this revision to Diff 114573. https://reviews.llvm.org/D34878 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/ARM.cpp lib/Driver/ToolChains/Arch/ARM.h test/Driver/clang-translation.c Index: test/Driver/clang-translation.c === --- test/Driver/clang-translation.c +++ test/Driver/clang-translation.c @@ -87,6 +87,18 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s +// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s +// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s +// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang Index: lib/Driver/ToolChains/Arch/ARM.h === --- lib/Driver/ToolChains/Arch/ARM.h +++ lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -131,6 +131,26 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + const Driver = TC.getDriver(); + arm::ReadTPMode ThreadPointer = ReadTPMode::Invalid; + if (Arg *A = + Args.getLastArg(options::OPT_mtp_mode_EQ)) { +ThreadPointer = llvm::StringSwitch(A->getValue()) +.Case("cp15", ReadTPMode::Cp15) +.Case("soft", ReadTPMode::Soft) +.Default(ReadTPMode::Invalid); +if (ThreadPointer != ReadTPMode::Invalid) + return ThreadPointer; +if (StringRef(A->getValue()).empty()) + D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); +else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); + } + return ReadTPMode::Soft; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -262,6 +282,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -303,6 +324,10 @@ } } + + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1689,6 +1689,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; Index: include/clang/Driver/CC1Options.td === --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -257,6 +257,8 @@ "precision">; def mfloat_abi : Separate<["-"], "mfloat-abi">,
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic updated this revision to Diff 114329. spetrovic marked 3 inline comments as done. https://reviews.llvm.org/D34878 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/ARM.cpp lib/Driver/ToolChains/Arch/ARM.h test/Driver/clang-translation.c Index: test/Driver/clang-translation.c === --- test/Driver/clang-translation.c +++ test/Driver/clang-translation.c @@ -87,6 +87,18 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s +// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s +// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target arm-linux -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s +// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang Index: lib/Driver/ToolChains/Arch/ARM.h === --- lib/Driver/ToolChains/Arch/ARM.h +++ lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -131,6 +131,31 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + const Driver = TC.getDriver(); + arm::ReadTPMode ThreadPointer = ReadTPMode::Invalid; + if (Arg *A = + Args.getLastArg(options::OPT_mtp_mode_EQ)) { +ThreadPointer = llvm::StringSwitch(A->getValue()) +.Case("cp15", ReadTPMode::Cp15) +.Case("soft", ReadTPMode::Soft) +.Default(ReadTPMode::Invalid); +if (ThreadPointer == ReadTPMode::Invalid) { + if (StringRef(A->getValue()).empty()) +D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); + else +D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); +} + } + + // If -mtp option not specified or takes invalid/empty argument + // choose soft mode. + if (ThreadPointer == ReadTPMode::Invalid) +ThreadPointer = ReadTPMode::Soft; + return ThreadPointer; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -262,6 +287,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -303,6 +329,10 @@ } } + + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1689,6 +1689,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; Index: include/clang/Driver/CC1Options.td
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic marked 3 inline comments as done. spetrovic added inline comments. Comment at: include/clang/Driver/Options.td:1664-1665 HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility kristof.beyls wrote: > Looking at the gcc documentation for this option > (https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html), gcc accepts 3 values: > 'soft', 'cp15' and 'auto', with the default setting being 'auto'. > This patch implements just 2 of those values: 'soft' and 'cp15'. > I think this is fine, as long as the default value is 'soft'. > The 'auto' value should automatically pick 'cp15' if that's going to work on > what you're targeting. If I understood correctly, that depends both on the > architecture version you're targeting and the operating system/kernel you're > targeting. So, there could be a lot of details to go through to get 'auto' > right in all cases. Which is why I think it's fine to leave an implementation > of 'auto' for later. > Is the default value 'soft'? I agree with your opinion about 'auto'. If -mtp option is not specified, yes, default value is soft. Comment at: lib/Driver/ToolChains/Arch/ARM.cpp:128 + const Driver = TC.getDriver(); + arm::ReadTPMode ThreadPointer = ReadTPMode::Invalid; + if (Arg *A = kristof.beyls wrote: > Wouldn't it be better to default to ReadTPMode::Soft when not -mtp command > line option is given? When there is no -mtp in command line ReadTPMode::Soft is default value, ReadTPMode::Invalid is in case when someone try to put in -mtp value that is not cp15 or soft (e.g. -mtp=x). Comment at: lib/Driver/ToolChains/Arch/ARM.cpp:145-146 + // choose soft mode. + if (ThreadPointer == ReadTPMode::Invalid) +ThreadPointer = ReadTPMode::Soft; + return ThreadPointer; kristof.beyls wrote: > and always give an error if an invalid mtp command line option was > given, rather than default back to soft mode? If 'mtp' takes invalid value, error is always provided. This is the case when there is no -mtp option in command line, you can see how the case of invalid mtp argument is handled in the code above. Comment at: lib/Driver/ToolChains/Clang.cpp:1348-1358 + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(getToolChain(), Args); + if (ThreadPointer == arm::ReadTPMode::Cp15) { +CmdArgs.push_back("-mtp"); +CmdArgs.push_back("cp15"); + } else { +assert(ThreadPointer == arm::ReadTPMode::Soft && + "Invalid mode for reading thread pointer"); kristof.beyls wrote: > My inexperience in this part of the code base is probably showing, but why is > this needed at all? > IIUC, in D34408, you modelled TPMode in the backend using a target feature, > and there isn't a custom -mtp option there? > Maybe this is left-over code from an earlier revision of D34408, that's no > longer needed? Well, actually you are right, we can remove this part of the code, I was thinking that maybe someone in future will need in backend that '-mtp' option also can be recgonized, so I added this, but you are right, I will remove this. Comment at: test/Driver/clang-translation.c:78-82 +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER %s +// ARMv7_THREAD_POINTER: "-target-feature" "+read-tp-hard" +// ARMv7_THREAD_POINTER: "-mtp" "cp15" +// ARMv7_THREAD_POINTER-NOT: "mtp" "soft" kristof.beyls wrote: > It probably would be good to also have a test that when no mtp option is > given, the equivalent of when '-mtp soft' is specified would happen. > Furthermore, my inexperience in this part of the code base probably shows, > but I'm puzzled as to why this test is looking for '-mtp' in the output. > Wouldn't the '-target-feature +read-tp-hard' be enough to convey the > information to the mid- and back-end? Checks for '-mtp' in the output are unnecessary when we remove part of the code that you mentioned in previous comment. Repository: rL LLVM https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. ping Repository: rL LLVM https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added inline comments. Comment at: lib/Driver/ToolChains/Arch/ARM.cpp:136 +if (ThreadPointer == ReadTPMode::Invalid && +!StringRef(A->getValue()).empty()) { + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); bruno wrote: > What happens if you pass an empty "-mtp=" to the driver? Will it silently > assume soft? Shouldn't it be an error too? I agree, it should be an error, I fixed that. Repository: rL LLVM https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic updated this revision to Diff 109571. spetrovic marked 2 inline comments as done. Repository: rL LLVM https://reviews.llvm.org/D34878 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/ARM.cpp lib/Driver/ToolChains/Arch/ARM.h lib/Driver/ToolChains/Clang.cpp test/Driver/clang-translation.c Index: test/Driver/clang-translation.c === --- test/Driver/clang-translation.c +++ test/Driver/clang-translation.c @@ -75,6 +75,12 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER %s +// ARMv7_THREAD_POINTER: "-target-feature" "+read-tp-hard" +// ARMv7_THREAD_POINTER: "-mtp" "cp15" +// ARMv7_THREAD_POINTER-NOT: "mtp" "soft" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang Index: lib/Driver/ToolChains/Clang.cpp === --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -1345,6 +1345,17 @@ CmdArgs.push_back("hard"); } + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(getToolChain(), Args); + if (ThreadPointer == arm::ReadTPMode::Cp15) { +CmdArgs.push_back("-mtp"); +CmdArgs.push_back("cp15"); + } else { +assert(ThreadPointer == arm::ReadTPMode::Soft && + "Invalid mode for reading thread pointer"); +CmdArgs.push_back("-mtp"); +CmdArgs.push_back("soft"); + } + // Forward the -mglobal-merge option for explicit control over the pass. if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge, options::OPT_mno_global_merge)) { Index: lib/Driver/ToolChains/Arch/ARM.h === --- lib/Driver/ToolChains/Arch/ARM.h +++ lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -122,6 +122,31 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + const Driver = TC.getDriver(); + arm::ReadTPMode ThreadPointer = ReadTPMode::Invalid; + if (Arg *A = + Args.getLastArg(options::OPT_mtp_mode_EQ)) { +ThreadPointer = llvm::StringSwitch(A->getValue()) +.Case("cp15", ReadTPMode::Cp15) +.Case("soft", ReadTPMode::Soft) +.Default(ReadTPMode::Invalid); +if (ThreadPointer == ReadTPMode::Invalid) { + if (StringRef(A->getValue()).empty()) +D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); + else +D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); +} + } + + // If -mtp option not specified or takes invalid/empty argument + // choose soft mode. + if (ThreadPointer == ReadTPMode::Invalid) +ThreadPointer = ReadTPMode::Soft; + return ThreadPointer; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -253,6 +278,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -294,6 +320,10 @@ } } + + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1661,6 +1661,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"],
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. Comments addressed. https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic updated this revision to Diff 109088. https://reviews.llvm.org/D34878 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/Driver/ToolChains/Arch/ARM.cpp lib/Driver/ToolChains/Arch/ARM.h lib/Driver/ToolChains/Clang.cpp test/Driver/clang-translation.c Index: test/Driver/clang-translation.c === --- test/Driver/clang-translation.c +++ test/Driver/clang-translation.c @@ -75,6 +75,12 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER %s +// ARMv7_THREAD_POINTER: "-target-feature" "+read-tp-hard" +// ARMv7_THREAD_POINTER: "-mtp" "cp15" +// ARMv7_THREAD_POINTER-NOT: "mtp" "soft" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang Index: lib/Driver/ToolChains/Clang.cpp === --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -1345,6 +1345,17 @@ CmdArgs.push_back("hard"); } + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(getToolChain(), Args); + if (ThreadPointer == arm::ReadTPMode::Cp15) { +CmdArgs.push_back("-mtp"); +CmdArgs.push_back("cp15"); + } else { +assert(ThreadPointer == arm::ReadTPMode::Soft && + "Invalid mode for reading thread pointer"); +CmdArgs.push_back("-mtp"); +CmdArgs.push_back("soft"); + } + // Forward the -mglobal-merge option for explicit control over the pass. if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge, options::OPT_mno_global_merge)) { Index: lib/Driver/ToolChains/Arch/ARM.h === --- lib/Driver/ToolChains/Arch/ARM.h +++ lib/Driver/ToolChains/Arch/ARM.h @@ -32,14 +32,21 @@ void appendEBLinkFlags(const llvm::opt::ArgList , llvm::opt::ArgStringList , const llvm::Triple ); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, SoftFP, Hard, }; FloatABI getARMFloatABI(const ToolChain , const llvm::opt::ArgList ); +ReadTPMode getReadTPMode(const ToolChain , const llvm::opt::ArgList ); bool useAAPCSForMachO(const llvm::Triple ); void getARMArchCPUFromArgs(const llvm::opt::ArgList , Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -122,6 +122,27 @@ T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain , const ArgList ) { + const Driver = TC.getDriver(); + arm::ReadTPMode ThreadPointer = ReadTPMode::Invalid; + if (Arg *A = + Args.getLastArg(options::OPT_mtp_mode_EQ)) { +ThreadPointer = llvm::StringSwitch(A->getValue()) +.Case("cp15", ReadTPMode::Cp15) +.Case("soft", ReadTPMode::Soft) +.Default(ReadTPMode::Invalid); +if (ThreadPointer == ReadTPMode::Invalid && +!StringRef(A->getValue()).empty()) { + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); + ThreadPointer = ReadTPMode::Soft; +} + } + if (ThreadPointer == ReadTPMode::Invalid) +ThreadPointer = ReadTPMode::Soft; + return ThreadPointer; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain , const ArgList ) { @@ -253,6 +274,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -294,6 +316,10 @@ } } + + if (ThreadPointer == arm::ReadTPMode::Cp15) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1661,6 +1661,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. Hi Bruno, Yes, GCC has similar option (-mtp=soft/hard), but name is not same. I put the same option name as in backend (https://reviews.llvm.org/D34408). https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. ping https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic added a comment. ping https://reviews.llvm.org/D34878 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34878: [ARM] Option for reading thread pointer from coprocessor register
spetrovic created this revision. Herald added subscribers: kristof.beyls, javed.absar, aemerson. This patch enables option for reading thread pointer directly from coprocessor register (-mread-tp-hard). This option is supported in llc also ( https://reviews.llvm.org/D34408 ). https://reviews.llvm.org/D34878 Files: include/clang/Driver/Options.td lib/Basic/Targets.cpp lib/Driver/ToolChains/Arch/ARM.cpp test/Driver/arm-features.c Index: test/Driver/arm-features.c === --- test/Driver/arm-features.c +++ test/Driver/arm-features.c @@ -7,6 +7,8 @@ // RUN: %clang -target arm-none-none-eabi -mcpu=generic+dsp -march=armv8m.main -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-DSP %s // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8m.main+dsp -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-DSP %s // CHECK-DSP: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+dsp" +// RUN: %clang -target arm-none-none-eabi -mread-tp-hard -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-READTP %s +// CHECK-READTP: "-target-feature" "+read-tp-hard" // RUN: %clang -target arm-none-none-eabi -mcpu=generic+nocrc -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRC %s // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8a+nocrc -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRC %s Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -283,6 +283,10 @@ } } + // Setting the way of reading thread pointer. + if (Args.getLastArg(options::OPT_mread_tp_hard)) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; Index: lib/Basic/Targets.cpp === --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -5094,6 +5094,7 @@ unsigned Crypto : 1; unsigned DSP : 1; unsigned Unaligned : 1; + unsigned ReadTpHard : 1; enum { LDREX_B = (1 << 0), /// byte (8-bit) @@ -5486,6 +5487,7 @@ Unaligned = 1; SoftFloat = SoftFloatABI = false; HWDiv = 0; +ReadTpHard = false; // This does not diagnose illegal cases like having both // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp". @@ -5526,7 +5528,8 @@ Unaligned = 0; } else if (Feature == "+fp16") { HW_FP |= HW_FP_HP; - } + } else if (Feature == "+read-tp-hard") +ReadTpHard = true; } HW_FP &= ~HW_FP_remove; Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1651,6 +1651,8 @@ HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mread_tp_hard : Flag<["-"], "mread-tp-hard">, Group, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; def mpure_code : Flag<["-"], "mpure-code">, Alias; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; Index: test/Driver/arm-features.c === --- test/Driver/arm-features.c +++ test/Driver/arm-features.c @@ -7,6 +7,8 @@ // RUN: %clang -target arm-none-none-eabi -mcpu=generic+dsp -march=armv8m.main -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-DSP %s // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8m.main+dsp -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-DSP %s // CHECK-DSP: "-cc1"{{.*}} "-triple" "thumbv8m.main-{{.*}} "-target-cpu" "generic"{{.*}} "-target-feature" "+dsp" +// RUN: %clang -target arm-none-none-eabi -mread-tp-hard -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-READTP %s +// CHECK-READTP: "-target-feature" "+read-tp-hard" // RUN: %clang -target arm-none-none-eabi -mcpu=generic+nocrc -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRC %s // RUN: %clang -target arm-none-none-eabi -mcpu=generic -march=armv8a+nocrc -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NOCRC %s Index: lib/Driver/ToolChains/Arch/ARM.cpp === --- lib/Driver/ToolChains/Arch/ARM.cpp +++ lib/Driver/ToolChains/Arch/ARM.cpp @@ -283,6 +283,10 @@ } } + // Setting the way of reading thread pointer. + if (Args.getLastArg(options::OPT_mread_tp_hard)) +Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg