blob: ec1309e3c2a0bdb4ef4965c3e1aba99aeb8f152e [file] [log] [blame]
Colin LeMahieu2c769202014-11-06 17:05:51 +00001//===-- 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
Colin LeMahieu86f218e2015-05-30 18:55:47 +000010#include "Hexagon.h"
11#include "HexagonFixupKinds.h"
Colin LeMahieu2c769202014-11-06 17:05:51 +000012#include "HexagonMCTargetDesc.h"
Colin LeMahieu86f218e2015-05-30 18:55:47 +000013#include "MCTargetDesc/HexagonBaseInfo.h"
14#include "MCTargetDesc/HexagonMCInstrInfo.h"
Colin LeMahieu2c769202014-11-06 17:05:51 +000015#include "llvm/MC/MCAsmBackend.h"
Colin LeMahieu86f218e2015-05-30 18:55:47 +000016#include "llvm/MC/MCAssembler.h"
Colin LeMahieu2c769202014-11-06 17:05:51 +000017#include "llvm/MC/MCELFObjectWriter.h"
18
19using namespace llvm;
Colin LeMahieu86f218e2015-05-30 18:55:47 +000020using namespace Hexagon;
Colin LeMahieu2c769202014-11-06 17:05:51 +000021
22namespace {
23
24class HexagonAsmBackend : public MCAsmBackend {
Colin LeMahieu86f218e2015-05-30 18:55:47 +000025 mutable uint64_t relaxedCnt;
26 std::unique_ptr <MCInstrInfo> MCII;
27 std::unique_ptr <MCInst *> RelaxTarget;
Colin LeMahieu2c769202014-11-06 17:05:51 +000028public:
Colin LeMahieu86f218e2015-05-30 18:55:47 +000029 HexagonAsmBackend(Target const & /*T*/) :
30 MCII (createHexagonMCInstrInfo()), RelaxTarget(new MCInst *){}
Colin LeMahieu2c769202014-11-06 17:05:51 +000031
32 unsigned getNumFixupKinds() const override { return 0; }
33
34 void applyFixup(MCFixup const & /*Fixup*/, char * /*Data*/,
35 unsigned /*DataSize*/, uint64_t /*Value*/,
36 bool /*IsPCRel*/) const override {
37 return;
38 }
39
Colin LeMahieu86f218e2015-05-30 18:55:47 +000040 bool isInstRelaxable(MCInst const &HMI) const {
41 const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
Colin LeMahieu86f218e2015-05-30 18:55:47 +000042 bool Relaxable = false;
43 // Branches and loop-setup insns are handled as necessary by relaxation.
44 if (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeJ ||
45 (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeNV &&
46 MCID.isBranch()) ||
47 (llvm::HexagonMCInstrInfo::getType(*MCII, HMI) == HexagonII::TypeCR &&
48 HMI.getOpcode() != Hexagon::C4_addipc))
49 if (HexagonMCInstrInfo::isExtendable(*MCII, HMI))
50 Relaxable = true;
51
52 return Relaxable;
53 }
54
55 /// MayNeedRelaxation - Check whether the given instruction may need
56 /// relaxation.
57 ///
58 /// \param Inst - The instruction to test.
Colin LeMahieub510fb32015-05-30 20:03:07 +000059 bool mayNeedRelaxation(MCInst const &Inst) const override {
Colin LeMahieu86f218e2015-05-30 18:55:47 +000060 assert(HexagonMCInstrInfo::isBundle(Inst));
61 bool PreviousIsExtender = false;
62 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
63 auto const &Inst = *I.getInst();
64 if (!PreviousIsExtender) {
65 if (isInstRelaxable(Inst))
66 return true;
67 }
68 PreviousIsExtender = HexagonMCInstrInfo::isImmext(Inst);
69 }
Colin LeMahieu2c769202014-11-06 17:05:51 +000070 return false;
71 }
72
Colin LeMahieu86f218e2015-05-30 18:55:47 +000073 /// fixupNeedsRelaxation - Target specific predicate for whether a given
74 /// fixup requires the associated instruction to be relaxed.
75 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
76 uint64_t Value,
77 const MCRelaxableFragment *DF,
Colin LeMahieub510fb32015-05-30 20:03:07 +000078 const MCAsmLayout &Layout) const override {
Colin LeMahieu86f218e2015-05-30 18:55:47 +000079 MCInst const &MCB = DF->getInst();
80 assert(HexagonMCInstrInfo::isBundle(MCB));
81
82 *RelaxTarget = nullptr;
83 MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
84 MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
85 // If we cannot resolve the fixup value, it requires relaxation.
86 if (!Resolved) {
87 switch ((unsigned)Fixup.getKind()) {
88 case fixup_Hexagon_B22_PCREL:
89 // GetFixupCount assumes B22 won't relax
90 // Fallthrough
91 default:
92 return false;
93 break;
94 case fixup_Hexagon_B13_PCREL:
95 case fixup_Hexagon_B15_PCREL:
96 case fixup_Hexagon_B9_PCREL:
97 case fixup_Hexagon_B7_PCREL: {
98 if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
99 ++relaxedCnt;
100 *RelaxTarget = &MCI;
101 return true;
102 } else {
103 return false;
104 }
105 break;
106 }
107 }
108 }
109 bool Relaxable = isInstRelaxable(MCI);
110 if (Relaxable == false)
111 return false;
112
113 MCFixupKind Kind = Fixup.getKind();
114 int64_t sValue = Value;
115 int64_t maxValue;
116
117 switch ((unsigned)Kind) {
118 case fixup_Hexagon_B7_PCREL:
119 maxValue = 1 << 8;
120 break;
121 case fixup_Hexagon_B9_PCREL:
122 maxValue = 1 << 10;
123 break;
124 case fixup_Hexagon_B15_PCREL:
125 maxValue = 1 << 16;
126 break;
127 case fixup_Hexagon_B22_PCREL:
128 maxValue = 1 << 23;
129 break;
130 default:
131 maxValue = INT64_MAX;
132 break;
133 }
134
135 bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
136
137 if (isFarAway) {
138 if (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_SIZE) {
139 ++relaxedCnt;
140 *RelaxTarget = &MCI;
141 return true;
142 }
143 }
144
145 return false;
146 }
147
148 /// Simple predicate for targets where !Resolved implies requiring relaxation
149 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
150 const MCRelaxableFragment *DF,
151 const MCAsmLayout &Layout) const override {
152 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
Colin LeMahieu2c769202014-11-06 17:05:51 +0000153 }
154
155 void relaxInstruction(MCInst const & /*Inst*/,
156 MCInst & /*Res*/) const override {
157 llvm_unreachable("relaxInstruction() unimplemented");
158 }
159
160 bool writeNopData(uint64_t /*Count*/,
161 MCObjectWriter * /*OW*/) const override {
162 return true;
163 }
164};
165} // end anonymous namespace
166
167namespace {
168class ELFHexagonAsmBackend : public HexagonAsmBackend {
169 uint8_t OSABI;
170
171public:
172 ELFHexagonAsmBackend(Target const &T, uint8_t OSABI)
173 : HexagonAsmBackend(T), OSABI(OSABI) {}
174
Rafael Espindola5560a4c2015-04-14 22:14:34 +0000175 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
Colin LeMahieu2c769202014-11-06 17:05:51 +0000176 StringRef CPU("HexagonV4");
177 return createHexagonELFObjectWriter(OS, OSABI, CPU);
178 }
179};
180} // end anonymous namespace
181
182namespace llvm {
183MCAsmBackend *createHexagonAsmBackend(Target const &T,
184 MCRegisterInfo const & /*MRI*/,
185 StringRef TT, StringRef /*CPU*/) {
186 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS());
187 return new ELFHexagonAsmBackend(T, OSABI);
188}
189}