diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-07-01 13:22:02 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-07-01 13:22:02 +0000 | 
| commit | 9df3605dea17e84f8183581f6103bd0c79e2a606 (patch) | |
| tree | 70a2f36ce9eb9bb213603cd7f2f120af53fc176f /lib/Target/ARM | |
| parent | 08bbd35a80bf7765fe0d3043f9eb5a2f2786b649 (diff) | |
Diffstat (limited to 'lib/Target/ARM')
| -rw-r--r-- | lib/Target/ARM/ARM.td | 32 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 45 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 15 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMInstrThumb.td | 8 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMInstructionSelector.cpp | 50 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMLegalizerInfo.cpp | 43 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMRegisterBankInfo.cpp | 12 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMRegisterInfo.td | 4 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMSchedule.td | 1 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMScheduleM3.td | 21 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMSubtarget.cpp | 77 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMSubtarget.h | 6 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMTargetMachine.cpp | 138 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMTargetMachine.h | 3 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMTargetObjectFile.cpp | 34 | ||||
| -rw-r--r-- | lib/Target/ARM/ARMTargetObjectFile.h | 2 | ||||
| -rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 2 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 17 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h | 6 | ||||
| -rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h | 83 | 
20 files changed, 335 insertions, 264 deletions
diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index 6f67183df6a1..c40b4450a5b5 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -222,6 +222,13 @@ def FeatureAvoidMOVsShOp : SubtargetFeature<"avoid-movs-shop",  def FeatureHasRetAddrStack : SubtargetFeature<"ret-addr-stack", "HasRetAddrStack", "true",                                       "Has return address stack">; +// Some processors have no branch predictor, which changes the expected cost of +// taking a branch which affects the choice of whether to use predicated +// instructions. +def FeatureHasNoBranchPredictor : SubtargetFeature<"no-branch-predictor", +                                                   "HasBranchPredictor", "false", +                                                   "Has no branch predictor">; +  /// DSP extension.  def FeatureDSP : SubtargetFeature<"dsp", "HasDSP", "true",                                "Supports DSP instructions in ARM and/or Thumb2">; @@ -262,6 +269,10 @@ def FeatureLongCalls : SubtargetFeature<"long-calls", "GenLongCalls", "true",                                          "Generate calls via indirect call "                                          "instructions">; +def FeatureExecuteOnly +    : SubtargetFeature<"execute-only", "GenExecuteOnly", "true", +                       "Enable the generation of execute only code.">; +  def FeatureReserveR9 : SubtargetFeature<"reserve-r9", "ReserveR9", "true",                                          "Reserve R9, making it unavailable as "                                          "GPR">; @@ -540,7 +551,7 @@ def ARMv7s   : Architecture<"armv7s",      "ARMv7a",   [ARMv7a]>;  //  // Dummy CPU, used to target architectures -def : ProcNoItin<"generic",                             []>; +def : ProcessorModel<"generic",     CortexA8Model,      []>;  def : ProcNoItin<"arm8",                                [ARMv4]>;  def : ProcNoItin<"arm810",                              [ARMv4]>; @@ -756,13 +767,19 @@ def : ProcessorModel<"cortex-r8",   CortexA8Model,      [ARMv7r,                                                           FeatureHasSlowFPVMLx,                                                           FeatureAvoidPartialCPSR]>; -def : ProcNoItin<"cortex-m3",                           [ARMv7m, ProcM3]>; -def : ProcNoItin<"sc300",                               [ARMv7m, ProcM3]>; +def : ProcessorModel<"cortex-m3", CortexM3Model,        [ARMv7m, +                                                         ProcM3, +                                                         FeatureHasNoBranchPredictor]>; + +def : ProcessorModel<"sc300",     CortexM3Model,        [ARMv7m, +                                                         ProcM3, +                                                         FeatureHasNoBranchPredictor]>; -def : ProcNoItin<"cortex-m4",                           [ARMv7em, +def : ProcessorModel<"cortex-m4", CortexM3Model,        [ARMv7em,                                                           FeatureVFP4,                                                           FeatureVFPOnlySP, -                                                         FeatureD16]>; +                                                         FeatureD16, +                                                         FeatureHasNoBranchPredictor]>;  def : ProcNoItin<"cortex-m7",                           [ARMv7em,                                                           FeatureFPARMv8, @@ -771,11 +788,12 @@ def : ProcNoItin<"cortex-m7",                           [ARMv7em,  def : ProcNoItin<"cortex-m23",                          [ARMv8mBaseline,                                                           FeatureNoMovt]>; -def : ProcNoItin<"cortex-m33",                          [ARMv8mMainline, +def : ProcessorModel<"cortex-m33", CortexM3Model,       [ARMv8mMainline,                                                           FeatureDSP,                                                           FeatureFPARMv8,                                                           FeatureD16, -                                                         FeatureVFPOnlySP]>; +                                                         FeatureVFPOnlySP, +                                                         FeatureHasNoBranchPredictor]>;  def : ProcNoItin<"cortex-a32",                           [ARMv8a,                                                           FeatureHWDivThumb, diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index e0810c358f2d..1ec6b24b2ed6 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1851,9 +1851,9 @@ isProfitableToIfCvt(MachineBasicBlock &MBB,  }  bool ARMBaseInstrInfo:: -isProfitableToIfCvt(MachineBasicBlock &, +isProfitableToIfCvt(MachineBasicBlock &TBB,                      unsigned TCycles, unsigned TExtra, -                    MachineBasicBlock &, +                    MachineBasicBlock &FBB,                      unsigned FCycles, unsigned FExtra,                      BranchProbability Probability) const {    if (!TCycles) @@ -1863,14 +1863,43 @@ isProfitableToIfCvt(MachineBasicBlock &,    // Here we scale up each component of UnpredCost to avoid precision issue when    // scaling TCycles/FCycles by Probability.    const unsigned ScalingUpFactor = 1024; -  unsigned TUnpredCost = Probability.scale(TCycles * ScalingUpFactor); -  unsigned FUnpredCost = + +  unsigned PredCost = (TCycles + FCycles + TExtra + FExtra) * ScalingUpFactor; +  unsigned UnpredCost; +  if (!Subtarget.hasBranchPredictor()) { +    // When we don't have a branch predictor it's always cheaper to not take a +    // branch than take it, so we have to take that into account. +    unsigned NotTakenBranchCost = 1; +    unsigned TakenBranchCost = Subtarget.getMispredictionPenalty(); +    unsigned TUnpredCycles, FUnpredCycles; +    if (!FCycles) { +      // Triangle: TBB is the fallthrough +      TUnpredCycles = TCycles + NotTakenBranchCost; +      FUnpredCycles = TakenBranchCost; +    } else { +      // Diamond: TBB is the block that is branched to, FBB is the fallthrough +      TUnpredCycles = TCycles + TakenBranchCost; +      FUnpredCycles = FCycles + NotTakenBranchCost; +    } +    // The total cost is the cost of each path scaled by their probabilites +    unsigned TUnpredCost = Probability.scale(TUnpredCycles * ScalingUpFactor); +    unsigned FUnpredCost = Probability.getCompl().scale(FUnpredCycles * ScalingUpFactor); +    UnpredCost = TUnpredCost + FUnpredCost; +    // When predicating assume that the first IT can be folded away but later +    // ones cost one cycle each +    if (Subtarget.isThumb2() && TCycles + FCycles > 4) { +      PredCost += ((TCycles + FCycles - 4) / 4) * ScalingUpFactor; +    } +  } else { +    unsigned TUnpredCost = Probability.scale(TCycles * ScalingUpFactor); +    unsigned FUnpredCost =        Probability.getCompl().scale(FCycles * ScalingUpFactor); -  unsigned UnpredCost = TUnpredCost + FUnpredCost; -  UnpredCost += 1 * ScalingUpFactor; // The branch itself -  UnpredCost += Subtarget.getMispredictionPenalty() * ScalingUpFactor / 10; +    UnpredCost = TUnpredCost + FUnpredCost; +    UnpredCost += 1 * ScalingUpFactor; // The branch itself +    UnpredCost += Subtarget.getMispredictionPenalty() * ScalingUpFactor / 10; +  } -  return (TCycles + FCycles + TExtra + FExtra) * ScalingUpFactor <= UnpredCost; +  return PredCost <= UnpredCost;  }  bool diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 2bcc707e9fc3..e42514acd76f 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -7580,6 +7580,9 @@ static SDValue createGPRPairNode(SelectionDAG &DAG, SDValue V) {    SDValue VHi = DAG.getAnyExtOrTrunc(        DAG.getNode(ISD::SRL, dl, MVT::i64, V, DAG.getConstant(32, dl, MVT::i32)),        dl, MVT::i32); +  bool isBigEndian = DAG.getDataLayout().isBigEndian(); +  if (isBigEndian) +    std::swap (VLo, VHi);    SDValue RegClass =        DAG.getTargetConstant(ARM::GPRPairRegClassID, dl, MVT::i32);    SDValue SubReg0 = DAG.getTargetConstant(ARM::gsub_0, dl, MVT::i32); @@ -7607,10 +7610,14 @@ static void ReplaceCMP_SWAP_64Results(SDNode *N,    MemOp[0] = cast<MemSDNode>(N)->getMemOperand();    cast<MachineSDNode>(CmpSwap)->setMemRefs(MemOp, MemOp + 1); -  Results.push_back(DAG.getTargetExtractSubreg(ARM::gsub_0, SDLoc(N), MVT::i32, -                                               SDValue(CmpSwap, 0))); -  Results.push_back(DAG.getTargetExtractSubreg(ARM::gsub_1, SDLoc(N), MVT::i32, -                                               SDValue(CmpSwap, 0))); +  bool isBigEndian = DAG.getDataLayout().isBigEndian(); + +  Results.push_back( +      DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_1 : ARM::gsub_0, +                                 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0))); +  Results.push_back( +      DAG.getTargetExtractSubreg(isBigEndian ? ARM::gsub_0 : ARM::gsub_1, +                                 SDLoc(N), MVT::i32, SDValue(CmpSwap, 0)));    Results.push_back(SDValue(CmpSwap, 2));  } diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 423f97ccacd6..891a8f482f0a 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -1416,12 +1416,12 @@ def tLEApcrelJT : tPseudoInst<(outs tGPR:$Rd),  let Size = 2, isBranch = 1, isTerminator = 1, isBarrier = 1,      isIndirectBranch = 1 in {  def tTBB_JT : tPseudoInst<(outs), -        (ins tGPR:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>, -        Sched<[WriteBr]>; +        (ins tGPRwithpc:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0, +         IIC_Br, []>, Sched<[WriteBr]>;  def tTBH_JT : tPseudoInst<(outs), -        (ins tGPR:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0, IIC_Br, []>, -        Sched<[WriteBr]>; +        (ins tGPRwithpc:$base, tGPR:$index, i32imm:$jt, i32imm:$pclbl), 0, +         IIC_Br, []>,  Sched<[WriteBr]>;  }  //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMInstructionSelector.cpp b/lib/Target/ARM/ARMInstructionSelector.cpp index 4cb0eca5ee5f..374176d1d737 100644 --- a/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/lib/Target/ARM/ARMInstructionSelector.cpp @@ -46,6 +46,10 @@ private:                    MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,                    const RegisterBankInfo &RBI) const; +  bool selectSelect(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, +                    MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, +                    const RegisterBankInfo &RBI) const; +    const ARMBaseInstrInfo &TII;    const ARMBaseRegisterInfo &TRI;    const ARMBaseTargetMachine &TM; @@ -346,6 +350,50 @@ bool ARMInstructionSelector::selectICmp(MachineInstrBuilder &MIB,    return true;  } +bool ARMInstructionSelector::selectSelect(MachineInstrBuilder &MIB, +                                          const ARMBaseInstrInfo &TII, +                                          MachineRegisterInfo &MRI, +                                          const TargetRegisterInfo &TRI, +                                          const RegisterBankInfo &RBI) const { +  auto &MBB = *MIB->getParent(); +  auto InsertBefore = std::next(MIB->getIterator()); +  auto &DebugLoc = MIB->getDebugLoc(); + +  // Compare the condition to 0. +  auto CondReg = MIB->getOperand(1).getReg(); +  assert(MRI.getType(CondReg).getSizeInBits() == 1 && +         RBI.getRegBank(CondReg, MRI, TRI)->getID() == ARM::GPRRegBankID && +         "Unsupported types for select operation"); +  auto CmpI = BuildMI(MBB, InsertBefore, DebugLoc, TII.get(ARM::CMPri)) +                  .addUse(CondReg) +                  .addImm(0) +                  .add(predOps(ARMCC::AL)); +  if (!constrainSelectedInstRegOperands(*CmpI, TII, TRI, RBI)) +    return false; + +  // Move a value into the result register based on the result of the +  // comparison. +  auto ResReg = MIB->getOperand(0).getReg(); +  auto TrueReg = MIB->getOperand(2).getReg(); +  auto FalseReg = MIB->getOperand(3).getReg(); +  assert(MRI.getType(ResReg) == MRI.getType(TrueReg) && +         MRI.getType(TrueReg) == MRI.getType(FalseReg) && +         MRI.getType(FalseReg).getSizeInBits() == 32 && +         RBI.getRegBank(TrueReg, MRI, TRI)->getID() == ARM::GPRRegBankID && +         RBI.getRegBank(FalseReg, MRI, TRI)->getID() == ARM::GPRRegBankID && +         "Unsupported types for select operation"); +  auto Mov1I = BuildMI(MBB, InsertBefore, DebugLoc, TII.get(ARM::MOVCCr)) +                   .addDef(ResReg) +                   .addUse(TrueReg) +                   .addUse(FalseReg) +                   .add(predOps(ARMCC::EQ, ARM::CPSR)); +  if (!constrainSelectedInstRegOperands(*Mov1I, TII, TRI, RBI)) +    return false; + +  MIB->eraseFromParent(); +  return true; +} +  bool ARMInstructionSelector::select(MachineInstr &I) const {    assert(I.getParent() && "Instruction should be in a basic block!");    assert(I.getParent()->getParent() && "Instruction should be in a function!"); @@ -448,6 +496,8 @@ bool ARMInstructionSelector::select(MachineInstr &I) const {    }    case G_ICMP:      return selectICmp(MIB, TII, MRI, TRI, RBI); +  case G_SELECT: +    return selectSelect(MIB, TII, MRI, TRI, RBI);    case G_GEP:      I.setDesc(TII.get(ARM::ADDrr));      MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); diff --git a/lib/Target/ARM/ARMLegalizerInfo.cpp b/lib/Target/ARM/ARMLegalizerInfo.cpp index 5873c7fb3872..f3e62d09cc30 100644 --- a/lib/Target/ARM/ARMLegalizerInfo.cpp +++ b/lib/Target/ARM/ARMLegalizerInfo.cpp @@ -55,10 +55,7 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {    for (unsigned Op : {G_SDIV, G_UDIV}) {      for (auto Ty : {s8, s16}) -      // FIXME: We need WidenScalar here, but in the case of targets with -      // software division we'll also need Libcall afterwards. Treat as Custom -      // until we have better support for chaining legalization actions. -      setAction({Op, Ty}, Custom); +      setAction({Op, Ty}, WidenScalar);      if (ST.hasDivideInARMMode())        setAction({Op, s32}, Legal);      else @@ -84,6 +81,10 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {    setAction({G_GEP, p0}, Legal);    setAction({G_GEP, 1, s32}, Legal); +  setAction({G_SELECT, s32}, Legal); +  setAction({G_SELECT, p0}, Legal); +  setAction({G_SELECT, 1, s1}, Legal); +    setAction({G_CONSTANT, s32}, Legal);    setAction({G_ICMP, s1}, Legal); @@ -118,40 +119,6 @@ bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI,    switch (MI.getOpcode()) {    default:      return false; -  case G_SDIV: -  case G_UDIV: { -    LLT Ty = MRI.getType(MI.getOperand(0).getReg()); -    if (Ty != LLT::scalar(16) && Ty != LLT::scalar(8)) -      return false; - -    // We need to widen to 32 bits and then maybe, if the target requires, -    // transform into a libcall. -    LegalizerHelper Helper(MIRBuilder.getMF()); - -    MachineInstr *NewMI = nullptr; -    Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) { -      // Store the new, 32-bit div instruction. -      if (MI->getOpcode() == G_SDIV || MI->getOpcode() == G_UDIV) -        NewMI = MI; -    }); - -    auto Result = Helper.widenScalar(MI, 0, LLT::scalar(32)); -    Helper.MIRBuilder.stopRecordingInsertions(); -    if (Result == LegalizerHelper::UnableToLegalize) { -      return false; -    } -    assert(NewMI && "Couldn't find widened instruction"); -    assert((NewMI->getOpcode() == G_SDIV || NewMI->getOpcode() == G_UDIV) && -           "Unexpected widened instruction"); -    assert(MRI.getType(NewMI->getOperand(0).getReg()).getSizeInBits() == 32 && -           "Unexpected type for the widened instruction"); - -    Result = Helper.legalizeInstrStep(*NewMI); -    if (Result == LegalizerHelper::UnableToLegalize) { -      return false; -    } -    return true; -  }    case G_SREM:    case G_UREM: {      unsigned OriginalResult = MI.getOperand(0).getReg(); diff --git a/lib/Target/ARM/ARMRegisterBankInfo.cpp b/lib/Target/ARM/ARMRegisterBankInfo.cpp index 2350d0c6ef69..11fb81a4f9fe 100644 --- a/lib/Target/ARM/ARMRegisterBankInfo.cpp +++ b/lib/Target/ARM/ARMRegisterBankInfo.cpp @@ -255,6 +255,18 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {      OperandsMapping =          getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], nullptr});      break; +  case G_SELECT: { +    LLT Ty2 = MRI.getType(MI.getOperand(1).getReg()); +    (void)Ty2; +    assert(Ty.getSizeInBits() == 32 && "Unsupported size for G_SELECT"); +    assert(Ty2.getSizeInBits() == 1 && "Unsupported size for G_SELECT"); +    OperandsMapping = +        getOperandsMapping({&ARM::ValueMappings[ARM::GPR3OpsIdx], +                            &ARM::ValueMappings[ARM::GPR3OpsIdx], +                            &ARM::ValueMappings[ARM::GPR3OpsIdx], +                            &ARM::ValueMappings[ARM::GPR3OpsIdx]}); +    break; +  }    case G_ICMP: {      LLT Ty2 = MRI.getType(MI.getOperand(2).getReg());      (void)Ty2; diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 02cbfb1fa9f1..b10583bc7983 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -245,6 +245,10 @@ def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {  // the general GPR register class above (MOV, e.g.)  def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)>; +// Thumb registers R0-R7 and the PC. Some instructions like TBB or THH allow +// the PC to be used as a destination operand as well. +def tGPRwithpc : RegisterClass<"ARM", [i32], 32, (add tGPR, PC)>; +  // The high registers in thumb mode, R8-R15.  def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)>; diff --git a/lib/Target/ARM/ARMSchedule.td b/lib/Target/ARM/ARMSchedule.td index 1c7902520f2d..53e012f13ee2 100644 --- a/lib/Target/ARM/ARMSchedule.td +++ b/lib/Target/ARM/ARMSchedule.td @@ -424,3 +424,4 @@ include "ARMScheduleA9.td"  include "ARMScheduleSwift.td"  include "ARMScheduleR52.td"  include "ARMScheduleA57.td" +include "ARMScheduleM3.td" diff --git a/lib/Target/ARM/ARMScheduleM3.td b/lib/Target/ARM/ARMScheduleM3.td new file mode 100644 index 000000000000..93f8299f9bd0 --- /dev/null +++ b/lib/Target/ARM/ARMScheduleM3.td @@ -0,0 +1,21 @@ +//=- ARMScheduleM3.td - ARM Cortex-M3 Scheduling Definitions -*- tablegen -*-=// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the machine model for the ARM Cortex-M3 processor. +// +//===----------------------------------------------------------------------===// + +def CortexM3Model : SchedMachineModel { +  let IssueWidth        = 1; // Only IT can be dual-issued, so assume single-issue +  let MicroOpBufferSize = 0; // In-order +  let LoadLatency       = 2; // Latency when not pipelined, not pc-relative +  let MispredictPenalty = 2; // Best case branch taken cost + +  let CompleteModel = 0; +} diff --git a/lib/Target/ARM/ARMSubtarget.cpp b/lib/Target/ARM/ARMSubtarget.cpp index d9d0c27c6304..2c42a1336166 100644 --- a/lib/Target/ARM/ARMSubtarget.cpp +++ b/lib/Target/ARM/ARMSubtarget.cpp @@ -11,6 +11,13 @@  //  //===----------------------------------------------------------------------===// +#include "ARM.h" + +#ifdef LLVM_BUILD_GLOBAL_ISEL +#include "ARMCallLowering.h" +#include "ARMLegalizerInfo.h" +#include "ARMRegisterBankInfo.h" +#endif  #include "ARMSubtarget.h"  #include "ARMFrameLowering.h"  #include "ARMInstrInfo.h" @@ -23,6 +30,13 @@  #include "llvm/ADT/StringRef.h"  #include "llvm/ADT/Triple.h"  #include "llvm/ADT/Twine.h" +#ifdef LLVM_BUILD_GLOBAL_ISEL +#include "llvm/CodeGen/GlobalISel/GISelAccessor.h" +#include "llvm/CodeGen/GlobalISel/IRTranslator.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelect.h" +#include "llvm/CodeGen/GlobalISel/Legalizer.h" +#include "llvm/CodeGen/GlobalISel/RegBankSelect.h" +#endif  #include "llvm/CodeGen/MachineFunction.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/GlobalValue.h" @@ -78,11 +92,6 @@ ARMSubtarget &ARMSubtarget::initializeSubtargetDependencies(StringRef CPU,    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); @@ -92,13 +101,41 @@ ARMFrameLowering *ARMSubtarget::initializeFrameLowering(StringRef CPU,    return new ARMFrameLowering(STI);  } +#ifdef LLVM_BUILD_GLOBAL_ISEL +namespace { + +struct ARMGISelActualAccessor : public GISelAccessor { +  std::unique_ptr<CallLowering> CallLoweringInfo; +  std::unique_ptr<InstructionSelector> InstSelector; +  std::unique_ptr<LegalizerInfo> Legalizer; +  std::unique_ptr<RegisterBankInfo> RegBankInfo; + +  const CallLowering *getCallLowering() const override { +    return CallLoweringInfo.get(); +  } + +  const InstructionSelector *getInstructionSelector() const override { +    return InstSelector.get(); +  } + +  const LegalizerInfo *getLegalizerInfo() const override { +    return Legalizer.get(); +  } + +  const RegisterBankInfo *getRegBankInfo() const override { +    return RegBankInfo.get(); +  } +}; + +} // end anonymous namespace +#endif +  ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,                             const std::string &FS,                             const ARMBaseTargetMachine &TM, bool IsLittle)      : ARMGenSubtargetInfo(TT, CPU, FS), UseMulOps(UseFusedMulOps), -      GenExecuteOnly(EnableExecuteOnly), CPUString(CPU), IsLittle(IsLittle), -      TargetTriple(TT), Options(TM.Options), TM(TM), -      FrameLowering(initializeFrameLowering(CPU, FS)), +      CPUString(CPU), IsLittle(IsLittle), TargetTriple(TT), Options(TM.Options), +      TM(TM), FrameLowering(initializeFrameLowering(CPU, FS)),        // At this point initializeSubtargetDependencies has been called so        // we can query directly.        InstrInfo(isThumb1Only() @@ -106,7 +143,29 @@ ARMSubtarget::ARMSubtarget(const Triple &TT, const std::string &CPU,                      : !isThumb()                            ? (ARMBaseInstrInfo *)new ARMInstrInfo(*this)                            : (ARMBaseInstrInfo *)new Thumb2InstrInfo(*this)), -      TLInfo(TM, *this) {} +      TLInfo(TM, *this) { +  assert((isThumb() || hasARMOps()) && +         "Target must either be thumb or support ARM operations!"); + +#ifndef LLVM_BUILD_GLOBAL_ISEL +  GISelAccessor *GISel = new GISelAccessor(); +#else +  ARMGISelActualAccessor *GISel = new ARMGISelActualAccessor(); +  GISel->CallLoweringInfo.reset(new ARMCallLowering(*getTargetLowering())); +  GISel->Legalizer.reset(new ARMLegalizerInfo(*this)); + +  auto *RBI = new ARMRegisterBankInfo(*getRegisterInfo()); + +  // FIXME: At this point, we can't rely on Subtarget having RBI. +  // It's awkward to mix passing RBI and the Subtarget; should we pass +  // TII/TRI as well? +  GISel->InstSelector.reset(createARMInstructionSelector( +      *static_cast<const ARMBaseTargetMachine *>(&TM), *this, *RBI)); + +  GISel->RegBankInfo.reset(RBI); +#endif +  setGISelAccessor(*GISel); +}  const CallLowering *ARMSubtarget::getCallLowering() const {    assert(GISel && "Access to GlobalISel APIs not set"); diff --git a/lib/Target/ARM/ARMSubtarget.h b/lib/Target/ARM/ARMSubtarget.h index d890d0fa777e..e15b17512c96 100644 --- a/lib/Target/ARM/ARMSubtarget.h +++ b/lib/Target/ARM/ARMSubtarget.h @@ -246,6 +246,11 @@ protected:    /// avoid issue "normal" call instructions to callees which do not return.    bool HasRetAddrStack = false; +  /// HasBranchPredictor - True if the subtarget has a branch predictor. Having +  /// a branch predictor or not changes the expected cost of taking a branch +  /// which affects the choice of whether to use predicated instructions. +  bool HasBranchPredictor = true; +    /// HasMPExtension - True if the subtarget supports Multiprocessing    /// extension (ARMv7 only).    bool HasMPExtension = false; @@ -554,6 +559,7 @@ public:    bool cheapPredicableCPSRDef() const { return CheapPredicableCPSRDef; }    bool avoidMOVsShifterOperand() const { return AvoidMOVsShifterOperand; }    bool hasRetAddrStack() const { return HasRetAddrStack; } +  bool hasBranchPredictor() const { return HasBranchPredictor; }    bool hasMPExtension() const { return HasMPExtension; }    bool hasDSP() const { return HasDSP; }    bool useNaClTrap() const { return UseNaClTrap; } diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index eb71e557ec91..c323a1d368de 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -11,11 +11,6 @@  //===----------------------------------------------------------------------===//  #include "ARM.h" -#include "ARMCallLowering.h" -#include "ARMLegalizerInfo.h" -#ifdef LLVM_BUILD_GLOBAL_ISEL -#include "ARMRegisterBankInfo.h" -#endif  #include "ARMSubtarget.h"  #include "ARMMacroFusion.h"  #include "ARMTargetMachine.h" @@ -29,7 +24,6 @@  #include "llvm/Analysis/TargetTransformInfo.h"  #include "llvm/CodeGen/ExecutionDepsFix.h"  #include "llvm/CodeGen/GlobalISel/CallLowering.h" -#include "llvm/CodeGen/GlobalISel/GISelAccessor.h"  #include "llvm/CodeGen/GlobalISel/IRTranslator.h"  #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"  #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" @@ -110,60 +104,20 @@ static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {  static ARMBaseTargetMachine::ARMABI  computeTargetABI(const Triple &TT, StringRef CPU,                   const TargetOptions &Options) { -  if (Options.MCOptions.getABIName() == "aapcs16") +  StringRef ABIName = Options.MCOptions.getABIName(); + +  if (ABIName.empty()) +    ABIName = ARM::computeDefaultTargetABI(TT, CPU); + +  if (ABIName == "aapcs16")      return ARMBaseTargetMachine::ARM_ABI_AAPCS16; -  else if (Options.MCOptions.getABIName().startswith("aapcs")) +  else if (ABIName.startswith("aapcs"))      return ARMBaseTargetMachine::ARM_ABI_AAPCS; -  else if (Options.MCOptions.getABIName().startswith("apcs")) +  else if (ABIName.startswith("apcs"))      return ARMBaseTargetMachine::ARM_ABI_APCS; -  assert(Options.MCOptions.getABIName().empty() && -         "Unknown target-abi option!"); - -  ARMBaseTargetMachine::ARMABI TargetABI = -      ARMBaseTargetMachine::ARM_ABI_UNKNOWN; - -  unsigned ArchKind = ARM::parseCPUArch(CPU); -  StringRef ArchName = ARM::getArchName(ArchKind); -  // FIXME: This is duplicated code from the front end and should be unified. -  if (TT.isOSBinFormatMachO()) { -    if (TT.getEnvironment() == Triple::EABI || -        (TT.getOS() == Triple::UnknownOS && TT.isOSBinFormatMachO()) || -        ARM::parseArchProfile(ArchName) == ARM::PK_M) { -      TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; -    } else if (TT.isWatchABI()) { -      TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS16; -    } else { -      TargetABI = ARMBaseTargetMachine::ARM_ABI_APCS; -    } -  } else if (TT.isOSWindows()) { -    // FIXME: this is invalid for WindowsCE -    TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; -  } else { -    // Select the default based on the platform. -    switch (TT.getEnvironment()) { -    case Triple::Android: -    case Triple::GNUEABI: -    case Triple::GNUEABIHF: -    case Triple::MuslEABI: -    case Triple::MuslEABIHF: -    case Triple::EABIHF: -    case Triple::EABI: -      TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; -      break; -    case Triple::GNU: -      TargetABI = ARMBaseTargetMachine::ARM_ABI_APCS; -      break; -    default: -      if (TT.isOSNetBSD()) -        TargetABI = ARMBaseTargetMachine::ARM_ABI_APCS; -      else -        TargetABI = ARMBaseTargetMachine::ARM_ABI_AAPCS; -      break; -    } -  } - -  return TargetABI; +  llvm_unreachable("Unhandled/unknown ABI Name!"); +  return ARMBaseTargetMachine::ARM_ABI_UNKNOWN;  }  static std::string computeDataLayout(const Triple &TT, StringRef CPU, @@ -248,61 +202,39 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT,                          CPU, FS, Options, getEffectiveRelocModel(TT, RM), CM,                          OL),        TargetABI(computeTargetABI(TT, CPU, Options)), -      TLOF(createTLOF(getTargetTriple())), -      Subtarget(TT, CPU, FS, *this, isLittle), isLittle(isLittle) { +      TLOF(createTLOF(getTargetTriple())), isLittle(isLittle) {    // Default to triple-appropriate float ABI -  if (Options.FloatABIType == FloatABI::Default) -    this->Options.FloatABIType = -        Subtarget.isTargetHardFloat() ? FloatABI::Hard : FloatABI::Soft; +  if (Options.FloatABIType == FloatABI::Default) { +    if (TargetTriple.getEnvironment() == Triple::GNUEABIHF || +        TargetTriple.getEnvironment() == Triple::MuslEABIHF || +        TargetTriple.getEnvironment() == Triple::EABIHF || +        TargetTriple.isOSWindows() || +        TargetABI == ARMBaseTargetMachine::ARM_ABI_AAPCS16) +      this->Options.FloatABIType = FloatABI::Hard; +    else +      this->Options.FloatABIType = FloatABI::Soft; +  }    // Default to triple-appropriate EABI    if (Options.EABIVersion == EABI::Default ||        Options.EABIVersion == EABI::Unknown) {      // musl is compatible with glibc with regard to EABI version -    if (Subtarget.isTargetGNUAEABI() || Subtarget.isTargetMuslAEABI()) +    if ((TargetTriple.getEnvironment() == Triple::GNUEABI || +	 TargetTriple.getEnvironment() == Triple::GNUEABIHF || +	 TargetTriple.getEnvironment() == Triple::MuslEABI || +	 TargetTriple.getEnvironment() == Triple::MuslEABIHF) && +	!(TargetTriple.isOSWindows() || TargetTriple.isOSDarwin()))        this->Options.EABIVersion = EABI::GNU;      else        this->Options.EABIVersion = EABI::EABI5;    }    initAsmInfo(); -  if (!Subtarget.isThumb() && !Subtarget.hasARMOps()) -    report_fatal_error("CPU: '" + Subtarget.getCPUString() + "' does not " -                       "support ARM mode execution!");  }  ARMBaseTargetMachine::~ARMBaseTargetMachine() = default; -#ifdef LLVM_BUILD_GLOBAL_ISEL -namespace { - -struct ARMGISelActualAccessor : public GISelAccessor { -  std::unique_ptr<CallLowering> CallLoweringInfo; -  std::unique_ptr<InstructionSelector> InstSelector; -  std::unique_ptr<LegalizerInfo> Legalizer; -  std::unique_ptr<RegisterBankInfo> RegBankInfo; - -  const CallLowering *getCallLowering() const override { -    return CallLoweringInfo.get(); -  } - -  const InstructionSelector *getInstructionSelector() const override { -    return InstSelector.get(); -  } - -  const LegalizerInfo *getLegalizerInfo() const override { -    return Legalizer.get(); -  } - -  const RegisterBankInfo *getRegBankInfo() const override { -    return RegBankInfo.get(); -  } -}; - -} // end anonymous namespace -#endif -  const ARMSubtarget *  ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {    Attribute CPUAttr = F.getFnAttribute("target-cpu"); @@ -334,24 +266,6 @@ ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {      // function that reside in TargetOptions.      resetTargetOptions(F);      I = llvm::make_unique<ARMSubtarget>(TargetTriple, CPU, FS, *this, isLittle); - -#ifndef LLVM_BUILD_GLOBAL_ISEL -    GISelAccessor *GISel = new GISelAccessor(); -#else -    ARMGISelActualAccessor *GISel = new ARMGISelActualAccessor(); -    GISel->CallLoweringInfo.reset(new ARMCallLowering(*I->getTargetLowering())); -    GISel->Legalizer.reset(new ARMLegalizerInfo(*I)); - -    auto *RBI = new ARMRegisterBankInfo(*I->getRegisterInfo()); - -    // FIXME: At this point, we can't rely on Subtarget having RBI. -    // It's awkward to mix passing RBI and the Subtarget; should we pass -    // TII/TRI as well? -    GISel->InstSelector.reset(createARMInstructionSelector(*this, *I, *RBI)); - -    GISel->RegBankInfo.reset(RBI); -#endif -    I->setGISelAccessor(*GISel);    }    return I.get();  } diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h index 2fcee73228fe..f41da3e8e223 100644 --- a/lib/Target/ARM/ARMTargetMachine.h +++ b/lib/Target/ARM/ARMTargetMachine.h @@ -36,7 +36,6 @@ public:  protected:    std::unique_ptr<TargetLoweringObjectFile> TLOF; -  ARMSubtarget Subtarget;    bool isLittle;    mutable StringMap<std::unique_ptr<ARMSubtarget>> SubtargetMap; @@ -47,8 +46,8 @@ public:                         CodeGenOpt::Level OL, bool isLittle);    ~ARMBaseTargetMachine() override; -  const ARMSubtarget *getSubtargetImpl() const { return &Subtarget; }    const ARMSubtarget *getSubtargetImpl(const Function &F) const override; +  const ARMSubtarget *getSubtargetImpl() const = delete;    bool isLittleEndian() const { return isLittle; }    /// \brief Get the TargetIRAnalysis for this target. diff --git a/lib/Target/ARM/ARMTargetObjectFile.cpp b/lib/Target/ARM/ARMTargetObjectFile.cpp index a5b27abeb27f..88bab64ffaf2 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -32,7 +32,7 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,                                          const TargetMachine &TM) {    const ARMBaseTargetMachine &ARM_TM = static_cast<const ARMBaseTargetMachine &>(TM);    bool isAAPCS_ABI = ARM_TM.TargetABI == ARMBaseTargetMachine::ARMABI::ARM_ABI_AAPCS; -  genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly(); +  //  genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly();    TargetLoweringObjectFileELF::Initialize(Ctx, TM);    InitializeELF(isAAPCS_ABI); @@ -43,16 +43,6 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,    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( @@ -74,21 +64,27 @@ getDebugThreadLocalSymbol(const MCSymbol *Sym) const {                                   getContext());  } -MCSection * -ARMElfTargetObjectFile::getExplicitSectionGlobal(const GlobalObject *GO, -                                                 SectionKind SK, const TargetMachine &TM) const { +static bool isExecuteOnlyFunction(const GlobalObject *GO, SectionKind SK, +                                  const TargetMachine &TM) { +  if (const Function *F = dyn_cast<Function>(GO)) +    if (TM.getSubtarget<ARMSubtarget>(*F).genExecuteOnly() && SK.isText()) +      return true; +  return false; +} + +MCSection *ARMElfTargetObjectFile::getExplicitSectionGlobal( +    const GlobalObject *GO, SectionKind SK, const TargetMachine &TM) const {    // Set execute-only access for the explicit section -  if (genExecuteOnly && SK.isText()) +  if (isExecuteOnlyFunction(GO, SK, TM))      SK = SectionKind::getExecuteOnly();    return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, SK, TM);  } -MCSection * -ARMElfTargetObjectFile::SelectSectionForGlobal(const GlobalObject *GO, -                                               SectionKind SK, const TargetMachine &TM) const { +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()) +  if (isExecuteOnlyFunction(GO, SK, TM))      SK = SectionKind::getExecuteOnly();    return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, SK, TM); diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h index dbb8128269dc..bd7aa1cfe02b 100644 --- a/lib/Target/ARM/ARMTargetObjectFile.h +++ b/lib/Target/ARM/ARMTargetObjectFile.h @@ -16,8 +16,6 @@  namespace llvm {  class ARMElfTargetObjectFile : public TargetLoweringObjectFileELF { -  mutable bool genExecuteOnly = false; -  protected:    const MCSection *AttributesSection = nullptr; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 585726208a8d..5ab236b7fd4c 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -486,7 +486,7 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,      }    } -  Size = 0; +  Size = 4;    return MCDisassembler::Fail;  } diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index 81760f03940a..22de728fe06e 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -738,13 +738,13 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,    }  } -void ARMAsmBackend::processFixupValue(const MCAssembler &Asm, -                                      const MCFixup &Fixup, -                                      const MCValue &Target, bool &IsResolved) { +bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm, +                                          const MCFixup &Fixup, +                                          const MCValue &Target) {    const MCSymbolRefExpr *A = Target.getSymA();    const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;    const unsigned FixupKind = Fixup.getKind() ; -  if (IsResolved && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) { +  if ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {      assert(Sym && "How did we resolve this?");      // If the symbol is external the linker will handle it. @@ -753,7 +753,7 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,      // If the symbol is out of range, produce a relocation and hope the      // linker can handle it. GNU AS produces an error in this case.      if (Sym->isExternal()) -      IsResolved = false; +      return true;    }    // Create relocations for unconditional branches to function symbols with    // different execution mode in ELF binaries. @@ -761,12 +761,12 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,      unsigned Type = dyn_cast<MCSymbolELF>(Sym)->getType();      if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)) {        if (Asm.isThumbFunc(Sym) && (FixupKind == ARM::fixup_arm_uncondbranch)) -        IsResolved = false; +        return true;        if (!Asm.isThumbFunc(Sym) && (FixupKind == ARM::fixup_arm_thumb_br ||                                      FixupKind == ARM::fixup_arm_thumb_bl ||                                      FixupKind == ARM::fixup_t2_condbranch ||                                      FixupKind == ARM::fixup_t2_uncondbranch)) -        IsResolved = false; +        return true;      }    }    // We must always generate a relocation for BL/BLX instructions if we have @@ -776,7 +776,8 @@ void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,              FixupKind == ARM::fixup_arm_blx ||              FixupKind == ARM::fixup_arm_uncondbl ||              FixupKind == ARM::fixup_arm_condbl)) -    IsResolved = false; +    return true; +  return false;  }  /// getFixupKindNumBytes - The number of bytes the fixup may change. diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h index 6a0ba2ed41c1..84b54bbb9a49 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -38,10 +38,8 @@ public:    const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; -  /// processFixupValue - Target hook to process the literal value of a fixup -  /// if necessary. -  void processFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, -                         const MCValue &Target, bool &IsResolved) override; +  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, +                             const MCValue &Target) override;    unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,                              const MCValue &Target, uint64_t Value, bool IsPCRel, diff --git a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h index 9f6c5d7bf920..831589ba0581 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h +++ b/lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h @@ -15,55 +15,47 @@  namespace llvm {  namespace ARM {  enum Fixups { -  // fixup_arm_ldst_pcrel_12 - 12-bit PC relative relocation for symbol -  // addresses +  // 12-bit PC relative relocation for symbol addresses    fixup_arm_ldst_pcrel_12 = FirstTargetFixupKind, -  // fixup_t2_ldst_pcrel_12 - Equivalent to fixup_arm_ldst_pcrel_12, with -  // the 16-bit halfwords reordered. +  // Equivalent to fixup_arm_ldst_pcrel_12, with the 16-bit halfwords reordered.    fixup_t2_ldst_pcrel_12, -  // fixup_arm_pcrel_10_unscaled - 10-bit PC relative relocation for symbol -  // addresses used in LDRD/LDRH/LDRB/etc. instructions. All bits are encoded. +  // 10-bit PC relative relocation for symbol addresses used in +  // LDRD/LDRH/LDRB/etc. instructions. All bits are encoded.    fixup_arm_pcrel_10_unscaled, -  // fixup_arm_pcrel_10 - 10-bit PC relative relocation for symbol addresses -  // used in VFP instructions where the lower 2 bits are not encoded -  // (so it's encoded as an 8-bit immediate). +  // 10-bit PC relative relocation for symbol addresses used in VFP instructions +  // where the lower 2 bits are not encoded (so it's encoded as an 8-bit +  // immediate).    fixup_arm_pcrel_10, -  // fixup_t2_pcrel_10 - Equivalent to fixup_arm_pcrel_10, accounting for -  // the short-swapped encoding of Thumb2 instructions. +  // Equivalent to fixup_arm_pcrel_10, accounting for the short-swapped encoding +  // of Thumb2 instructions.    fixup_t2_pcrel_10, -  // fixup_arm_pcrel_9 - 9-bit PC relative relocation for symbol addresses -  // used in VFP instructions where bit 0 not encoded (so it's encoded as an -  // 8-bit immediate). +  // 9-bit PC relative relocation for symbol addresses used in VFP instructions +  // where bit 0 not encoded (so it's encoded as an 8-bit immediate).    fixup_arm_pcrel_9, -  // fixup_t2_pcrel_9 - Equivalent to fixup_arm_pcrel_9, accounting for -  // the short-swapped encoding of Thumb2 instructions. +  // Equivalent to fixup_arm_pcrel_9, accounting for the short-swapped encoding +  // of Thumb2 instructions.    fixup_t2_pcrel_9, -  // fixup_thumb_adr_pcrel_10 - 10-bit PC relative relocation for symbol -  // addresses where the lower 2 bits are not encoded (so it's encoded as an -  // 8-bit immediate). +  // 10-bit PC relative relocation for symbol addresses where the lower 2 bits +  // are not encoded (so it's encoded as an 8-bit immediate).    fixup_thumb_adr_pcrel_10, -  // fixup_arm_adr_pcrel_12 - 12-bit PC relative relocation for the ADR -  // instruction. +  // 12-bit PC relative relocation for the ADR instruction.    fixup_arm_adr_pcrel_12, -  // fixup_t2_adr_pcrel_12 - 12-bit PC relative relocation for the ADR -  // instruction. +  // 12-bit PC relative relocation for the ADR instruction.    fixup_t2_adr_pcrel_12, -  // fixup_arm_condbranch - 24-bit PC relative relocation for conditional branch -  // instructions.  +  // 24-bit PC relative relocation for conditional branch instructions.    fixup_arm_condbranch, -  // fixup_arm_uncondbranch - 24-bit PC relative relocation for  -  // branch instructions. (unconditional) +  // 24-bit PC relative relocation for branch instructions. (unconditional)    fixup_arm_uncondbranch, -  // fixup_t2_condbranch - 20-bit PC relative relocation for Thumb2 direct -  // uconditional branch instructions. +  // 20-bit PC relative relocation for Thumb2 direct uconditional branch +  // instructions.    fixup_t2_condbranch, -  // fixup_t2_uncondbranch - 20-bit PC relative relocation for Thumb2 direct -  // branch unconditional branch instructions. +  // 20-bit PC relative relocation for Thumb2 direct branch unconditional branch +  // instructions.    fixup_t2_uncondbranch, -  // fixup_arm_thumb_br - 12-bit fixup for Thumb B instructions. +  // 12-bit fixup for Thumb B instructions.    fixup_arm_thumb_br,    // The following fixups handle the ARM BL instructions. These can be @@ -75,42 +67,41 @@ enum Fixups {    // MachO does not draw a distinction between the two cases, so it will treat    // fixup_arm_uncondbl and fixup_arm_condbl as identical fixups. -  // fixup_arm_uncondbl - Fixup for unconditional ARM BL instructions. +  // Fixup for unconditional ARM BL instructions.    fixup_arm_uncondbl, -  // fixup_arm_condbl - Fixup for ARM BL instructions with nontrivial -  // conditionalisation. +  // Fixup for ARM BL instructions with nontrivial conditionalisation.    fixup_arm_condbl, -  // fixup_arm_blx - Fixup for ARM BLX instructions. +  // Fixup for ARM BLX instructions.    fixup_arm_blx, -  // fixup_arm_thumb_bl - Fixup for Thumb BL instructions. +  // Fixup for Thumb BL instructions.    fixup_arm_thumb_bl, -  // fixup_arm_thumb_blx - Fixup for Thumb BLX instructions. +  // Fixup for Thumb BLX instructions.    fixup_arm_thumb_blx, -  // fixup_arm_thumb_cb - Fixup for Thumb branch instructions. +  // Fixup for Thumb branch instructions.    fixup_arm_thumb_cb, -  // fixup_arm_thumb_cp - Fixup for Thumb load/store from constant pool instrs. +  // Fixup for Thumb load/store from constant pool instrs.    fixup_arm_thumb_cp, -  // fixup_arm_thumb_bcc - Fixup for Thumb conditional branching instructions. +  // Fixup for Thumb conditional branching instructions.    fixup_arm_thumb_bcc,    // The next two are for the movt/movw pair    // the 16bit imm field are split into imm{15-12} and imm{11-0}    fixup_arm_movt_hi16, // :upper16:    fixup_arm_movw_lo16, // :lower16: -  fixup_t2_movt_hi16, // :upper16: -  fixup_t2_movw_lo16, // :lower16: +  fixup_t2_movt_hi16,  // :upper16: +  fixup_t2_movw_lo16,  // :lower16: -  // fixup_arm_mod_imm - Fixup for mod_imm +  // Fixup for mod_imm    fixup_arm_mod_imm, -  // fixup_t2_so_imm - Fixup for Thumb2 8-bit rotated operand +  // Fixup for Thumb2 8-bit rotated operand    fixup_t2_so_imm,    // Marker @@ -118,6 +109,6 @@ enum Fixups {    NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind  };  } -} +} // namespace llvm  #endif  | 
