diff options
author | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2015-12-30 13:13:10 +0000 |
commit | 9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a (patch) | |
tree | b466a4817f79516eb1df8eae92bccf62ecc84003 /contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp | |
parent | f09a28d1de99fda4f5517fb12670fc36552f4927 (diff) | |
parent | e194cd6d03d91631334d9d5e55b506036f423cc8 (diff) | |
download | FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.zip FreeBSD-src-9b5bf5c4f53d65d6a48722d7410ed7cb15f5ba3a.tar.gz |
Update llvm to trunk r256633.
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp index 99ea2fa..b73af82 100644 --- a/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/contrib/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -13,7 +13,9 @@ #include "MCTargetDesc/HexagonBaseInfo.h" #include "MCTargetDesc/HexagonMCInstrInfo.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCInstrInfo.h" @@ -33,14 +35,28 @@ class HexagonAsmBackend : public MCAsmBackend { mutable uint64_t relaxedCnt; std::unique_ptr <MCInstrInfo> MCII; std::unique_ptr <MCInst *> RelaxTarget; + MCInst * Extender; public: HexagonAsmBackend(Target const &T, uint8_t OSABI, StringRef CPU) : - OSABI(OSABI), MCII (T.createMCInstrInfo()), RelaxTarget(new MCInst *){} + OSABI(OSABI), MCII (T.createMCInstrInfo()), RelaxTarget(new MCInst *), + Extender(nullptr) {} MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override { return createHexagonELFObjectWriter(OS, OSABI, CPU); } + void setExtender(MCContext &Context) const { + if (Extender == nullptr) + const_cast<HexagonAsmBackend *>(this)->Extender = new (Context) MCInst; + } + + MCInst *takeExtender() const { + assert(Extender != nullptr); + MCInst * Result = Extender; + const_cast<HexagonAsmBackend *>(this)->Extender = nullptr; + return Result; + } + unsigned getNumFixupKinds() const override { return Hexagon::NumTargetFixupKinds; } @@ -222,6 +238,7 @@ public: if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) { ++relaxedCnt; *RelaxTarget = &MCI; + setExtender(Layout.getAssembler().getContext()); return true; } else { return false; @@ -262,6 +279,7 @@ public: if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) { ++relaxedCnt; *RelaxTarget = &MCI; + setExtender(Layout.getAssembler().getContext()); return true; } } @@ -276,9 +294,35 @@ public: llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced"); } - void relaxInstruction(MCInst const & /*Inst*/, - MCInst & /*Res*/) const override { - llvm_unreachable("relaxInstruction() unimplemented"); + void relaxInstruction(MCInst const & Inst, + MCInst & Res) const override { + assert(HexagonMCInstrInfo::isBundle(Inst) && + "Hexagon relaxInstruction only works on bundles"); + + Res = HexagonMCInstrInfo::createBundle(); + // Copy the results into the bundle. + bool Update = false; + for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) { + MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst()); + + // if immediate extender needed, add it in + if (*RelaxTarget == &CrntHMI) { + Update = true; + assert((HexagonMCInstrInfo::bundleSize(Res) < HEXAGON_PACKET_SIZE) && + "No room to insert extender for relaxation"); + + MCInst *HMIx = takeExtender(); + *HMIx = HexagonMCInstrInfo::deriveExtender( + *MCII, CrntHMI, + HexagonMCInstrInfo::getExtendableOperand(*MCII, CrntHMI)); + Res.addOperand(MCOperand::createInst(HMIx)); + *RelaxTarget = nullptr; + } + // now copy over the original instruction(the one we may have extended) + Res.addOperand(MCOperand::createInst(I.getInst())); + } + (void)Update; + assert(Update && "Didn't find relaxation target"); } bool writeNopData(uint64_t Count, |