LCOV - code coverage report
Current view: top level - lib/Target/ARM/MCTargetDesc - ARMAsmBackend.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 363 414 87.7 %
Date: 2018-06-17 00:07:59 Functions: 17 17 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "MCTargetDesc/ARMAsmBackend.h"
      11             : #include "MCTargetDesc/ARMAddressingModes.h"
      12             : #include "MCTargetDesc/ARMAsmBackendDarwin.h"
      13             : #include "MCTargetDesc/ARMAsmBackendELF.h"
      14             : #include "MCTargetDesc/ARMAsmBackendWinCOFF.h"
      15             : #include "MCTargetDesc/ARMFixupKinds.h"
      16             : #include "MCTargetDesc/ARMMCTargetDesc.h"
      17             : #include "llvm/ADT/StringSwitch.h"
      18             : #include "llvm/BinaryFormat/ELF.h"
      19             : #include "llvm/BinaryFormat/MachO.h"
      20             : #include "llvm/MC/MCAsmBackend.h"
      21             : #include "llvm/MC/MCAssembler.h"
      22             : #include "llvm/MC/MCContext.h"
      23             : #include "llvm/MC/MCDirectives.h"
      24             : #include "llvm/MC/MCELFObjectWriter.h"
      25             : #include "llvm/MC/MCExpr.h"
      26             : #include "llvm/MC/MCFixupKindInfo.h"
      27             : #include "llvm/MC/MCObjectWriter.h"
      28             : #include "llvm/MC/MCRegisterInfo.h"
      29             : #include "llvm/MC/MCSectionELF.h"
      30             : #include "llvm/MC/MCSectionMachO.h"
      31             : #include "llvm/MC/MCSubtargetInfo.h"
      32             : #include "llvm/MC/MCValue.h"
      33             : #include "llvm/Support/Debug.h"
      34             : #include "llvm/Support/EndianStream.h"
      35             : #include "llvm/Support/ErrorHandling.h"
      36             : #include "llvm/Support/Format.h"
      37             : #include "llvm/Support/TargetParser.h"
      38             : #include "llvm/Support/raw_ostream.h"
      39             : using namespace llvm;
      40             : 
      41             : namespace {
      42             : class ARMELFObjectWriter : public MCELFObjectTargetWriter {
      43             : public:
      44             :   ARMELFObjectWriter(uint8_t OSABI)
      45             :       : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM,
      46             :                                 /*HasRelocationAddend*/ false) {}
      47             : };
      48             : } // end anonymous namespace
      49             : 
      50       14767 : const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
      51             :   const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
      52             :       // This table *must* be in the order that the fixup_* kinds are defined in
      53             :       // ARMFixupKinds.h.
      54             :       //
      55             :       // Name                      Offset (bits) Size (bits)     Flags
      56             :       {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      57             :       {"fixup_t2_ldst_pcrel_12", 0, 32,
      58             :        MCFixupKindInfo::FKF_IsPCRel |
      59             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      60             :       {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      61             :       {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      62             :       {"fixup_t2_pcrel_10", 0, 32,
      63             :        MCFixupKindInfo::FKF_IsPCRel |
      64             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      65             :       {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      66             :       {"fixup_t2_pcrel_9", 0, 32,
      67             :        MCFixupKindInfo::FKF_IsPCRel |
      68             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      69             :       {"fixup_thumb_adr_pcrel_10", 0, 8,
      70             :        MCFixupKindInfo::FKF_IsPCRel |
      71             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      72             :       {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      73             :       {"fixup_t2_adr_pcrel_12", 0, 32,
      74             :        MCFixupKindInfo::FKF_IsPCRel |
      75             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      76             :       {"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      77             :       {"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      78             :       {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      79             :       {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      80             :       {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
      81             :       {"fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      82             :       {"fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      83             :       {"fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
      84             :       {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
      85             :       {"fixup_arm_thumb_blx", 0, 32,
      86             :        MCFixupKindInfo::FKF_IsPCRel |
      87             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      88             :       {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
      89             :       {"fixup_arm_thumb_cp", 0, 8,
      90             :        MCFixupKindInfo::FKF_IsPCRel |
      91             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
      92             :       {"fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
      93             :       // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
      94             :       // - 19.
      95             :       {"fixup_arm_movt_hi16", 0, 20, 0},
      96             :       {"fixup_arm_movw_lo16", 0, 20, 0},
      97             :       {"fixup_t2_movt_hi16", 0, 20, 0},
      98             :       {"fixup_t2_movw_lo16", 0, 20, 0},
      99             :       {"fixup_arm_mod_imm", 0, 12, 0},
     100             :       {"fixup_t2_so_imm", 0, 26, 0},
     101             :   };
     102             :   const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = {
     103             :       // This table *must* be in the order that the fixup_* kinds are defined in
     104             :       // ARMFixupKinds.h.
     105             :       //
     106             :       // Name                      Offset (bits) Size (bits)     Flags
     107             :       {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     108             :       {"fixup_t2_ldst_pcrel_12", 0, 32,
     109             :        MCFixupKindInfo::FKF_IsPCRel |
     110             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     111             :       {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     112             :       {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     113             :       {"fixup_t2_pcrel_10", 0, 32,
     114             :        MCFixupKindInfo::FKF_IsPCRel |
     115             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     116             :       {"fixup_arm_pcrel_9", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     117             :       {"fixup_t2_pcrel_9", 0, 32,
     118             :        MCFixupKindInfo::FKF_IsPCRel |
     119             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     120             :       {"fixup_thumb_adr_pcrel_10", 8, 8,
     121             :        MCFixupKindInfo::FKF_IsPCRel |
     122             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     123             :       {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     124             :       {"fixup_t2_adr_pcrel_12", 0, 32,
     125             :        MCFixupKindInfo::FKF_IsPCRel |
     126             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     127             :       {"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
     128             :       {"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
     129             :       {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     130             :       {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     131             :       {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
     132             :       {"fixup_arm_uncondbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
     133             :       {"fixup_arm_condbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
     134             :       {"fixup_arm_blx", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
     135             :       {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
     136             :       {"fixup_arm_thumb_blx", 0, 32,
     137             :        MCFixupKindInfo::FKF_IsPCRel |
     138             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     139             :       {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
     140             :       {"fixup_arm_thumb_cp", 8, 8,
     141             :        MCFixupKindInfo::FKF_IsPCRel |
     142             :            MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
     143             :       {"fixup_arm_thumb_bcc", 8, 8, MCFixupKindInfo::FKF_IsPCRel},
     144             :       // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
     145             :       // - 19.
     146             :       {"fixup_arm_movt_hi16", 12, 20, 0},
     147             :       {"fixup_arm_movw_lo16", 12, 20, 0},
     148             :       {"fixup_t2_movt_hi16", 12, 20, 0},
     149             :       {"fixup_t2_movw_lo16", 12, 20, 0},
     150             :       {"fixup_arm_mod_imm", 20, 12, 0},
     151             :       {"fixup_t2_so_imm", 26, 6, 0},
     152             :   };
     153             : 
     154       14767 :   if (Kind < FirstTargetFixupKind)
     155        6318 :     return MCAsmBackend::getFixupKindInfo(Kind);
     156             : 
     157             :   assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
     158             :          "Invalid kind!");
     159        8449 :   return (Endian == support::little ? InfosLE
     160        8449 :                                     : InfosBE)[Kind - FirstTargetFixupKind];
     161             : }
     162             : 
     163        1152 : void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
     164        1152 :   switch (Flag) {
     165             :   default:
     166             :     break;
     167             :   case MCAF_Code16:
     168             :     setIsThumb(true);
     169             :     break;
     170             :   case MCAF_Code32:
     171             :     setIsThumb(false);
     172             :     break;
     173             :   }
     174        1152 : }
     175             : 
     176       23774 : unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op,
     177             :                                          const MCSubtargetInfo &STI) const {
     178             :   bool HasThumb2 = STI.getFeatureBits()[ARM::FeatureThumb2];
     179             :   bool HasV8MBaselineOps = STI.getFeatureBits()[ARM::HasV8MBaselineOps];
     180             : 
     181       23774 :   switch (Op) {
     182             :   default:
     183             :     return Op;
     184         213 :   case ARM::tBcc:
     185         213 :     return HasThumb2 ? (unsigned)ARM::t2Bcc : Op;
     186         140 :   case ARM::tLDRpci:
     187         140 :     return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op;
     188          17 :   case ARM::tADR:
     189          17 :     return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
     190         212 :   case ARM::tB:
     191         212 :     return HasV8MBaselineOps ? (unsigned)ARM::t2B : Op;
     192          25 :   case ARM::tCBZ:
     193          25 :     return ARM::tHINT;
     194          26 :   case ARM::tCBNZ:
     195          26 :     return ARM::tHINT;
     196             :   }
     197             : }
     198             : 
     199       23735 : bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst,
     200             :                                       const MCSubtargetInfo &STI) const {
     201       23735 :   if (getRelaxedOpcode(Inst.getOpcode(), STI) != Inst.getOpcode())
     202             :     return true;
     203       23319 :   return false;
     204             : }
     205             : 
     206         371 : const char *ARMAsmBackend::reasonForFixupRelaxation(const MCFixup &Fixup,
     207             :                                                     uint64_t Value) const {
     208         371 :   switch ((unsigned)Fixup.getKind()) {
     209          85 :   case ARM::fixup_arm_thumb_br: {
     210             :     // Relaxing tB to t2B. tB has a signed 12-bit displacement with the
     211             :     // low bit being an implied zero. There's an implied +4 offset for the
     212             :     // branch, so we adjust the other way here to determine what's
     213             :     // encodable.
     214             :     //
     215             :     // Relax if the value is too big for a (signed) i8.
     216          85 :     int64_t Offset = int64_t(Value) - 4;
     217          85 :     if (Offset > 2046 || Offset < -2048)
     218             :       return "out of range pc-relative fixup value";
     219             :     break;
     220             :   }
     221         142 :   case ARM::fixup_arm_thumb_bcc: {
     222             :     // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
     223             :     // low bit being an implied zero. There's an implied +4 offset for the
     224             :     // branch, so we adjust the other way here to determine what's
     225             :     // encodable.
     226             :     //
     227             :     // Relax if the value is too big for a (signed) i8.
     228         142 :     int64_t Offset = int64_t(Value) - 4;
     229         142 :     if (Offset > 254 || Offset < -256)
     230             :       return "out of range pc-relative fixup value";
     231             :     break;
     232             :   }
     233         117 :   case ARM::fixup_thumb_adr_pcrel_10:
     234             :   case ARM::fixup_arm_thumb_cp: {
     235             :     // If the immediate is negative, greater than 1020, or not a multiple
     236             :     // of four, the wide version of the instruction must be used.
     237         117 :     int64_t Offset = int64_t(Value) - 4;
     238         117 :     if (Offset & 3)
     239             :       return "misaligned pc-relative fixup value";
     240         107 :     else if (Offset > 1020 || Offset < 0)
     241             :       return "out of range pc-relative fixup value";
     242             :     break;
     243             :   }
     244          27 :   case ARM::fixup_arm_thumb_cb: {
     245             :     // If we have a Thumb CBZ or CBNZ instruction and its target is the next
     246             :     // instruction it is actually out of range for the instruction.
     247             :     // It will be changed to a NOP.
     248          27 :     int64_t Offset = (Value & ~1);
     249          27 :     if (Offset == 2)
     250             :       return "will be converted to nop";
     251             :     break;
     252             :   }
     253           0 :   default:
     254           0 :     llvm_unreachable("Unexpected fixup kind in reasonForFixupRelaxation()!");
     255             :   }
     256         346 :   return nullptr;
     257             : }
     258             : 
     259         195 : bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
     260             :                                          const MCRelaxableFragment *DF,
     261             :                                          const MCAsmLayout &Layout) const {
     262         195 :   return reasonForFixupRelaxation(Fixup, Value);
     263             : }
     264             : 
     265          39 : void ARMAsmBackend::relaxInstruction(const MCInst &Inst,
     266             :                                      const MCSubtargetInfo &STI,
     267             :                                      MCInst &Res) const {
     268          39 :   unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode(), STI);
     269             : 
     270             :   // Sanity check w/ diagnostic if we get here w/ a bogus instruction.
     271          39 :   if (RelaxedOp == Inst.getOpcode()) {
     272             :     SmallString<256> Tmp;
     273             :     raw_svector_ostream OS(Tmp);
     274           0 :     Inst.dump_pretty(OS);
     275           0 :     OS << "\n";
     276           0 :     report_fatal_error("unexpected instruction to relax: " + OS.str());
     277             :   }
     278             : 
     279             :   // If we are changing Thumb CBZ or CBNZ instruction to a NOP, aka tHINT, we
     280             :   // have to change the operands too.
     281          39 :   if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) &&
     282             :       RelaxedOp == ARM::tHINT) {
     283             :     Res.setOpcode(RelaxedOp);
     284           4 :     Res.addOperand(MCOperand::createImm(0));
     285           4 :     Res.addOperand(MCOperand::createImm(14));
     286           4 :     Res.addOperand(MCOperand::createReg(0));
     287           2 :     return;
     288             :   }
     289             : 
     290             :   // The rest of instructions we're relaxing have the same operands.
     291             :   // We just need to update to the proper opcode.
     292             :   Res = Inst;
     293             :   Res.setOpcode(RelaxedOp);
     294             : }
     295             : 
     296        2369 : bool ARMAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
     297             :   const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
     298             :   const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
     299             :   const uint32_t ARMv4_NopEncoding = 0xe1a00000;   // using MOV r0,r0
     300             :   const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP
     301        2369 :   if (isThumb()) {
     302             :     const uint16_t nopEncoding =
     303        2464 :         hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
     304        1232 :     uint64_t NumNops = Count / 2;
     305        1320 :     for (uint64_t i = 0; i != NumNops; ++i)
     306          44 :       support::endian::write(OS, nopEncoding, Endian);
     307        1232 :     if (Count & 1)
     308             :       OS << '\0';
     309             :     return true;
     310             :   }
     311             :   // ARM mode
     312             :   const uint32_t nopEncoding =
     313        2274 :       hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
     314        1137 :   uint64_t NumNops = Count / 4;
     315        1175 :   for (uint64_t i = 0; i != NumNops; ++i)
     316          19 :     support::endian::write(OS, nopEncoding, Endian);
     317             :   // FIXME: should this function return false when unable to write exactly
     318             :   // 'Count' bytes with NOP encodings?
     319        1137 :   switch (Count % 4) {
     320             :   default:
     321             :     break; // No leftover bytes to write
     322             :   case 1:
     323             :     OS << '\0';
     324             :     break;
     325           5 :   case 2:
     326           5 :     OS.write("\0\0", 2);
     327           5 :     break;
     328           0 :   case 3:
     329           0 :     OS.write("\0\0\xa0", 3);
     330           0 :     break;
     331             :   }
     332             : 
     333             :   return true;
     334             : }
     335             : 
     336             : static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian) {
     337         336 :   if (IsLittleEndian) {
     338             :     // Note that the halfwords are stored high first and low second in thumb;
     339             :     // so we need to swap the fixup value here to map properly.
     340             :     uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
     341         323 :     Swapped |= (Value & 0x0000FFFF) << 16;
     342             :     return Swapped;
     343             :   } else
     344             :     return Value;
     345             : }
     346             : 
     347             : static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
     348             :                               bool IsLittleEndian) {
     349             :   uint32_t Value;
     350             : 
     351         967 :   if (IsLittleEndian) {
     352         964 :     Value = (SecondHalf & 0xFFFF) << 16;
     353         964 :     Value |= (FirstHalf & 0xFFFF);
     354             :   } else {
     355             :     Value = (SecondHalf & 0xFFFF);
     356           3 :     Value |= (FirstHalf & 0xFFFF) << 16;
     357             :   }
     358             : 
     359             :   return Value;
     360             : }
     361             : 
     362        5113 : unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
     363             :                                          const MCFixup &Fixup,
     364             :                                          const MCValue &Target, uint64_t Value,
     365             :                                          bool IsResolved, MCContext &Ctx,
     366             :                                          const MCSubtargetInfo* STI) const {
     367        5113 :   unsigned Kind = Fixup.getKind();
     368             : 
     369             :   // MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
     370             :   // and .word relocations they put the Thumb bit into the addend if possible.
     371             :   // Other relocation types don't want this bit though (branches couldn't encode
     372             :   // it if it *was* present, and no other relocations exist) and it can
     373             :   // interfere with checking valid expressions.
     374        5113 :   if (const MCSymbolRefExpr *A = Target.getSymA()) {
     375        4667 :     if (A->hasSubsectionsViaSymbols() && Asm.isThumbFunc(&A->getSymbol()) &&
     376          22 :         (Kind == FK_Data_4 || Kind == ARM::fixup_arm_movw_lo16 ||
     377          21 :          Kind == ARM::fixup_arm_movt_hi16 || Kind == ARM::fixup_t2_movw_lo16 ||
     378             :          Kind == ARM::fixup_t2_movt_hi16))
     379           3 :       Value |= 1;
     380             :   }
     381             : 
     382        5113 :   switch (Kind) {
     383             :   default:
     384           0 :     Ctx.reportError(Fixup.getLoc(), "bad relocation fixup type");
     385           0 :     return 0;
     386        2247 :   case FK_Data_1:
     387             :   case FK_Data_2:
     388             :   case FK_Data_4:
     389        2247 :     return Value;
     390           3 :   case FK_SecRel_2:
     391           3 :     return Value;
     392          11 :   case FK_SecRel_4:
     393          11 :     return Value;
     394          36 :   case ARM::fixup_arm_movt_hi16:
     395             :     assert(STI != nullptr);
     396          71 :     if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
     397           9 :       Value >>= 16;
     398             :     LLVM_FALLTHROUGH;
     399             :   case ARM::fixup_arm_movw_lo16: {
     400          74 :     unsigned Hi4 = (Value & 0xF000) >> 12;
     401          74 :     unsigned Lo12 = Value & 0x0FFF;
     402             :     // inst{19-16} = Hi4;
     403             :     // inst{11-0} = Lo12;
     404          74 :     Value = (Hi4 << 16) | (Lo12);
     405          74 :     return Value;
     406             :   }
     407          63 :   case ARM::fixup_t2_movt_hi16:
     408             :     assert(STI != nullptr);
     409         125 :     if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
     410          43 :       Value >>= 16;
     411             :     LLVM_FALLTHROUGH;
     412             :   case ARM::fixup_t2_movw_lo16: {
     413         125 :     unsigned Hi4 = (Value & 0xF000) >> 12;
     414         125 :     unsigned i = (Value & 0x800) >> 11;
     415         125 :     unsigned Mid3 = (Value & 0x700) >> 8;
     416         125 :     unsigned Lo8 = Value & 0x0FF;
     417             :     // inst{19-16} = Hi4;
     418             :     // inst{26} = i;
     419             :     // inst{14-12} = Mid3;
     420             :     // inst{7-0} = Lo8;
     421         125 :     Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
     422         125 :     return swapHalfWords(Value, Endian == support::little);
     423             :   }
     424          27 :   case ARM::fixup_arm_ldst_pcrel_12:
     425             :     // ARM PC-relative values are offset by 8.
     426          27 :     Value -= 4;
     427             :     LLVM_FALLTHROUGH;
     428          40 :   case ARM::fixup_t2_ldst_pcrel_12: {
     429             :     // Offset by 4, adjusted by two due to the half-word ordering of thumb.
     430          40 :     Value -= 4;
     431             :     bool isAdd = true;
     432          40 :     if ((int64_t)Value < 0) {
     433           9 :       Value = -Value;
     434             :       isAdd = false;
     435             :     }
     436          40 :     if (Value >= 4096) {
     437           2 :       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
     438           2 :       return 0;
     439             :     }
     440          38 :     Value |= isAdd << 23;
     441             : 
     442             :     // Same addressing mode as fixup_arm_pcrel_10,
     443             :     // but with 16-bit halfwords swapped.
     444          38 :     if (Kind == ARM::fixup_t2_ldst_pcrel_12)
     445          13 :       return swapHalfWords(Value, Endian == support::little);
     446             : 
     447          25 :     return Value;
     448             :   }
     449           7 :   case ARM::fixup_arm_adr_pcrel_12: {
     450             :     // ARM PC-relative values are offset by 8.
     451           7 :     Value -= 8;
     452             :     unsigned opc = 4; // bits {24-21}. Default to add: 0b0100
     453           7 :     if ((int64_t)Value < 0) {
     454           1 :       Value = -Value;
     455             :       opc = 2; // 0b0010
     456             :     }
     457           7 :     if (ARM_AM::getSOImmVal(Value) == -1) {
     458           0 :       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
     459           0 :       return 0;
     460             :     }
     461             :     // Encode the immediate and shift the opcode into place.
     462           7 :     return ARM_AM::getSOImmVal(Value) | (opc << 21);
     463             :   }
     464             : 
     465           2 :   case ARM::fixup_t2_adr_pcrel_12: {
     466           2 :     Value -= 4;
     467             :     unsigned opc = 0;
     468           2 :     if ((int64_t)Value < 0) {
     469           1 :       Value = -Value;
     470             :       opc = 5;
     471             :     }
     472             : 
     473           2 :     uint32_t out = (opc << 21);
     474           2 :     out |= (Value & 0x800) << 15;
     475           2 :     out |= (Value & 0x700) << 4;
     476           2 :     out |= (Value & 0x0FF);
     477             : 
     478           2 :     return swapHalfWords(out, Endian == support::little);
     479             :   }
     480             : 
     481        1007 :   case ARM::fixup_arm_condbranch:
     482             :   case ARM::fixup_arm_uncondbranch:
     483             :   case ARM::fixup_arm_uncondbl:
     484             :   case ARM::fixup_arm_condbl:
     485             :   case ARM::fixup_arm_blx:
     486             :     // These values don't encode the low two bits since they're always zero.
     487             :     // Offset by 8 just as above.
     488             :     if (const MCSymbolRefExpr *SRE =
     489        1007 :             dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
     490         998 :       if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
     491             :         return 0;
     492        1007 :     return 0xffffff & ((Value - 8) >> 2);
     493          81 :   case ARM::fixup_t2_uncondbranch: {
     494          81 :     Value = Value - 4;
     495          81 :     if (!isInt<25>(Value)) {
     496           2 :       Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
     497           2 :       return 0;
     498             :     }
     499             : 
     500          79 :     Value >>= 1; // Low bit is not encoded.
     501             : 
     502             :     uint32_t out = 0;
     503          79 :     bool I = Value & 0x800000;
     504          79 :     bool J1 = Value & 0x400000;
     505          79 :     bool J2 = Value & 0x200000;
     506             :     J1 ^= I;
     507             :     J2 ^= I;
     508             : 
     509          79 :     out |= I << 26;                 // S bit
     510          79 :     out |= !J1 << 13;               // J1 bit
     511          79 :     out |= !J2 << 11;               // J2 bit
     512          79 :     out |= (Value & 0x1FF800) << 5; // imm6 field
     513          79 :     out |= (Value & 0x0007FF);      // imm11 field
     514             : 
     515          79 :     return swapHalfWords(out, Endian == support::little);
     516             :   }
     517          32 :   case ARM::fixup_t2_condbranch: {
     518          32 :     Value = Value - 4;
     519          32 :     if (!isInt<21>(Value)) {
     520           2 :       Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
     521           2 :       return 0;
     522             :     }
     523             : 
     524          30 :     Value >>= 1; // Low bit is not encoded.
     525             : 
     526             :     uint64_t out = 0;
     527          30 :     out |= (Value & 0x80000) << 7; // S bit
     528          30 :     out |= (Value & 0x40000) >> 7; // J2 bit
     529          30 :     out |= (Value & 0x20000) >> 4; // J1 bit
     530          30 :     out |= (Value & 0x1F800) << 5; // imm6 field
     531          30 :     out |= (Value & 0x007FF);      // imm11 field
     532             : 
     533          30 :     return swapHalfWords(out, Endian == support::little);
     534             :   }
     535         964 :   case ARM::fixup_arm_thumb_bl: {
     536        2882 :     if (!isInt<25>(Value - 4) ||
     537         184 :         (!STI->getFeatureBits()[ARM::FeatureThumb2] &&
     538         122 :          !STI->getFeatureBits()[ARM::HasV8MBaselineOps] &&
     539         112 :          !STI->getFeatureBits()[ARM::HasV6MOps] &&
     540             :          !isInt<23>(Value - 4))) {
     541          14 :       Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
     542          14 :       return 0;
     543             :     }
     544             : 
     545             :     // The value doesn't encode the low bit (always zero) and is offset by
     546             :     // four. The 32-bit immediate value is encoded as
     547             :     //   imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
     548             :     // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
     549             :     // The value is encoded into disjoint bit positions in the destination
     550             :     // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
     551             :     // J = either J1 or J2 bit
     552             :     //
     553             :     //   BL:  xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
     554             :     //
     555             :     // Note that the halfwords are stored high first, low second; so we need
     556             :     // to transpose the fixup value here to map properly.
     557         950 :     uint32_t offset = (Value - 4) >> 1;
     558         950 :     uint32_t signBit = (offset & 0x800000) >> 23;
     559         950 :     uint32_t I1Bit = (offset & 0x400000) >> 22;
     560         950 :     uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
     561         950 :     uint32_t I2Bit = (offset & 0x200000) >> 21;
     562         950 :     uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
     563         950 :     uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
     564         950 :     uint32_t imm11Bits = (offset & 0x000007FF);
     565             : 
     566         950 :     uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
     567        1900 :     uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
     568         950 :                            (uint16_t)imm11Bits);
     569         950 :     return joinHalfWords(FirstHalf, SecondHalf, Endian == support::little);
     570             :   }
     571          19 :   case ARM::fixup_arm_thumb_blx: {
     572             :     // The value doesn't encode the low two bits (always zero) and is offset by
     573             :     // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
     574             :     //   imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
     575             :     // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
     576             :     // The value is encoded into disjoint bit positions in the destination
     577             :     // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
     578             :     // J = either J1 or J2 bit, 0 = zero.
     579             :     //
     580             :     //   BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
     581             :     //
     582             :     // Note that the halfwords are stored high first, low second; so we need
     583             :     // to transpose the fixup value here to map properly.
     584          19 :     if (Value % 4 != 0) {
     585           2 :       Ctx.reportError(Fixup.getLoc(), "misaligned ARM call destination");
     586           2 :       return 0;
     587             :     }
     588             : 
     589          17 :     uint32_t offset = (Value - 4) >> 2;
     590             :     if (const MCSymbolRefExpr *SRE =
     591          17 :             dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
     592          15 :       if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
     593             :         offset = 0;
     594          17 :     uint32_t signBit = (offset & 0x400000) >> 22;
     595          17 :     uint32_t I1Bit = (offset & 0x200000) >> 21;
     596          17 :     uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
     597          17 :     uint32_t I2Bit = (offset & 0x100000) >> 20;
     598          17 :     uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
     599          17 :     uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
     600          17 :     uint32_t imm10LBits = (offset & 0x3FF);
     601             : 
     602          17 :     uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
     603          34 :     uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
     604          17 :                            ((uint16_t)imm10LBits) << 1);
     605          17 :     return joinHalfWords(FirstHalf, SecondHalf, Endian == support::little);
     606             :   }
     607             :   case ARM::fixup_thumb_adr_pcrel_10:
     608             :   case ARM::fixup_arm_thumb_cp:
     609             :     // On CPUs supporting Thumb2, this will be relaxed to an ldr.w, otherwise we
     610             :     // could have an error on our hands.
     611             :     assert(STI != nullptr);
     612          99 :     if (!STI->getFeatureBits()[ARM::FeatureThumb2] && IsResolved) {
     613          85 :       const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
     614          85 :       if (FixupDiagnostic) {
     615           9 :         Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
     616           9 :         return 0;
     617             :       }
     618             :     }
     619             :     // Offset by 4, and don't encode the low two bits.
     620          90 :     return ((Value - 4) >> 2) & 0xff;
     621          20 :   case ARM::fixup_arm_thumb_cb: {
     622             :     // CB instructions can only branch to offsets in [4, 126] in multiples of 2
     623             :     // so ensure that the raw value LSB is zero and it lies in [2, 130].
     624             :     // An offset of 2 will be relaxed to a NOP.
     625          20 :     if ((int64_t)Value < 2 || Value > 0x82 || Value & 1) {
     626          12 :       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
     627          12 :       return 0;
     628             :     }
     629             :     // Offset by 4 and don't encode the lower bit, which is always 0.
     630             :     // FIXME: diagnose if no Thumb2
     631           8 :     uint32_t Binary = (Value - 4) >> 1;
     632           8 :     return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
     633             :   }
     634             :   case ARM::fixup_arm_thumb_br:
     635             :     // Offset by 4 and don't encode the lower bit, which is always 0.
     636             :     assert(STI != nullptr);
     637          92 :     if (!STI->getFeatureBits()[ARM::FeatureThumb2] &&
     638             :         !STI->getFeatureBits()[ARM::HasV8MBaselineOps]) {
     639           7 :       const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
     640           7 :       if (FixupDiagnostic) {
     641           3 :         Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
     642           3 :         return 0;
     643             :       }
     644             :     }
     645          81 :     return ((Value - 4) >> 1) & 0x7ff;
     646             :   case ARM::fixup_arm_thumb_bcc:
     647             :     // Offset by 4 and don't encode the lower bit, which is always 0.
     648             :     assert(STI != nullptr);
     649         129 :     if (!STI->getFeatureBits()[ARM::FeatureThumb2]) {
     650          84 :       const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
     651          84 :       if (FixupDiagnostic) {
     652           2 :         Ctx.reportError(Fixup.getLoc(), FixupDiagnostic);
     653           2 :         return 0;
     654             :       }
     655             :     }
     656         127 :     return ((Value - 4) >> 1) & 0xff;
     657           1 :   case ARM::fixup_arm_pcrel_10_unscaled: {
     658           1 :     Value = Value - 8; // ARM fixups offset by an additional word and don't
     659             :                        // need to adjust for the half-word ordering.
     660             :     bool isAdd = true;
     661           1 :     if ((int64_t)Value < 0) {
     662           0 :       Value = -Value;
     663             :       isAdd = false;
     664             :     }
     665             :     // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8].
     666           1 :     if (Value >= 256) {
     667           0 :       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
     668           0 :       return 0;
     669             :     }
     670           1 :     Value = (Value & 0xf) | ((Value & 0xf0) << 4);
     671           1 :     return Value | (isAdd << 23);
     672             :   }
     673          73 :   case ARM::fixup_arm_pcrel_10:
     674          73 :     Value = Value - 4; // ARM fixups offset by an additional word and don't
     675             :                        // need to adjust for the half-word ordering.
     676             :     LLVM_FALLTHROUGH;
     677         148 :   case ARM::fixup_t2_pcrel_10: {
     678             :     // Offset by 4, adjusted by two due to the half-word ordering of thumb.
     679         148 :     Value = Value - 4;
     680             :     bool isAdd = true;
     681         148 :     if ((int64_t)Value < 0) {
     682          82 :       Value = -Value;
     683             :       isAdd = false;
     684             :     }
     685             :     // These values don't encode the low two bits since they're always zero.
     686         148 :     Value >>= 2;
     687         148 :     if (Value >= 256) {
     688           0 :       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
     689           0 :       return 0;
     690             :     }
     691         148 :     Value |= isAdd << 23;
     692             : 
     693             :     // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords
     694             :     // swapped.
     695         148 :     if (Kind == ARM::fixup_t2_pcrel_10)
     696          75 :       return swapHalfWords(Value, Endian == support::little);
     697             : 
     698          73 :     return Value;
     699             :   }
     700           0 :   case ARM::fixup_arm_pcrel_9:
     701           0 :     Value = Value - 4; // ARM fixups offset by an additional word and don't
     702             :                        // need to adjust for the half-word ordering.
     703             :     LLVM_FALLTHROUGH;
     704           0 :   case ARM::fixup_t2_pcrel_9: {
     705             :     // Offset by 4, adjusted by two due to the half-word ordering of thumb.
     706           0 :     Value = Value - 4;
     707             :     bool isAdd = true;
     708           0 :     if ((int64_t)Value < 0) {
     709           0 :       Value = -Value;
     710             :       isAdd = false;
     711             :     }
     712             :     // These values don't encode the low bit since it's always zero.
     713           0 :     if (Value & 1) {
     714           0 :       Ctx.reportError(Fixup.getLoc(), "invalid value for this fixup");
     715           0 :       return 0;
     716             :     }
     717           0 :     Value >>= 1;
     718           0 :     if (Value >= 256) {
     719           0 :       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value");
     720           0 :       return 0;
     721             :     }
     722           0 :     Value |= isAdd << 23;
     723             : 
     724             :     // Same addressing mode as fixup_arm_pcrel_9, but with 16-bit halfwords
     725             :     // swapped.
     726           0 :     if (Kind == ARM::fixup_t2_pcrel_9)
     727           0 :       return swapHalfWords(Value, Endian == support::little);
     728             : 
     729           0 :     return Value;
     730             :   }
     731           7 :   case ARM::fixup_arm_mod_imm:
     732           7 :     Value = ARM_AM::getSOImmVal(Value);
     733           7 :     if (Value >> 12) {
     734           1 :       Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
     735           1 :       return 0;
     736             :     }
     737           6 :     return Value;
     738          13 :   case ARM::fixup_t2_so_imm: {
     739          13 :     Value = ARM_AM::getT2SOImmVal(Value);
     740          13 :     if ((int64_t)Value < 0) {
     741           1 :       Ctx.reportError(Fixup.getLoc(), "out of range immediate fixup value");
     742           1 :       return 0;
     743             :     }
     744             :     // Value will contain a 12-bit value broken up into a 4-bit shift in bits
     745             :     // 11:8 and the 8-bit immediate in 0:7. The instruction has the immediate
     746             :     // in 0:7. The 4-bit shift is split up into i:imm3 where i is placed at bit
     747             :     // 10 of the upper half-word and imm3 is placed at 14:12 of the lower
     748             :     // half-word.
     749             :     uint64_t EncValue = 0;
     750          12 :     EncValue |= (Value & 0x800) << 15;
     751          12 :     EncValue |= (Value & 0x700) << 4;
     752          12 :     EncValue |= (Value & 0xff);
     753          12 :     return swapHalfWords(EncValue, Endian == support::little);
     754             :   }
     755             :   }
     756             : }
     757             : 
     758        1514 : bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
     759             :                                           const MCFixup &Fixup,
     760             :                                           const MCValue &Target) {
     761        1514 :   const MCSymbolRefExpr *A = Target.getSymA();
     762        1514 :   const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
     763        1514 :   const unsigned FixupKind = Fixup.getKind() ;
     764        1514 :   if ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
     765             :     assert(Sym && "How did we resolve this?");
     766             : 
     767             :     // If the symbol is external the linker will handle it.
     768             :     // FIXME: Should we handle it as an optimization?
     769             : 
     770             :     // If the symbol is out of range, produce a relocation and hope the
     771             :     // linker can handle it. GNU AS produces an error in this case.
     772          77 :     if (Sym->isExternal())
     773             :       return true;
     774             :   }
     775             :   // Create relocations for unconditional branches to function symbols with
     776             :   // different execution mode in ELF binaries.
     777        2510 :   if (Sym && Sym->isELF()) {
     778         504 :     unsigned Type = cast<MCSymbolELF>(Sym)->getType();
     779         504 :     if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)) {
     780          28 :       if (Asm.isThumbFunc(Sym) && (FixupKind == ARM::fixup_arm_uncondbranch))
     781             :         return true;
     782          44 :       if (!Asm.isThumbFunc(Sym) && (FixupKind == ARM::fixup_arm_thumb_br ||
     783          17 :                                     FixupKind == ARM::fixup_arm_thumb_bl ||
     784          14 :                                     FixupKind == ARM::fixup_t2_condbranch ||
     785             :                                     FixupKind == ARM::fixup_t2_uncondbranch))
     786             :         return true;
     787             :     }
     788             :   }
     789             :   // We must always generate a relocation for BL/BLX instructions if we have
     790             :   // a symbol to reference, as the linker relies on knowing the destination
     791             :   // symbol's thumb-ness to get interworking right.
     792        2488 :   if (A && (FixupKind == ARM::fixup_arm_thumb_blx ||
     793        1014 :             FixupKind == ARM::fixup_arm_blx ||
     794        1004 :             FixupKind == ARM::fixup_arm_uncondbl ||
     795             :             FixupKind == ARM::fixup_arm_condbl))
     796             :     return true;
     797        1449 :   return false;
     798             : }
     799             : 
     800             : /// getFixupKindNumBytes - The number of bytes the fixup may change.
     801        5113 : static unsigned getFixupKindNumBytes(unsigned Kind) {
     802        5113 :   switch (Kind) {
     803           0 :   default:
     804           0 :     llvm_unreachable("Unknown fixup kind!");
     805             : 
     806             :   case FK_Data_1:
     807             :   case ARM::fixup_arm_thumb_bcc:
     808             :   case ARM::fixup_arm_thumb_cp:
     809             :   case ARM::fixup_thumb_adr_pcrel_10:
     810             :     return 1;
     811             : 
     812         182 :   case FK_Data_2:
     813             :   case ARM::fixup_arm_thumb_br:
     814             :   case ARM::fixup_arm_thumb_cb:
     815             :   case ARM::fixup_arm_mod_imm:
     816         182 :     return 2;
     817             : 
     818        1115 :   case ARM::fixup_arm_pcrel_10_unscaled:
     819             :   case ARM::fixup_arm_ldst_pcrel_12:
     820             :   case ARM::fixup_arm_pcrel_10:
     821             :   case ARM::fixup_arm_pcrel_9:
     822             :   case ARM::fixup_arm_adr_pcrel_12:
     823             :   case ARM::fixup_arm_uncondbl:
     824             :   case ARM::fixup_arm_condbl:
     825             :   case ARM::fixup_arm_blx:
     826             :   case ARM::fixup_arm_condbranch:
     827             :   case ARM::fixup_arm_uncondbranch:
     828        1115 :     return 3;
     829             : 
     830        3565 :   case FK_Data_4:
     831             :   case ARM::fixup_t2_ldst_pcrel_12:
     832             :   case ARM::fixup_t2_condbranch:
     833             :   case ARM::fixup_t2_uncondbranch:
     834             :   case ARM::fixup_t2_pcrel_10:
     835             :   case ARM::fixup_t2_pcrel_9:
     836             :   case ARM::fixup_t2_adr_pcrel_12:
     837             :   case ARM::fixup_arm_thumb_bl:
     838             :   case ARM::fixup_arm_thumb_blx:
     839             :   case ARM::fixup_arm_movt_hi16:
     840             :   case ARM::fixup_arm_movw_lo16:
     841             :   case ARM::fixup_t2_movt_hi16:
     842             :   case ARM::fixup_t2_movw_lo16:
     843             :   case ARM::fixup_t2_so_imm:
     844        3565 :     return 4;
     845             : 
     846           3 :   case FK_SecRel_2:
     847           3 :     return 2;
     848          11 :   case FK_SecRel_4:
     849          11 :     return 4;
     850             :   }
     851             : }
     852             : 
     853             : /// getFixupKindContainerSizeBytes - The number of bytes of the
     854             : /// container involved in big endian.
     855          43 : static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
     856          43 :   switch (Kind) {
     857           0 :   default:
     858           0 :     llvm_unreachable("Unknown fixup kind!");
     859             : 
     860             :   case FK_Data_1:
     861             :     return 1;
     862           1 :   case FK_Data_2:
     863           1 :     return 2;
     864           6 :   case FK_Data_4:
     865           6 :     return 4;
     866             : 
     867           3 :   case ARM::fixup_arm_thumb_bcc:
     868             :   case ARM::fixup_arm_thumb_cp:
     869             :   case ARM::fixup_thumb_adr_pcrel_10:
     870             :   case ARM::fixup_arm_thumb_br:
     871             :   case ARM::fixup_arm_thumb_cb:
     872             :     // Instruction size is 2 bytes.
     873           3 :     return 2;
     874             : 
     875          32 :   case ARM::fixup_arm_pcrel_10_unscaled:
     876             :   case ARM::fixup_arm_ldst_pcrel_12:
     877             :   case ARM::fixup_arm_pcrel_10:
     878             :   case ARM::fixup_arm_adr_pcrel_12:
     879             :   case ARM::fixup_arm_uncondbl:
     880             :   case ARM::fixup_arm_condbl:
     881             :   case ARM::fixup_arm_blx:
     882             :   case ARM::fixup_arm_condbranch:
     883             :   case ARM::fixup_arm_uncondbranch:
     884             :   case ARM::fixup_t2_ldst_pcrel_12:
     885             :   case ARM::fixup_t2_condbranch:
     886             :   case ARM::fixup_t2_uncondbranch:
     887             :   case ARM::fixup_t2_pcrel_10:
     888             :   case ARM::fixup_t2_adr_pcrel_12:
     889             :   case ARM::fixup_arm_thumb_bl:
     890             :   case ARM::fixup_arm_thumb_blx:
     891             :   case ARM::fixup_arm_movt_hi16:
     892             :   case ARM::fixup_arm_movw_lo16:
     893             :   case ARM::fixup_t2_movt_hi16:
     894             :   case ARM::fixup_t2_movw_lo16:
     895             :   case ARM::fixup_arm_mod_imm:
     896             :   case ARM::fixup_t2_so_imm:
     897             :     // Instruction size is 4 bytes.
     898          32 :     return 4;
     899             :   }
     900             : }
     901             : 
     902        5113 : void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
     903             :                                const MCValue &Target,
     904             :                                MutableArrayRef<char> Data, uint64_t Value,
     905             :                                bool IsResolved,
     906             :                                const MCSubtargetInfo* STI) const {
     907        5113 :   unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
     908        5113 :   MCContext &Ctx = Asm.getContext();
     909        5113 :   Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx, STI);
     910        5113 :   if (!Value)
     911             :     return; // Doesn't change encoding.
     912             : 
     913        3775 :   unsigned Offset = Fixup.getOffset();
     914             :   assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
     915             : 
     916             :   // Used to point to big endian bytes.
     917             :   unsigned FullSizeBytes;
     918        3775 :   if (Endian == support::big) {
     919          43 :     FullSizeBytes = getFixupKindContainerSizeBytes(Fixup.getKind());
     920             :     assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
     921             :     assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
     922             :   }
     923             : 
     924             :   // For each byte of the fragment that the fixup touches, mask in the bits from
     925             :   // the fixup value. The Value has been "split up" into the appropriate
     926             :   // bitfields above.
     927       29801 :   for (unsigned i = 0; i != NumBytes; ++i) {
     928       13013 :     unsigned Idx = Endian == support::little ? i : (FullSizeBytes - 1 - i);
     929       26026 :     Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
     930             :   }
     931             : }
     932             : 
     933             : namespace CU {
     934             : 
     935             : /// Compact unwind encoding values.
     936             : enum CompactUnwindEncodings {
     937             :   UNWIND_ARM_MODE_MASK                         = 0x0F000000,
     938             :   UNWIND_ARM_MODE_FRAME                        = 0x01000000,
     939             :   UNWIND_ARM_MODE_FRAME_D                      = 0x02000000,
     940             :   UNWIND_ARM_MODE_DWARF                        = 0x04000000,
     941             : 
     942             :   UNWIND_ARM_FRAME_STACK_ADJUST_MASK           = 0x00C00000,
     943             : 
     944             :   UNWIND_ARM_FRAME_FIRST_PUSH_R4               = 0x00000001,
     945             :   UNWIND_ARM_FRAME_FIRST_PUSH_R5               = 0x00000002,
     946             :   UNWIND_ARM_FRAME_FIRST_PUSH_R6               = 0x00000004,
     947             : 
     948             :   UNWIND_ARM_FRAME_SECOND_PUSH_R8              = 0x00000008,
     949             :   UNWIND_ARM_FRAME_SECOND_PUSH_R9              = 0x00000010,
     950             :   UNWIND_ARM_FRAME_SECOND_PUSH_R10             = 0x00000020,
     951             :   UNWIND_ARM_FRAME_SECOND_PUSH_R11             = 0x00000040,
     952             :   UNWIND_ARM_FRAME_SECOND_PUSH_R12             = 0x00000080,
     953             : 
     954             :   UNWIND_ARM_FRAME_D_REG_COUNT_MASK            = 0x00000F00,
     955             : 
     956             :   UNWIND_ARM_DWARF_SECTION_OFFSET              = 0x00FFFFFF
     957             : };
     958             : 
     959             : } // end CU namespace
     960             : 
     961             : /// Generate compact unwind encoding for the function based on the CFI
     962             : /// instructions. If the CFI instructions describe a frame that cannot be
     963             : /// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
     964             : /// tells the runtime to fallback and unwind using dwarf.
     965          18 : uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
     966             :     ArrayRef<MCCFIInstruction> Instrs) const {
     967             :   DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
     968             :   // Only armv7k uses CFI based unwinding.
     969          18 :   if (Subtype != MachO::CPU_SUBTYPE_ARM_V7K)
     970             :     return 0;
     971             :   // No .cfi directives means no frame.
     972           9 :   if (Instrs.empty())
     973             :     return 0;
     974             :   // Start off assuming CFA is at SP+0.
     975             :   int CFARegister = ARM::SP;
     976             :   int CFARegisterOffset = 0;
     977             :   // Mark savable registers as initially unsaved
     978             :   DenseMap<unsigned, int> RegOffsets;
     979             :   int FloatRegCount = 0;
     980             :   // Process each .cfi directive and build up compact unwind info.
     981          77 :   for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
     982             :     int Reg;
     983          35 :     const MCCFIInstruction &Inst = Instrs[i];
     984          35 :     switch (Inst.getOperation()) {
     985           7 :     case MCCFIInstruction::OpDefCfa: // DW_CFA_def_cfa
     986           7 :       CFARegisterOffset = -Inst.getOffset();
     987           7 :       CFARegister = MRI.getLLVMRegNum(Inst.getRegister(), true);
     988           7 :       break;
     989           0 :     case MCCFIInstruction::OpDefCfaOffset: // DW_CFA_def_cfa_offset
     990           0 :       CFARegisterOffset = -Inst.getOffset();
     991           0 :       break;
     992           0 :     case MCCFIInstruction::OpDefCfaRegister: // DW_CFA_def_cfa_register
     993           0 :       CFARegister = MRI.getLLVMRegNum(Inst.getRegister(), true);
     994           0 :       break;
     995          28 :     case MCCFIInstruction::OpOffset: // DW_CFA_offset
     996          28 :       Reg = MRI.getLLVMRegNum(Inst.getRegister(), true);
     997          56 :       if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg))
     998          46 :         RegOffsets[Reg] = Inst.getOffset();
     999          10 :       else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
    1000          10 :         RegOffsets[Reg] = Inst.getOffset();
    1001           5 :         ++FloatRegCount;
    1002             :       } else {
    1003             :         DEBUG_WITH_TYPE("compact-unwind",
    1004             :                         llvm::dbgs() << ".cfi_offset on unknown register="
    1005             :                                      << Inst.getRegister() << "\n");
    1006             :         return CU::UNWIND_ARM_MODE_DWARF;
    1007             :       }
    1008             :       break;
    1009             :     case MCCFIInstruction::OpRelOffset: // DW_CFA_advance_loc
    1010             :       // Ignore
    1011             :       break;
    1012             :     default:
    1013             :       // Directive not convertable to compact unwind, bail out.
    1014             :       DEBUG_WITH_TYPE("compact-unwind",
    1015             :                       llvm::dbgs()
    1016             :                           << "CFI directive not compatiable with comact "
    1017             :                              "unwind encoding, opcode=" << Inst.getOperation()
    1018             :                           << "\n");
    1019             :       return CU::UNWIND_ARM_MODE_DWARF;
    1020             :       break;
    1021             :     }
    1022             :   }
    1023             : 
    1024             :   // If no frame set up, return no unwind info.
    1025           7 :   if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
    1026             :     return 0;
    1027             : 
    1028             :   // Verify standard frame (lr/r7) was used.
    1029           7 :   if (CFARegister != ARM::R7) {
    1030             :     DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "frame register is "
    1031             :                                                    << CFARegister
    1032             :                                                    << " instead of r7\n");
    1033             :     return CU::UNWIND_ARM_MODE_DWARF;
    1034             :   }
    1035           7 :   int StackAdjust = CFARegisterOffset - 8;
    1036          14 :   if (RegOffsets.lookup(ARM::LR) != (-4 - StackAdjust)) {
    1037             :     DEBUG_WITH_TYPE("compact-unwind",
    1038             :                     llvm::dbgs()
    1039             :                         << "LR not saved as standard frame, StackAdjust="
    1040             :                         << StackAdjust
    1041             :                         << ", CFARegisterOffset=" << CFARegisterOffset
    1042             :                         << ", lr save at offset=" << RegOffsets[14] << "\n");
    1043             :     return CU::UNWIND_ARM_MODE_DWARF;
    1044             :   }
    1045          14 :   if (RegOffsets.lookup(ARM::R7) != (-8 - StackAdjust)) {
    1046             :     DEBUG_WITH_TYPE("compact-unwind",
    1047             :                     llvm::dbgs() << "r7 not saved as standard frame\n");
    1048             :     return CU::UNWIND_ARM_MODE_DWARF;
    1049             :   }
    1050             :   uint32_t CompactUnwindEncoding = CU::UNWIND_ARM_MODE_FRAME;
    1051             : 
    1052             :   // If var-args are used, there may be a stack adjust required.
    1053           7 :   switch (StackAdjust) {
    1054             :   case 0:
    1055             :     break;
    1056           0 :   case 4:
    1057             :     CompactUnwindEncoding |= 0x00400000;
    1058           0 :     break;
    1059           0 :   case 8:
    1060             :     CompactUnwindEncoding |= 0x00800000;
    1061           0 :     break;
    1062           1 :   case 12:
    1063             :     CompactUnwindEncoding |= 0x00C00000;
    1064           1 :     break;
    1065             :   default:
    1066             :     DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs()
    1067             :                                           << ".cfi_def_cfa stack adjust ("
    1068             :                                           << StackAdjust << ") out of range\n");
    1069             :     return CU::UNWIND_ARM_MODE_DWARF;
    1070             :   }
    1071             : 
    1072             :   // If r6 is saved, it must be right below r7.
    1073             :   static struct {
    1074             :     unsigned Reg;
    1075             :     unsigned Encoding;
    1076             :   } GPRCSRegs[] = {{ARM::R6, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R6},
    1077             :                    {ARM::R5, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R5},
    1078             :                    {ARM::R4, CU::UNWIND_ARM_FRAME_FIRST_PUSH_R4},
    1079             :                    {ARM::R12, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R12},
    1080             :                    {ARM::R11, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R11},
    1081             :                    {ARM::R10, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R10},
    1082             :                    {ARM::R9, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R9},
    1083             :                    {ARM::R8, CU::UNWIND_ARM_FRAME_SECOND_PUSH_R8}};
    1084             : 
    1085             :   int CurOffset = -8 - StackAdjust;
    1086          90 :   for (auto CSReg : GPRCSRegs) {
    1087          43 :     auto Offset = RegOffsets.find(CSReg.Reg);
    1088          43 :     if (Offset == RegOffsets.end())
    1089          34 :       continue;
    1090             : 
    1091           9 :     int RegOffset = Offset->second;
    1092           9 :     if (RegOffset != CurOffset - 4) {
    1093             :       DEBUG_WITH_TYPE("compact-unwind",
    1094             :                       llvm::dbgs() << MRI.getName(CSReg.Reg) << " saved at "
    1095             :                                    << RegOffset << " but only supported at "
    1096             :                                    << CurOffset << "\n");
    1097           1 :       return CU::UNWIND_ARM_MODE_DWARF;
    1098             :     }
    1099           8 :     CompactUnwindEncoding |= CSReg.Encoding;
    1100             :     CurOffset -= 4;
    1101             :   }
    1102             : 
    1103             :   // If no floats saved, we are done.
    1104           5 :   if (FloatRegCount == 0)
    1105             :     return CompactUnwindEncoding;
    1106             : 
    1107             :   // Switch mode to include D register saving.
    1108           2 :   CompactUnwindEncoding &= ~CU::UNWIND_ARM_MODE_MASK;
    1109           2 :   CompactUnwindEncoding |= CU::UNWIND_ARM_MODE_FRAME_D;
    1110             : 
    1111             :   // FIXME: supporting more than 4 saved D-registers compactly would be trivial,
    1112             :   // but needs coordination with the linker and libunwind.
    1113           2 :   if (FloatRegCount > 4) {
    1114             :     DEBUG_WITH_TYPE("compact-unwind",
    1115             :                     llvm::dbgs() << "unsupported number of D registers saved ("
    1116             :                                  << FloatRegCount << ")\n");
    1117             :       return CU::UNWIND_ARM_MODE_DWARF;
    1118             :   }
    1119             : 
    1120             :   // Floating point registers must either be saved sequentially, or we defer to
    1121             :   // DWARF. No gaps allowed here so check that each saved d-register is
    1122             :   // precisely where it should be.
    1123             :   static unsigned FPRCSRegs[] = { ARM::D8, ARM::D10, ARM::D12, ARM::D14 };
    1124           7 :   for (int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
    1125           5 :     auto Offset = RegOffsets.find(FPRCSRegs[Idx]);
    1126           5 :     if (Offset == RegOffsets.end()) {
    1127             :       DEBUG_WITH_TYPE("compact-unwind",
    1128             :                       llvm::dbgs() << FloatRegCount << " D-regs saved, but "
    1129             :                                    << MRI.getName(FPRCSRegs[Idx])
    1130             :                                    << " not saved\n");
    1131           0 :       return CU::UNWIND_ARM_MODE_DWARF;
    1132           5 :     } else if (Offset->second != CurOffset - 8) {
    1133             :       DEBUG_WITH_TYPE("compact-unwind",
    1134             :                       llvm::dbgs() << FloatRegCount << " D-regs saved, but "
    1135             :                                    << MRI.getName(FPRCSRegs[Idx])
    1136             :                                    << " saved at " << Offset->second
    1137             :                                    << ", expected at " << CurOffset - 8
    1138             :                                    << "\n");
    1139             :       return CU::UNWIND_ARM_MODE_DWARF;
    1140             :     }
    1141             :     CurOffset -= 8;
    1142             :   }
    1143             : 
    1144           2 :   return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
    1145             : }
    1146             : 
    1147             : static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch) {
    1148         919 :   ARM::ArchKind AK = ARM::parseArch(Arch);
    1149         919 :   switch (AK) {
    1150             :   default:
    1151             :     return MachO::CPU_SUBTYPE_ARM_V7;
    1152             :   case ARM::ArchKind::ARMV4T:
    1153             :     return MachO::CPU_SUBTYPE_ARM_V4T;
    1154             :   case ARM::ArchKind::ARMV5T:
    1155             :   case ARM::ArchKind::ARMV5TE:
    1156             :   case ARM::ArchKind::ARMV5TEJ:
    1157             :     return MachO::CPU_SUBTYPE_ARM_V5;
    1158             :   case ARM::ArchKind::ARMV6:
    1159             :   case ARM::ArchKind::ARMV6K:
    1160             :     return MachO::CPU_SUBTYPE_ARM_V6;
    1161             :   case ARM::ArchKind::ARMV7A:
    1162             :     return MachO::CPU_SUBTYPE_ARM_V7;
    1163             :   case ARM::ArchKind::ARMV7S:
    1164             :     return MachO::CPU_SUBTYPE_ARM_V7S;
    1165             :   case ARM::ArchKind::ARMV7K:
    1166             :     return MachO::CPU_SUBTYPE_ARM_V7K;
    1167             :   case ARM::ArchKind::ARMV6M:
    1168             :     return MachO::CPU_SUBTYPE_ARM_V6M;
    1169             :   case ARM::ArchKind::ARMV7M:
    1170             :     return MachO::CPU_SUBTYPE_ARM_V7M;
    1171             :   case ARM::ArchKind::ARMV7EM:
    1172             :     return MachO::CPU_SUBTYPE_ARM_V7EM;
    1173             :   }
    1174             : }
    1175             : 
    1176        3835 : static MCAsmBackend *createARMAsmBackend(const Target &T,
    1177             :                                          const MCSubtargetInfo &STI,
    1178             :                                          const MCRegisterInfo &MRI,
    1179             :                                          const MCTargetOptions &Options,
    1180             :                                          support::endianness Endian) {
    1181             :   const Triple &TheTriple = STI.getTargetTriple();
    1182        3835 :   switch (TheTriple.getObjectFormat()) {
    1183           0 :   default:
    1184           0 :     llvm_unreachable("unsupported object format");
    1185         919 :   case Triple::MachO: {
    1186         919 :     MachO::CPUSubTypeARM CS = getMachOSubTypeFromArch(TheTriple.getArchName());
    1187         919 :     return new ARMAsmBackendDarwin(T, STI, MRI, CS);
    1188             :   }
    1189          88 :   case Triple::COFF:
    1190             :     assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
    1191          88 :     return new ARMAsmBackendWinCOFF(T, STI);
    1192        2828 :   case Triple::ELF:
    1193             :     assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target");
    1194        2828 :     uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
    1195        2828 :     return new ARMAsmBackendELF(T, STI, OSABI, Endian);
    1196             :   }
    1197             : }
    1198             : 
    1199        3774 : MCAsmBackend *llvm::createARMLEAsmBackend(const Target &T,
    1200             :                                           const MCSubtargetInfo &STI,
    1201             :                                           const MCRegisterInfo &MRI,
    1202             :                                           const MCTargetOptions &Options) {
    1203        3774 :   return createARMAsmBackend(T, STI, MRI, Options, support::little);
    1204             : }
    1205             : 
    1206          61 : MCAsmBackend *llvm::createARMBEAsmBackend(const Target &T,
    1207             :                                           const MCSubtargetInfo &STI,
    1208             :                                           const MCRegisterInfo &MRI,
    1209             :                                           const MCTargetOptions &Options) {
    1210          61 :   return createARMAsmBackend(T, STI, MRI, Options, support::big);
    1211             : }

Generated by: LCOV version 1.13