/src/keystone/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===// |
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 | | // This class extends MCInstrInfo to allow Hexagon specific MCInstr queries |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "HexagonMCInstrInfo.h" |
15 | | |
16 | | #include "Hexagon.h" |
17 | | #include "HexagonBaseInfo.h" |
18 | | #include "HexagonMCChecker.h" |
19 | | |
20 | | #include "llvm/MC/MCContext.h" |
21 | | #include "llvm/MC/MCExpr.h" |
22 | | #include "llvm/MC/MCInstrInfo.h" |
23 | | #include "llvm/MC/MCSubtargetInfo.h" |
24 | | |
25 | | namespace llvm_ks { |
26 | | void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value, |
27 | 0 | MCContext &Context) { |
28 | 0 | MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context))); |
29 | 0 | } |
30 | | |
31 | | void HexagonMCInstrInfo::addConstExtender(MCContext &Context, |
32 | | MCInstrInfo const &MCII, MCInst &MCB, |
33 | 2.66k | MCInst const &MCI) { |
34 | 2.66k | assert(HexagonMCInstrInfo::isBundle(MCB)); |
35 | 2.66k | MCOperand const &exOp = |
36 | 2.66k | MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); |
37 | | |
38 | | // Create the extender. |
39 | 2.66k | MCInst *XMCI = |
40 | 2.66k | new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp)); |
41 | | |
42 | 2.66k | MCB.addOperand(MCOperand::createInst(XMCI)); |
43 | 2.66k | } |
44 | | |
45 | | iterator_range<MCInst::const_iterator> |
46 | 35.4k | HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) { |
47 | 35.4k | assert(isBundle(MCI)); |
48 | 35.4k | return make_range(MCI.begin() + bundleInstructionsOffset, MCI.end()); |
49 | 35.4k | } |
50 | | |
51 | 27.8k | size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) { |
52 | 27.8k | if (HexagonMCInstrInfo::isBundle(MCI)) |
53 | 27.8k | return (MCI.size() - bundleInstructionsOffset); |
54 | 0 | else |
55 | 0 | return (1); |
56 | 27.8k | } |
57 | | |
58 | | bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII, |
59 | | MCSubtargetInfo const &STI, |
60 | | MCContext &Context, MCInst &MCB, |
61 | 3.96k | HexagonMCChecker *Check) { |
62 | | // Examine the packet and convert pairs of instructions to compound |
63 | | // instructions when possible. |
64 | 3.96k | if (!HexagonDisableCompound) |
65 | 3.96k | HexagonMCInstrInfo::tryCompound(MCII, Context, MCB); |
66 | | // Check the bundle for errors. |
67 | 3.96k | bool CheckOk = Check ? Check->check() : true; |
68 | 3.96k | if (!CheckOk) |
69 | 368 | return false; |
70 | 3.59k | HexagonMCShuffle(MCII, STI, MCB); |
71 | | // Examine the packet and convert pairs of instructions to duplex |
72 | | // instructions when possible. |
73 | 3.59k | MCInst InstBundlePreDuplex = MCInst(MCB); |
74 | 3.59k | if (!HexagonDisableDuplex) { |
75 | 3.59k | SmallVector<DuplexCandidate, 8> possibleDuplexes; |
76 | 3.59k | possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(MCII, MCB); |
77 | 3.59k | HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes); |
78 | 3.59k | } |
79 | | // Examines packet and pad the packet, if needed, when an |
80 | | // end-loop is in the bundle. |
81 | 3.59k | HexagonMCInstrInfo::padEndloop(Context, MCB); |
82 | | // If compounding and duplexing didn't reduce the size below |
83 | | // 4 or less we have a packet that is too big. |
84 | 3.59k | if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) |
85 | 0 | return false; |
86 | 3.59k | HexagonMCShuffle(MCII, STI, MCB); |
87 | 3.59k | return true; |
88 | 3.59k | } |
89 | | |
90 | | void HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII, |
91 | 0 | MCContext &Context, MCInst &MCI) { |
92 | 0 | assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) || |
93 | 0 | HexagonMCInstrInfo::isExtended(MCII, MCI)); |
94 | 0 | MCOperand &exOp = |
95 | 0 | MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI)); |
96 | | // If the extended value is a constant, then use it for the extended and |
97 | | // for the extender instructions, masking off the lower 6 bits and |
98 | | // including the assumed bits. |
99 | 0 | int64_t Value; |
100 | 0 | if (exOp.getExpr()->evaluateAsAbsolute(Value)) { |
101 | 0 | unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MCI); |
102 | 0 | exOp.setExpr(MCConstantExpr::create((Value & 0x3f) << Shift, Context)); |
103 | 0 | } |
104 | 0 | } |
105 | | |
106 | 3.97k | MCInst HexagonMCInstrInfo::createBundle() { |
107 | 3.97k | MCInst Result; |
108 | 3.97k | Result.setOpcode(Hexagon::BUNDLE); |
109 | 3.97k | Result.addOperand(MCOperand::createImm(0)); |
110 | 3.97k | return Result; |
111 | 3.97k | } |
112 | | |
113 | | MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass, |
114 | | MCInst const &inst0, |
115 | 1 | MCInst const &inst1) { |
116 | 1 | assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf"); |
117 | 1 | MCInst *duplexInst = new (Context) MCInst; |
118 | 1 | duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass); |
119 | | |
120 | 1 | MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0)); |
121 | 1 | MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1)); |
122 | 1 | duplexInst->addOperand(MCOperand::createInst(SubInst0)); |
123 | 1 | duplexInst->addOperand(MCOperand::createInst(SubInst1)); |
124 | 1 | return duplexInst; |
125 | 1 | } |
126 | | |
127 | | MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII, |
128 | | MCInst const &Inst, |
129 | 2.80k | MCOperand const &MO) { |
130 | 2.80k | assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) || |
131 | 2.80k | HexagonMCInstrInfo::isExtended(MCII, Inst)); |
132 | | |
133 | 2.80k | MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst); |
134 | 2.80k | MCInst XMI; |
135 | 2.80k | XMI.setOpcode((Desc.isBranch() || Desc.isCall() || |
136 | 2.80k | HexagonMCInstrInfo::getType(MCII, Inst) == HexagonII::TypeCR) |
137 | 2.80k | ? Hexagon::A4_ext_b |
138 | 2.80k | : Hexagon::A4_ext); |
139 | 2.80k | if (MO.isImm()) |
140 | 0 | XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f))); |
141 | 2.80k | else if (MO.isExpr()) |
142 | 2.80k | XMI.addOperand(MCOperand::createExpr(MO.getExpr())); |
143 | 0 | else |
144 | 0 | llvm_unreachable("invalid extendable operand"); |
145 | 2.80k | return XMI; |
146 | 2.80k | } |
147 | | |
148 | | MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB, |
149 | 1.63k | size_t Index) { |
150 | 1.63k | assert(Index <= bundleSize(MCB)); |
151 | 1.63k | if (Index == 0) |
152 | 818 | return nullptr; |
153 | 820 | MCInst const *Inst = |
154 | 820 | MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst(); |
155 | 820 | if (isImmext(*Inst)) |
156 | 814 | return Inst; |
157 | 6 | return nullptr; |
158 | 820 | } |
159 | | |
160 | | void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context, |
161 | | MCInstrInfo const &MCII, MCInst &MCB, |
162 | 6.34k | MCInst const &MCI, bool MustExtend) { |
163 | 6.34k | if (isConstExtended(MCII, MCI) || MustExtend) |
164 | 2.66k | addConstExtender(Context, MCII, MCB, MCI); |
165 | 6.34k | } |
166 | | |
167 | | HexagonII::MemAccessSize |
168 | 0 | HexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const &MCI) { |
169 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
170 | |
|
171 | 0 | return (HexagonII::MemAccessSize((F >> HexagonII::MemAccessSizePos) & |
172 | 0 | HexagonII::MemAccesSizeMask)); |
173 | 0 | } |
174 | | |
175 | | unsigned HexagonMCInstrInfo::getBitCount(MCInstrInfo const &MCII, |
176 | 0 | MCInst const &MCI) { |
177 | 0 | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
178 | 0 | return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); |
179 | 0 | } |
180 | | |
181 | | // Return constant extended operand number. |
182 | | unsigned short HexagonMCInstrInfo::getCExtOpNum(MCInstrInfo const &MCII, |
183 | 0 | MCInst const &MCI) { |
184 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
185 | 0 | return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); |
186 | 0 | } |
187 | | |
188 | | MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII, |
189 | 430k | MCInst const &MCI) { |
190 | 430k | return (MCII.get(MCI.getOpcode())); |
191 | 430k | } |
192 | | |
193 | | unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII, |
194 | 5.36k | MCInst const &MCI) { |
195 | 5.36k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
196 | 5.36k | return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask); |
197 | 5.36k | } |
198 | | |
199 | | MCOperand const & |
200 | | HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII, |
201 | 2.69k | MCInst const &MCI) { |
202 | 2.69k | unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI); |
203 | 2.69k | MCOperand const &MO = MCI.getOperand(O); |
204 | | |
205 | 2.69k | assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) || |
206 | 2.69k | HexagonMCInstrInfo::isExtended(MCII, MCI)) && |
207 | 2.69k | (MO.isImm() || MO.isExpr())); |
208 | 2.69k | return (MO); |
209 | 2.69k | } |
210 | | |
211 | | unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII, |
212 | 1.90k | MCInst const &MCI) { |
213 | 1.90k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
214 | 1.90k | return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask); |
215 | 1.90k | } |
216 | | |
217 | | unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII, |
218 | 1.90k | MCInst const &MCI) { |
219 | 1.90k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
220 | 1.90k | return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask); |
221 | 1.90k | } |
222 | | |
223 | | // Return the max value that a constant extendable operand can have |
224 | | // without being extended. |
225 | | int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII, |
226 | 2.41k | MCInst const &MCI) { |
227 | 2.41k | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
228 | 2.41k | unsigned isSigned = |
229 | 2.41k | (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; |
230 | 2.41k | unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; |
231 | | |
232 | 2.41k | if (isSigned) // if value is signed |
233 | 2.40k | return ~(-1U << (bits - 1)); |
234 | 16 | else |
235 | 16 | return ~(-1U << bits); |
236 | 2.41k | } |
237 | | |
238 | | // Return the min value that a constant extendable operand can have |
239 | | // without being extended. |
240 | | int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII, |
241 | 2.41k | MCInst const &MCI) { |
242 | 2.41k | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
243 | 2.41k | unsigned isSigned = |
244 | 2.41k | (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask; |
245 | 2.41k | unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask; |
246 | | |
247 | 2.41k | if (isSigned) // if value is signed |
248 | 2.40k | return -1U << (bits - 1); |
249 | 16 | else |
250 | 16 | return 0; |
251 | 2.41k | } |
252 | | |
253 | | char const *HexagonMCInstrInfo::getName(MCInstrInfo const &MCII, |
254 | 0 | MCInst const &MCI) { |
255 | 0 | return MCII.getName(MCI.getOpcode()); |
256 | 0 | } |
257 | | |
258 | | unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII, |
259 | 0 | MCInst const &MCI) { |
260 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
261 | 0 | return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask); |
262 | 0 | } |
263 | | |
264 | | MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII, |
265 | 2.38k | MCInst const &MCI) { |
266 | 2.38k | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
267 | 2.38k | unsigned const O = |
268 | 2.38k | (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask; |
269 | 2.38k | MCOperand const &MCO = MCI.getOperand(O); |
270 | | |
271 | 2.38k | assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || |
272 | 2.38k | HexagonMCInstrInfo::hasNewValue(MCII, MCI)) && |
273 | 2.38k | MCO.isReg()); |
274 | 2.38k | return (MCO); |
275 | 2.38k | } |
276 | | |
277 | | /// Return the new value or the newly produced value. |
278 | | unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII, |
279 | 0 | MCInst const &MCI) { |
280 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
281 | 0 | return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2); |
282 | 0 | } |
283 | | |
284 | | MCOperand const & |
285 | | HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII, |
286 | 0 | MCInst const &MCI) { |
287 | 0 | unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI); |
288 | 0 | MCOperand const &MCO = MCI.getOperand(O); |
289 | |
|
290 | 0 | assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) || |
291 | 0 | HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) && |
292 | 0 | MCO.isReg()); |
293 | 0 | return (MCO); |
294 | 0 | } |
295 | | |
296 | | int HexagonMCInstrInfo::getSubTarget(MCInstrInfo const &MCII, |
297 | 0 | MCInst const &MCI) { |
298 | 0 | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
299 | |
|
300 | 0 | HexagonII::SubTarget Target = static_cast<HexagonII::SubTarget>( |
301 | 0 | (F >> HexagonII::validSubTargetPos) & HexagonII::validSubTargetMask); |
302 | |
|
303 | 0 | switch (Target) { |
304 | 0 | default: |
305 | 0 | return Hexagon::ArchV4; |
306 | 0 | case HexagonII::HasV5SubT: |
307 | 0 | return Hexagon::ArchV5; |
308 | 0 | } |
309 | 0 | } |
310 | | |
311 | | // Return the Hexagon ISA class for the insn. |
312 | | unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII, |
313 | 134k | MCInst const &MCI) { |
314 | 134k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
315 | | |
316 | 134k | return ((F >> HexagonII::TypePos) & HexagonII::TypeMask); |
317 | 134k | } |
318 | | |
319 | | unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, |
320 | | MCSubtargetInfo const &STI, |
321 | 22.1k | MCInst const &MCI) { |
322 | 22.1k | const InstrItinerary *II = STI.getSchedModel().InstrItineraries; |
323 | 22.1k | int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); |
324 | 22.1k | return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); |
325 | 22.1k | } |
326 | | |
327 | 0 | bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) { |
328 | 0 | if (!HexagonMCInstrInfo::isBundle(MCI)) |
329 | 0 | return false; |
330 | | |
331 | 0 | for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) { |
332 | 0 | auto MI = I.getInst(); |
333 | 0 | if (isImmext(*MI)) |
334 | 0 | return true; |
335 | 0 | } |
336 | | |
337 | 0 | return false; |
338 | 0 | } |
339 | | |
340 | 1.63k | bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) { |
341 | 1.63k | return extenderForIndex(MCB, Index) != nullptr; |
342 | 1.63k | } |
343 | | |
344 | | // Return whether the instruction is a legal new-value producer. |
345 | | bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII, |
346 | 10.8k | MCInst const &MCI) { |
347 | 10.8k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
348 | 10.8k | return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask); |
349 | 10.8k | } |
350 | | |
351 | | /// Return whether the insn produces a second value. |
352 | | bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII, |
353 | 5.57k | MCInst const &MCI) { |
354 | 5.57k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
355 | 5.57k | return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2); |
356 | 5.57k | } |
357 | | |
358 | 456 | MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) { |
359 | 456 | assert(isBundle(MCB)); |
360 | 456 | assert(Index < HEXAGON_PACKET_SIZE); |
361 | 456 | return *MCB.getOperand(bundleInstructionsOffset + Index).getInst(); |
362 | 456 | } |
363 | | |
364 | 159k | bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) { |
365 | 159k | auto Result = Hexagon::BUNDLE == MCI.getOpcode(); |
366 | 159k | assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm())); |
367 | 159k | return Result; |
368 | 159k | } |
369 | | |
370 | | // Return whether the insn is an actual insn. |
371 | 0 | bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) { |
372 | 0 | return (!HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() && |
373 | 0 | !HexagonMCInstrInfo::isPrefix(MCII, MCI) && |
374 | 0 | HexagonMCInstrInfo::getType(MCII, MCI) != HexagonII::TypeENDLOOP); |
375 | 0 | } |
376 | | |
377 | | bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII, |
378 | 2.38k | MCInst const &MCI) { |
379 | 2.38k | return (getType(MCII, MCI) == HexagonII::TypeCOMPOUND); |
380 | 2.38k | } |
381 | | |
382 | 0 | bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) { |
383 | 0 | return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) || |
384 | 0 | (Reg >= Hexagon::D8 && Reg <= Hexagon::D11)); |
385 | 0 | } |
386 | | |
387 | 10.1k | bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) { |
388 | 10.1k | return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI); |
389 | 10.1k | } |
390 | | |
391 | | // Return whether the instruction needs to be constant extended. |
392 | | // 1) Always return true if the instruction has 'isExtended' flag set. |
393 | | // |
394 | | // isExtendable: |
395 | | // 2) For immediate extended operands, return true only if the value is |
396 | | // out-of-range. |
397 | | // 3) For global address, always return true. |
398 | | |
399 | | bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, |
400 | 6.34k | MCInst const &MCI) { |
401 | 6.34k | if (HexagonMCInstrInfo::isExtended(MCII, MCI)) |
402 | 0 | return true; |
403 | | // Branch insns are handled as necessary by relaxation. |
404 | 6.34k | if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) || |
405 | 6.34k | (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCOMPOUND && |
406 | 4.08k | HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) || |
407 | 6.34k | (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV && |
408 | 4.08k | HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch())) |
409 | 2.26k | return false; |
410 | | // Otherwise loop instructions and other CR insts are handled by relaxation |
411 | 4.08k | else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) && |
412 | 4.08k | (MCI.getOpcode() != Hexagon::C4_addipc)) |
413 | 370 | return false; |
414 | 3.71k | else if (!HexagonMCInstrInfo::isExtendable(MCII, MCI)) |
415 | 1.15k | return false; |
416 | | |
417 | 2.56k | MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI); |
418 | | |
419 | | // We could be using an instruction with an extendable immediate and shoehorn |
420 | | // a global address into it. If it is a global address it will be constant |
421 | | // extended. We do this for COMBINE. |
422 | | // We currently only handle isGlobal() because it is the only kind of |
423 | | // object we are going to end up with here for now. |
424 | | // In the future we probably should add isSymbol(), etc. |
425 | 2.56k | assert(!MO.isImm()); |
426 | 2.56k | int64_t Value; |
427 | 2.56k | if (!MO.getExpr()->evaluateAsAbsolute(Value)) |
428 | 143 | return true; |
429 | 2.41k | int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI); |
430 | 2.41k | int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI); |
431 | 2.41k | return (MinValue > Value || Value > MaxValue); |
432 | 2.56k | } |
433 | | |
434 | | bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII, |
435 | 12.5k | MCInst const &MCI) { |
436 | 12.5k | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
437 | 12.5k | return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask; |
438 | 12.5k | } |
439 | | |
440 | | bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII, |
441 | 12.6k | MCInst const &MCI) { |
442 | 12.6k | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
443 | 12.6k | return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask; |
444 | 12.6k | } |
445 | | |
446 | 3.15k | bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) { |
447 | 3.15k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
448 | 3.15k | return ((F >> HexagonII::FPPos) & HexagonII::FPMask); |
449 | 3.15k | } |
450 | | |
451 | 66.4k | bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) { |
452 | 66.4k | auto Op = MCI.getOpcode(); |
453 | 66.4k | return (Op == Hexagon::A4_ext_b || Op == Hexagon::A4_ext_c || |
454 | 66.4k | Op == Hexagon::A4_ext_g || Op == Hexagon::A4_ext); |
455 | 66.4k | } |
456 | | |
457 | 13.3k | bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) { |
458 | 13.3k | assert(isBundle(MCI)); |
459 | 13.3k | int64_t Flags = MCI.getOperand(0).getImm(); |
460 | 13.3k | return (Flags & innerLoopMask) != 0; |
461 | 13.3k | } |
462 | | |
463 | 0 | bool HexagonMCInstrInfo::isIntReg(unsigned Reg) { |
464 | 0 | return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31); |
465 | 0 | } |
466 | | |
467 | 537 | bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) { |
468 | 537 | return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) || |
469 | 537 | (Reg >= Hexagon::R16 && Reg <= Hexagon::R23)); |
470 | 537 | } |
471 | | |
472 | | // Return whether the insn is a new-value consumer. |
473 | | bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII, |
474 | 17.1k | MCInst const &MCI) { |
475 | 17.1k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
476 | 17.1k | return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask); |
477 | 17.1k | } |
478 | | |
479 | | // Return whether the operand can be constant extended. |
480 | | bool HexagonMCInstrInfo::isOperandExtended(MCInstrInfo const &MCII, |
481 | | MCInst const &MCI, |
482 | 0 | unsigned short OperandNum) { |
483 | 0 | uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
484 | 0 | return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) == |
485 | 0 | OperandNum; |
486 | 0 | } |
487 | | |
488 | 10.3k | bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) { |
489 | 10.3k | assert(isBundle(MCI)); |
490 | 10.3k | int64_t Flags = MCI.getOperand(0).getImm(); |
491 | 10.3k | return (Flags & outerLoopMask) != 0; |
492 | 10.3k | } |
493 | | |
494 | | bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII, |
495 | 3.15k | MCInst const &MCI) { |
496 | 3.15k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
497 | 3.15k | return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); |
498 | 3.15k | } |
499 | | |
500 | | bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII, |
501 | 3.19k | MCInst const &MCI) { |
502 | 3.19k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
503 | 3.19k | return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask); |
504 | 3.19k | } |
505 | | |
506 | | /// Return whether the insn is newly predicated. |
507 | | bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII, |
508 | 10.6k | MCInst const &MCI) { |
509 | 10.6k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
510 | 10.6k | return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask); |
511 | 10.6k | } |
512 | | |
513 | | bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII, |
514 | 2.40k | MCInst const &MCI) { |
515 | 2.40k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
516 | 2.40k | return ( |
517 | 2.40k | !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask)); |
518 | 2.40k | } |
519 | | |
520 | 0 | bool HexagonMCInstrInfo::isPredReg(unsigned Reg) { |
521 | 0 | return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0); |
522 | 0 | } |
523 | | |
524 | 0 | bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) { |
525 | 0 | return (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypePREFIX); |
526 | 0 | } |
527 | | |
528 | 16.8k | bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) { |
529 | 16.8k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
530 | 16.8k | return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask); |
531 | 16.8k | } |
532 | | |
533 | 410 | bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) { |
534 | 410 | assert(isBundle(MCI)); |
535 | 410 | auto Flags = MCI.getOperand(0).getImm(); |
536 | 410 | return (Flags & memReorderDisabledMask) != 0; |
537 | 410 | } |
538 | | |
539 | 0 | bool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) { |
540 | 0 | assert(isBundle(MCI)); |
541 | 0 | auto Flags = MCI.getOperand(0).getImm(); |
542 | 0 | return (Flags & memStoreReorderEnabledMask) != 0; |
543 | 0 | } |
544 | | |
545 | 11.7k | bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) { |
546 | 11.7k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
547 | 11.7k | return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask); |
548 | 11.7k | } |
549 | | |
550 | | bool HexagonMCInstrInfo::isSoloAin1(MCInstrInfo const &MCII, |
551 | 11.7k | MCInst const &MCI) { |
552 | 11.7k | const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags; |
553 | 11.7k | return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask); |
554 | 11.7k | } |
555 | | |
556 | 0 | bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) { |
557 | 0 | if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) && |
558 | 0 | (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST)) |
559 | 0 | return true; |
560 | 0 | return false; |
561 | 0 | } |
562 | | |
563 | 201 | int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) { |
564 | 201 | auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) |
565 | 201 | << 8; |
566 | 201 | if (MCI.size() <= Index) |
567 | 0 | return Sentinal; |
568 | 201 | MCOperand const &MCO = MCI.getOperand(Index); |
569 | 201 | if (!MCO.isExpr()) |
570 | 0 | return Sentinal; |
571 | 201 | int64_t Value; |
572 | 201 | if (!MCO.getExpr()->evaluateAsAbsolute(Value)) |
573 | 0 | return Sentinal; |
574 | 201 | return Value; |
575 | 201 | } |
576 | | |
577 | 3.59k | void HexagonMCInstrInfo::padEndloop(MCContext &Context, MCInst &MCB) { |
578 | 3.59k | MCInst Nop; |
579 | 3.59k | Nop.setOpcode(Hexagon::A2_nop); |
580 | 3.59k | assert(isBundle(MCB)); |
581 | 3.59k | while ((HexagonMCInstrInfo::isInnerLoop(MCB) && |
582 | 3.59k | (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) || |
583 | 3.59k | ((HexagonMCInstrInfo::isOuterLoop(MCB) && |
584 | 3.59k | (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE)))) |
585 | 0 | MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop))); |
586 | 3.59k | } |
587 | | |
588 | | bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII, |
589 | 11.8k | MCInst const &MCI) { |
590 | 11.8k | if (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) |
591 | 736 | return false; |
592 | | |
593 | 11.0k | unsigned SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); |
594 | 11.0k | switch (SchedClass) { |
595 | 0 | case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123: |
596 | 0 | case Hexagon::Sched::ALU64_tc_2_SLOT23: |
597 | 0 | case Hexagon::Sched::ALU64_tc_3x_SLOT23: |
598 | 0 | case Hexagon::Sched::M_tc_2_SLOT23: |
599 | 0 | case Hexagon::Sched::M_tc_3x_SLOT23: |
600 | 0 | case Hexagon::Sched::S_2op_tc_2_SLOT23: |
601 | 0 | case Hexagon::Sched::S_3op_tc_2_SLOT23: |
602 | 0 | case Hexagon::Sched::S_3op_tc_3x_SLOT23: |
603 | 0 | return true; |
604 | 11.0k | } |
605 | 11.0k | return false; |
606 | 11.0k | } |
607 | | |
608 | | void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB, |
609 | 1 | DuplexCandidate Candidate) { |
610 | 1 | assert(Candidate.packetIndexI < MCB.size()); |
611 | 1 | assert(Candidate.packetIndexJ < MCB.size()); |
612 | 1 | assert(isBundle(MCB)); |
613 | 1 | MCInst *Duplex = |
614 | 1 | deriveDuplex(Context, Candidate.iClass, |
615 | 1 | *MCB.getOperand(Candidate.packetIndexJ).getInst(), |
616 | 1 | *MCB.getOperand(Candidate.packetIndexI).getInst()); |
617 | 1 | assert(Duplex != nullptr); |
618 | 1 | MCB.getOperand(Candidate.packetIndexI).setInst(Duplex); |
619 | 1 | MCB.erase(MCB.begin() + Candidate.packetIndexJ); |
620 | 1 | } |
621 | | |
622 | 0 | void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) { |
623 | 0 | assert(isBundle(MCI)); |
624 | 0 | MCOperand &Operand = MCI.getOperand(0); |
625 | 0 | Operand.setImm(Operand.getImm() | innerLoopMask); |
626 | 0 | } |
627 | | |
628 | 0 | void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) { |
629 | 0 | assert(isBundle(MCI)); |
630 | 0 | MCOperand &Operand = MCI.getOperand(0); |
631 | 0 | Operand.setImm(Operand.getImm() | memReorderDisabledMask); |
632 | 0 | assert(isMemReorderDisabled(MCI)); |
633 | 0 | } |
634 | | |
635 | 0 | void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) { |
636 | 0 | assert(isBundle(MCI)); |
637 | 0 | MCOperand &Operand = MCI.getOperand(0); |
638 | 0 | Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask); |
639 | 0 | assert(isMemStoreReorderEnabled(MCI)); |
640 | 0 | } |
641 | | |
642 | 0 | void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { |
643 | 0 | assert(isBundle(MCI)); |
644 | 0 | MCOperand &Operand = MCI.getOperand(0); |
645 | 0 | Operand.setImm(Operand.getImm() | outerLoopMask); |
646 | 0 | } |
647 | | } |