[llvm] r289784 - [ARM] Implement execute-only support in CodeGen

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 30 19:59:32 PDT 2017


Hi Prakhar,

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.

A couple of concerns, FWIW:

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.
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.

I've gone ahead and updated it thusly:

echristo at athyra ~/s/llvm> git svn dcommit ; cd tools/clang/ ; git svn
dcommit
Committing to https://llvm.org/svn/llvm-project/llvm/trunk ...
M lib/Target/ARM/ARM.td
M lib/Target/ARM/ARMSubtarget.cpp
M lib/Target/ARM/ARMTargetObjectFile.cpp
M lib/Target/ARM/ARMTargetObjectFile.h
M test/CodeGen/ARM/constantfp.ll
M test/CodeGen/ARM/execute-only-big-stack-frame.ll
M test/CodeGen/ARM/execute-only-section.ll
M test/CodeGen/ARM/execute-only.ll
Committed r306927
M test/CodeGen/ARM/execute-only-section.ll
M test/CodeGen/ARM/execute-only.ll
M test/CodeGen/ARM/execute-only-big-stack-frame.ll
M test/CodeGen/ARM/constantfp.ll
M lib/Target/ARM/ARMSubtarget.cpp
M lib/Target/ARM/ARMTargetObjectFile.h
M lib/Target/ARM/ARMTargetObjectFile.cpp
M lib/Target/ARM/ARM.td
r306927 = 3d3e534c24741f26d7cd432488561431d7ad1db1
(refs/remotes/origin/master)
Committing to https://llvm.org/svn/llvm-project/cfe/trunk ...
C test/Driver/arm-execute-only.c => test/CodeGen/arm-execute-only.c
M lib/Driver/ToolChains/Arch/ARM.cpp
M test/Driver/arm-execute-only.c
Committed r306928
M test/Driver/arm-execute-only.c
A test/CodeGen/arm-execute-only.c
M lib/Driver/ToolChains/Arch/ARM.cpp
r306928 = f903f6da7ea5c96325dca9f1b32e0dea845fcca2
(refs/remotes/origin/master)

feel free to take a look for this sort of thing in the future.

Thanks! :)

-eric


On Thu, Dec 15, 2016 at 1:08 AM Prakhar Bahuguna via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

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


More information about the llvm-commits mailing list