<div dir="ltr">Hi Prakhar,<div><br></div><div>FWIW this wasn't quite the right way to write this support. The default subtarget shouldn't be used (and I'll be removing it after this patch) and in general we don't pass command line options to the backend if we can help it.</div><div><br></div><div>A couple of concerns, FWIW:</div><div><br></div><div>a) The existing support, and my rewrite split the desire across individual functions and not at the module level. I'm not entirely sure this is what you intended, but it is what you got.</div><div>b) The existing support wouldn't have handled LTO very well. The rewrite will handle it a bit better, but you could still have problems if you meant for this to apply to functions that weren't originally compiled with -mexecute-only.</div><div><br></div><div>I've gone ahead and updated it thusly:</div><div><br></div><div><div>echristo@athyra ~/s/llvm> git svn dcommit ; cd tools/clang/ ; git svn dcommit</div><div>Committing to <a href="https://llvm.org/svn/llvm-project/llvm/trunk">https://llvm.org/svn/llvm-project/llvm/trunk</a> ...</div><div><span style="white-space:pre">       </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARM.td</div><div><span style="white-space:pre"> </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARMSubtarget.cpp</div><div><span style="white-space:pre">       </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARMTargetObjectFile.cpp</div><div><span style="white-space:pre">        </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARMTargetObjectFile.h</div><div><span style="white-space:pre">  </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/constantfp.ll</div><div><span style="white-space:pre">        </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/execute-only-big-stack-frame.ll</div><div><span style="white-space:pre">      </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/execute-only-section.ll</div><div><span style="white-space:pre">      </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/execute-only.ll</div><div>Committed r306927</div><div><span style="white-space:pre">      </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/execute-only-section.ll</div><div><span style="white-space:pre">      </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/execute-only.ll</div><div><span style="white-space:pre">      </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/execute-only-big-stack-frame.ll</div><div><span style="white-space:pre">      </span>M<span style="white-space:pre">    </span>test/CodeGen/ARM/constantfp.ll</div><div><span style="white-space:pre">        </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARMSubtarget.cpp</div><div><span style="white-space:pre">       </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARMTargetObjectFile.h</div><div><span style="white-space:pre">  </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARMTargetObjectFile.cpp</div><div><span style="white-space:pre">        </span>M<span style="white-space:pre">    </span>lib/Target/ARM/ARM.td</div><div>r306927 = 3d3e534c24741f26d7cd432488561431d7ad1db1 (refs/remotes/origin/master)</div><div>Committing to <a href="https://llvm.org/svn/llvm-project/cfe/trunk">https://llvm.org/svn/llvm-project/cfe/trunk</a> ...<br></div><div><span style="white-space:pre">     </span>C<span style="white-space:pre">    </span>test/Driver/arm-execute-only.c => test/CodeGen/arm-execute-only.c</div><div><span style="white-space:pre">  </span>M<span style="white-space:pre">    </span>lib/Driver/ToolChains/Arch/ARM.cpp</div><div><span style="white-space:pre">    </span>M<span style="white-space:pre">    </span>test/Driver/arm-execute-only.c</div><div>Committed r306928</div><div><span style="white-space:pre">        </span>M<span style="white-space:pre">    </span>test/Driver/arm-execute-only.c</div><div><span style="white-space:pre">        </span>A<span style="white-space:pre">    </span>test/CodeGen/arm-execute-only.c</div><div><span style="white-space:pre">       </span>M<span style="white-space:pre">    </span>lib/Driver/ToolChains/Arch/ARM.cpp</div><div>r306928 = f903f6da7ea5c96325dca9f1b32e0dea845fcca2 (refs/remotes/origin/master)</div><div><br></div><div>feel free to take a look for this sort of thing in the future.</div><div><br></div><div>Thanks! :)</div><div><br></div><div>-eric</div><div><br></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Dec 15, 2016 at 1:08 AM Prakhar Bahuguna via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: prakhar<br>
Date: Thu Dec 15 01:59:08 2016<br>
New Revision: 289784<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=289784&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=289784&view=rev</a><br>
Log:<br>
[ARM] Implement execute-only support in CodeGen<br>
<br>
This implements execute-only support for ARM code generation, which<br>
prevents the compiler from generating data accesses to code sections.<br>
The following changes are involved:<br>
<br>
* Add the CodeGen option "-arm-execute-only" to the ARM code generator.<br>
* Add the clang flag "-mexecute-only" as well as the GCC-compatible<br>
  alias "-mpure-code" to enable this option.<br>
* When enabled, literal pools are replaced with MOVW/MOVT instructions,<br>
  with VMOV used in addition for floating-point literals. As the MOVT<br>
  instruction is required, execute-only support is only available in<br>
  Thumb mode for targets supporting ARMv8-M baseline or Thumb2.<br>
* Jump tables are placed in data sections when in execute-only mode.<br>
* The execute-only text section is assigned section ID 0, and is<br>
  marked as unreadable with the SHF_ARM_PURECODE flag with symbol 'y'.<br>
  This also overrides selection of ELF sections for globals.<br>
<br>
Added:<br>
    llvm/trunk/test/CodeGen/ARM/execute-only-big-stack-frame.ll<br>
    llvm/trunk/test/CodeGen/ARM/execute-only-section.ll<br>
    llvm/trunk/test/CodeGen/ARM/execute-only.ll<br>
    llvm/trunk/test/MC/ELF/ARM/execute-only-section.s<br>
Modified:<br>
    llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h<br>
    llvm/trunk/include/llvm/MC/SectionKind.h<br>
    llvm/trunk/include/llvm/Support/ELF.h<br>
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp<br>
    llvm/trunk/lib/MC/MCContext.cpp<br>
    llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp<br>
    llvm/trunk/lib/MC/MCSectionELF.cpp<br>
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td<br>
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td<br>
    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td<br>
    llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMSubtarget.h<br>
    llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp<br>
    llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h<br>
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp<br>
    llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp<br>
    llvm/trunk/test/CodeGen/ARM/constantfp.ll<br>
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h Thu Dec 15 01:59:08 2016<br>
@@ -33,7 +33,7 @@ namespace llvm {<br>
<br>
 class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {<br>
   bool UseInitArray;<br>
-  mutable unsigned NextUniqueID = 0;<br>
+  mutable unsigned NextUniqueID = 1;  // ID 0 is reserved for execute-only sections<br>
<br>
 protected:<br>
   MCSymbolRefExpr::VariantKind PLTRelativeVariantKind =<br>
<br>
Modified: llvm/trunk/include/llvm/MC/SectionKind.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/SectionKind.h?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/SectionKind.h?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/MC/SectionKind.h (original)<br>
+++ llvm/trunk/include/llvm/MC/SectionKind.h Thu Dec 15 01:59:08 2016<br>
@@ -28,6 +28,9 @@ class SectionKind {<br>
     /// Text - Text section, used for functions and other executable code.<br>
     Text,<br>
<br>
+           /// ExecuteOnly, Text section that is not readable.<br>
+           ExecuteOnly,<br>
+<br>
     /// ReadOnly - Data that is never written to at program runtime by the<br>
     /// program or the dynamic linker.  Things in the top-level readonly<br>
     /// SectionKind are not mergeable.<br>
@@ -112,7 +115,10 @@ class SectionKind {<br>
 public:<br>
<br>
   bool isMetadata() const { return K == Metadata; }<br>
-  bool isText() const { return K == Text; }<br>
+<br>
+  bool isText() const { return K == Text || K == ExecuteOnly; }<br>
+<br>
+  bool isExecuteOnly() const { return K == ExecuteOnly; }<br>
<br>
   bool isReadOnly() const {<br>
     return K == ReadOnly || isMergeableCString() ||<br>
@@ -172,6 +178,7 @@ public:<br>
<br>
   static SectionKind getMetadata() { return get(Metadata); }<br>
   static SectionKind getText() { return get(Text); }<br>
+  static SectionKind getExecuteOnly() { return get(ExecuteOnly); }<br>
   static SectionKind getReadOnly() { return get(ReadOnly); }<br>
   static SectionKind getMergeable1ByteCString() {<br>
     return get(Mergeable1ByteCString);<br>
<br>
Modified: llvm/trunk/include/llvm/Support/ELF.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELF.h?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELF.h?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/ELF.h (original)<br>
+++ llvm/trunk/include/llvm/Support/ELF.h Thu Dec 15 01:59:08 2016<br>
@@ -804,6 +804,9 @@ enum : unsigned {<br>
   // Section data is string data by default.<br>
   SHF_MIPS_STRING = 0x80000000,<br>
<br>
+  // Make code section unreadable when in execute-only mode<br>
+  SHF_ARM_PURECODE = 0x20000000,<br>
+<br>
   SHF_AMDGPU_HSA_GLOBAL = 0x00100000,<br>
   SHF_AMDGPU_HSA_READONLY = 0x00200000,<br>
   SHF_AMDGPU_HSA_CODE = 0x00400000,<br>
<br>
Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Thu Dec 15 01:59:08 2016<br>
@@ -181,6 +181,9 @@ static unsigned getELFSectionFlags(Secti<br>
   if (K.isText())<br>
     Flags |= ELF::SHF_EXECINSTR;<br>
<br>
+  if (K.isExecuteOnly())<br>
+    Flags |= ELF::SHF_ARM_PURECODE;<br>
+<br>
   if (K.isWriteable())<br>
     Flags |= ELF::SHF_WRITE;<br>
<br>
@@ -312,6 +315,9 @@ selectELFSectionForGlobal(MCContext &Ctx<br>
     UniqueID = *NextUniqueID;<br>
     (*NextUniqueID)++;<br>
   }<br>
+  // Use 0 as the unique ID for execute-only text<br>
+  if (Kind.isExecuteOnly())<br>
+    UniqueID = 0;<br>
   return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,<br>
                            EntrySize, Group, UniqueID);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/MC/MCContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCContext.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCContext.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCContext.cpp Thu Dec 15 01:59:08 2016<br>
@@ -368,7 +368,9 @@ MCSectionELF *MCContext::getELFSection(c<br>
   StringRef CachedName = Entry.first.SectionName;<br>
<br>
   SectionKind Kind;<br>
-  if (Flags & ELF::SHF_EXECINSTR)<br>
+  if (Flags & ELF::SHF_ARM_PURECODE)<br>
+    Kind = SectionKind::getExecuteOnly();<br>
+  else if (Flags & ELF::SHF_EXECINSTR)<br>
     Kind = SectionKind::getText();<br>
   else<br>
     Kind = SectionKind::getReadOnly();<br>
<br>
Modified: llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp Thu Dec 15 01:59:08 2016<br>
@@ -293,6 +293,9 @@ static unsigned parseSectionFlags(String<br>
     case 'd':<br>
       flags |= ELF::XCORE_SHF_DP_SECTION;<br>
       break;<br>
+    case 'y':<br>
+      flags |= ELF::SHF_ARM_PURECODE;<br>
+      break;<br>
     case 'G':<br>
       flags |= ELF::SHF_GROUP;<br>
       break;<br>
<br>
Modified: llvm/trunk/lib/MC/MCSectionELF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionELF.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionELF.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/MC/MCSectionELF.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCSectionELF.cpp Thu Dec 15 01:59:08 2016<br>
@@ -110,6 +110,8 @@ void MCSectionELF::PrintSwitchToSection(<br>
     OS << 'c';<br>
   if (Flags & ELF::XCORE_SHF_DP_SECTION)<br>
     OS << 'd';<br>
+  if (Flags & ELF::SHF_ARM_PURECODE)<br>
+    OS << 'y';<br>
<br>
   OS << '"';<br>
<br>
<br>
Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)<br>
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Thu Dec 15 01:59:08 2016<br>
@@ -423,6 +423,9 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF<br>
   BCase(SHF_GROUP)<br>
   BCase(SHF_TLS)<br>
   switch(Object->Header.Machine) {<br>
+  case ELF::EM_ARM:<br>
+    BCase(SHF_ARM_PURECODE)<br>
+    break;<br>
   case ELF::EM_AMDGPU:<br>
     BCase(SHF_AMDGPU_HSA_GLOBAL)<br>
     BCase(SHF_AMDGPU_HSA_READONLY)<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Thu Dec 15 01:59:08 2016<br>
@@ -232,6 +232,8 @@ void ARMAsmPrinter::printOperand(const M<br>
     break;<br>
   }<br>
   case MachineOperand::MO_ConstantPoolIndex:<br>
+    if (Subtarget->genExecuteOnly())<br>
+      llvm_unreachable("execute-only should not generate constant pools");<br>
     GetCPISymbol(MO.getIndex())->print(O, MAI);<br>
     break;<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Thu Dec 15 01:59:08 2016<br>
@@ -423,7 +423,7 @@ bool ARMConstantIslands::runOnMachineFun<br>
     MadeChange |= optimizeThumb2Branches();<br>
<br>
   // Optimize jump tables using TBB / TBH.<br>
-  if (GenerateTBB)<br>
+  if (GenerateTBB && !STI->genExecuteOnly())<br>
     MadeChange |= optimizeThumb2JumpTables();<br>
<br>
   // After a while, this might be made debug-only, but it is not expensive.<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Dec 15 01:59:08 2016<br>
@@ -3152,7 +3152,8 @@ SDValue ARMTargetLowering::LowerGlobalAd<br>
       (isa<GlobalVariable>(GV) && cast<GlobalVariable>(GV)->isConstant()) ||<br>
       isa<Function>(GV);<br>
<br>
-  if (TM.shouldAssumeDSOLocal(*GV->getParent(), GV))<br>
+  // promoteToConstantPool only if not generating XO text section<br>
+  if (TM.shouldAssumeDSOLocal(*GV->getParent(), GV) && !Subtarget->genExecuteOnly())<br>
     if (SDValue V = promoteToConstantPool(GV, DAG, PtrVT, dl))<br>
       return V;<br>
<br>
@@ -4492,10 +4493,10 @@ SDValue ARMTargetLowering::LowerBR_JT(SD<br>
   Table = DAG.getNode(ARMISD::WrapperJT, dl, MVT::i32, JTI);<br>
   Index = DAG.getNode(ISD::MUL, dl, PTy, Index, DAG.getConstant(4, dl, PTy));<br>
   SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table);<br>
-  if (Subtarget->isThumb2()) {<br>
-    // Thumb2 uses a two-level jump. That is, it jumps into the jump table<br>
+  if (Subtarget->isThumb2() || (Subtarget->hasV8MBaselineOps() && Subtarget->isThumb())) {<br>
+    // Thumb2 and ARMv8-M use a two-level jump. That is, it jumps into the jump table<br>
     // which does another jump to the destination. This also makes it easier<br>
-    // to translate it to TBB / TBH later.<br>
+    // to translate it to TBB / TBH later (Thumb2 only).<br>
     // FIXME: This might not work if the function is extremely large.<br>
     return DAG.getNode(ARMISD::BR2_JT, dl, MVT::Other, Chain,<br>
                        Addr, Op.getOperand(2), JTI);<br>
@@ -5571,11 +5572,28 @@ static SDValue isNEONModifiedImm(uint64_<br>
<br>
 SDValue ARMTargetLowering::LowerConstantFP(SDValue Op, SelectionDAG &DAG,<br>
                                            const ARMSubtarget *ST) const {<br>
-  if (!ST->hasVFP3())<br>
-    return SDValue();<br>
-<br>
   bool IsDouble = Op.getValueType() == MVT::f64;<br>
   ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Op);<br>
+  const APFloat &FPVal = CFP->getValueAPF();<br>
+<br>
+  // Prevent floating-point constants from using literal loads<br>
+  // when execute-only is enabled.<br>
+  if (ST->genExecuteOnly()) {<br>
+    APInt INTVal = FPVal.bitcastToAPInt();<br>
+    SDLoc DL(CFP);<br>
+    if (IsDouble) {<br>
+      SDValue Lo = DAG.getConstant(INTVal.trunc(32), DL, MVT::i32);<br>
+      SDValue Hi = DAG.getConstant(INTVal.lshr(32).trunc(32), DL, MVT::i32);<br>
+      if (!ST->isLittle())<br>
+        std::swap(Lo, Hi);<br>
+      return DAG.getNode(ARMISD::VMOVDRR, DL, MVT::f64, Lo, Hi);<br>
+    } else {<br>
+      return DAG.getConstant(INTVal, DL, MVT::i32);<br>
+    }<br>
+  }<br>
+<br>
+  if (!ST->hasVFP3())<br>
+    return SDValue();<br>
<br>
   // Use the default (constant pool) lowering for double constants when we have<br>
   // an SP-only FPU<br>
@@ -5583,7 +5601,6 @@ SDValue ARMTargetLowering::LowerConstant<br>
     return SDValue();<br>
<br>
   // Try splatting with a VMOV.f32...<br>
-  const APFloat &FPVal = CFP->getValueAPF();<br>
   int ImmVal = IsDouble ? ARM_AM::getFP64Imm(FPVal) : ARM_AM::getFP32Imm(FPVal);<br>
<br>
   if (ImmVal != -1) {<br>
@@ -7617,7 +7634,10 @@ SDValue ARMTargetLowering::LowerOperatio<br>
   switch (Op.getOpcode()) {<br>
   default: llvm_unreachable("Don't know how to custom lower this!");<br>
   case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG);<br>
-  case ISD::ConstantPool:  return LowerConstantPool(Op, DAG);<br>
+  case ISD::ConstantPool:<br>
+    if (Subtarget->genExecuteOnly())<br>
+      llvm_unreachable("execute-only should not generate constant pools");<br>
+    return LowerConstantPool(Op, DAG);<br>
   case ISD::BlockAddress:  return LowerBlockAddress(Op, DAG);<br>
   case ISD::GlobalAddress:<br>
     switch (Subtarget->getTargetTriple().getObjectFormat()) {<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Dec 15 01:59:08 2016<br>
@@ -398,6 +398,14 @@ class tPseudoInst<dag oops, dag iops, in<br>
   list<Predicate> Predicates = [IsThumb];<br>
 }<br>
<br>
+// PseudoInst that's in ARMv8-M baseline (Somewhere between Thumb and Thumb2)<br>
+class t2basePseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,<br>
+                    list<dag> pattern><br>
+  : PseudoInst<oops, iops, itin, pattern> {<br>
+  let Size = sz;<br>
+  list<Predicate> Predicates = [IsThumb,HasV8MBaseline];<br>
+}<br>
+<br>
 // PseudoInst that's Thumb2-mode only.<br>
 class t2PseudoInst<dag oops, dag iops, int sz, InstrItinClass itin,<br>
                     list<dag> pattern><br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Dec 15 01:59:08 2016<br>
@@ -330,6 +330,8 @@ def DontUseVMOVSR : Predicate<"!Subtarge<br>
 def IsLE             : Predicate<"MF->getDataLayout().isLittleEndian()">;<br>
 def IsBE             : Predicate<"MF->getDataLayout().isBigEndian()">;<br>
<br>
+def GenExecuteOnly : Predicate<"Subtarget->genExecuteOnly()">;<br>
+<br>
 //===----------------------------------------------------------------------===//<br>
 // ARM Flag Definitions.<br>
<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Thu Dec 15 01:59:08 2016<br>
@@ -3381,7 +3381,9 @@ def t2B   : T2I<(outs), (ins thumb_br_ta<br>
 }<br>
<br>
 let Size = 4, isNotDuplicable = 1, isIndirectBranch = 1 in {<br>
-def t2BR_JT : t2PseudoInst<(outs),<br>
+<br>
+// available in both v8-M.Baseline and Thumb2 targets<br>
+def t2BR_JT : t2basePseudoInst<(outs),<br>
           (ins GPR:$target, GPR:$index, i32imm:$jt),<br>
            0, IIC_Br,<br>
           [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt)]>,<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp Thu Dec 15 01:59:08 2016<br>
@@ -91,6 +91,8 @@ bool ARMAsmPrinter::lowerOperand(const M<br>
     MCOp = GetSymbolRef(MO, GetJTISymbol(MO.getIndex()));<br>
     break;<br>
   case MachineOperand::MO_ConstantPoolIndex:<br>
+    if (Subtarget->genExecuteOnly())<br>
+      llvm_unreachable("execute-only should not generate constant pools");<br>
     MCOp = GetSymbolRef(MO, GetCPISymbol(MO.getIndex()));<br>
     break;<br>
   case MachineOperand::MO_BlockAddress:<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMSubtarget.cpp Thu Dec 15 01:59:08 2016<br>
@@ -76,6 +76,11 @@ ARMSubtarget &ARMSubtarget::initializeSu<br>
   return *this;<br>
 }<br>
<br>
+/// EnableExecuteOnly - Enables the generation of execute-only code on supported<br>
+/// targets<br>
+static cl::opt<bool><br>
+EnableExecuteOnly("arm-execute-only");<br>
+<br>
 ARMFrameLowering *ARMSubtarget::initializeFrameLowering(StringRef CPU,<br>
                                                         StringRef FS) {<br>
   ARMSubtarget &STI = initializeSubtargetDependencies(CPU, FS);<br>
@@ -90,7 +95,8 @@ ARMSubtarget::ARMSubtarget(const Triple<br>
                            const ARMBaseTargetMachine &TM, bool IsLittle)<br>
     : ARMGenSubtargetInfo(TT, CPU, FS), UseMulOps(UseFusedMulOps),<br>
       CPUString(CPU), IsLittle(IsLittle), TargetTriple(TT), Options(TM.Options),<br>
-      TM(TM), FrameLowering(initializeFrameLowering(CPU, FS)),<br>
+      TM(TM), GenExecuteOnly(EnableExecuteOnly),<br>
+      FrameLowering(initializeFrameLowering(CPU, FS)),<br>
       // At this point initializeSubtargetDependencies has been called so<br>
       // we can query directly.<br>
       InstrInfo(isThumb1Only()<br>
@@ -169,6 +175,10 @@ void ARMSubtarget::initSubtargetFeatures<br>
   // Assert this for now to make the change obvious.<br>
   assert(hasV6T2Ops() || !hasThumb2());<br>
<br>
+  // Execute only support requires movt support<br>
+  if (genExecuteOnly())<br>
+    assert(hasV8MBaselineOps() && !NoMovt && "Cannot generate execute-only code for this target");<br>
+<br>
   // Keep a pointer to static instruction cost data for the specified CPU.<br>
   SchedModel = getSchedModelForCPU(CPUString);<br>
<br>
@@ -353,7 +363,7 @@ bool ARMSubtarget::useMovt(const Machine<br>
   // immediates as it is inherently position independent, and may be out of<br>
   // range otherwise.<br>
   return !NoMovt && hasV8MBaselineOps() &&<br>
-         (isTargetWindows() || !MF.getFunction()->optForMinSize());<br>
+         (isTargetWindows() || !MF.getFunction()->optForMinSize() || genExecuteOnly());<br>
 }<br>
<br>
 bool ARMSubtarget::useFastISel() const {<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMSubtarget.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMSubtarget.h?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMSubtarget.h (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMSubtarget.h Thu Dec 15 01:59:08 2016<br>
@@ -301,6 +301,9 @@ protected:<br>
   /// Generate calls via indirect call instructions.<br>
   bool GenLongCalls = false;<br>
<br>
+  /// Generate code that does not contain data access to code sections.<br>
+  bool GenExecuteOnly = false;<br>
+<br>
   /// Target machine allowed unsafe FP math (such as use of NEON fp)<br>
   bool UnsafeFPMath = false;<br>
<br>
@@ -494,6 +497,7 @@ public:<br>
   bool useNaClTrap() const { return UseNaClTrap; }<br>
   bool useSjLjEH() const { return UseSjLjEH; }<br>
   bool genLongCalls() const { return GenLongCalls; }<br>
+  bool genExecuteOnly() const { return GenExecuteOnly; }<br>
<br>
   bool hasFP16() const { return HasFP16; }<br>
   bool hasD16() const { return HasD16; }<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.cpp Thu Dec 15 01:59:08 2016<br>
@@ -27,8 +27,10 @@ using namespace dwarf;<br>
<br>
 void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,<br>
                                         const TargetMachine &TM) {<br>
-  bool isAAPCS_ABI = static_cast<const ARMTargetMachine &>(TM).TargetABI ==<br>
-                     ARMTargetMachine::ARMABI::ARM_ABI_AAPCS;<br>
+  const ARMTargetMachine &ARM_TM = static_cast<const ARMTargetMachine &>(TM);<br>
+  bool isAAPCS_ABI = ARM_TM.TargetABI == ARMTargetMachine::ARMABI::ARM_ABI_AAPCS;<br>
+  genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly();<br>
+<br>
   TargetLoweringObjectFileELF::Initialize(Ctx, TM);<br>
   InitializeELF(isAAPCS_ABI);<br>
<br>
@@ -38,6 +40,16 @@ void ARMElfTargetObjectFile::Initialize(<br>
<br>
   AttributesSection =<br>
       getContext().getELFSection(".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);<br>
+<br>
+  // Make code section unreadable when in execute-only mode<br>
+  if (genExecuteOnly) {<br>
+    unsigned  Type = ELF::SHT_PROGBITS;<br>
+    unsigned Flags = ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_ARM_PURECODE;<br>
+    // Since we cannot modify flags for an existing section, we create a new<br>
+    // section with the right flags, and use 0 as the unique ID for<br>
+    // execute-only text<br>
+    TextSection = Ctx.getELFSection(".text", Type, Flags, 0, "", 0U);<br>
+  }<br>
 }<br>
<br>
 const MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference(<br>
@@ -58,3 +70,23 @@ getDebugThreadLocalSymbol(const MCSymbol<br>
   return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_ARM_TLSLDO,<br>
                                  getContext());<br>
 }<br>
+<br>
+MCSection *<br>
+ARMElfTargetObjectFile::getExplicitSectionGlobal(const GlobalObject *GO,<br>
+                                                 SectionKind SK, const TargetMachine &TM) const {<br>
+  // Set execute-only access for the explicit section<br>
+  if (genExecuteOnly && SK.isText())<br>
+    SK = SectionKind::getExecuteOnly();<br>
+<br>
+  return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, SK, TM);<br>
+}<br>
+<br>
+MCSection *<br>
+ARMElfTargetObjectFile::SelectSectionForGlobal(const GlobalObject *GO,<br>
+                                               SectionKind SK, const TargetMachine &TM) const {<br>
+  // Place the global in the execute-only text section<br>
+  if (genExecuteOnly && SK.isText())<br>
+    SK = SectionKind::getExecuteOnly();<br>
+<br>
+  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, SK, TM);<br>
+}<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h (original)<br>
+++ llvm/trunk/lib/Target/ARM/ARMTargetObjectFile.h Thu Dec 15 01:59:08 2016<br>
@@ -18,6 +18,7 @@ class MCContext;<br>
 class TargetMachine;<br>
<br>
 class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF {<br>
+  mutable bool genExecuteOnly = false;<br>
 protected:<br>
   const MCSection *AttributesSection;<br>
 public:<br>
@@ -36,6 +37,12 @@ public:<br>
<br>
   /// \brief Describe a TLS variable address within debug info.<br>
   const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override;<br>
+<br>
+  MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,<br>
+                                      const TargetMachine &TM) const override;<br>
+<br>
+  MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,<br>
+                                    const TargetMachine &TM) const override;<br>
 };<br>
<br>
 } // end namespace llvm<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Thu Dec 15 01:59:08 2016<br>
@@ -5453,6 +5453,9 @@ bool ARMAsmParser::parseOperand(OperandV<br>
     if (getParser().parseExpression(SubExprVal))<br>
       return true;<br>
     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);<br>
+<br>
+    // execute-only: we assume that assembly programmers know what they are<br>
+    // doing and allow literal pool creation here<br>
     Operands.push_back(ARMOperand::CreateConstantPoolImm(SubExprVal, S, E));<br>
     return false;<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/ARM/ThumbRegisterInfo.cpp Thu Dec 15 01:59:08 2016<br>
@@ -126,6 +126,7 @@ static void emitThumbRegPlusImmInReg(<br>
     bool CanChangeCC, const TargetInstrInfo &TII,<br>
     const ARMBaseRegisterInfo &MRI, unsigned MIFlags = MachineInstr::NoFlags) {<br>
   MachineFunction &MF = *MBB.getParent();<br>
+  const ARMSubtarget &ST = MF.getSubtarget<ARMSubtarget>();<br>
   bool isHigh = !isARMLowRegister(DestReg) ||<br>
                 (BaseReg != 0 && !isARMLowRegister(BaseReg));<br>
   bool isSub = false;<br>
@@ -154,6 +155,9 @@ static void emitThumbRegPlusImmInReg(<br>
     AddDefaultT1CC(BuildMI(MBB, MBBI, dl, TII.get(ARM::tRSB), LdReg))<br>
         .addReg(LdReg, RegState::Kill)<br>
         .setMIFlags(MIFlags);<br>
+  } else if (ST.genExecuteOnly()) {<br>
+    BuildMI(MBB, MBBI, dl, TII.get(ARM::t2MOVi32imm), LdReg)<br>
+      .addImm(NumBytes).setMIFlags(MIFlags);<br>
   } else<br>
     MRI.emitLoadConstPool(MBB, MBBI, dl, LdReg, 0, NumBytes, ARMCC::AL, 0,<br>
                           MIFlags);<br>
@@ -570,7 +574,7 @@ void ThumbRegisterInfo::eliminateFrameIn<br>
     unsigned TmpReg = MI.getOperand(0).getReg();<br>
     bool UseRR = false;<br>
     if (Opcode == ARM::tLDRspi) {<br>
-      if (FrameReg == ARM::SP)<br>
+      if (FrameReg == ARM::SP || STI.genExecuteOnly())<br>
         emitThumbRegPlusImmInReg(MBB, II, dl, TmpReg, FrameReg,<br>
                                  Offset, false, TII, *this);<br>
       else {<br>
@@ -594,7 +598,7 @@ void ThumbRegisterInfo::eliminateFrameIn<br>
       bool UseRR = false;<br>
<br>
       if (Opcode == ARM::tSTRspi) {<br>
-        if (FrameReg == ARM::SP)<br>
+        if (FrameReg == ARM::SP || STI.genExecuteOnly())<br>
           emitThumbRegPlusImmInReg(MBB, II, dl, VReg, FrameReg,<br>
                                    Offset, false, TII, *this);<br>
         else {<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/constantfp.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/constantfp.ll?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/constantfp.ll?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/constantfp.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/constantfp.ll Thu Dec 15 01:59:08 2016<br>
@@ -2,6 +2,25 @@<br>
 ; RUN: llc -mtriple=armv7 -mattr=+neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEONFP %s<br>
 ; RUN: llc -mtriple=armv7 -mattr=-neon -mcpu=cortex-a8 %s -o - | FileCheck --check-prefix=CHECK-NONEON %s<br>
<br>
+; RUN: llc -mtriple=thumbv7m -mcpu=cortex-m4 %s -o - \<br>
+; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s<br>
+<br>
+; RUN: llc -mtriple=thumbv7m -arm-execute-only -mcpu=cortex-m4 %s -o - \<br>
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s<br>
+<br>
+; RUN: llc -mtriple=thumbv7meb -arm-execute-only -mcpu=cortex-m4 %s -o - \<br>
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s<br>
+<br>
+; RUN: llc -mtriple=thumbv8m.main -mattr=fp-armv8 %s -o - \<br>
+; RUN: | FileCheck --check-prefix=CHECK-NO-XO %s<br>
+<br>
+; RUN: llc -mtriple=thumbv8m.main -arm-execute-only -mattr=fp-armv8 %s -o - \<br>
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE %s<br>
+<br>
+; RUN: llc -mtriple=thumbv8m.maineb -arm-execute-only -mattr=fp-armv8 %s -o - \<br>
+; RUN: | FileCheck --check-prefix=CHECK-XO-FLOAT --check-prefix=CHECK-XO-DOUBLE-BE %s<br>
+<br>
+<br>
 define arm_aapcs_vfpcc float @test_vmov_f32() {<br>
 ; CHECK-LABEL: test_vmov_f32:<br>
 ; CHECK: vmov.f32 d0, #1.0<br>
@@ -16,6 +35,14 @@ define arm_aapcs_vfpcc float @test_vmov_<br>
<br>
 ; CHECK-NONEON-LABEL: test_vmov_imm:<br>
 ; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-NO-XO-LABEL: test_vmov_imm:<br>
+; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-FLOAT-LABEL: test_vmov_imm:<br>
+; CHECK-XO-FLOAT: movs [[REG:r[0-9]+]], #0<br>
+; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]<br>
+; CHECK-XO-FLOAT-NOT: vldr<br>
   ret float 0.0<br>
 }<br>
<br>
@@ -25,6 +52,14 @@ define arm_aapcs_vfpcc float @test_vmvn_<br>
<br>
 ; CHECK-NONEON-LABEL: test_vmvn_imm:<br>
 ; CHECK-NONEON: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-NO-XO-LABEL: test_vmvn_imm:<br>
+; CHECK-NO-XO: vldr s0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-FLOAT-LABEL: test_vmvn_imm:<br>
+; CHECK-XO-FLOAT: mvn [[REG:r[0-9]+]], #-1342177280<br>
+; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]<br>
+; CHECK-XO-FLOAT-NOT: vldr<br>
   ret float <a href="tel:(858)%20993-4080" value="+18589934080" target="_blank">8589934080</a>.0<br>
 }<br>
<br>
@@ -44,6 +79,19 @@ define arm_aapcs_vfpcc double @test_vmov<br>
<br>
 ; CHECK-NONEON-LABEL: test_vmov_double_imm:<br>
 ; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-NO-XO-LABEL: test_vmov_double_imm:<br>
+; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-DOUBLE-LABEL: test_vmov_double_imm:<br>
+; CHECK-XO-DOUBLE: movs [[REG:r[0-9]+]], #0<br>
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]]<br>
+; CHECK-XO-DOUBLE-NOT: vldr<br>
+<br>
+; CHECK-XO-DOUBLE-BE-LABEL: test_vmov_double_imm:<br>
+; CHECK-XO-DOUBLE-BE: movs [[REG:r[0-9]+]], #0<br>
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG]], [[REG]]<br>
+; CHECK-XO-DOUBLE-NOT: vldr<br>
   ret double 0.0<br>
 }<br>
<br>
@@ -53,6 +101,19 @@ define arm_aapcs_vfpcc double @test_vmvn<br>
<br>
 ; CHECK-NONEON-LABEL: test_vmvn_double_imm:<br>
 ; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-NO-XO-LABEL: test_vmvn_double_imm:<br>
+; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-DOUBLE-LABEL: test_vmvn_double_imm:<br>
+; CHECK-XO-DOUBLE: mvn [[REG:r[0-9]+]], #-1342177280<br>
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG]], [[REG]]<br>
+; CHECK-XO-DOUBLE-NOT: vldr<br>
+<br>
+; CHECK-XO-DOUBLE-BE-LABEL: test_vmvn_double_imm:<br>
+; CHECK-XO-DOUBLE-BE: mvn [[REG:r[0-9]+]], #-1342177280<br>
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG]], [[REG]]<br>
+; CHECK-XO-DOUBLE-BE-NOT: vldr<br>
   ret double 0x4fffffff4fffffff<br>
 }<br>
<br>
@@ -64,5 +125,54 @@ define arm_aapcs_vfpcc double @test_notv<br>
<br>
 ; CHECK-NONEON-LABEL: test_notvmvn_double_imm:<br>
 ; CHECK-NONEON: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-NO-XO-LABEL: test_notvmvn_double_imm:<br>
+; CHECK-NO-XO: vldr d0, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-DOUBLE-LABEL: test_notvmvn_double_imm:<br>
+; CHECK-XO-DOUBLE: mvn [[REG1:r[0-9]+]], #-1342177280<br>
+; CHECK-XO-DOUBLE: mov.w [[REG2:r[0-9]+]], #-1<br>
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]<br>
+; CHECK-XO-DOUBLE-NOT: vldr<br>
+<br>
+; CHECK-XO-DOUBLE-BE-LABEL: test_notvmvn_double_imm:<br>
+; CHECK-XO-DOUBLE-BE: mov.w [[REG1:r[0-9]+]], #-1<br>
+; CHECK-XO-DOUBLE-BE: mvn [[REG2:r[0-9]+]], #-1342177280<br>
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]<br>
+; CHECK-XO-DOUBLE-BE-NOT: vldr<br>
   ret double 0x4fffffffffffffff<br>
 }<br>
+<br>
+define arm_aapcs_vfpcc float @lower_const_f32_xo() {<br>
+; CHECK-NO-XO-LABEL: lower_const_f32_xo<br>
+; CHECK-NO-XO: vldr {{s[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-FLOAT-LABEL: lower_const_f32_xo<br>
+; CHECK-XO-FLOAT: movw [[REG:r[0-9]+]], #29884<br>
+; CHECK-XO-FLOAT: movt [[REG]], #16083<br>
+; CHECK-XO-FLOAT: vmov {{s[0-9]+}}, [[REG]]<br>
+; CHECK-XO-FLOAT-NOT: vldr<br>
+  ret float 0x3FDA6E9780000000<br>
+}<br>
+<br>
+define arm_aapcs_vfpcc double @lower_const_f64_xo() {<br>
+; CHECK-NO-XO-LABEL: lower_const_f64_xo<br>
+; CHECK-NO-XO: vldr {{d[0-9]+}}, {{.?LCPI[0-9]+_[0-9]+}}<br>
+<br>
+; CHECK-XO-DOUBLE-LABEL: lower_const_f64_xo<br>
+; CHECK-XO-DOUBLE: movw [[REG1:r[0-9]+]], #6291<br>
+; CHECK-XO-DOUBLE: movw [[REG2:r[0-9]+]], #27263<br>
+; CHECK-XO-DOUBLE: movt [[REG1]], #16340<br>
+; CHECK-XO-DOUBLE: movt [[REG2]], #29884<br>
+; CHECK-XO-DOUBLE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]<br>
+; CHECK-XO-DOUBLE-NOT: vldr<br>
+<br>
+; CHECK-XO-DOUBLE-BE-LABEL: lower_const_f64_xo<br>
+; CHECK-XO-DOUBLE-BE: movw [[REG1:r[0-9]+]], #27263<br>
+; CHECK-XO-DOUBLE-BE: movw [[REG2:r[0-9]+]], #6291<br>
+; CHECK-XO-DOUBLE-BE: movt [[REG1]], #29884<br>
+; CHECK-XO-DOUBLE-BE: movt [[REG2]], #16340<br>
+; CHECK-XO-DOUBLE-BE: vmov {{d[0-9]+}}, [[REG2]], [[REG1]]<br>
+; CHECK-XO-DOUBLE-BE-NOT: vldr<br>
+  ret double 3.140000e-01<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM/execute-only-big-stack-frame.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only-big-stack-frame.ll?rev=289784&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only-big-stack-frame.ll?rev=289784&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/execute-only-big-stack-frame.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM/execute-only-big-stack-frame.ll Thu Dec 15 01:59:08 2016<br>
@@ -0,0 +1,46 @@<br>
+; RUN: llc < %s -mtriple=thumbv7m -arm-execute-only -O0 %s -o - \<br>
+; RUN:  | FileCheck --check-prefix=CHECK-SUBW-ADDW %s<br>
+; RUN: llc < %s -mtriple=thumbv8m.base -arm-execute-only -O0 %s -o - \<br>
+; RUN:  | FileCheck --check-prefix=CHECK-MOVW-MOVT-ADD %s<br>
+; RUN: llc < %s -mtriple=thumbv8m.main -arm-execute-only -O0 %s -o - \<br>
+; RUN:  | FileCheck --check-prefix=CHECK-SUBW-ADDW %s<br>
+<br>
+define i8 @test_big_stack_frame() {<br>
+; CHECK-SUBW-ADDW-LABEL: test_big_stack_frame:<br>
+; CHECK-SUBW-ADDW-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-SUBW-ADDW:       sub.w sp, sp, #65536<br>
+; CHECK-SUBW-ADDW-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-SUBW-ADDW:       add.w [[REG1:r[0-9]+]], sp, #255<br>
+; CHECK-SUBW-ADDW:       add.w {{r[0-9]+}}, [[REG1]], #65280<br>
+; CHECK-SUBW-ADDW-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-SUBW-ADDW:       add.w lr, sp, #61440<br>
+; CHECK-SUBW-ADDW-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-SUBW-ADDW:       add.w sp, sp, #65536<br>
+<br>
+; CHECK-MOVW-MOVT-ADD-LABEL: test_big_stack_frame:<br>
+; CHECK-MOVW-MOVT-ADD-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-MOVW-MOVT-ADD:       movw [[REG1:r[0-9]+]], #0<br>
+; CHECK-MOVW-MOVT-ADD:       movt [[REG1]], #65535<br>
+; CHECK-MOVW-MOVT-ADD:       add sp, [[REG1]]<br>
+; CHECK-MOVW-MOVT-ADD-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-MOVW-MOVT-ADD:       movw [[REG2:r[0-9]+]], #65532<br>
+; CHECK-MOVW-MOVT-ADD:       movt [[REG2]], #0<br>
+; CHECK-MOVW-MOVT-ADD:       add [[REG2]], sp<br>
+; CHECK-MOVW-MOVT-ADD-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-MOVW-MOVT-ADD:       movw [[REG3:r[0-9]+]], #65532<br>
+; CHECK-MOVW-MOVT-ADD:       movt [[REG3]], #0<br>
+; CHECK-MOVW-MOVT-ADD:       add [[REG3]], sp<br>
+; CHECK-MOVW-MOVT-ADD-NOT:   ldr {{r[0-9]+}}, .{{.*}}<br>
+; CHECK-MOVW-MOVT-ADD:       movw [[REG4:r[0-9]+]], #0<br>
+; CHECK-MOVW-MOVT-ADD:       movt [[REG4]], #1<br>
+; CHECK-MOVW-MOVT-ADD:       add sp, [[REG4]]<br>
+<br>
+entry:<br>
+  %s1 = alloca i8<br>
+  %buffer = alloca [65528 x i8], align 1<br>
+  call void @foo(i8* %s1)<br>
+  %load = load i8, i8* %s1<br>
+  ret i8 %load<br>
+}<br>
+<br>
+declare void @foo(i8*)<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM/execute-only-section.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only-section.ll?rev=289784&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only-section.ll?rev=289784&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/execute-only-section.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM/execute-only-section.ll Thu Dec 15 01:59:08 2016<br>
@@ -0,0 +1,23 @@<br>
+; RUN: llc < %s -mtriple=thumbv7m -arm-execute-only %s -o - | FileCheck %s<br>
+; RUN: llc < %s -mtriple=thumbv8m.base -arm-execute-only %s -o - | FileCheck %s<br>
+; RUN: llc < %s -mtriple=thumbv8m.main -arm-execute-only %s -o - | FileCheck %s<br>
+<br>
+; CHECK:     .section .text,"axy",%progbits,unique,0<br>
+; CHECK-NOT: .section<br>
+; CHECK-NOT: .text<br>
+; CHECK:     .globl test_SectionForGlobal<br>
+; CHECK:     .type test_SectionForGlobal,%function<br>
+define void @test_SectionForGlobal() {<br>
+entry:<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK:     .section .test,"axy",%progbits<br>
+; CHECK-NOT: .section<br>
+; CHECK-NOT: .text<br>
+; CHECK:     .globl test_ExplicitSectionForGlobal<br>
+; CHECK:     .type test_ExplicitSectionForGlobal,%function<br>
+define void @test_ExplicitSectionForGlobal() section ".test" {<br>
+entry:<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/ARM/execute-only.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only.ll?rev=289784&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/execute-only.ll?rev=289784&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/execute-only.ll (added)<br>
+++ llvm/trunk/test/CodeGen/ARM/execute-only.ll Thu Dec 15 01:59:08 2016<br>
@@ -0,0 +1,82 @@<br>
+; RUN: llc -mtriple=thumbv8m.base-eabi -arm-execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2BASE %s<br>
+; RUN: llc -mtriple=thumbv7m-eabi      -arm-execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2 %s<br>
+; RUN: llc -mtriple=thumbv8m.main-eabi -arm-execute-only %s -o - | FileCheck --check-prefix=CHECK --check-prefix=CHECK-T2 %s<br>
+<br>
+@var = global i32 0<br>
+<br>
+define i32 @global() minsize {<br>
+; CHECK-LABEL: global:<br>
+; CHECK: movw [[GLOBDEST:r[0-9]+]], :lower16:var<br>
+; CHECK: movt [[GLOBDEST]], :upper16:var<br>
+<br>
+  %val = load i32, i32* @var<br>
+  ret i32 %val<br>
+}<br>
+<br>
+define i32 @jump_table(i32 %c, i32 %a, i32 %b) #0 {<br>
+; CHECK-LABEL: jump_table:<br>
+; CHECK-T2: adr.w   [[REG_JT:r[0-9]+]], .LJTI1_0<br>
+; CHECK-T2: add.w   [[REG_ENTRY:r[0-9]+]], [[REG_JT]], {{r[0-9]+}}, lsl #2<br>
+; CHECK-T2: mov     pc, [[REG_ENTRY]]<br>
+<br>
+; CHECK-T2BASE: lsls    [[REG_OFFSET:r[0-9]+]], {{r[0-9]+}}, #2<br>
+; CHECK-T2BASE: adr     [[REG_JT:r[0-9]+]], .LJTI1_0<br>
+; CHECK-T2BASE: adds    [[REG_ENTRY:r[0-9]+]], [[REG_OFFSET]], [[REG_JT]]<br>
+; CHECK-T2BASE: mov     pc, [[REG_ENTRY]]<br>
+<br>
+; CHECK-LABEL: .LJTI1_0:<br>
+; CHECK-NEXT: b.w<br>
+; CHECK-NEXT: b.w<br>
+; CHECK-NEXT: b.w<br>
+; CHECK-NEXT: b.w<br>
+; CHECK-NEXT: b.w<br>
+; CHECK-NEXT: b.w<br>
+<br>
+entry:<br>
+  switch i32 %c, label %return [<br>
+    i32 1, label %<a href="http://sw.bb" rel="noreferrer" target="_blank">sw.bb</a><br>
+    i32 2, label %sw.bb1<br>
+    i32 3, label %sw.bb3<br>
+    i32 4, label %sw.bb4<br>
+    i32 5, label %sw.bb6<br>
+    i32 6, label %sw.bb8<br>
+  ]<br>
+<br>
+<a href="http://sw.bb" rel="noreferrer" target="_blank">sw.bb</a>:                                            ; preds = %entry<br>
+  %add = add nsw i32 %a, 6<br>
+  br label %return<br>
+<br>
+sw.bb1:                                           ; preds = %entry<br>
+  %add2 = add nsw i32 %a, 4<br>
+  br label %return<br>
+<br>
+sw.bb3:                                           ; preds = %entry<br>
+  %sub = add nsw i32 %a, -3<br>
+  br label %return<br>
+<br>
+sw.bb4:                                           ; preds = %entry<br>
+  %add5 = add nsw i32 %b, 5<br>
+  br label %return<br>
+<br>
+sw.bb6:                                           ; preds = %entry<br>
+  %add7 = add nsw i32 %a, 1<br>
+  br label %return<br>
+<br>
+sw.bb8:                                           ; preds = %entry<br>
+  %add9 = add nsw i32 %a, 2<br>
+  br label %return<br>
+<br>
+return:                                           ; preds = %entry, %sw.bb8, %sw.bb6, %sw.bb4, %sw.bb3, %sw.bb1, %<a href="http://sw.bb" rel="noreferrer" target="_blank">sw.bb</a><br>
+  %retval.0 = phi i32 [ %add9, %sw.bb8 ], [ %add7, %sw.bb6 ], [ %add5, %sw.bb4 ], [ %sub, %sw.bb3 ], [ %add2, %sw.bb1 ], [ %add, %<a href="http://sw.bb" rel="noreferrer" target="_blank">sw.bb</a> ], [ 0, %entry ]<br>
+  ret i32 %retval.0<br>
+}<br>
+<br>
+@.str = private unnamed_addr constant [4 x i8] c"FOO\00", align 1<br>
+<br>
+define hidden i8* @string_literal() {<br>
+entry:<br>
+; CHECK-LABEL: string_literal:<br>
+; CHECK-NOT: .asciz<br>
+; CHECK: .fnend<br>
+    ret i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0)<br>
+}<br>
<br>
Added: llvm/trunk/test/MC/ELF/ARM/execute-only-section.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/ARM/execute-only-section.s?rev=289784&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/ARM/execute-only-section.s?rev=289784&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/MC/ELF/ARM/execute-only-section.s (added)<br>
+++ llvm/trunk/test/MC/ELF/ARM/execute-only-section.s Thu Dec 15 01:59:08 2016<br>
@@ -0,0 +1,44 @@<br>
+// RUN: llvm-mc -filetype=obj -triple thumbv7m-arm-linux-gnu %s -o - \<br>
+// RUN: | llvm-readobj -s -t | FileCheck %s<br>
+<br>
+        .section        .text,"axy",%progbits,unique,0<br>
+        .globl  foo<br>
+        .align  2<br>
+        .type   foo,%function<br>
+        .code   16<br>
+        .thumb_func<br>
+foo:<br>
+        .fnstart<br>
+        bx      lr<br>
+.Lfunc_end0:<br>
+        .size   foo, .Lfunc_end0-foo<br>
+        .fnend<br>
+<br>
+        .section        ".note.GNU-stack","",%progbits<br>
+<br>
+<br>
+// CHECK:      Section {<br>
+// CHECK:        Name: .text (16)<br>
+// CHECK-NEXT:   Type: SHT_PROGBITS (0x1)<br>
+// CHECK-NEXT:   Flags [ (0x6)<br>
+// CHECK-NEXT:     SHF_ALLOC (0x2)<br>
+// CHECK-NEXT:     SHF_EXECINSTR (0x4)<br>
+// CHECK-NEXT:   ]<br>
+// CHECK:        Size: 0<br>
+// CHECK:      }<br>
+<br>
+// CHECK:      Section {<br>
+// CHECK:        Name: .text (16)<br>
+// CHECK-NEXT:   Type: SHT_PROGBITS (0x1)<br>
+// CHECK-NEXT:   Flags [ (0x20000006)<br>
+// CHECK-NEXT:     SHF_ALLOC (0x2)<br>
+// CHECK-NEXT:     SHF_ARM_PURECODE (0x20000000)<br>
+// CHECK-NEXT:     SHF_EXECINSTR (0x4)<br>
+// CHECK-NEXT:   ]<br>
+// CHECK:        Size: 2<br>
+// CHECK:      }<br>
+<br>
+// CHECK: Symbol {<br>
+// CHECK:   Name: foo (22)<br>
+// CHECK:   Section: .text (0x3)<br>
+// CHECK: }<br>
<br>
Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=289784&r1=289783&r2=289784&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=289784&r1=289783&r2=289784&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)<br>
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Thu Dec 15 01:59:08 2016<br>
@@ -1069,6 +1069,10 @@ static const EnumEntry<unsigned> ElfAMDG<br>
   LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_AGENT)<br>
 };<br>
<br>
+static const EnumEntry<unsigned> ElfARMSectionFlags[] = {<br>
+  LLVM_READOBJ_ENUM_ENT(ELF, SHF_ARM_PURECODE)<br>
+};<br>
+<br>
 static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = {<br>
   LLVM_READOBJ_ENUM_ENT(ELF, SHF_HEX_GPREL)<br>
 };<br>
@@ -3596,6 +3600,10 @@ template <class ELFT> void LLVMStyle<ELF<br>
       SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags),<br>
                           std::end(ElfAMDGPUSectionFlags));<br>
       break;<br>
+    case EM_ARM:<br>
+      SectionFlags.insert(SectionFlags.end(), std::begin(ElfARMSectionFlags),<br>
+                          std::end(ElfARMSectionFlags));<br>
+      break;<br>
     case EM_HEXAGON:<br>
       SectionFlags.insert(SectionFlags.end(),<br>
                           std::begin(ElfHexagonSectionFlags),<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div></div>