1//===-- HexagonAsmBackend.cpp - Hexagon 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 "Hexagon.h" 11#include "HexagonFixupKinds.h" 12#include "HexagonMCTargetDesc.h" 13#include "MCTargetDesc/HexagonBaseInfo.h" 14#include "MCTargetDesc/HexagonMCInstrInfo.h" 15#include "llvm/MC/MCAsmBackend.h" 16#include "llvm/MC/MCAsmLayout.h" 17#include "llvm/MC/MCAssembler.h" 18#include "llvm/MC/MCContext.h" 19#include "llvm/MC/MCELFObjectWriter.h" 20#include "llvm/MC/MCFixupKindInfo.h" 21#include "llvm/MC/MCInstrInfo.h" 22#include "llvm/Support/Debug.h" 23#include "llvm/Support/TargetRegistry.h" 24 25using namespace llvm; 26using namespace Hexagon; 27 28#define DEBUG_TYPE "hexagon-asm-backend" 29 30namespace { 31 32class HexagonAsmBackend : public MCAsmBackend { 33 uint8_t OSABI; 34 StringRef CPU; 35 mutable uint64_t relaxedCnt; 36 std::unique_ptr <MCInstrInfo> MCII; 37 std::unique_ptr <MCInst *> RelaxTarget; 38 MCInst * Extender; 39public: 40 HexagonAsmBackend(Target const &T, uint8_t OSABI, StringRef CPU) : 41 OSABI(OSABI), MCII (T.createMCInstrInfo()), RelaxTarget(new MCInst *), 42 Extender(nullptr) {} 43 44 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { 45 return createHexagonELFObjectWriter(OS, OSABI, CPU); 46 } 47 48 void setExtender(MCContext &Context) const { 49 if (Extender == nullptr) 50 const_cast<HexagonAsmBackend *>(this)->Extender = new (Context) MCInst; 51 } 52 53 MCInst *takeExtender() const { 54 assert(Extender != nullptr); 55 MCInst * Result = Extender; 56 const_cast<HexagonAsmBackend *>(this)->Extender = nullptr; 57 return Result; 58 } 59 60 unsigned getNumFixupKinds() const override { 61 return Hexagon::NumTargetFixupKinds; 62 } 63 64 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { 65 const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = { 66 // This table *must* be in same the order of fixup_* kinds in 67 // HexagonFixupKinds.h. 68 // 69 // namei offset bits flags 70 {"fixup_Hexagon_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 71 {"fixup_Hexagon_B15_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 72 {"fixup_Hexagon_B7_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 73 {"fixup_Hexagon_LO16", 0, 32, 0}, 74 {"fixup_Hexagon_HI16", 0, 32, 0}, 75 {"fixup_Hexagon_32", 0, 32, 0}, 76 {"fixup_Hexagon_16", 0, 32, 0}, 77 {"fixup_Hexagon_8", 0, 32, 0}, 78 {"fixup_Hexagon_GPREL16_0", 0, 32, 0}, 79 {"fixup_Hexagon_GPREL16_1", 0, 32, 0}, 80 {"fixup_Hexagon_GPREL16_2", 0, 32, 0}, 81 {"fixup_Hexagon_GPREL16_3", 0, 32, 0}, 82 {"fixup_Hexagon_HL16", 0, 32, 0}, 83 {"fixup_Hexagon_B13_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 84 {"fixup_Hexagon_B9_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 85 {"fixup_Hexagon_B32_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 86 {"fixup_Hexagon_32_6_X", 0, 32, 0}, 87 {"fixup_Hexagon_B22_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 88 {"fixup_Hexagon_B15_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 89 {"fixup_Hexagon_B13_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 90 {"fixup_Hexagon_B9_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 91 {"fixup_Hexagon_B7_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 92 {"fixup_Hexagon_16_X", 0, 32, 0}, 93 {"fixup_Hexagon_12_X", 0, 32, 0}, 94 {"fixup_Hexagon_11_X", 0, 32, 0}, 95 {"fixup_Hexagon_10_X", 0, 32, 0}, 96 {"fixup_Hexagon_9_X", 0, 32, 0}, 97 {"fixup_Hexagon_8_X", 0, 32, 0}, 98 {"fixup_Hexagon_7_X", 0, 32, 0}, 99 {"fixup_Hexagon_6_X", 0, 32, 0}, 100 {"fixup_Hexagon_32_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 101 {"fixup_Hexagon_COPY", 0, 32, 0}, 102 {"fixup_Hexagon_GLOB_DAT", 0, 32, 0}, 103 {"fixup_Hexagon_JMP_SLOT", 0, 32, 0}, 104 {"fixup_Hexagon_RELATIVE", 0, 32, 0}, 105 {"fixup_Hexagon_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 106 {"fixup_Hexagon_GOTREL_LO16", 0, 32, 0}, 107 {"fixup_Hexagon_GOTREL_HI16", 0, 32, 0}, 108 {"fixup_Hexagon_GOTREL_32", 0, 32, 0}, 109 {"fixup_Hexagon_GOT_LO16", 0, 32, 0}, 110 {"fixup_Hexagon_GOT_HI16", 0, 32, 0}, 111 {"fixup_Hexagon_GOT_32", 0, 32, 0}, 112 {"fixup_Hexagon_GOT_16", 0, 32, 0}, 113 {"fixup_Hexagon_DTPMOD_32", 0, 32, 0}, 114 {"fixup_Hexagon_DTPREL_LO16", 0, 32, 0}, 115 {"fixup_Hexagon_DTPREL_HI16", 0, 32, 0}, 116 {"fixup_Hexagon_DTPREL_32", 0, 32, 0}, 117 {"fixup_Hexagon_DTPREL_16", 0, 32, 0}, 118 {"fixup_Hexagon_GD_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 119 {"fixup_Hexagon_LD_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 120 {"fixup_Hexagon_GD_GOT_LO16", 0, 32, 0}, 121 {"fixup_Hexagon_GD_GOT_HI16", 0, 32, 0}, 122 {"fixup_Hexagon_GD_GOT_32", 0, 32, 0}, 123 {"fixup_Hexagon_GD_GOT_16", 0, 32, 0}, 124 {"fixup_Hexagon_LD_GOT_LO16", 0, 32, 0}, 125 {"fixup_Hexagon_LD_GOT_HI16", 0, 32, 0}, 126 {"fixup_Hexagon_LD_GOT_32", 0, 32, 0}, 127 {"fixup_Hexagon_LD_GOT_16", 0, 32, 0}, 128 {"fixup_Hexagon_IE_LO16", 0, 32, 0}, 129 {"fixup_Hexagon_IE_HI16", 0, 32, 0}, 130 {"fixup_Hexagon_IE_32", 0, 32, 0}, 131 {"fixup_Hexagon_IE_16", 0, 32, 0}, 132 {"fixup_Hexagon_IE_GOT_LO16", 0, 32, 0}, 133 {"fixup_Hexagon_IE_GOT_HI16", 0, 32, 0}, 134 {"fixup_Hexagon_IE_GOT_32", 0, 32, 0}, 135 {"fixup_Hexagon_IE_GOT_16", 0, 32, 0}, 136 {"fixup_Hexagon_TPREL_LO16", 0, 32, 0}, 137 {"fixup_Hexagon_TPREL_HI16", 0, 32, 0}, 138 {"fixup_Hexagon_TPREL_32", 0, 32, 0}, 139 {"fixup_Hexagon_TPREL_16", 0, 32, 0}, 140 {"fixup_Hexagon_6_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, 141 {"fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0}, 142 {"fixup_Hexagon_GOTREL_16_X", 0, 32, 0}, 143 {"fixup_Hexagon_GOTREL_11_X", 0, 32, 0}, 144 {"fixup_Hexagon_GOT_32_6_X", 0, 32, 0}, 145 {"fixup_Hexagon_GOT_16_X", 0, 32, 0}, 146 {"fixup_Hexagon_GOT_11_X", 0, 32, 0}, 147 {"fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0}, 148 {"fixup_Hexagon_DTPREL_16_X", 0, 32, 0}, 149 {"fixup_Hexagon_DTPREL_11_X", 0, 32, 0}, 150 {"fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0}, 151 {"fixup_Hexagon_GD_GOT_16_X", 0, 32, 0}, 152 {"fixup_Hexagon_GD_GOT_11_X", 0, 32, 0}, 153 {"fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0}, 154 {"fixup_Hexagon_LD_GOT_16_X", 0, 32, 0}, 155 {"fixup_Hexagon_LD_GOT_11_X", 0, 32, 0}, 156 {"fixup_Hexagon_IE_32_6_X", 0, 32, 0}, 157 {"fixup_Hexagon_IE_16_X", 0, 32, 0}, 158 {"fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0}, 159 {"fixup_Hexagon_IE_GOT_16_X", 0, 32, 0}, 160 {"fixup_Hexagon_IE_GOT_11_X", 0, 32, 0}, 161 {"fixup_Hexagon_TPREL_32_6_X", 0, 32, 0}, 162 {"fixup_Hexagon_TPREL_16_X", 0, 32, 0}, 163 {"fixup_Hexagon_TPREL_11_X", 0, 32, 0}}; 164 165 if (Kind < FirstTargetFixupKind) { 166 return MCAsmBackend::getFixupKindInfo(Kind); 167 } 168 169 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 170 "Invalid kind!"); 171 return Infos[Kind - FirstTargetFixupKind]; 172 } 173 174 void applyFixup(MCFixup const & /*Fixup*/, char * /*Data*/, 175 unsigned /*DataSize*/, uint64_t /*Value*/, 176 bool /*IsPCRel*/) const override { 177 return; 178 } 179 180 bool isInstRelaxable(MCInst const &HMI) const { 181 const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI); 182 bool Relaxable = false; 183 // Branches and loop-setup insns are handled as necessary by relaxation. 184 if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ || 185 (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNV && 186 MCID.isBranch()) || 187 (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR && 188 HMI.getOpcode() != Hexagon::C4_addipc)) 189 if (HexagonMCInstrInfo::isExtendable(*MCII, HMI)) 190 Relaxable = true; 191 192 return Relaxable; 193 } 194 195 /// MayNeedRelaxation - Check whether the given instruction may need 196 /// relaxation. 197 /// 198 /// \param Inst - The instruction to test. 199 bool mayNeedRelaxation(MCInst const &Inst) const override { 200 assert(HexagonMCInstrInfo::isBundle(Inst)); 201 bool PreviousIsExtender = false; 202 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(Inst)) { 203 auto const &Inst = *I.getInst(); 204 if (!PreviousIsExtender) { 205 if (isInstRelaxable(Inst)) 206 return true; 207 } 208 PreviousIsExtender = HexagonMCInstrInfo::isImmext(Inst); 209 } 210 return false; 211 } 212 213 /// fixupNeedsRelaxation - Target specific predicate for whether a given 214 /// fixup requires the associated instruction to be relaxed. 215 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, 216 uint64_t Value, 217 const MCRelaxableFragment *DF, 218 const MCAsmLayout &Layout) const override { 219 MCInst const &MCB = DF->getInst(); 220 assert(HexagonMCInstrInfo::isBundle(MCB)); 221 222 *RelaxTarget = nullptr; 223 MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction( 224 MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE)); 225 // If we cannot resolve the fixup value, it requires relaxation. 226 if (!Resolved) { 227 switch ((unsigned)Fixup.getKind()) { 228 case fixup_Hexagon_B22_PCREL: 229 // GetFixupCount assumes B22 won't relax 230 // Fallthrough 231 default: 232 return false; 233 break; 234 case fixup_Hexagon_B13_PCREL: 235 case fixup_Hexagon_B15_PCREL: 236 case fixup_Hexagon_B9_PCREL: 237 case fixup_Hexagon_B7_PCREL: { 238 if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) { 239 ++relaxedCnt; 240 *RelaxTarget = &MCI; 241 setExtender(Layout.getAssembler().getContext()); 242 return true; 243 } else { 244 return false; 245 } 246 break; 247 } 248 } 249 } 250 bool Relaxable = isInstRelaxable(MCI); 251 if (Relaxable == false) 252 return false; 253 254 MCFixupKind Kind = Fixup.getKind(); 255 int64_t sValue = Value; 256 int64_t maxValue; 257 258 switch ((unsigned)Kind) { 259 case fixup_Hexagon_B7_PCREL: 260 maxValue = 1 << 8; 261 break; 262 case fixup_Hexagon_B9_PCREL: 263 maxValue = 1 << 10; 264 break; 265 case fixup_Hexagon_B15_PCREL: 266 maxValue = 1 << 16; 267 break; 268 case fixup_Hexagon_B22_PCREL: 269 maxValue = 1 << 23; 270 break; 271 default: 272 maxValue = INT64_MAX; 273 break; 274 } 275 276 bool isFarAway = -maxValue > sValue || sValue > maxValue - 1; 277 278 if (isFarAway) { 279 if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) { 280 ++relaxedCnt; 281 *RelaxTarget = &MCI; 282 setExtender(Layout.getAssembler().getContext()); 283 return true; 284 } 285 } 286 287 return false; 288 } 289 290 /// Simple predicate for targets where !Resolved implies requiring relaxation 291 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, 292 const MCRelaxableFragment *DF, 293 const MCAsmLayout &Layout) const override { 294 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced"); 295 } 296 297 void relaxInstruction(MCInst const & Inst, 298 MCInst & Res) const override { 299 assert(HexagonMCInstrInfo::isBundle(Inst) && 300 "Hexagon relaxInstruction only works on bundles"); 301 302 Res = HexagonMCInstrInfo::createBundle(); 303 // Copy the results into the bundle. 304 bool Update = false; 305 for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) { 306 MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst()); 307 308 // if immediate extender needed, add it in 309 if (*RelaxTarget == &CrntHMI) { 310 Update = true; 311 assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) && 312 "No room to insert extender for relaxation"); 313 314 MCInst *HMIx = takeExtender(); 315 *HMIx = HexagonMCInstrInfo::deriveExtender( 316 *MCII, CrntHMI, 317 HexagonMCInstrInfo::getExtendableOperand(*MCII, CrntHMI)); 318 Res.addOperand(MCOperand::createInst(HMIx)); 319 *RelaxTarget = nullptr; 320 } 321 // now copy over the original instruction(the one we may have extended) 322 Res.addOperand(MCOperand::createInst(I.getInst())); 323 } 324 (void)Update; 325 assert(Update && "Didn't find relaxation target"); 326 } 327 328 bool writeNopData(uint64_t Count, 329 MCObjectWriter * OW) const override { 330 static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP. 331 ParseIn = 0x00004000, // In packet parse-bits. 332 ParseEnd = 0x0000c000; // End of packet parse-bits. 333 334 while(Count % HEXAGON_INSTR_SIZE) { 335 DEBUG(dbgs() << "Alignment not a multiple of the instruction size:" << 336 Count % HEXAGON_INSTR_SIZE << "/" << HEXAGON_INSTR_SIZE << "\n"); 337 --Count; 338 OW->write8(0); 339 } 340 341 while(Count) { 342 Count -= HEXAGON_INSTR_SIZE; 343 // Close the packet whenever a multiple of the maximum packet size remains 344 uint32_t ParseBits = (Count % (HEXAGON_PACKET_SIZE * HEXAGON_INSTR_SIZE))? 345 ParseIn: ParseEnd; 346 OW->write32(Nopcode | ParseBits); 347 } 348 return true; 349 } 350}; 351} // end anonymous namespace 352 353namespace llvm { 354MCAsmBackend *createHexagonAsmBackend(Target const &T, 355 MCRegisterInfo const & /*MRI*/, 356 const Triple &TT, StringRef CPU) { 357 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS()); 358 return new HexagonAsmBackend(T, OSABI, CPU); 359} 360} 361