7
7
//
8
8
// ===----------------------------------------------------------------------===//
9
9
10
+ #include " Hexagon.h"
11
+ #include " HexagonFixupKinds.h"
10
12
#include " HexagonMCTargetDesc.h"
13
+ #include " MCTargetDesc/HexagonBaseInfo.h"
14
+ #include " MCTargetDesc/HexagonMCInstrInfo.h"
11
15
#include " llvm/MC/MCAsmBackend.h"
16
+ #include " llvm/MC/MCAssembler.h"
12
17
#include " llvm/MC/MCELFObjectWriter.h"
13
18
14
19
using namespace llvm ;
20
+ using namespace Hexagon ;
15
21
16
22
namespace {
17
23
18
24
class HexagonAsmBackend : public MCAsmBackend {
25
+ mutable uint64_t relaxedCnt;
26
+ std::unique_ptr <MCInstrInfo> MCII;
27
+ std::unique_ptr <MCInst *> RelaxTarget;
19
28
public:
20
- HexagonAsmBackend (Target const & /* T*/ ) {}
29
+ HexagonAsmBackend (Target const & /* T*/ ) :
30
+ MCII (createHexagonMCInstrInfo()), RelaxTarget(new MCInst *){}
21
31
22
32
unsigned getNumFixupKinds () const override { return 0 ; }
23
33
@@ -27,14 +37,121 @@ class HexagonAsmBackend : public MCAsmBackend {
27
37
return ;
28
38
}
29
39
30
- bool mayNeedRelaxation (MCInst const & /* Inst*/ ) const override {
40
+ bool isInstRelaxable (MCInst const &HMI) const {
41
+ const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc (*MCII, HMI);
42
+ assert (&MCID && " invalid instruction" );
43
+
44
+ bool Relaxable = false ;
45
+ // Branches and loop-setup insns are handled as necessary by relaxation.
46
+ if (llvm::HexagonMCInstrInfo::getType (*MCII, HMI) == HexagonII::TypeJ ||
47
+ (llvm::HexagonMCInstrInfo::getType (*MCII, HMI) == HexagonII::TypeNV &&
48
+ MCID.isBranch ()) ||
49
+ (llvm::HexagonMCInstrInfo::getType (*MCII, HMI) == HexagonII::TypeCR &&
50
+ HMI.getOpcode () != Hexagon::C4_addipc))
51
+ if (HexagonMCInstrInfo::isExtendable (*MCII, HMI))
52
+ Relaxable = true ;
53
+
54
+ return Relaxable;
55
+ }
56
+
57
+ // / MayNeedRelaxation - Check whether the given instruction may need
58
+ // / relaxation.
59
+ // /
60
+ // / \param Inst - The instruction to test.
61
+ bool mayNeedRelaxation (MCInst const &Inst) const {
62
+ assert (HexagonMCInstrInfo::isBundle (Inst));
63
+ bool PreviousIsExtender = false ;
64
+ for (auto const &I : HexagonMCInstrInfo::bundleInstructions (Inst)) {
65
+ auto const &Inst = *I.getInst ();
66
+ if (!PreviousIsExtender) {
67
+ if (isInstRelaxable (Inst))
68
+ return true ;
69
+ }
70
+ PreviousIsExtender = HexagonMCInstrInfo::isImmext (Inst);
71
+ }
72
+ return false ;
73
+ }
74
+
75
+ // / fixupNeedsRelaxation - Target specific predicate for whether a given
76
+ // / fixup requires the associated instruction to be relaxed.
77
+ bool fixupNeedsRelaxationAdvanced (const MCFixup &Fixup, bool Resolved,
78
+ uint64_t Value,
79
+ const MCRelaxableFragment *DF,
80
+ const MCAsmLayout &Layout) const {
81
+ MCInst const &MCB = DF->getInst ();
82
+ assert (HexagonMCInstrInfo::isBundle (MCB));
83
+
84
+ *RelaxTarget = nullptr ;
85
+ MCInst &MCI = const_cast <MCInst &>(HexagonMCInstrInfo::instruction (
86
+ MCB, Fixup.getOffset () / HEXAGON_INSTR_SIZE));
87
+ // If we cannot resolve the fixup value, it requires relaxation.
88
+ if (!Resolved) {
89
+ switch ((unsigned )Fixup.getKind ()) {
90
+ case fixup_Hexagon_B22_PCREL:
91
+ // GetFixupCount assumes B22 won't relax
92
+ // Fallthrough
93
+ default :
94
+ return false ;
95
+ break ;
96
+ case fixup_Hexagon_B13_PCREL:
97
+ case fixup_Hexagon_B15_PCREL:
98
+ case fixup_Hexagon_B9_PCREL:
99
+ case fixup_Hexagon_B7_PCREL: {
100
+ if (HexagonMCInstrInfo::bundleSize (MCB) < HEXAGON_PACKET_SIZE) {
101
+ ++relaxedCnt;
102
+ *RelaxTarget = &MCI;
103
+ return true ;
104
+ } else {
105
+ return false ;
106
+ }
107
+ break ;
108
+ }
109
+ }
110
+ }
111
+ bool Relaxable = isInstRelaxable (MCI);
112
+ if (Relaxable == false )
113
+ return false ;
114
+
115
+ MCFixupKind Kind = Fixup.getKind ();
116
+ int64_t sValue = Value;
117
+ int64_t maxValue;
118
+
119
+ switch ((unsigned )Kind) {
120
+ case fixup_Hexagon_B7_PCREL:
121
+ maxValue = 1 << 8 ;
122
+ break ;
123
+ case fixup_Hexagon_B9_PCREL:
124
+ maxValue = 1 << 10 ;
125
+ break ;
126
+ case fixup_Hexagon_B15_PCREL:
127
+ maxValue = 1 << 16 ;
128
+ break ;
129
+ case fixup_Hexagon_B22_PCREL:
130
+ maxValue = 1 << 23 ;
131
+ break ;
132
+ default :
133
+ maxValue = INT64_MAX;
134
+ break ;
135
+ }
136
+
137
+ bool isFarAway = -maxValue > sValue || sValue > maxValue - 1 ;
138
+
139
+ if (isFarAway) {
140
+ if (HexagonMCInstrInfo::bundleSize (MCB) < HEXAGON_PACKET_SIZE) {
141
+ ++relaxedCnt;
142
+ *RelaxTarget = &MCI;
143
+ return true ;
144
+ }
145
+ }
146
+
31
147
return false ;
32
148
}
33
149
34
- bool fixupNeedsRelaxation (MCFixup const & /* Fixup*/ , uint64_t /* Value*/ ,
35
- MCRelaxableFragment const * /* DF*/ ,
36
- MCAsmLayout const & /* Layout*/ ) const override {
37
- llvm_unreachable (" fixupNeedsRelaxation() unimplemented" );
150
+ // / Simple predicate for targets where !Resolved implies requiring relaxation
151
+ bool fixupNeedsRelaxation (const MCFixup &Fixup, uint64_t Value,
152
+ const MCRelaxableFragment *DF,
153
+ const MCAsmLayout &Layout) const override {
154
+ llvm_unreachable (" Handled by fixupNeedsRelaxationAdvanced" );
38
155
}
39
156
40
157
void relaxInstruction (MCInst const & /* Inst*/ ,
0 commit comments