ARMAsmBackend.cpp revision f2a1c83c86ceefb9a241aa728d1d1239a64b894e
1d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim//===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===// 2d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim// 3d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim// The LLVM Compiler Infrastructure 4d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim// 5d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim// This file is distributed under the University of Illinois Open Source 6d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim// License. See LICENSE.TXT for details. 7d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim// 8d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim//===----------------------------------------------------------------------===// 9d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 10d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "MCTargetDesc/ARMMCTargetDesc.h" 11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMAddressingModes.h" 12be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMBaseInfo.h" 13be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "MCTargetDesc/ARMFixupKinds.h" 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCAsmBackend.h" 15d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/MC/MCAssembler.h" 167a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach#include "llvm/MC/MCContext.h" 175be6d2af38c29e3653998978345220974cc40c01Jim Grosbach#include "llvm/MC/MCDirectives.h" 18285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#include "llvm/MC/MCELFObjectWriter.h" 19d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/MC/MCExpr.h" 20f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h" 21aa4b7dd13ba83152473950d7014a29686dc7eef6Daniel Dunbar#include "llvm/MC/MCMachObjectWriter.h" 22d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/MC/MCObjectWriter.h" 23d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/MC/MCSectionELF.h" 24d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/MC/MCSectionMachO.h" 25d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach#include "llvm/MC/MCSubtargetInfo.h" 269b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach#include "llvm/MC/MCValue.h" 2736d76a8dbc87b62de82a4a8c0d7cb4bb2a202934Daniel Dunbar#include "llvm/Object/MachOFormat.h" 28eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck#include "llvm/Support/ELF.h" 29d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/Support/ErrorHandling.h" 30d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim#include "llvm/Support/raw_ostream.h" 31d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kimusing namespace llvm; 32d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 33d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kimnamespace { 346024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolaclass ARMELFObjectWriter : public MCELFObjectTargetWriter { 356024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindolapublic: 36dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola ARMELFObjectWriter(uint8_t OSABI) 37dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM, 38bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola /*HasRelocationAddend*/ false) {} 396024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola}; 406024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola 4178c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Chengclass ARMAsmBackend : public MCAsmBackend { 42d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach const MCSubtargetInfo* STI; 435be6d2af38c29e3653998978345220974cc40c01Jim Grosbach bool isThumbMode; // Currently emitting Thumb code. 44d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kimpublic: 45d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach ARMAsmBackend(const Target &T, const StringRef TT) 46d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach : MCAsmBackend(), STI(ARM_MC::createARMMCSubtargetInfo(TT, "", "")), 47b9d3ff872908bcf648b826c1c48db2cacd813b95Jim Grosbach isThumbMode(TT.startswith("thumb")) {} 48d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach 49d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach ~ARMAsmBackend() { 50d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach delete STI; 51d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach } 52d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 532761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar unsigned getNumFixupKinds() const { return ARM::NumTargetFixupKinds; } 542761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 55d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach bool hasNOP() const { 56d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach return (STI->getFeatureBits() & ARM::HasV6T2Ops) != 0; 57d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach } 58d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach 592761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { 602761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar const static MCFixupKindInfo Infos[ARM::NumTargetFixupKinds] = { 612761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar// This table *must* be in the order that the fixup_* kinds are defined in 622761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar// ARMFixupKinds.h. 632761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar// 642761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar// Name Offset (bits) Size (bits) Flags 652abba8496cb394af53b531e95067d5cae78bb9eeJim Grosbach{ "fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 662761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | 672761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, 682f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach{ "fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 69681460f954e9c13ffd2f02f27bba048ccf90abafJim Grosbach{ "fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 702761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | 712761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, 722761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_thumb_adr_pcrel_10",0, 8, MCFixupKindInfo::FKF_IsPCRel | 732761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, 742abba8496cb394af53b531e95067d5cae78bb9eeJim Grosbach{ "fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 752761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_t2_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | 762761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, 77685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim{ "fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, 78685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim{ "fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, 792761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 802761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 812761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 82cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy{ "fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, 83cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy{ "fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, 847b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach{ "fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel }, 852761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 8690b5a08e1ffc4a1c18f7fa964ca561fa4b03c314Jim Grosbach{ "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, 872761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar{ "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, 889da7892fbe1c9e7c592c5928e36724a0e190a777Jim Grosbach{ "fixup_arm_thumb_cp", 0, 8, MCFixupKindInfo::FKF_IsPCRel | 899da7892fbe1c9e7c592c5928e36724a0e190a777Jim Grosbach MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}, 90fea51fc007598176d48fb7319a9bf471efb93127Eric Christopher{ "fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel }, 91f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng// movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 - 19. 92f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_arm_movt_hi16", 0, 20, 0 }, 93f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_arm_movw_lo16", 0, 20, 0 }, 94f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_t2_movt_hi16", 0, 20, 0 }, 95f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_t2_movw_lo16", 0, 20, 0 }, 96f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_arm_movt_hi16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, 97f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_arm_movw_lo16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, 98f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_t2_movt_hi16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, 99f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng{ "fixup_t2_movw_lo16_pcrel", 0, 20, MCFixupKindInfo::FKF_IsPCRel }, 1002761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar }; 1012761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 1022761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar if (Kind < FirstTargetFixupKind) 10378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng return MCAsmBackend::getFixupKindInfo(Kind); 1042761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 1052761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 1062761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar "Invalid kind!"); 1072761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar return Infos[Kind - FirstTargetFixupKind]; 1082761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar } 1092761fc427082215c2affcc9d8db8491400bc9e5dDaniel Dunbar 1109b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach /// processFixupValue - Target hook to process the literal value of a fixup 1119b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach /// if necessary. 1129b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, 1139b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach const MCFixup &Fixup, const MCFragment *DF, 1147b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach MCValue &Target, uint64_t &Value, 1157a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach bool &IsResolved); 1169b5b125c34b47e0e7eef2548acee8bf1448c4b71Jim Grosbach 117cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 118cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 119cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer uint64_t Value) const; 120cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 121ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach bool mayNeedRelaxation(const MCInst &Inst) const; 122d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 123370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach bool fixupNeedsRelaxation(const MCFixup &Fixup, 124370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach uint64_t Value, 125370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach const MCInstFragment *DF, 126370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach const MCAsmLayout &Layout) const; 127370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach 128ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach void relaxInstruction(const MCInst &Inst, MCInst &Res) const; 129d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 130ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach bool writeNopData(uint64_t Count, MCObjectWriter *OW) const; 1313787a40e038d6444a1b0e93f1cdc55fb006a5392Jim Grosbach 132ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbach void handleAssemblerFlag(MCAssemblerFlag Flag) { 1335be6d2af38c29e3653998978345220974cc40c01Jim Grosbach switch (Flag) { 1345be6d2af38c29e3653998978345220974cc40c01Jim Grosbach default: break; 1355be6d2af38c29e3653998978345220974cc40c01Jim Grosbach case MCAF_Code16: 1365be6d2af38c29e3653998978345220974cc40c01Jim Grosbach setIsThumb(true); 1375be6d2af38c29e3653998978345220974cc40c01Jim Grosbach break; 1385be6d2af38c29e3653998978345220974cc40c01Jim Grosbach case MCAF_Code32: 1395be6d2af38c29e3653998978345220974cc40c01Jim Grosbach setIsThumb(false); 1405be6d2af38c29e3653998978345220974cc40c01Jim Grosbach break; 1415be6d2af38c29e3653998978345220974cc40c01Jim Grosbach } 1423787a40e038d6444a1b0e93f1cdc55fb006a5392Jim Grosbach } 1435be6d2af38c29e3653998978345220974cc40c01Jim Grosbach 1445be6d2af38c29e3653998978345220974cc40c01Jim Grosbach unsigned getPointerSize() const { return 4; } 1455be6d2af38c29e3653998978345220974cc40c01Jim Grosbach bool isThumb() const { return isThumbMode; } 1465be6d2af38c29e3653998978345220974cc40c01Jim Grosbach void setIsThumb(bool it) { isThumbMode = it; } 147d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim}; 148b75c651e22a63907b727664f044283bf9c9fb885Chris Lattner} // end anonymous namespace 149d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 150f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbachstatic unsigned getRelaxedOpcode(unsigned Op) { 151f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach switch (Op) { 152f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach default: return Op; 153256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach case ARM::tBcc: return ARM::t2Bcc; 154256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach case ARM::tLDRpciASM: return ARM::t2LDRpci; 1559363c58dc2473a6470d3e7037afe8a215bee7e3eJim Grosbach case ARM::tADR: return ARM::t2ADR; 156fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach case ARM::tB: return ARM::t2B; 157f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach } 158f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach} 159f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach 160ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbachbool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst) const { 161f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach if (getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode()) 162f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach return true; 163d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim return false; 164d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim} 165d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 166370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbachbool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, 167370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach uint64_t Value, 168370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach const MCInstFragment *DF, 169370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach const MCAsmLayout &Layout) const { 170e545ee20f1b6ea6c03919cc9bc1a4a059c2f03b6Benjamin Kramer switch ((unsigned)Fixup.getKind()) { 171fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach case ARM::fixup_arm_thumb_br: { 172fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach // Relaxing tB to t2B. tB has a signed 12-bit displacement with the 173fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach // low bit being an implied zero. There's an implied +4 offset for the 174fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach // branch, so we adjust the other way here to determine what's 175fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach // encodable. 176fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach // 177fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach // Relax if the value is too big for a (signed) i8. 178fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach int64_t Offset = int64_t(Value) - 4; 179fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach return Offset > 2046 || Offset < -2048; 180fa1f74470a51a57b7b8feb4c4ba18501c3f2709aJim Grosbach } 181256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach case ARM::fixup_arm_thumb_bcc: { 182256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the 183256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach // low bit being an implied zero. There's an implied +4 offset for the 184256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach // branch, so we adjust the other way here to determine what's 185256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach // encodable. 186256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach // 187256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach // Relax if the value is too big for a (signed) i8. 188256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach int64_t Offset = int64_t(Value) - 4; 189256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach return Offset > 254 || Offset < -256; 190256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach } 1919363c58dc2473a6470d3e7037afe8a215bee7e3eJim Grosbach case ARM::fixup_thumb_adr_pcrel_10: 192256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach case ARM::fixup_arm_thumb_cp: { 193d26bad079d6977309699e0bc9203451904acbd86Jim Grosbach // If the immediate is negative, greater than 1020, or not a multiple 194d26bad079d6977309699e0bc9203451904acbd86Jim Grosbach // of four, the wide version of the instruction must be used. 195256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach int64_t Offset = int64_t(Value) - 4; 196d26bad079d6977309699e0bc9203451904acbd86Jim Grosbach return Offset > 1020 || Offset < 0 || Offset & 3; 197256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach } 198256ba4f42a16da2b3ffc757aa7bf191890765580Jim Grosbach } 199e545ee20f1b6ea6c03919cc9bc1a4a059c2f03b6Benjamin Kramer llvm_unreachable("Unexpected fixup kind in fixupNeedsRelaxation()!"); 200370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach} 201370b78d795154899a22ca2b4674e890661ff1d59Jim Grosbach 202ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbachvoid ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { 203f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); 204f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach 205f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach // Sanity check w/ diagnostic if we get here w/ a bogus instruction. 206f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach if (RelaxedOp == Inst.getOpcode()) { 207f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach SmallString<256> Tmp; 208f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach raw_svector_ostream OS(Tmp); 209f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach Inst.dump_pretty(OS); 210f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach OS << "\n"; 211f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach report_fatal_error("unexpected instruction to relax: " + OS.str()); 212f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach } 213f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach 214f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach // The instructions we're relaxing have (so far) the same operands. 215f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach // We just need to update to the proper opcode. 216f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach Res = Inst; 217f503ef6800fcbda99d6ae581ee8cfe3204becb3cJim Grosbach Res.setOpcode(RelaxedOp); 218d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim} 219d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 220ec3433852dd11e8ff60c9610b4c84468e5935f2bJim Grosbachbool ARMAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { 221d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8 222d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP 223f2a1c83c86ceefb9a241aa728d1d1239a64b894eDavid Sehr const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0 224b84acd24687c721e3da46bb56a94d393bc5a8cbcJim Grosbach const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP 2255be6d2af38c29e3653998978345220974cc40c01Jim Grosbach if (isThumb()) { 226d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach const uint16_t nopEncoding = hasNOP() ? Thumb2_16bitNopEncoding 227d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach : Thumb1_16bitNopEncoding; 228a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach uint64_t NumNops = Count / 2; 229a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach for (uint64_t i = 0; i != NumNops; ++i) 230d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach OW->Write16(nopEncoding); 231a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach if (Count & 1) 232a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach OW->Write8(0); 2335be6d2af38c29e3653998978345220974cc40c01Jim Grosbach return true; 2345be6d2af38c29e3653998978345220974cc40c01Jim Grosbach } 2355be6d2af38c29e3653998978345220974cc40c01Jim Grosbach // ARM mode 236d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach const uint32_t nopEncoding = hasNOP() ? ARMv6T2_NopEncoding 237d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach : ARMv4_NopEncoding; 238a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach uint64_t NumNops = Count / 4; 239a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach for (uint64_t i = 0; i != NumNops; ++i) 240d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach OW->Write32(nopEncoding); 241d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach // FIXME: should this function return false when unable to write exactly 242d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach // 'Count' bytes with NOP encodings? 243a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach switch (Count % 4) { 244a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach default: break; // No leftover bytes to write 245a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach case 1: OW->Write8(0); break; 246a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach case 2: OW->Write16(0); break; 247a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach case 3: OW->Write16(0); OW->Write8(0xa0); break; 248a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach } 249a3dbd3a2444f2531763ba05b64a30932542a631fJim Grosbach 250cecbc3d28277ff4916326311cbf87335ed05d106Rafael Espindola return true; 25187dc3aa2d87871f1affc6f3f2fa587c7b6725d83Jim Grosbach} 252d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 2537a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbachstatic unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, 2547a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach MCContext *Ctx = NULL) { 2557a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach unsigned Kind = Fixup.getKind(); 2560c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim switch (Kind) { 2570c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim default: 2580c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim llvm_unreachable("Unknown fixup kind!"); 2596ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach case FK_Data_1: 2606ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach case FK_Data_2: 2610c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim case FK_Data_4: 2622ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim return Value; 2630c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim case ARM::fixup_arm_movt_hi16: 264f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Value >>= 16; 265f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng // Fallthrough 266f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_arm_movw_lo16: 267861b9c6a397f2ed4b5601cacbc9121d0b07d1f65Jason W Kim case ARM::fixup_arm_movt_hi16_pcrel: 26886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16_pcrel: { 2692ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim unsigned Hi4 = (Value & 0xF000) >> 12; 2702ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim unsigned Lo12 = Value & 0x0FFF; 2712ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim // inst{19-16} = Hi4; 2722ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim // inst{11-0} = Lo12; 2732ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim Value = (Hi4 << 16) | (Lo12); 2740c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim return Value; 2752ccf148fbaaf9ea15233d7ef09e31ca0fa6ee3beJason W Kim } 276f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 277f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Value >>= 16; 278f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng // Fallthrough 279f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 2808b45456700f1e156b0a14000124f274dfac86f14Jim Grosbach case ARM::fixup_t2_movt_hi16_pcrel: //FIXME: Shouldn't this be shifted like 2818b45456700f1e156b0a14000124f274dfac86f14Jim Grosbach // the other hi16 fixup? 282f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: { 283f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng unsigned Hi4 = (Value & 0xF000) >> 12; 284f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng unsigned i = (Value & 0x800) >> 11; 285f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng unsigned Mid3 = (Value & 0x700) >> 8; 286f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng unsigned Lo8 = Value & 0x0FF; 287f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng // inst{19-16} = Hi4; 288f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng // inst{26} = i; 289f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng // inst{14-12} = Mid3; 290f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng // inst{7-0} = Lo8; 291f391e9f696183a8dfb6b0d1e791687a520552f85Jim Grosbach Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8); 292f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng uint64_t swapped = (Value & 0xFFFF0000) >> 16; 293f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng swapped |= (Value & 0x0000FFFF) << 16; 294f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng return swapped; 295f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng } 296d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson case ARM::fixup_arm_ldst_pcrel_12: 2970c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim // ARM PC-relative values are offset by 8. 29805018c2f2872a05b1a2fff1a9934621ba1f38084Owen Anderson Value -= 4; 299fe7fac74b4edaf9cc04460fc21aa949e5533aea2Owen Anderson // FALLTHROUGH 300d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson case ARM::fixup_t2_ldst_pcrel_12: { 301d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson // Offset by 4, adjusted by two due to the half-word ordering of thumb. 30205018c2f2872a05b1a2fff1a9934621ba1f38084Owen Anderson Value -= 4; 303d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson bool isAdd = true; 3040c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim if ((int64_t)Value < 0) { 3050c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim Value = -Value; 3060c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim isAdd = false; 3070c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim } 3087a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (Ctx && Value >= 4096) 3097a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach Ctx->FatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); 3100c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim Value |= isAdd << 23; 3117e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach 312d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson // Same addressing mode as fixup_arm_pcrel_10, 313d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson // but with 16-bit halfwords swapped. 314d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson if (Kind == ARM::fixup_t2_ldst_pcrel_12) { 315d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson uint64_t swapped = (Value & 0xFFFF0000) >> 16; 316d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson swapped |= (Value & 0x0000FFFF) << 16; 317d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson return swapped; 318d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson } 3197e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach 3200c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim return Value; 3210c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim } 322d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::fixup_thumb_adr_pcrel_10: 323d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach return ((Value - 4) >> 2) & 0xff; 324dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: { 325dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // ARM PC-relative values are offset by 8. 326dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach Value -= 8; 327dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach unsigned opc = 4; // bits {24-21}. Default to add: 0b0100 328dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach if ((int64_t)Value < 0) { 329dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach Value = -Value; 330dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach opc = 2; // 0b0010 331dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 3327a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (Ctx && ARM_AM::getSOImmVal(Value) == -1) 3337a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach Ctx->FatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); 334dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach // Encode the immediate and shift the opcode into place. 335dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach return ARM_AM::getSOImmVal(Value) | (opc << 21); 336dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach } 337e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach 338a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson case ARM::fixup_t2_adr_pcrel_12: { 339a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson Value -= 4; 340a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson unsigned opc = 0; 341a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson if ((int64_t)Value < 0) { 342a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson Value = -Value; 343a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson opc = 5; 344a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson } 345a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson 346a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uint32_t out = (opc << 21); 347741ad15e26d1717433f326743800f30c63c6a9c1Owen Anderson out |= (Value & 0x800) << 15; 348a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson out |= (Value & 0x700) << 4; 349a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson out |= (Value & 0x0FF); 350e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach 351a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson uint64_t swapped = (out & 0xFFFF0000) >> 16; 352a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson swapped |= (out & 0x0000FFFF) << 16; 353a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson return swapped; 354a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson } 355e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach 356685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 357685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 358cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy case ARM::fixup_arm_uncondbl: 359cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy case ARM::fixup_arm_condbl: 3607b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach case ARM::fixup_arm_blx: 3610c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim // These values don't encode the low two bits since they're always zero. 3620c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim // Offset by 8 just as above. 363662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 0xffffff & ((Value - 8) >> 2); 364c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson case ARM::fixup_t2_uncondbranch: { 36563ee22065dc4e8af7f4bf99c25b82da132700267Owen Anderson Value = Value - 4; 366fb20d890756b75d6ccfa7ab17f170a877d425dc6Owen Anderson Value >>= 1; // Low bit is not encoded. 3677e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach 36856a2535474dd4482c432b3c75c3dab4b2f3dd1e2Jim Grosbach uint32_t out = 0; 369c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool I = Value & 0x800000; 370c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J1 = Value & 0x400000; 371c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson bool J2 = Value & 0x200000; 372c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson J1 ^= I; 373c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson J2 ^= I; 374e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach 375c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson out |= I << 26; // S bit 376c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson out |= !J1 << 13; // J1 bit 377c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson out |= !J2 << 11; // J2 bit 378c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson out |= (Value & 0x1FF800) << 5; // imm6 field 379c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson out |= (Value & 0x0007FF); // imm11 field 380e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach 381c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson uint64_t swapped = (out & 0xFFFF0000) >> 16; 382c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson swapped |= (out & 0x0000FFFF) << 16; 383c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson return swapped; 384c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson } 385c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson case ARM::fixup_t2_condbranch: { 386c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Value = Value - 4; 387c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson Value >>= 1; // Low bit is not encoded. 388e8eb1ea6acd54538b42491b95d8fc6281d4b5710Jim Grosbach 389c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson uint64_t out = 0; 3908f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson out |= (Value & 0x80000) << 7; // S bit 3918f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson out |= (Value & 0x40000) >> 7; // J2 bit 3928f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson out |= (Value & 0x20000) >> 4; // J1 bit 3938f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson out |= (Value & 0x1F800) << 5; // imm6 field 3948f0794331765661f92cf074f638acb1ea927bb5dOwen Anderson out |= (Value & 0x007FF); // imm11 field 3957e294cfcf97cd7b94bf5c4de0f214480ec13adadJim Grosbach 39656a2535474dd4482c432b3c75c3dab4b2f3dd1e2Jim Grosbach uint32_t swapped = (out & 0xFFFF0000) >> 16; 397fb20d890756b75d6ccfa7ab17f170a877d425dc6Owen Anderson swapped |= (out & 0x0000FFFF) << 16; 398fb20d890756b75d6ccfa7ab17f170a877d425dc6Owen Anderson return swapped; 399fb20d890756b75d6ccfa7ab17f170a877d425dc6Owen Anderson } 400662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: { 4012d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // The value doesn't encode the low bit (always zero) and is offset by 4022d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // four. The 32-bit immediate value is encoded as 4032d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // imm32 = SignExtend(S:I1:I2:imm10:imm11:0) 4042d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S). 4052d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // The value is encoded into disjoint bit positions in the destination 4062d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // opcode. x = unchanged, I = immediate value bit, S = sign extension bit, 4072d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // J = either J1 or J2 bit 4082d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // 4092d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // BL: xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII 4102d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // 4112d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // Note that the halfwords are stored high first, low second; so we need 4122d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // to transpose the fixup value here to map properly. 4132d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t offset = (Value - 4) >> 1; 4142d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t signBit = (offset & 0x800000) >> 23; 4152d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t I1Bit = (offset & 0x400000) >> 22; 4162d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit; 4172d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t I2Bit = (offset & 0x200000) >> 21; 4182d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit; 4192d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t imm10Bits = (offset & 0x1FF800) >> 11; 4202d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t imm11Bits = (offset & 0x000007FF); 4212d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby 4222d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t Binary = 0; 4232d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits); 4242d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) | 4252d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby (uint16_t)imm11Bits); 4262d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby Binary |= secondHalf << 16; 4272d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby Binary |= firstHalf; 4282d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby return Binary; 4292d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby 43009aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling } 43109aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling case ARM::fixup_arm_thumb_blx: { 4322d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // The value doesn't encode the low two bits (always zero) and is offset by 4332d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as 4342d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00) 4352d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S). 4362d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // The value is encoded into disjoint bit positions in the destination 4372d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // opcode. x = unchanged, I = immediate value bit, S = sign extension bit, 4382d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // J = either J1 or J2 bit, 0 = zero. 4392d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // 4402d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0 4412d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // 4422d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // Note that the halfwords are stored high first, low second; so we need 4432d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby // to transpose the fixup value here to map properly. 4442d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t offset = (Value - 2) >> 2; 4452d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t signBit = (offset & 0x400000) >> 22; 4462d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t I1Bit = (offset & 0x200000) >> 21; 4472d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit; 4482d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t I2Bit = (offset & 0x100000) >> 20; 4492d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit; 4502d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t imm10HBits = (offset & 0xFFC00) >> 10; 4512d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t imm10LBits = (offset & 0x3FF); 4522d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby 4532d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t Binary = 0; 4542d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits); 4552d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) | 4562d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby ((uint16_t)imm10LBits) << 1); 4572d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby Binary |= secondHalf << 16; 4582d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby Binary |= firstHalf; 4592d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby return Binary; 460662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach } 461b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 4620c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach // Offset by 4, and don't encode the low two bits. Two bytes of that 4630c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach // 'off by 4' is implicitly handled by the half-word ordering of the 4640c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach // Thumb encoding, so we only need to adjust by 2 here. 4650c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach return ((Value - 2) >> 2) & 0xff; 466b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: { 467dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling // Offset by 4 and don't encode the lower bit, which is always 0. 468dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling uint32_t Binary = (Value - 4) >> 1; 46986abd48fd01080f08eec1b46f92c90308b03bfd4Owen Anderson return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3); 470dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling } 471e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 472e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach // Offset by 4 and don't encode the lower bit, which is always 0. 473e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach return ((Value - 4) >> 1) & 0x7ff; 47401086451393ef33e82b6fad623989dd97dd70edfJim Grosbach case ARM::fixup_arm_thumb_bcc: 47501086451393ef33e82b6fad623989dd97dd70edfJim Grosbach // Offset by 4 and don't encode the lower bit, which is always 0. 47601086451393ef33e82b6fad623989dd97dd70edfJim Grosbach return ((Value - 4) >> 1) & 0xff; 4772f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach case ARM::fixup_arm_pcrel_10_unscaled: { 4782f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Value = Value - 8; // ARM fixups offset by an additional word and don't 4792f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // need to adjust for the half-word ordering. 4802f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach bool isAdd = true; 4812f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach if ((int64_t)Value < 0) { 4822f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach Value = -Value; 4832f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach isAdd = false; 4842f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 485bf3c322640fdaf6e4a60a59ed8cb108a7f6685adJim Grosbach // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8]. 4867a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (Ctx && Value >= 256) 4877a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach Ctx->FatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); 488bf3c322640fdaf6e4a60a59ed8cb108a7f6685adJim Grosbach Value = (Value & 0xf) | ((Value & 0xf0) << 4); 4892f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach return Value | (isAdd << 23); 4902f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach } 4910c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach case ARM::fixup_arm_pcrel_10: 492e2e0f58809374265bd75edeefae8817e7ade62b4Owen Anderson Value = Value - 4; // ARM fixups offset by an additional word and don't 4930c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach // need to adjust for the half-word ordering. 4940c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach // Fall through. 4950c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach case ARM::fixup_t2_pcrel_10: { 4960c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach // Offset by 4, adjusted by two due to the half-word ordering of thumb. 497e2e0f58809374265bd75edeefae8817e7ade62b4Owen Anderson Value = Value - 4; 4980c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim bool isAdd = true; 4990c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim if ((int64_t)Value < 0) { 5000c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim Value = -Value; 5010c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim isAdd = false; 5020c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim } 5030c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim // These values don't encode the low two bits since they're always zero. 5040c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim Value >>= 2; 5057a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (Ctx && Value >= 256) 5067a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach Ctx->FatalError(Fixup.getLoc(), "out of range pc-relative fixup value"); 5070c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim Value |= isAdd << 23; 5080c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach 5092f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords 5102f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach // swapped. 511d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson if (Kind == ARM::fixup_t2_pcrel_10) { 51256a2535474dd4482c432b3c75c3dab4b2f3dd1e2Jim Grosbach uint32_t swapped = (Value & 0xFFFF0000) >> 16; 513255eafbd498e7d41ceef45ee0ad13bfde573ff82Owen Anderson swapped |= (Value & 0x0000FFFF) << 16; 514d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson return swapped; 515d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson } 5160c2c217244573cdfb4be8b7fa62670412b4c1e71Jim Grosbach 5170c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim return Value; 5180c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim } 5190c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim } 5200c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim} 5210c628c2617a2c25cabea6d1cb8bd13b79b3cb15aJason W Kim 5227a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbachvoid ARMAsmBackend::processFixupValue(const MCAssembler &Asm, 5237a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach const MCAsmLayout &Layout, 5247a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach const MCFixup &Fixup, 5257a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach const MCFragment *DF, 5267a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach MCValue &Target, uint64_t &Value, 5277a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach bool &IsResolved) { 5287a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach const MCSymbolRefExpr *A = Target.getSymA(); 5297a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // Some fixups to thumb function symbols need the low bit (thumb bit) 5307a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // twiddled. 5317a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if ((unsigned)Fixup.getKind() != ARM::fixup_arm_ldst_pcrel_12 && 5327a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() != ARM::fixup_t2_ldst_pcrel_12 && 5337a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() != ARM::fixup_arm_adr_pcrel_12 && 5347a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() != ARM::fixup_thumb_adr_pcrel_10 && 5357a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() != ARM::fixup_t2_adr_pcrel_12 && 5367a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() != ARM::fixup_arm_thumb_cp) { 5377a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (A) { 5387a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); 5397a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (Asm.isThumbFunc(&Sym)) 5407a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach Value |= 1; 5417a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } 5427a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach } 5437a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // We must always generate a relocation for BL/BLX instructions if we have 5447a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // a symbol to reference, as the linker relies on knowing the destination 5457a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // symbol's thumb-ness to get interworking right. 5467a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx || 5477a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl || 5487a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() == ARM::fixup_arm_blx || 5497a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() == ARM::fixup_arm_uncondbl || 5507a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (unsigned)Fixup.getKind() == ARM::fixup_arm_condbl)) 5517a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach IsResolved = false; 5527a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach 5537a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // Try to get the encoded value for the fixup as-if we're mapping it into 5547a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // the instruction. This allows adjustFixupValue() to issue a diagnostic 5557a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach // if the value aren't invalid. 5567a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach (void)adjustFixupValue(Fixup, Value, &Asm.getContext()); 5577a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach} 5587a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach 559d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling/// getFixupKindNumBytes - The number of bytes the fixup may change. 560c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbachstatic unsigned getFixupKindNumBytes(unsigned Kind) { 561679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach switch (Kind) { 562662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach default: 563662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach llvm_unreachable("Unknown fixup kind!"); 564b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 5656ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach case FK_Data_1: 56601086451393ef33e82b6fad623989dd97dd70edfJim Grosbach case ARM::fixup_arm_thumb_bcc: 567b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 568d40963c4065432ec7e47879d3ca665a54ee903b6Jim Grosbach case ARM::fixup_thumb_adr_pcrel_10: 569b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling return 1; 570b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 5716ec6eeb692fa11b569af8b69b2bb11cc84f04926Jim Grosbach case FK_Data_2: 572e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 573b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 574dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling return 2; 575dff2f7151f695b86db8c4b0c6604463bdb8a63eaBill Wendling 5762f196747f15240691bd4e622f7995edfedf90f61Jim Grosbach case ARM::fixup_arm_pcrel_10_unscaled: 577662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 578662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_pcrel_10: 579662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_adr_pcrel_12: 580cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy case ARM::fixup_arm_uncondbl: 581cb0809b82b126e79b99755ae4fc3d9733faea038James Molloy case ARM::fixup_arm_condbl: 5827b25ecf6adbf3c4709c48033acfeb6ebbb4452abJim Grosbach case ARM::fixup_arm_blx: 583685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 584685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 585662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 3; 586b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling 587b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case FK_Data_4: 588d7b3f5870d9d04351d9cd363d9d6af01482a2eb8Owen Anderson case ARM::fixup_t2_ldst_pcrel_12: 589c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson case ARM::fixup_t2_condbranch: 590c266600bec4b5ba0ee93ffdfeaafcab8f1295145Owen Anderson case ARM::fixup_t2_uncondbranch: 591d8e351b96f5fd7007fbdd636acaa1fc9f6e18f3cOwen Anderson case ARM::fixup_t2_pcrel_10: 592a838a25d59838adfa91463f6a918ae3adeb352c1Owen Anderson case ARM::fixup_t2_adr_pcrel_12: 593662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 59409aa3f0ef35d9241c92439d74b8d5e9a81d814c2Bill Wendling case ARM::fixup_arm_thumb_blx: 595f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_arm_movt_hi16: 596f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_arm_movw_lo16: 597f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_arm_movt_hi16_pcrel: 598f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_arm_movw_lo16_pcrel: 599f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 600f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 601f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16_pcrel: 602f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: 603662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach return 4; 604679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach } 605679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach} 606679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach 607cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramervoid ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, 608cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer unsigned DataSize, uint64_t Value) const { 609c466b937dbdbaabeef0097fe340de1b8f49a3508Jim Grosbach unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); 6107a3afa91ad8f68428373948fc16375e99bff3c6fJim Grosbach Value = adjustFixupValue(Fixup, Value); 611d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling if (!Value) return; // Doesn't change encoding. 612d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling 613d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling unsigned Offset = Fixup.getOffset(); 614d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!"); 615679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach 616cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer // For each byte of the fragment that the fixup touches, mask in the bits from 617cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer // the fixup value. The Value has been "split up" into the appropriate 618cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer // bitfields above. 619679cbd3b215b1769a6035e334f9009aeeb940dddJim Grosbach for (unsigned i = 0; i != NumBytes; ++i) 620d832fa053b86f42a5bc1e55e979b61c1115a8053Bill Wendling Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff); 621d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim} 62252e635ea3512cfcd03587201b20100074e5b6ac9Bill Wendling 623cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramernamespace { 624cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 625cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer// FIXME: This should be in a separate file. 626cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer// ELF is an ELF of course... 627cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramerclass ELFARMAsmBackend : public ARMAsmBackend { 628cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramerpublic: 629cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer uint8_t OSABI; 630cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer ELFARMAsmBackend(const Target &T, const StringRef TT, 631cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer uint8_t _OSABI) 632cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer : ARMAsmBackend(T, TT), OSABI(_OSABI) { } 633cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 634cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 635cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer return createARMELFObjectWriter(OS, OSABI); 636cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 637cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer}; 638cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 639cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer// FIXME: This should be in a separate file. 640cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramerclass DarwinARMAsmBackend : public ARMAsmBackend { 641cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramerpublic: 642cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer const object::mach::CPUSubtypeARM Subtype; 643cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer DarwinARMAsmBackend(const Target &T, const StringRef TT, 644cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer object::mach::CPUSubtypeARM st) 645cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer : ARMAsmBackend(T, TT), Subtype(st) { 646cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer HasDataInCodeSupport = true; 647cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 648cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 649cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 650cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer return createARMMachObjectWriter(OS, /*Is64Bit=*/false, 651cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer object::mach::CTM_ARM, 652cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer Subtype); 653cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 654cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 655cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 656cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer return false; 657cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer } 658cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer}; 659cb4028b91d7c1b0163d1b6c85911668d3d19c75aBenjamin Kramer 660f73fd7278f2bebd435c84c55a79db8ccb07d3534Jim Grosbach} // end anonymous namespace 661d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim 662536a88ad5bf160232205192a7ce72e50bfadbdedRoman DivackyMCAsmBackend *llvm::createARMAsmBackend(const Target &T, StringRef TT, StringRef CPU) { 6631721324d97e2b05c9276ffe116dfb6c808521c2bOwen Anderson Triple TheTriple(TT); 664912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 665912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar if (TheTriple.isOSDarwin()) { 666a6eb2562b62fc293295f2fede2608753563e7005Evan Cheng if (TheTriple.getArchName() == "armv4t" || 667a6eb2562b62fc293295f2fede2608753563e7005Evan Cheng TheTriple.getArchName() == "thumbv4t") 668d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V4T); 669a6eb2562b62fc293295f2fede2608753563e7005Evan Cheng else if (TheTriple.getArchName() == "armv5e" || 670a6eb2562b62fc293295f2fede2608753563e7005Evan Cheng TheTriple.getArchName() == "thumbv5e") 671d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V5TEJ); 672a6eb2562b62fc293295f2fede2608753563e7005Evan Cheng else if (TheTriple.getArchName() == "armv6" || 6731721324d97e2b05c9276ffe116dfb6c808521c2bOwen Anderson TheTriple.getArchName() == "thumbv6") 674d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V6); 675eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson else if (TheTriple.getArchName() == "armv7f" || 676eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson TheTriple.getArchName() == "thumbv7f") 677eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V7F); 678eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson else if (TheTriple.getArchName() == "armv7k" || 679eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson TheTriple.getArchName() == "thumbv7k") 680eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V7K); 681eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson else if (TheTriple.getArchName() == "armv7s" || 682eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson TheTriple.getArchName() == "thumbv7s") 683eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V7S); 684d0d3f7e01ff7f83575816f6e1d75aa2224ebc2cbJim Grosbach return new DarwinARMAsmBackend(T, TT, object::mach::CSARM_V7); 6851721324d97e2b05c9276ffe116dfb6c808521c2bOwen Anderson } 686912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 687912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar if (TheTriple.isOSWindows()) 688d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim assert(0 && "Windows not supported on ARM"); 689912225e18559a73228099330a4c253fdccf9fa3dDaniel Dunbar 690dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS()); 691dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola return new ELFARMAsmBackend(T, TT, OSABI); 692d4d4f4f488d46a9743a0c494b42b22a1b15e0e7dJason W Kim} 693