LLVM 24.0.0git
HexagonInstrInfo.cpp
Go to the documentation of this file.
1//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the Hexagon implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "HexagonInstrInfo.h"
17#include "HexagonRegisterInfo.h"
18#include "HexagonSubtarget.h"
19#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/StringRef.h"
43#include "llvm/IR/DebugLoc.h"
45#include "llvm/MC/MCAsmInfo.h"
47#include "llvm/MC/MCInstrDesc.h"
51#include "llvm/Support/Debug.h"
56#include <cassert>
57#include <cstdint>
58#include <cstring>
59#include <iterator>
60#include <optional>
61#include <string>
62#include <utility>
63
64using namespace llvm;
65
66#define DEBUG_TYPE "hexagon-instrinfo"
67
68#define GET_INSTRINFO_CTOR_DTOR
69#define GET_INSTRMAP_INFO
71#include "HexagonGenDFAPacketizer.inc"
72#include "HexagonGenInstrInfo.inc"
73
74cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
75 cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
76 "packetization boundary."));
77
78static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
79 cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));
80
82 "disable-hexagon-nv-schedule", cl::Hidden,
83 cl::desc("Disable schedule adjustment for new value stores."));
84
86 "enable-timing-class-latency", cl::Hidden, cl::init(false),
87 cl::desc("Enable timing class latency"));
88
90 "enable-alu-forwarding", cl::Hidden, cl::init(true),
91 cl::desc("Enable vec alu forwarding"));
92
94 "enable-acc-forwarding", cl::Hidden, cl::init(true),
95 cl::desc("Enable vec acc forwarding"));
96
97static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
98 cl::init(true), cl::Hidden,
99 cl::desc("branch relax asm"));
100
101static cl::opt<bool>
102 UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden,
103 cl::desc("Use the DFA based hazard recognizer."));
104
105/// Constants for Hexagon instructions.
106const int Hexagon_MEMW_OFFSET_MAX = 4095;
107const int Hexagon_MEMW_OFFSET_MIN = -4096;
108const int Hexagon_MEMD_OFFSET_MAX = 8191;
109const int Hexagon_MEMD_OFFSET_MIN = -8192;
110const int Hexagon_MEMH_OFFSET_MAX = 2047;
111const int Hexagon_MEMH_OFFSET_MIN = -2048;
112const int Hexagon_MEMB_OFFSET_MAX = 1023;
113const int Hexagon_MEMB_OFFSET_MIN = -1024;
114const int Hexagon_ADDI_OFFSET_MAX = 32767;
115const int Hexagon_ADDI_OFFSET_MIN = -32768;
116
117// Pin the vtable to this file.
118void HexagonInstrInfo::anchor() {}
119
121 : HexagonGenInstrInfo(ST, RegInfo, Hexagon::ADJCALLSTACKDOWN,
122 Hexagon::ADJCALLSTACKUP),
123 RegInfo(ST.getHwMode()), Subtarget(ST) {}
124
125namespace llvm {
126namespace HexagonFUnits {
127 bool isSlot0Only(unsigned units);
128}
129}
130
132 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
133 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
134}
135
137 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&
138 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));
139}
140
141/// Calculate number of instructions excluding the debug instructions.
144 unsigned Count = 0;
145 for (; MIB != MIE; ++MIB) {
146 if (!MIB->isDebugInstr())
147 ++Count;
148 }
149 return Count;
150}
151
152// Check if the A2_tfrsi instruction is cheap or not. If the operand has
153// to be constant-extendend it is not cheap since it occupies two slots
154// in a packet.
156 // Enable the following steps only at Os/Oz
157 if (!(MI.getMF()->getFunction().hasOptSize()))
158 return MI.isAsCheapAsAMove();
159
160 if (MI.getOpcode() == Hexagon::A2_tfrsi) {
161 auto Op = MI.getOperand(1);
162 // If the instruction has a global address as operand, it is not cheap
163 // since the operand will be constant extended.
164 if (Op.isGlobal())
165 return false;
166 // If the instruction has an operand of size > 16bits, its will be
167 // const-extended and hence, it is not cheap.
168 if (Op.isImm()) {
169 int64_t Imm = Op.getImm();
170 if (!isInt<16>(Imm))
171 return false;
172 }
173 }
174 return MI.isAsCheapAsAMove();
175}
176
177// Do not sink floating point instructions that updates USR register.
178// Example:
179// feclearexcept
180// F2_conv_w2sf
181// fetestexcept
182// MachineSink sinks F2_conv_w2sf and we are not able to catch exceptions.
183// TODO: On some of these floating point instructions, USR is marked as Use.
184// In reality, these instructions also Def the USR. If USR is marked as Def,
185// some of the assumptions in assembler packetization are broken.
187 // Assumption: A floating point instruction that reads the USR will write
188 // the USR as well.
189 if (isFloat(MI) && MI.hasRegisterImplicitUseOperand(Hexagon::USR))
190 return false;
191 return true;
192}
193
194/// Find the hardware loop instruction used to set-up the specified loop.
195/// On Hexagon, we have two instructions used to set-up the hardware loop
196/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
197/// to indicate the end of a loop.
199 unsigned EndLoopOp, MachineBasicBlock *TargetBB,
201 unsigned LOOPi;
202 unsigned LOOPr;
203 if (EndLoopOp == Hexagon::ENDLOOP0) {
204 LOOPi = Hexagon::J2_loop0i;
205 LOOPr = Hexagon::J2_loop0r;
206 } else { // EndLoopOp == Hexagon::EndLOOP1
207 LOOPi = Hexagon::J2_loop1i;
208 LOOPr = Hexagon::J2_loop1r;
209 }
210
211 // The loop set-up instruction will be in a predecessor block
212 for (MachineBasicBlock *PB : BB->predecessors()) {
213 // If this has been visited, already skip it.
214 if (!Visited.insert(PB).second)
215 continue;
216 if (PB == BB)
217 continue;
218 for (MachineInstr &I : llvm::reverse(PB->instrs())) {
219 unsigned Opc = I.getOpcode();
220 if (Opc == LOOPi || Opc == LOOPr)
221 return &I;
222 // We've reached a different loop, which means the loop01 has been
223 // removed.
224 if (Opc == EndLoopOp && I.getOperand(0).getMBB() != TargetBB)
225 return nullptr;
226 }
227 // Check the predecessors for the LOOP instruction.
228 if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))
229 return Loop;
230 }
231 return nullptr;
232}
233
234/// Gather register def/uses from MI.
235/// This treats possible (predicated) defs as actually happening ones
236/// (conservatively).
237static inline void parseOperands(const MachineInstr &MI,
239 Defs.clear();
240 Uses.clear();
241
242 for (const MachineOperand &MO : MI.operands()) {
243 if (!MO.isReg())
244 continue;
245
246 Register Reg = MO.getReg();
247 if (!Reg)
248 continue;
249
250 if (MO.isUse())
251 Uses.push_back(MO.getReg());
252
253 if (MO.isDef())
254 Defs.push_back(MO.getReg());
255 }
256}
257
258// Position dependent, so check twice for swap.
259static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
260 switch (Ga) {
262 default:
263 return false;
265 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
267 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
268 Gb == HexagonII::HSIG_A);
270 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
273 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
274 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
275 Gb == HexagonII::HSIG_A);
277 return (Gb == HexagonII::HSIG_A);
279 return (Gb == HexagonII::HSIG_Compound);
280 }
281 return false;
282}
283
284/// isLoadFromStackSlot - If the specified machine instruction is a direct
285/// load from a stack slot, return the virtual or physical register number of
286/// the destination along with the FrameIndex of the loaded stack slot. If
287/// not, return 0. This predicate must return 0 if the instruction has
288/// any side effects other than loading from the stack slot.
290 int &FrameIndex) const {
291 switch (MI.getOpcode()) {
292 default:
293 break;
294 case Hexagon::L2_loadri_io:
295 case Hexagon::L2_loadrd_io:
296 case Hexagon::V6_vL32b_ai:
297 case Hexagon::V6_vL32b_nt_ai:
298 case Hexagon::V6_vL32Ub_ai:
299 case Hexagon::LDriw_pred:
300 case Hexagon::LDriw_ctr:
301 case Hexagon::PS_vloadrq_ai:
302 case Hexagon::PS_vloadrw_ai:
303 case Hexagon::PS_vloadrw_nt_ai:
304 case Hexagon::PS_loadrl: {
305 const MachineOperand OpFI = MI.getOperand(1);
306 if (!OpFI.isFI())
307 return 0;
308 const MachineOperand OpOff = MI.getOperand(2);
309 if (!OpOff.isImm() || OpOff.getImm() != 0)
310 return 0;
311 FrameIndex = OpFI.getIndex();
312 return MI.getOperand(0).getReg();
313 }
314
315 case Hexagon::L2_ploadrit_io:
316 case Hexagon::L2_ploadrif_io:
317 case Hexagon::L2_ploadrdt_io:
318 case Hexagon::L2_ploadrdf_io: {
319 const MachineOperand OpFI = MI.getOperand(2);
320 if (!OpFI.isFI())
321 return 0;
322 const MachineOperand OpOff = MI.getOperand(3);
323 if (!OpOff.isImm() || OpOff.getImm() != 0)
324 return 0;
325 FrameIndex = OpFI.getIndex();
326 return MI.getOperand(0).getReg();
327 }
328 }
329
330 return 0;
331}
332
333/// isStoreToStackSlot - If the specified machine instruction is a direct
334/// store to a stack slot, return the virtual or physical register number of
335/// the source reg along with the FrameIndex of the loaded stack slot. If
336/// not, return 0. This predicate must return 0 if the instruction has
337/// any side effects other than storing to the stack slot.
339 int &FrameIndex) const {
340 switch (MI.getOpcode()) {
341 default:
342 break;
343 case Hexagon::S2_storerb_io:
344 case Hexagon::S2_storerh_io:
345 case Hexagon::S2_storeri_io:
346 case Hexagon::S2_storerd_io:
347 case Hexagon::V6_vS32b_ai:
348 case Hexagon::V6_vS32Ub_ai:
349 case Hexagon::STriw_pred:
350 case Hexagon::STriw_ctr:
351 case Hexagon::PS_vstorerq_ai:
352 case Hexagon::PS_vstorerw_ai:
353 case Hexagon::PS_storerl: {
354 const MachineOperand &OpFI = MI.getOperand(0);
355 if (!OpFI.isFI())
356 return 0;
357 const MachineOperand &OpOff = MI.getOperand(1);
358 if (!OpOff.isImm() || OpOff.getImm() != 0)
359 return 0;
360 FrameIndex = OpFI.getIndex();
361 return MI.getOperand(2).getReg();
362 }
363
364 case Hexagon::S2_pstorerbt_io:
365 case Hexagon::S2_pstorerbf_io:
366 case Hexagon::S2_pstorerht_io:
367 case Hexagon::S2_pstorerhf_io:
368 case Hexagon::S2_pstorerit_io:
369 case Hexagon::S2_pstorerif_io:
370 case Hexagon::S2_pstorerdt_io:
371 case Hexagon::S2_pstorerdf_io: {
372 const MachineOperand &OpFI = MI.getOperand(1);
373 if (!OpFI.isFI())
374 return 0;
375 const MachineOperand &OpOff = MI.getOperand(2);
376 if (!OpOff.isImm() || OpOff.getImm() != 0)
377 return 0;
378 FrameIndex = OpFI.getIndex();
379 return MI.getOperand(3).getReg();
380 }
381 }
382
383 return 0;
384}
385
386/// This function checks if the instruction or bundle of instructions
387/// has load from stack slot and returns frameindex and machine memory
388/// operand of that instruction if true.
390 const MachineInstr &MI,
392 if (MI.isBundle()) {
393 const MachineBasicBlock *MBB = MI.getParent();
395 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
397 return true;
398 return false;
399 }
400
402}
403
404/// This function checks if the instruction or bundle of instructions
405/// has store to stack slot and returns frameindex and machine memory
406/// operand of that instruction if true.
408 const MachineInstr &MI,
410 if (MI.isBundle()) {
411 const MachineBasicBlock *MBB = MI.getParent();
413 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
415 return true;
416 return false;
417 }
418
420}
421
422/// This function can analyze one/two way branching only and should (mostly) be
423/// called by target independent side.
424/// First entry is always the opcode of the branching instruction, except when
425/// the Cond vector is supposed to be empty, e.g., when analyzeBranch fails, a
426/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
427/// e.g. Jump_c p will have
428/// Cond[0] = Jump_c
429/// Cond[1] = p
430/// HW-loop ENDLOOP:
431/// Cond[0] = ENDLOOP
432/// Cond[1] = MBB
433/// New value jump:
434/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
435/// Cond[1] = R
436/// Cond[2] = Imm
439 MachineBasicBlock *&FBB,
441 bool AllowModify) const {
442 TBB = nullptr;
443 FBB = nullptr;
444 Cond.clear();
445
446 // If the block has no terminators, it just falls into the block after it.
448 if (I == MBB.instr_begin())
449 return false;
450
451 // A basic block may looks like this:
452 //
453 // [ insn
454 // EH_LABEL
455 // insn
456 // insn
457 // insn
458 // EH_LABEL
459 // insn ]
460 //
461 // It has two succs but does not have a terminator
462 // Don't know how to handle it.
463 do {
464 --I;
465 if (I->isEHLabel())
466 // Don't analyze EH branches.
467 return true;
468 } while (I != MBB.instr_begin());
469
470 I = MBB.instr_end();
471 --I;
472
473 while (I->isDebugInstr()) {
474 if (I == MBB.instr_begin())
475 return false;
476 --I;
477 }
478
479 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
480 I->getOperand(0).isMBB();
481 // Delete the J2_jump if it's equivalent to a fall-through.
482 if (AllowModify && JumpToBlock &&
483 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
484 LLVM_DEBUG(dbgs() << "\nErasing the jump to successor block\n";);
485 I->eraseFromParent();
486 I = MBB.instr_end();
487 if (I == MBB.instr_begin())
488 return false;
489 --I;
490 }
491 if (!isUnpredicatedTerminator(*I))
492 return false;
493
494 // Get the last instruction in the block.
495 MachineInstr *LastInst = &*I;
496 MachineInstr *SecondLastInst = nullptr;
497 // Find one more terminator if present.
498 while (true) {
499 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
500 if (!SecondLastInst)
501 SecondLastInst = &*I;
502 else
503 // This is a third branch.
504 return true;
505 }
506 if (I == MBB.instr_begin())
507 break;
508 --I;
509 }
510
511 int LastOpcode = LastInst->getOpcode();
512 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
513 // If the branch target is not a basic block, it could be a tail call.
514 // (It is, if the target is a function.)
515 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
516 return true;
517 if (SecLastOpcode == Hexagon::J2_jump &&
518 !SecondLastInst->getOperand(0).isMBB())
519 return true;
520
521 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
522 bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);
523
524 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
525 return true;
526
527 // If there is only one terminator instruction, process it.
528 if (LastInst && !SecondLastInst) {
529 if (LastOpcode == Hexagon::J2_jump) {
530 TBB = LastInst->getOperand(0).getMBB();
531 return false;
532 }
533 if (isEndLoopN(LastOpcode)) {
534 TBB = LastInst->getOperand(0).getMBB();
535 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
536 Cond.push_back(LastInst->getOperand(0));
537 return false;
538 }
539 if (LastOpcodeHasJMP_c) {
540 TBB = LastInst->getOperand(1).getMBB();
541 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
542 Cond.push_back(LastInst->getOperand(0));
543 return false;
544 }
545 // Only supporting rr/ri versions of new-value jumps.
546 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
547 TBB = LastInst->getOperand(2).getMBB();
548 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
549 Cond.push_back(LastInst->getOperand(0));
550 Cond.push_back(LastInst->getOperand(1));
551 return false;
552 }
553 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
554 << " with one jump\n";);
555 // Otherwise, don't know what this is.
556 return true;
557 }
558
559 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
560 bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);
561 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
562 if (!SecondLastInst->getOperand(1).isMBB())
563 return true;
564 TBB = SecondLastInst->getOperand(1).getMBB();
565 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
566 Cond.push_back(SecondLastInst->getOperand(0));
567 FBB = LastInst->getOperand(0).getMBB();
568 return false;
569 }
570
571 // Only supporting rr/ri versions of new-value jumps.
572 if (SecLastOpcodeHasNVJump &&
573 (SecondLastInst->getNumExplicitOperands() == 3) &&
574 (LastOpcode == Hexagon::J2_jump)) {
575 TBB = SecondLastInst->getOperand(2).getMBB();
576 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
577 Cond.push_back(SecondLastInst->getOperand(0));
578 Cond.push_back(SecondLastInst->getOperand(1));
579 FBB = LastInst->getOperand(0).getMBB();
580 return false;
581 }
582
583 // If the block ends with two Hexagon:JMPs, handle it. The second one is not
584 // executed, so remove it.
585 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
586 TBB = SecondLastInst->getOperand(0).getMBB();
587 I = LastInst->getIterator();
588 if (AllowModify)
589 I->eraseFromParent();
590 return false;
591 }
592
593 // If the block ends with an ENDLOOP, and J2_jump, handle it.
594 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
595 TBB = SecondLastInst->getOperand(0).getMBB();
596 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
597 Cond.push_back(SecondLastInst->getOperand(0));
598 FBB = LastInst->getOperand(0).getMBB();
599 return false;
600 }
601 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
602 << " with two jumps";);
603 // Otherwise, can't handle this.
604 return true;
605}
606
608 int *BytesRemoved) const {
609 assert(!BytesRemoved && "code size not handled");
610
611 LLVM_DEBUG(dbgs() << "\nRemoving branches out of " << printMBBReference(MBB));
613 unsigned Count = 0;
614 while (I != MBB.begin()) {
615 --I;
616 if (I->isDebugInstr())
617 continue;
618 // Only removing branches from end of MBB.
619 if (!I->isBranch())
620 return Count;
621 if (Count && (I->getOpcode() == Hexagon::J2_jump))
622 llvm_unreachable("Malformed basic block: unconditional branch not last");
623 MBB.erase(&MBB.back());
624 I = MBB.end();
625 ++Count;
626 }
627 return Count;
628}
629
634 const DebugLoc &DL,
635 int *BytesAdded) const {
636 unsigned BOpc = Hexagon::J2_jump;
637 unsigned BccOpc = Hexagon::J2_jumpt;
638 assert(validateBranchCond(Cond) && "Invalid branching condition");
639 assert(TBB && "insertBranch must not be told to insert a fallthrough");
640 assert(!BytesAdded && "code size not handled");
641
642 // Check if reverseBranchCondition has asked to reverse this branch
643 // If we want to reverse the branch an odd number of times, we want
644 // J2_jumpf.
645 if (!Cond.empty() && Cond[0].isImm())
646 BccOpc = Cond[0].getImm();
647
648 if (!FBB) {
649 if (Cond.empty()) {
650 // Due to a bug in TailMerging/CFG Optimization, we need to add a
651 // special case handling of a predicated jump followed by an
652 // unconditional jump. If not, Tail Merging and CFG Optimization go
653 // into an infinite loop.
654 MachineBasicBlock *NewTBB, *NewFBB;
656 auto Term = MBB.getFirstTerminator();
657 if (Term != MBB.end() && isPredicated(*Term) &&
658 !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&
659 MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {
662 return insertBranch(MBB, TBB, nullptr, Cond, DL);
663 }
664 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
665 } else if (isEndLoopN(Cond[0].getImm())) {
666 int EndLoopOp = Cond[0].getImm();
667 assert(Cond[1].isMBB());
668 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
669 // Check for it, and change the BB target if needed.
671 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
672 VisitedBBs);
673 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
674 Loop->getOperand(0).setMBB(TBB);
675 // Add the ENDLOOP after the finding the LOOP0.
676 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
677 } else if (isNewValueJump(Cond[0].getImm())) {
678 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
679 // New value jump
680 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
681 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
682 RegState Flags1 = getUndefRegState(Cond[1].isUndef());
683 LLVM_DEBUG(dbgs() << "\nInserting NVJump for "
685 if (Cond[2].isReg()) {
686 RegState Flags2 = getUndefRegState(Cond[2].isUndef());
687 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
688 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
689 } else if(Cond[2].isImm()) {
690 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
691 addImm(Cond[2].getImm()).addMBB(TBB);
692 } else
693 llvm_unreachable("Invalid condition for branching");
694 } else {
695 assert((Cond.size() == 2) && "Malformed cond vector");
696 const MachineOperand &RO = Cond[1];
697 RegState Flags = getUndefRegState(RO.isUndef());
698 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
699 }
700 return 1;
701 }
702 assert((!Cond.empty()) &&
703 "Cond. cannot be empty when multiple branchings are required");
704 assert((!isNewValueJump(Cond[0].getImm())) &&
705 "NV-jump cannot be inserted with another branch");
706 // Special case for hardware loops. The condition is a basic block.
707 if (isEndLoopN(Cond[0].getImm())) {
708 int EndLoopOp = Cond[0].getImm();
709 assert(Cond[1].isMBB());
710 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
711 // Check for it, and change the BB target if needed.
713 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
714 VisitedBBs);
715 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
716 Loop->getOperand(0).setMBB(TBB);
717 // Add the ENDLOOP after the finding the LOOP0.
718 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
719 } else {
720 const MachineOperand &RO = Cond[1];
721 RegState Flags = getUndefRegState(RO.isUndef());
722 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
723 }
724 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
725
726 return 2;
727}
728
729namespace {
730class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
731 MachineInstr *Loop, *EndLoop;
732 MachineFunction *MF;
733 const HexagonInstrInfo *TII;
734 int64_t TripCount;
735 Register LoopCount;
736 DebugLoc DL;
737
738public:
739 HexagonPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop)
740 : Loop(Loop), EndLoop(EndLoop), MF(Loop->getParent()->getParent()),
741 TII(MF->getSubtarget<HexagonSubtarget>().getInstrInfo()),
742 DL(Loop->getDebugLoc()) {
743 // Inspect the Loop instruction up-front, as it may be deleted when we call
744 // createTripCountGreaterCondition.
745 TripCount = Loop->getOpcode() == Hexagon::J2_loop0r
746 ? -1
747 : Loop->getOperand(1).getImm();
748 if (TripCount == -1)
749 LoopCount = Loop->getOperand(1).getReg();
750 }
751
752 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
753 // Only ignore the terminator.
754 return MI == EndLoop;
755 }
756
757 std::optional<bool> createTripCountGreaterCondition(
758 int TC, MachineBasicBlock &MBB,
759 SmallVectorImpl<MachineOperand> &Cond) override {
760 if (TripCount == -1) {
761 // Check if we're done with the loop.
762 Register Done = TII->createVR(MF, MVT::i1);
763 MachineInstr *NewCmp = BuildMI(&MBB, DL,
764 TII->get(Hexagon::C2_cmpgtui), Done)
765 .addReg(LoopCount)
766 .addImm(TC);
767 Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
768 Cond.push_back(NewCmp->getOperand(0));
769 return {};
770 }
771
772 return TripCount > TC;
773 }
774
775 void setPreheader(MachineBasicBlock *NewPreheader) override {
776 NewPreheader->splice(NewPreheader->getFirstTerminator(), Loop->getParent(),
777 Loop);
778 }
779
780 void adjustTripCount(int TripCountAdjust) override {
781 // If the loop trip count is a compile-time value, then just change the
782 // value.
783 if (Loop->getOpcode() == Hexagon::J2_loop0i ||
784 Loop->getOpcode() == Hexagon::J2_loop1i) {
785 int64_t TripCount = Loop->getOperand(1).getImm() + TripCountAdjust;
786 assert(TripCount > 0 && "Can't create an empty or negative loop!");
787 Loop->getOperand(1).setImm(TripCount);
788 return;
789 }
790
791 // The loop trip count is a run-time value. We generate code to subtract
792 // one from the trip count, and update the loop instruction.
793 Register LoopCount = Loop->getOperand(1).getReg();
794 Register NewLoopCount = TII->createVR(MF, MVT::i32);
795 BuildMI(*Loop->getParent(), Loop, Loop->getDebugLoc(),
796 TII->get(Hexagon::A2_addi), NewLoopCount)
797 .addReg(LoopCount)
798 .addImm(TripCountAdjust);
799 Loop->getOperand(1).setReg(NewLoopCount);
800 }
801
802 void disposed(LiveIntervals *LIS) override {
803 if (LIS)
805 Loop->eraseFromParent();
806 }
807};
808} // namespace
809
810std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
812 // We really "analyze" only hardware loops right now.
814
815 if (I != LoopBB->end() && isEndLoopN(I->getOpcode())) {
817 MachineInstr *LoopInst = findLoopInstr(
818 LoopBB, I->getOpcode(), I->getOperand(0).getMBB(), VisitedBBs);
819 if (LoopInst)
820 return std::make_unique<HexagonPipelinerLoopInfo>(LoopInst, &*I);
821 }
822 return nullptr;
823}
824
826 unsigned NumCycles, unsigned ExtraPredCycles,
827 BranchProbability Probability) const {
828 return nonDbgBBSize(&MBB) <= 3;
829}
830
832 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
833 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
834 const {
835 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
836}
837
839 unsigned NumInstrs, BranchProbability Probability) const {
840 return NumInstrs <= 4;
841}
842
843static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
845 const MachineBasicBlock &B = *MI.getParent();
846 Regs.addLiveIns(B);
847 auto E = MachineBasicBlock::const_iterator(MI.getIterator());
848 for (auto I = B.begin(); I != E; ++I) {
849 Clobbers.clear();
850 Regs.stepForward(*I, Clobbers);
851 }
852}
853
854static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
855 const MachineBasicBlock &B = *MI.getParent();
856 Regs.addLiveOuts(B);
857 auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();
858 for (auto I = B.rbegin(); I != E; ++I)
859 Regs.stepBackward(*I);
860}
861
864 const DebugLoc &DL, Register DestReg,
865 Register SrcReg, bool KillSrc,
866 bool RenamableDest,
867 bool RenamableSrc) const {
868 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
869 RegState KillFlag = getKillRegState(KillSrc);
870
871 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
872 BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)
873 .addReg(SrcReg, KillFlag);
874 return;
875 }
876 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
877 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)
878 .addReg(SrcReg, KillFlag);
879 return;
880 }
881 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
882 // Map Pd = Ps to Pd = or(Ps, Ps).
883 BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)
884 .addReg(SrcReg).addReg(SrcReg, KillFlag);
885 return;
886 }
887 if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
888 Hexagon::IntRegsRegClass.contains(SrcReg)) {
889 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
890 .addReg(SrcReg, KillFlag);
891 return;
892 }
893 if (Hexagon::IntRegsRegClass.contains(DestReg) &&
894 Hexagon::CtrRegsRegClass.contains(SrcReg)) {
895 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)
896 .addReg(SrcReg, KillFlag);
897 return;
898 }
899 if (Hexagon::ModRegsRegClass.contains(DestReg) &&
900 Hexagon::IntRegsRegClass.contains(SrcReg)) {
901 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
902 .addReg(SrcReg, KillFlag);
903 return;
904 }
905 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
906 Hexagon::IntRegsRegClass.contains(DestReg)) {
907 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
908 .addReg(SrcReg, KillFlag);
909 return;
910 }
911 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
912 Hexagon::PredRegsRegClass.contains(DestReg)) {
913 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)
914 .addReg(SrcReg, KillFlag);
915 return;
916 }
917 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
918 Hexagon::IntRegsRegClass.contains(DestReg)) {
919 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
920 .addReg(SrcReg, KillFlag);
921 return;
922 }
923 if (Hexagon::HvxVRRegClass.contains(SrcReg, DestReg)) {
924 BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).
925 addReg(SrcReg, KillFlag);
926 return;
927 }
928 if (Hexagon::HvxWRRegClass.contains(SrcReg, DestReg)) {
929 LivePhysRegs LiveAtMI(HRI);
930 getLiveInRegsAt(LiveAtMI, *I);
931 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
932 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
933 RegState UndefLo = getUndefRegState(!LiveAtMI.contains(SrcLo));
934 RegState UndefHi = getUndefRegState(!LiveAtMI.contains(SrcHi));
935 BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)
936 .addReg(SrcHi, KillFlag | UndefHi)
937 .addReg(SrcLo, KillFlag | UndefLo);
938 return;
939 }
940 if (Hexagon::HvxQRRegClass.contains(SrcReg, DestReg)) {
941 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)
942 .addReg(SrcReg)
943 .addReg(SrcReg, KillFlag);
944 return;
945 }
946 if (Hexagon::HvxQRRegClass.contains(SrcReg) &&
947 Hexagon::HvxVRRegClass.contains(DestReg)) {
948 llvm_unreachable("Unimplemented pred to vec");
949 return;
950 }
951 if (Hexagon::HvxQRRegClass.contains(DestReg) &&
952 Hexagon::HvxVRRegClass.contains(SrcReg)) {
953 llvm_unreachable("Unimplemented vec to pred");
954 return;
955 }
956 if (Hexagon::HlxLRRegClass.contains(SrcReg, DestReg)) {
957 BuildMI(MBB, I, DL, get(Hexagon::LX_assign), DestReg)
958 .addReg(SrcReg, KillFlag);
959 return;
960 }
961 if (Hexagon::HlxLLRRegClass.contains(SrcReg, DestReg)) {
962 BuildMI(MBB, I, DL, get(Hexagon::LX_assign_w), DestReg)
963 .addReg(SrcReg, KillFlag);
964 return;
965 }
966
967#ifndef NDEBUG
968 // Show the invalid registers to ease debugging.
969 dbgs() << "Invalid registers for copy in " << printMBBReference(MBB) << ": "
970 << printReg(DestReg, &HRI) << " = " << printReg(SrcReg, &HRI) << '\n';
971#endif
972 llvm_unreachable("Unimplemented");
973}
974
977 Register SrcReg, bool isKill, int FI,
978 const TargetRegisterClass *RC,
979 Register VReg,
980 MachineInstr::MIFlag Flags) const {
981 DebugLoc DL = MBB.findDebugLoc(I);
982 MachineFunction &MF = *MBB.getParent();
983 MachineFrameInfo &MFI = MF.getFrameInfo();
984 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
985 RegState KillFlag = getKillRegState(isKill);
986
987 int MFIIndex = FI;
988 MachineFrameInfo *MMFI = &MFI;
989 if (HMFI.isVTCMStackIndex(FI)) {
990 MFIIndex = HMFI.getMappedVTCMObjectIndex(FI);
991 MMFI = &HMFI.getVTCMFrameInfo();
992 }
995 MMFI->getObjectSize(MFIIndex), MMFI->getObjectAlign(MFIIndex));
996
997 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
998 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
999 .addFrameIndex(FI).addImm(0)
1000 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1001 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
1002 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
1003 .addFrameIndex(FI).addImm(0)
1004 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1005 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
1006 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
1007 .addFrameIndex(FI).addImm(0)
1008 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1009 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
1010 BuildMI(MBB, I, DL, get(Hexagon::STriw_ctr))
1011 .addFrameIndex(FI).addImm(0)
1012 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1013 } else if (Hexagon::CircRegsRegClass.hasSubClassEq(RC)) {
1014 BuildMI(MBB, I, DL, get(Hexagon::STriw_circ))
1015 .addFrameIndex(FI)
1016 .addReg(SrcReg, KillFlag)
1017 .addMemOperand(MMO);
1018 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
1019 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))
1020 .addFrameIndex(FI).addImm(0)
1021 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1022 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
1023 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))
1024 .addFrameIndex(FI).addImm(0)
1025 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1026 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1027 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))
1028 .addFrameIndex(FI).addImm(0)
1029 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1030 } else if (Hexagon::HlxLRRegClass.hasSubClassEq(RC)) {
1031 BuildMI(MBB, I, DL, get(Hexagon::PS_storerl))
1032 .addFrameIndex(FI)
1033 .addImm(0)
1034 .addReg(SrcReg, KillFlag)
1035 .addMemOperand(MMO);
1036 } else {
1037 llvm_unreachable("Unimplemented");
1038 }
1039}
1040
1043 Register DestReg, int FI,
1044 const TargetRegisterClass *RC,
1045 Register VReg, unsigned SubReg,
1046 MachineInstr::MIFlag Flags) const {
1047 DebugLoc DL = MBB.findDebugLoc(I);
1048 MachineFunction &MF = *MBB.getParent();
1049 MachineFrameInfo &MFI = MF.getFrameInfo();
1050 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
1051
1052 int MFIIndex = FI;
1053 MachineFrameInfo *MMFI = &MFI;
1054 if (HMFI.isVTCMStackIndex(FI)) {
1055 MFIIndex = HMFI.getMappedVTCMObjectIndex(FI);
1056 MMFI = &HMFI.getVTCMFrameInfo();
1057 }
1060 MMFI->getObjectSize(MFIIndex), MMFI->getObjectAlign(MFIIndex));
1061
1062 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
1063 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
1064 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1065 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
1066 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
1067 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1068 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
1069 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
1070 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1071 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
1072 BuildMI(MBB, I, DL, get(Hexagon::LDriw_ctr), DestReg)
1073 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1074 } else if (Hexagon::CircRegsRegClass.hasSubClassEq(RC)) {
1075 BuildMI(MBB, I, DL, get(Hexagon::LDriw_circ), DestReg)
1076 .addFrameIndex(FI)
1077 .addMemOperand(MMO);
1078 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
1079 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
1080 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1081 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
1082 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)
1083 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1084 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1085 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)
1086 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1087 } else if (Hexagon::HlxLRRegClass.hasSubClassEq(RC)) {
1088 BuildMI(MBB, I, DL, get(Hexagon::PS_loadrl), DestReg)
1089 .addFrameIndex(FI)
1090 .addImm(0)
1091 .addMemOperand(MMO);
1092 } else {
1093 llvm_unreachable("Can't store this register to stack slot");
1094 }
1095}
1096
1097/// expandPostRAPseudo - This function is called for all pseudo instructions
1098/// that remain after register allocation. Many pseudo instructions are
1099/// created to help register allocation. This is the place to convert them
1100/// into real instructions. The target can edit MI in place, or it can insert
1101/// new instructions and erase MI. The function should return true if
1102/// anything was changed.
1104 MachineBasicBlock &MBB = *MI.getParent();
1105 MachineFunction &MF = *MBB.getParent();
1107 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1108 LivePhysRegs LiveIn(HRI), LiveOut(HRI);
1109 DebugLoc DL = MI.getDebugLoc();
1110 unsigned Opc = MI.getOpcode();
1111
1112 auto RealCirc = [&](unsigned Opc, bool HasImm, unsigned MxOp) {
1113 Register M_CSx = MI.getOperand(MxOp).getReg();
1114 Register Mx = HRI.getSubReg(M_CSx, Hexagon::isub_hi);
1115 unsigned CSOp = HasImm ? 5 : 4;
1116 auto MIB = BuildMI(MBB, MI, DL, get(Opc));
1117 for (unsigned i = 0; i != CSOp; ++i)
1118 if (i == MxOp)
1119 MIB.addReg(Mx);
1120 else
1121 MIB.add(MI.getOperand(i));
1122 Register CSx = (M_CSx == Hexagon::CS_M0 ? Hexagon::CS0 : Hexagon::CS1);
1123 MIB.addReg(CSx, RegState::Implicit);
1124 MBB.erase(MI);
1125 return true;
1126 };
1127
1128 auto UseAligned = [&](const MachineInstr &MI, Align NeedAlign) {
1129 if (MI.memoperands().empty())
1130 return false;
1131 return all_of(MI.memoperands(), [NeedAlign](const MachineMemOperand *MMO) {
1132 return MMO->getAlign() >= NeedAlign;
1133 });
1134 };
1135
1136 switch (Opc) {
1137 case Hexagon::PS_call_instrprof_custom: {
1138 auto Op0 = MI.getOperand(0);
1139 assert(Op0.isGlobal() &&
1140 "First operand must be a global containing handler name.");
1141 const GlobalValue *NameVar = Op0.getGlobal();
1142 const GlobalVariable *GV = dyn_cast<GlobalVariable>(NameVar);
1143 auto *Arr = cast<ConstantDataArray>(GV->getInitializer());
1144 StringRef NameStr = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();
1145
1146 MachineOperand &Op1 = MI.getOperand(1);
1147 // Set R0 with the imm value to be passed to the custom profiling handler.
1148 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrsi), Hexagon::R0)
1149 .addImm(Op1.getImm());
1150 // The call to the custom handler is being treated as a special one as the
1151 // callee is responsible for saving and restoring all the registers
1152 // (including caller saved registers) it needs to modify. This is
1153 // done to reduce the impact of instrumentation on the code being
1154 // instrumented/profiled.
1155 // NOTE: R14, R15 and R28 are reserved for PLT handling. These registers
1156 // are in the Def list of the Hexagon::PS_call_instrprof_custom and
1157 // therefore will be handled appropriately duing register allocation.
1158
1159 // TODO: It may be a good idea to add a separate pseudo instruction for
1160 // static relocation which doesn't need to reserve r14, r15 and r28.
1161
1162 auto MIB = BuildMI(MBB, MI, DL, get(Hexagon::J2_call))
1164 .addDef(Hexagon::R29, RegState::ImplicitDefine)
1165 .addDef(Hexagon::R30, RegState::ImplicitDefine)
1166 .addDef(Hexagon::R14, RegState::ImplicitDefine)
1167 .addDef(Hexagon::R15, RegState::ImplicitDefine)
1168 .addDef(Hexagon::R28, RegState::ImplicitDefine);
1169 const char *cstr = MF.createExternalSymbolName(NameStr);
1170 MIB.addExternalSymbol(cstr);
1171 MBB.erase(MI);
1172 return true;
1173 }
1174 case TargetOpcode::COPY: {
1175 MachineOperand &MD = MI.getOperand(0);
1176 MachineOperand &MS = MI.getOperand(1);
1177 MachineBasicBlock::iterator MBBI = MI.getIterator();
1178 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
1179 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
1180 std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);
1181 }
1182 MBB.erase(MBBI);
1183 return true;
1184 }
1185 case Hexagon::PS_aligna:
1186 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())
1187 .addReg(HRI.getFrameRegister())
1188 .addImm(-MI.getOperand(1).getImm());
1189 MBB.erase(MI);
1190 return true;
1191 case Hexagon::V6_vassignp: {
1192 Register SrcReg = MI.getOperand(1).getReg();
1193 Register DstReg = MI.getOperand(0).getReg();
1194 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
1195 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1196 getLiveInRegsAt(LiveIn, MI);
1197 RegState UndefLo = getUndefRegState(!LiveIn.contains(SrcLo));
1198 RegState UndefHi = getUndefRegState(!LiveIn.contains(SrcHi));
1199 RegState Kill = getKillRegState(MI.getOperand(1).isKill());
1200 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)
1201 .addReg(SrcHi, UndefHi)
1202 .addReg(SrcLo, Kill | UndefLo);
1203 MBB.erase(MI);
1204 return true;
1205 }
1206 case Hexagon::V6_lo:
1207 case Hexagon::LX_lo: {
1208 Register SrcReg = MI.getOperand(1).getReg();
1209 Register DstReg = MI.getOperand(0).getReg();
1210 Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
1211 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());
1212 MBB.erase(MI);
1213 return true;
1214 }
1215 case Hexagon::V6_hi:
1216 case Hexagon::LX_hi: {
1217 Register SrcReg = MI.getOperand(1).getReg();
1218 Register DstReg = MI.getOperand(0).getReg();
1219 Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1220 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());
1221 MBB.erase(MI);
1222 return true;
1223 }
1224 case Hexagon::PS_vloadrv_ai: {
1225 Register DstReg = MI.getOperand(0).getReg();
1226 const MachineOperand &BaseOp = MI.getOperand(1);
1227 assert(BaseOp.getSubReg() == 0);
1228 int Offset = MI.getOperand(2).getImm();
1229 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1230 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
1231 : Hexagon::V6_vL32Ub_ai;
1232 BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
1233 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1234 .addImm(Offset)
1235 .cloneMemRefs(MI);
1236 MBB.erase(MI);
1237 return true;
1238 }
1239 case Hexagon::PS_loadrl: {
1240 Register DstReg = MI.getOperand(0).getReg();
1241 const MachineOperand &BaseOp = MI.getOperand(1);
1242 assert(BaseOp.getSubReg() == 0);
1243 int Offset = MI.getOperand(2).getImm();
1244 Register BaseReg = BaseOp.getReg();
1245 BuildMI(MBB, MI, DL, get(Hexagon::A2_addi), BaseReg)
1246 .addReg(BaseReg, getRegState(BaseOp) | RegState::Kill)
1247 .addImm(Offset);
1248 BuildMI(MBB, MI, DL, get(Hexagon::LX_L16b_pseudo), DstReg)
1249 .addReg(BaseReg, getRegState(BaseOp))
1250 .addReg(Hexagon::VSP, RegState::Implicit)
1251 .cloneMemRefs(MI);
1252 MBB.erase(MI);
1253 return true;
1254 }
1255 case Hexagon::PS_vloadrw_ai: {
1256 Register DstReg = MI.getOperand(0).getReg();
1257 const MachineOperand &BaseOp = MI.getOperand(1);
1258 assert(BaseOp.getSubReg() == 0);
1259 int Offset = MI.getOperand(2).getImm();
1260 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1261 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1262 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
1263 : Hexagon::V6_vL32Ub_ai;
1264 BuildMI(MBB, MI, DL, get(NewOpc),
1265 HRI.getSubReg(DstReg, Hexagon::vsub_lo))
1266 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
1267 .addImm(Offset)
1268 .cloneMemRefs(MI);
1269 BuildMI(MBB, MI, DL, get(NewOpc),
1270 HRI.getSubReg(DstReg, Hexagon::vsub_hi))
1271 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1272 .addImm(Offset + VecOffset)
1273 .cloneMemRefs(MI);
1274 MBB.erase(MI);
1275 return true;
1276 }
1277 case Hexagon::PS_vstorerv_ai: {
1278 const MachineOperand &SrcOp = MI.getOperand(2);
1279 assert(SrcOp.getSubReg() == 0);
1280 const MachineOperand &BaseOp = MI.getOperand(0);
1281 assert(BaseOp.getSubReg() == 0);
1282 int Offset = MI.getOperand(1).getImm();
1283 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1284 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
1285 : Hexagon::V6_vS32Ub_ai;
1286 BuildMI(MBB, MI, DL, get(NewOpc))
1287 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1288 .addImm(Offset)
1290 .cloneMemRefs(MI);
1291 MBB.erase(MI);
1292 return true;
1293 }
1294 case Hexagon::PS_storerl: {
1295 const MachineOperand &SrcOp = MI.getOperand(2);
1296 assert(SrcOp.getSubReg() == 0);
1297 const MachineOperand &BaseOp = MI.getOperand(0);
1298 assert(BaseOp.getSubReg() == 0);
1299 Register BaseReg = BaseOp.getReg();
1300 int Offset = MI.getOperand(1).getImm();
1301 BuildMI(MBB, MI, DL, get(Hexagon::A2_addi), BaseReg)
1302 .addReg(BaseReg, getRegState(BaseOp) | RegState::Kill)
1303 .addImm(Offset);
1304 BuildMI(MBB, MI, DL, get(Hexagon::LX_S16b_pseudo))
1305 .addReg(BaseReg, getRegState(BaseOp))
1307 .addReg(Hexagon::VSP, RegState::Implicit)
1308 .cloneMemRefs(MI);
1309 MBB.erase(MI);
1310 return true;
1311 }
1312 case Hexagon::PS_vstorerw_ai: {
1313 Register SrcReg = MI.getOperand(2).getReg();
1314 const MachineOperand &BaseOp = MI.getOperand(0);
1315 assert(BaseOp.getSubReg() == 0);
1316 int Offset = MI.getOperand(1).getImm();
1317 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1318 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1319 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
1320 : Hexagon::V6_vS32Ub_ai;
1321 BuildMI(MBB, MI, DL, get(NewOpc))
1322 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
1323 .addImm(Offset)
1324 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))
1325 .cloneMemRefs(MI);
1326 BuildMI(MBB, MI, DL, get(NewOpc))
1327 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1328 .addImm(Offset + VecOffset)
1329 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))
1330 .cloneMemRefs(MI);
1331 MBB.erase(MI);
1332 return true;
1333 }
1334 case Hexagon::PS_true: {
1335 Register Reg = MI.getOperand(0).getReg();
1336 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1337 .addReg(Reg, RegState::Undef)
1338 .addReg(Reg, RegState::Undef);
1339 MBB.erase(MI);
1340 return true;
1341 }
1342 case Hexagon::PS_false: {
1343 Register Reg = MI.getOperand(0).getReg();
1344 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1345 .addReg(Reg, RegState::Undef)
1346 .addReg(Reg, RegState::Undef);
1347 MBB.erase(MI);
1348 return true;
1349 }
1350 case Hexagon::PS_qtrue: {
1351 BuildMI(MBB, MI, DL, get(Hexagon::V6_veqw), MI.getOperand(0).getReg())
1352 .addReg(Hexagon::V0, RegState::Undef)
1353 .addReg(Hexagon::V0, RegState::Undef);
1354 MBB.erase(MI);
1355 return true;
1356 }
1357 case Hexagon::PS_qfalse: {
1358 BuildMI(MBB, MI, DL, get(Hexagon::V6_vgtw), MI.getOperand(0).getReg())
1359 .addReg(Hexagon::V0, RegState::Undef)
1360 .addReg(Hexagon::V0, RegState::Undef);
1361 MBB.erase(MI);
1362 return true;
1363 }
1364 case Hexagon::PS_vdd0: {
1365 Register Vd = MI.getOperand(0).getReg();
1366 BuildMI(MBB, MI, DL, get(Hexagon::V6_vsubw_dv), Vd)
1368 .addReg(Vd, RegState::Undef);
1369 MBB.erase(MI);
1370 return true;
1371 }
1372 case Hexagon::PS_vmulw: {
1373 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
1374 Register DstReg = MI.getOperand(0).getReg();
1375 Register Src1Reg = MI.getOperand(1).getReg();
1376 Register Src2Reg = MI.getOperand(2).getReg();
1377 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1378 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1379 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1380 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1381 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1382 HRI.getSubReg(DstReg, Hexagon::isub_hi))
1383 .addReg(Src1SubHi)
1384 .addReg(Src2SubHi);
1385 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1386 HRI.getSubReg(DstReg, Hexagon::isub_lo))
1387 .addReg(Src1SubLo)
1388 .addReg(Src2SubLo);
1389 MBB.erase(MI);
1390 return true;
1391 }
1392 case Hexagon::PS_vmulw_acc: {
1393 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
1394 Register DstReg = MI.getOperand(0).getReg();
1395 Register Src1Reg = MI.getOperand(1).getReg();
1396 Register Src2Reg = MI.getOperand(2).getReg();
1397 Register Src3Reg = MI.getOperand(3).getReg();
1398 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1399 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1400 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1401 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1402 Register Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);
1403 Register Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);
1404 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1405 HRI.getSubReg(DstReg, Hexagon::isub_hi))
1406 .addReg(Src1SubHi)
1407 .addReg(Src2SubHi)
1408 .addReg(Src3SubHi);
1409 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1410 HRI.getSubReg(DstReg, Hexagon::isub_lo))
1411 .addReg(Src1SubLo)
1412 .addReg(Src2SubLo)
1413 .addReg(Src3SubLo);
1414 MBB.erase(MI);
1415 return true;
1416 }
1417 case Hexagon::PS_pselect: {
1418 const MachineOperand &Op0 = MI.getOperand(0);
1419 const MachineOperand &Op1 = MI.getOperand(1);
1420 const MachineOperand &Op2 = MI.getOperand(2);
1421 const MachineOperand &Op3 = MI.getOperand(3);
1422 Register Rd = Op0.getReg();
1423 Register Pu = Op1.getReg();
1424 Register Rs = Op2.getReg();
1425 Register Rt = Op3.getReg();
1426 DebugLoc DL = MI.getDebugLoc();
1427 RegState K1 = getKillRegState(Op1.isKill());
1428 RegState K2 = getKillRegState(Op2.isKill());
1429 RegState K3 = getKillRegState(Op3.isKill());
1430 if (Rd != Rs)
1431 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1432 .addReg(Pu, (Rd == Rt) ? K1 : RegState::NoFlags)
1433 .addReg(Rs, K2);
1434 if (Rd != Rt)
1435 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1436 .addReg(Pu, K1)
1437 .addReg(Rt, K3);
1438 MBB.erase(MI);
1439 return true;
1440 }
1441 case Hexagon::PS_vselect: {
1442 const MachineOperand &Op0 = MI.getOperand(0);
1443 const MachineOperand &Op1 = MI.getOperand(1);
1444 const MachineOperand &Op2 = MI.getOperand(2);
1445 const MachineOperand &Op3 = MI.getOperand(3);
1446 getLiveOutRegsAt(LiveOut, MI);
1447 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());
1448 Register PReg = Op1.getReg();
1449 assert(Op1.getSubReg() == 0);
1450 RegState PState = getRegState(Op1);
1451
1452 if (Op0.getReg() != Op2.getReg()) {
1453 RegState S =
1454 Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill : PState;
1455 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
1456 .add(Op0)
1457 .addReg(PReg, S)
1458 .add(Op2);
1459 if (IsDestLive)
1460 T.addReg(Op0.getReg(), RegState::Implicit);
1461 IsDestLive = true;
1462 }
1463 if (Op0.getReg() != Op3.getReg()) {
1464 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
1465 .add(Op0)
1466 .addReg(PReg, PState)
1467 .add(Op3);
1468 if (IsDestLive)
1469 T.addReg(Op0.getReg(), RegState::Implicit);
1470 }
1471 MBB.erase(MI);
1472 return true;
1473 }
1474 case Hexagon::PS_wselect: {
1475 MachineOperand &Op0 = MI.getOperand(0);
1476 MachineOperand &Op1 = MI.getOperand(1);
1477 MachineOperand &Op2 = MI.getOperand(2);
1478 MachineOperand &Op3 = MI.getOperand(3);
1479 getLiveOutRegsAt(LiveOut, MI);
1480 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());
1481 Register PReg = Op1.getReg();
1482 assert(Op1.getSubReg() == 0);
1483 RegState PState = getRegState(Op1);
1484
1485 if (Op0.getReg() != Op2.getReg()) {
1486 RegState S =
1487 Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill : PState;
1488 Register SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);
1489 Register SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);
1490 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
1491 .add(Op0)
1492 .addReg(PReg, S)
1493 .addReg(SrcHi)
1494 .addReg(SrcLo);
1495 if (IsDestLive)
1496 T.addReg(Op0.getReg(), RegState::Implicit);
1497 IsDestLive = true;
1498 }
1499 if (Op0.getReg() != Op3.getReg()) {
1500 Register SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);
1501 Register SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);
1502 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
1503 .add(Op0)
1504 .addReg(PReg, PState)
1505 .addReg(SrcHi)
1506 .addReg(SrcLo);
1507 if (IsDestLive)
1508 T.addReg(Op0.getReg(), RegState::Implicit);
1509 }
1510 MBB.erase(MI);
1511 return true;
1512 }
1513
1514 case Hexagon::PS_crash: {
1515 // Generate a misaligned load that is guaranteed to cause a crash.
1516 class CrashPseudoSourceValue : public PseudoSourceValue {
1517 public:
1518 CrashPseudoSourceValue(const TargetMachine &TM)
1519 : PseudoSourceValue(TargetCustom, TM) {}
1520
1521 bool isConstant(const MachineFrameInfo *) const override {
1522 return false;
1523 }
1524 bool isAliased(const MachineFrameInfo *) const override {
1525 return false;
1526 }
1527 bool mayAlias(const MachineFrameInfo *) const override {
1528 return false;
1529 }
1530 void printCustom(raw_ostream &OS) const override {
1531 OS << "MisalignedCrash";
1532 }
1533 };
1534
1535 static const CrashPseudoSourceValue CrashPSV(MF.getTarget());
1537 MachinePointerInfo(&CrashPSV),
1539 Align(1));
1540 BuildMI(MBB, MI, DL, get(Hexagon::PS_loadrdabs), Hexagon::D13)
1541 .addImm(0xBADC0FEE) // Misaligned load.
1542 .addMemOperand(MMO);
1543 MBB.erase(MI);
1544 return true;
1545 }
1546
1547 case Hexagon::PS_tailcall_i:
1548 MI.setDesc(get(Hexagon::J2_jump));
1549 return true;
1550 case Hexagon::PS_tailcall_r:
1551 case Hexagon::PS_jmpret:
1552 MI.setDesc(get(Hexagon::J2_jumpr));
1553 return true;
1554 case Hexagon::PS_jmprett:
1555 MI.setDesc(get(Hexagon::J2_jumprt));
1556 return true;
1557 case Hexagon::PS_jmpretf:
1558 MI.setDesc(get(Hexagon::J2_jumprf));
1559 return true;
1560 case Hexagon::PS_jmprettnewpt:
1561 MI.setDesc(get(Hexagon::J2_jumprtnewpt));
1562 return true;
1563 case Hexagon::PS_jmpretfnewpt:
1564 MI.setDesc(get(Hexagon::J2_jumprfnewpt));
1565 return true;
1566 case Hexagon::PS_jmprettnew:
1567 MI.setDesc(get(Hexagon::J2_jumprtnew));
1568 return true;
1569 case Hexagon::PS_jmpretfnew:
1570 MI.setDesc(get(Hexagon::J2_jumprfnew));
1571 return true;
1572
1573 case Hexagon::PS_loadrub_pci:
1574 return RealCirc(Hexagon::L2_loadrub_pci, /*HasImm*/true, /*MxOp*/4);
1575 case Hexagon::PS_loadrb_pci:
1576 return RealCirc(Hexagon::L2_loadrb_pci, /*HasImm*/true, /*MxOp*/4);
1577 case Hexagon::PS_loadruh_pci:
1578 return RealCirc(Hexagon::L2_loadruh_pci, /*HasImm*/true, /*MxOp*/4);
1579 case Hexagon::PS_loadrh_pci:
1580 return RealCirc(Hexagon::L2_loadrh_pci, /*HasImm*/true, /*MxOp*/4);
1581 case Hexagon::PS_loadri_pci:
1582 return RealCirc(Hexagon::L2_loadri_pci, /*HasImm*/true, /*MxOp*/4);
1583 case Hexagon::PS_loadrd_pci:
1584 return RealCirc(Hexagon::L2_loadrd_pci, /*HasImm*/true, /*MxOp*/4);
1585 case Hexagon::PS_loadrub_pcr:
1586 return RealCirc(Hexagon::L2_loadrub_pcr, /*HasImm*/false, /*MxOp*/3);
1587 case Hexagon::PS_loadrb_pcr:
1588 return RealCirc(Hexagon::L2_loadrb_pcr, /*HasImm*/false, /*MxOp*/3);
1589 case Hexagon::PS_loadruh_pcr:
1590 return RealCirc(Hexagon::L2_loadruh_pcr, /*HasImm*/false, /*MxOp*/3);
1591 case Hexagon::PS_loadrh_pcr:
1592 return RealCirc(Hexagon::L2_loadrh_pcr, /*HasImm*/false, /*MxOp*/3);
1593 case Hexagon::PS_loadri_pcr:
1594 return RealCirc(Hexagon::L2_loadri_pcr, /*HasImm*/false, /*MxOp*/3);
1595 case Hexagon::PS_loadrd_pcr:
1596 return RealCirc(Hexagon::L2_loadrd_pcr, /*HasImm*/false, /*MxOp*/3);
1597 case Hexagon::PS_storerb_pci:
1598 return RealCirc(Hexagon::S2_storerb_pci, /*HasImm*/true, /*MxOp*/3);
1599 case Hexagon::PS_storerh_pci:
1600 return RealCirc(Hexagon::S2_storerh_pci, /*HasImm*/true, /*MxOp*/3);
1601 case Hexagon::PS_storerf_pci:
1602 return RealCirc(Hexagon::S2_storerf_pci, /*HasImm*/true, /*MxOp*/3);
1603 case Hexagon::PS_storeri_pci:
1604 return RealCirc(Hexagon::S2_storeri_pci, /*HasImm*/true, /*MxOp*/3);
1605 case Hexagon::PS_storerd_pci:
1606 return RealCirc(Hexagon::S2_storerd_pci, /*HasImm*/true, /*MxOp*/3);
1607 case Hexagon::PS_storerb_pcr:
1608 return RealCirc(Hexagon::S2_storerb_pcr, /*HasImm*/false, /*MxOp*/2);
1609 case Hexagon::PS_storerh_pcr:
1610 return RealCirc(Hexagon::S2_storerh_pcr, /*HasImm*/false, /*MxOp*/2);
1611 case Hexagon::PS_storerf_pcr:
1612 return RealCirc(Hexagon::S2_storerf_pcr, /*HasImm*/false, /*MxOp*/2);
1613 case Hexagon::PS_storeri_pcr:
1614 return RealCirc(Hexagon::S2_storeri_pcr, /*HasImm*/false, /*MxOp*/2);
1615 case Hexagon::PS_storerd_pcr:
1616 return RealCirc(Hexagon::S2_storerd_pcr, /*HasImm*/false, /*MxOp*/2);
1617 }
1618
1619 return false;
1620}
1621
1624 MachineBasicBlock &MBB = *MI.getParent();
1625 const DebugLoc &DL = MI.getDebugLoc();
1626 unsigned Opc = MI.getOpcode();
1628
1629 switch (Opc) {
1630 case Hexagon::V6_vgather_vscatter_mh_pseudo:
1631 // This is mainly a place holder. It will be extended.
1632 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
1633 .add(MI.getOperand(2))
1634 .add(MI.getOperand(3))
1635 .add(MI.getOperand(4));
1636 BuildMI(MBB, MI, DL, get(Hexagon::V6_vscattermh))
1637 .add(MI.getOperand(2))
1638 .add(MI.getOperand(3))
1639 .add(MI.getOperand(4))
1640 .addReg(Hexagon::VTMP);
1641 MBB.erase(MI);
1642 return First.getInstrIterator();
1643 case Hexagon::V6_vgathermh_pseudo:
1644 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
1645 .add(MI.getOperand(2))
1646 .add(MI.getOperand(3))
1647 .add(MI.getOperand(4));
1648 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1649 .add(MI.getOperand(0))
1650 .addImm(MI.getOperand(1).getImm())
1651 .addReg(Hexagon::VTMP);
1652 MBB.erase(MI);
1653 return First.getInstrIterator();
1654
1655 case Hexagon::V6_vgathermw_pseudo:
1656 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))
1657 .add(MI.getOperand(2))
1658 .add(MI.getOperand(3))
1659 .add(MI.getOperand(4));
1660 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1661 .add(MI.getOperand(0))
1662 .addImm(MI.getOperand(1).getImm())
1663 .addReg(Hexagon::VTMP);
1664 MBB.erase(MI);
1665 return First.getInstrIterator();
1666
1667 case Hexagon::V6_vgathermhw_pseudo:
1668 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))
1669 .add(MI.getOperand(2))
1670 .add(MI.getOperand(3))
1671 .add(MI.getOperand(4));
1672 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1673 .add(MI.getOperand(0))
1674 .addImm(MI.getOperand(1).getImm())
1675 .addReg(Hexagon::VTMP);
1676 MBB.erase(MI);
1677 return First.getInstrIterator();
1678
1679 case Hexagon::V6_vgathermhq_pseudo:
1680 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))
1681 .add(MI.getOperand(2))
1682 .add(MI.getOperand(3))
1683 .add(MI.getOperand(4))
1684 .add(MI.getOperand(5));
1685 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1686 .add(MI.getOperand(0))
1687 .addImm(MI.getOperand(1).getImm())
1688 .addReg(Hexagon::VTMP);
1689 MBB.erase(MI);
1690 return First.getInstrIterator();
1691
1692 case Hexagon::V6_vgathermwq_pseudo:
1693 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))
1694 .add(MI.getOperand(2))
1695 .add(MI.getOperand(3))
1696 .add(MI.getOperand(4))
1697 .add(MI.getOperand(5));
1698 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1699 .add(MI.getOperand(0))
1700 .addImm(MI.getOperand(1).getImm())
1701 .addReg(Hexagon::VTMP);
1702 MBB.erase(MI);
1703 return First.getInstrIterator();
1704
1705 case Hexagon::V6_vgathermhwq_pseudo:
1706 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))
1707 .add(MI.getOperand(2))
1708 .add(MI.getOperand(3))
1709 .add(MI.getOperand(4))
1710 .add(MI.getOperand(5));
1711 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1712 .add(MI.getOperand(0))
1713 .addImm(MI.getOperand(1).getImm())
1714 .addReg(Hexagon::VTMP);
1715 MBB.erase(MI);
1716 return First.getInstrIterator();
1717 }
1718
1719 return MI.getIterator();
1720}
1721
1722// We indicate that we want to reverse the branch by
1723// inserting the reversed branching opcode.
1726 if (Cond.empty())
1727 return true;
1728 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1729 unsigned opcode = Cond[0].getImm();
1730 //unsigned temp;
1731 assert(get(opcode).isBranch() && "Should be a branching condition.");
1732 if (isEndLoopN(opcode))
1733 return true;
1734 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1735 Cond[0].setImm(NewOpcode);
1736 return false;
1737}
1738
1744
1748
1750 unsigned BasePos, OffsetPos;
1751 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
1752 return false;
1753 return isPostIncrement(MI) && MI.getOperand(OffsetPos).isImm();
1754}
1755
1756// Returns true if an instruction is predicated irrespective of the predicate
1757// sense. For example, all of the following will return true.
1758// if (p0) R1 = add(R2, R3)
1759// if (!p0) R1 = add(R2, R3)
1760// if (p0.new) R1 = add(R2, R3)
1761// if (!p0.new) R1 = add(R2, R3)
1762// Note: New-value stores are not included here as in the current
1763// implementation, we don't need to check their predicate sense.
1765 const uint64_t F = MI.getDesc().TSFlags;
1767}
1768
1771 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1772 isEndLoopN(Cond[0].getImm())) {
1773 LLVM_DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
1774 return false;
1775 }
1776 int Opc = MI.getOpcode();
1777 assert (isPredicable(MI) && "Expected predicable instruction");
1778 bool invertJump = predOpcodeHasNot(Cond);
1779
1780 // We have to predicate MI "in place", i.e. after this function returns,
1781 // MI will need to be transformed into a predicated form. To avoid com-
1782 // plicated manipulations with the operands (handling tied operands,
1783 // etc.), build a new temporary instruction, then overwrite MI with it.
1784
1785 MachineBasicBlock &B = *MI.getParent();
1786 DebugLoc DL = MI.getDebugLoc();
1787 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1788 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
1789 unsigned NOp = 0, NumOps = MI.getNumOperands();
1790 while (NOp < NumOps) {
1791 MachineOperand &Op = MI.getOperand(NOp);
1792 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1793 break;
1794 T.add(Op);
1795 NOp++;
1796 }
1797
1798 Register PredReg;
1799 unsigned PredRegPos;
1800 RegState PredRegFlags = {};
1801 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1802 (void)GotPredReg;
1803 assert(GotPredReg);
1804 T.addReg(PredReg, PredRegFlags);
1805 while (NOp < NumOps)
1806 T.add(MI.getOperand(NOp++));
1807
1808 MI.setDesc(get(PredOpc));
1809 while (unsigned n = MI.getNumOperands())
1810 MI.removeOperand(n-1);
1811 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
1812 MI.addOperand(T->getOperand(i));
1813
1814 MachineBasicBlock::instr_iterator TI = T->getIterator();
1815 B.erase(TI);
1816
1817 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1818 MRI.clearKillFlags(PredReg);
1819 return true;
1820}
1821
1823 ArrayRef<MachineOperand> Pred2) const {
1824 // TODO: Fix this
1825 return false;
1826}
1827
1829 std::vector<MachineOperand> &Pred,
1830 bool SkipDead) const {
1831 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1832
1833 for (const MachineOperand &MO : MI.operands()) {
1834 if (MO.isReg()) {
1835 if (!MO.isDef())
1836 continue;
1837 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1838 if (RC == &Hexagon::PredRegsRegClass) {
1839 Pred.push_back(MO);
1840 return true;
1841 }
1842 continue;
1843 } else if (MO.isRegMask()) {
1844 for (Register PR : Hexagon::PredRegsRegClass) {
1845 if (!MI.modifiesRegister(PR, &HRI))
1846 continue;
1847 Pred.push_back(MO);
1848 return true;
1849 }
1850 }
1851 }
1852 return false;
1853}
1854
1856 if (!MI.getDesc().isPredicable())
1857 return false;
1858
1859 if (MI.isCall() || isTailCall(MI)) {
1860 if (!Subtarget.usePredicatedCalls())
1861 return false;
1862 }
1863
1864 // HVX loads are not predicable on v60, but are on v62.
1865 if (!Subtarget.hasV62Ops()) {
1866 switch (MI.getOpcode()) {
1867 case Hexagon::V6_vL32b_ai:
1868 case Hexagon::V6_vL32b_pi:
1869 case Hexagon::V6_vL32b_ppu:
1870 case Hexagon::V6_vL32b_cur_ai:
1871 case Hexagon::V6_vL32b_cur_pi:
1872 case Hexagon::V6_vL32b_cur_ppu:
1873 case Hexagon::V6_vL32b_nt_ai:
1874 case Hexagon::V6_vL32b_nt_pi:
1875 case Hexagon::V6_vL32b_nt_ppu:
1876 case Hexagon::V6_vL32b_tmp_ai:
1877 case Hexagon::V6_vL32b_tmp_pi:
1878 case Hexagon::V6_vL32b_tmp_ppu:
1879 case Hexagon::V6_vL32b_nt_cur_ai:
1880 case Hexagon::V6_vL32b_nt_cur_pi:
1881 case Hexagon::V6_vL32b_nt_cur_ppu:
1882 case Hexagon::V6_vL32b_nt_tmp_ai:
1883 case Hexagon::V6_vL32b_nt_tmp_pi:
1884 case Hexagon::V6_vL32b_nt_tmp_ppu:
1885 return false;
1886 }
1887 }
1888 return true;
1889}
1890
1892 bool Invert) const {
1893 if (Invert)
1894 return false;
1895
1896 switch (Inst.getOpcode()) {
1897 // TODO: Add more instructions to be handled by MachineCombiner.
1898 case Hexagon::F2_sfadd:
1900 default:
1901 return false;
1902 }
1903}
1904
1906 const MachineBasicBlock *MBB,
1907 const MachineFunction &MF) const {
1908 // Debug info is never a scheduling boundary. It's necessary to be explicit
1909 // due to the special treatment of IT instructions below, otherwise a
1910 // dbg_value followed by an IT will result in the IT instruction being
1911 // considered a scheduling hazard, which is wrong. It should be the actual
1912 // instruction preceding the dbg_value instruction(s), just like it is
1913 // when debug info is not present.
1914 if (MI.isDebugInstr())
1915 return false;
1916
1917 // Throwing call is a boundary.
1918 if (MI.isCall()) {
1919 // Don't mess around with no return calls.
1920 if (doesNotReturn(MI))
1921 return true;
1922 // If any of the block's successors is a landing pad, this could be a
1923 // throwing call.
1924 for (auto *I : MBB->successors())
1925 if (I->isEHPad())
1926 return true;
1927 }
1928
1929 // Terminators and labels can't be scheduled around.
1930 if (MI.getDesc().isTerminator() || MI.isPosition())
1931 return true;
1932
1933 // INLINEASM_BR can jump to another block
1934 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
1935 return true;
1936
1937 if (MI.isInlineAsm() && !ScheduleInlineAsm)
1938 return true;
1939
1940 return false;
1941}
1942
1943/// Measure the specified inline asm to determine an approximation of its
1944/// length.
1945/// Comments (which run till the next SeparatorString or newline) do not
1946/// count as an instruction.
1947/// Any other non-whitespace text is considered an instruction, with
1948/// multiple instructions separated by SeparatorString or newlines.
1949/// Variable-length instructions are not handled here; this function
1950/// may be overloaded in the target code to do that.
1951/// Hexagon counts the number of ##'s and adjust for that many
1952/// constant exenders.
1954 const MCAsmInfo &MAI,
1955 const TargetSubtargetInfo *STI) const {
1956 StringRef AStr(Str);
1957 // Count the number of instructions in the asm.
1958 bool atInsnStart = true;
1959 unsigned Length = 0;
1960 const unsigned MaxInstLength = MAI.getMaxInstLength(STI);
1961 for (; *Str; ++Str) {
1962 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1963 strlen(MAI.getSeparatorString())) == 0)
1964 atInsnStart = true;
1965 if (atInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {
1966 Length += MaxInstLength;
1967 atInsnStart = false;
1968 }
1969 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
1970 MAI.getCommentString().size()) == 0)
1971 atInsnStart = false;
1972 }
1973
1974 // Add to size number of constant extenders seen * 4.
1975 StringRef Occ("##");
1976 Length += AStr.count(Occ)*4;
1977 return Length;
1978}
1979
1987
1988/// For a comparison instruction, return the source registers in
1989/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1990/// compares against in CmpValue. Return true if the comparison instruction
1991/// can be analyzed.
1993 Register &SrcReg2, int64_t &Mask,
1994 int64_t &Value) const {
1995 unsigned Opc = MI.getOpcode();
1996
1997 // Set mask and the first source register.
1998 switch (Opc) {
1999 case Hexagon::C2_cmpeq:
2000 case Hexagon::C2_cmpeqp:
2001 case Hexagon::C2_cmpgt:
2002 case Hexagon::C2_cmpgtp:
2003 case Hexagon::C2_cmpgtu:
2004 case Hexagon::C2_cmpgtup:
2005 case Hexagon::C4_cmpneq:
2006 case Hexagon::C4_cmplte:
2007 case Hexagon::C4_cmplteu:
2008 case Hexagon::C2_cmpeqi:
2009 case Hexagon::C2_cmpgti:
2010 case Hexagon::C2_cmpgtui:
2011 case Hexagon::C4_cmpneqi:
2012 case Hexagon::C4_cmplteui:
2013 case Hexagon::C4_cmpltei:
2014 SrcReg = MI.getOperand(1).getReg();
2015 Mask = ~0;
2016 break;
2017 case Hexagon::A4_cmpbeq:
2018 case Hexagon::A4_cmpbgt:
2019 case Hexagon::A4_cmpbgtu:
2020 case Hexagon::A4_cmpbeqi:
2021 case Hexagon::A4_cmpbgti:
2022 case Hexagon::A4_cmpbgtui:
2023 SrcReg = MI.getOperand(1).getReg();
2024 Mask = 0xFF;
2025 break;
2026 case Hexagon::A4_cmpheq:
2027 case Hexagon::A4_cmphgt:
2028 case Hexagon::A4_cmphgtu:
2029 case Hexagon::A4_cmpheqi:
2030 case Hexagon::A4_cmphgti:
2031 case Hexagon::A4_cmphgtui:
2032 SrcReg = MI.getOperand(1).getReg();
2033 Mask = 0xFFFF;
2034 break;
2035 }
2036
2037 // Set the value/second source register.
2038 switch (Opc) {
2039 case Hexagon::C2_cmpeq:
2040 case Hexagon::C2_cmpeqp:
2041 case Hexagon::C2_cmpgt:
2042 case Hexagon::C2_cmpgtp:
2043 case Hexagon::C2_cmpgtu:
2044 case Hexagon::C2_cmpgtup:
2045 case Hexagon::A4_cmpbeq:
2046 case Hexagon::A4_cmpbgt:
2047 case Hexagon::A4_cmpbgtu:
2048 case Hexagon::A4_cmpheq:
2049 case Hexagon::A4_cmphgt:
2050 case Hexagon::A4_cmphgtu:
2051 case Hexagon::C4_cmpneq:
2052 case Hexagon::C4_cmplte:
2053 case Hexagon::C4_cmplteu:
2054 SrcReg2 = MI.getOperand(2).getReg();
2055 Value = 0;
2056 return true;
2057
2058 case Hexagon::C2_cmpeqi:
2059 case Hexagon::C2_cmpgtui:
2060 case Hexagon::C2_cmpgti:
2061 case Hexagon::C4_cmpneqi:
2062 case Hexagon::C4_cmplteui:
2063 case Hexagon::C4_cmpltei:
2064 case Hexagon::A4_cmpbeqi:
2065 case Hexagon::A4_cmpbgti:
2066 case Hexagon::A4_cmpbgtui:
2067 case Hexagon::A4_cmpheqi:
2068 case Hexagon::A4_cmphgti:
2069 case Hexagon::A4_cmphgtui: {
2070 SrcReg2 = 0;
2071 const MachineOperand &Op2 = MI.getOperand(2);
2072 if (!Op2.isImm())
2073 return false;
2074 Value = MI.getOperand(2).getImm();
2075 return true;
2076 }
2077 }
2078
2079 return false;
2080}
2081
2083 const MachineInstr &MI,
2084 unsigned *PredCost) const {
2085 return getInstrTimingClassLatency(ItinData, MI);
2086}
2087
2089 const TargetSubtargetInfo &STI) const {
2091 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
2092}
2093
2094// Inspired by this pair:
2095// %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]
2096// S2_storeri_io %r29, 132, killed %r1; flags: mem:ST4[FixedStack1]
2097// Currently AA considers the addresses in these instructions to be aliasing.
2099 const MachineInstr &MIa, const MachineInstr &MIb) const {
2102 return false;
2103
2104 // Instructions that are pure loads, not loads and stores like memops are not
2105 // dependent.
2106 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))
2107 return true;
2108
2109 // Get the base register in MIa.
2110 unsigned BasePosA, OffsetPosA;
2111 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))
2112 return false;
2113 const MachineOperand &BaseA = MIa.getOperand(BasePosA);
2114 Register BaseRegA = BaseA.getReg();
2115 unsigned BaseSubA = BaseA.getSubReg();
2116
2117 // Get the base register in MIb.
2118 unsigned BasePosB, OffsetPosB;
2119 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))
2120 return false;
2121 const MachineOperand &BaseB = MIb.getOperand(BasePosB);
2122 Register BaseRegB = BaseB.getReg();
2123 unsigned BaseSubB = BaseB.getSubReg();
2124
2125 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)
2126 return false;
2127
2128 // Get the access sizes.
2129 unsigned SizeA = getMemAccessSize(MIa);
2130 unsigned SizeB = getMemAccessSize(MIb);
2131
2132 // Get the offsets. Handle immediates only for now.
2133 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);
2134 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);
2135 if (!MIa.getOperand(OffsetPosA).isImm() ||
2136 !MIb.getOperand(OffsetPosB).isImm())
2137 return false;
2138 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();
2139 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();
2140
2141 // This is a mem access with the same base register and known offsets from it.
2142 // Reason about it.
2143 if (OffsetA > OffsetB) {
2144 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
2145 return SizeB <= OffDiff;
2146 }
2147 if (OffsetA < OffsetB) {
2148 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
2149 return SizeA <= OffDiff;
2150 }
2151
2152 return false;
2153}
2154
2155/// If the instruction is an increment of a constant value, return the amount.
2157 int &Value) const {
2158 if (isPostIncrement(MI)) {
2159 unsigned BasePos = 0, OffsetPos = 0;
2160 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
2161 return false;
2162 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
2163 if (OffsetOp.isImm()) {
2164 Value = OffsetOp.getImm();
2165 return true;
2166 }
2167 } else if (MI.getOpcode() == Hexagon::A2_addi) {
2168 const MachineOperand &AddOp = MI.getOperand(2);
2169 if (AddOp.isImm()) {
2170 Value = AddOp.getImm();
2171 return true;
2172 }
2173 }
2174
2175 return false;
2176}
2177
2178std::pair<unsigned, unsigned>
2180 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,
2182}
2183
2186 using namespace HexagonII;
2187
2188 static const std::pair<unsigned, const char*> Flags[] = {
2189 {MO_PCREL, "hexagon-pcrel"},
2190 {MO_GOT, "hexagon-got"},
2191 {MO_LO16, "hexagon-lo16"},
2192 {MO_HI16, "hexagon-hi16"},
2193 {MO_GPREL, "hexagon-gprel"},
2194 {MO_GDGOT, "hexagon-gdgot"},
2195 {MO_GDPLT, "hexagon-gdplt"},
2196 {MO_IE, "hexagon-ie"},
2197 {MO_IEGOT, "hexagon-iegot"},
2198 {MO_TPREL, "hexagon-tprel"}
2199 };
2200 return ArrayRef(Flags);
2201}
2202
2205 using namespace HexagonII;
2206
2207 static const std::pair<unsigned, const char*> Flags[] = {
2208 {HMOTF_ConstExtended, "hexagon-ext"}
2209 };
2210 return ArrayRef(Flags);
2211}
2212
2215 const TargetRegisterClass *TRC;
2216 if (VT == MVT::i1) {
2217 TRC = &Hexagon::PredRegsRegClass;
2218 } else if (VT == MVT::i32 || VT == MVT::f32) {
2219 TRC = &Hexagon::IntRegsRegClass;
2220 } else if (VT == MVT::i64 || VT == MVT::f64) {
2221 TRC = &Hexagon::DoubleRegsRegClass;
2222 } else {
2223 llvm_unreachable("Cannot handle this register class");
2224 }
2225
2226 Register NewReg = MRI.createVirtualRegister(TRC);
2227 return NewReg;
2228}
2229
2233
2235 const uint64_t F = MI.getDesc().TSFlags;
2237}
2238
2242
2244 return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&
2245 !MI.getDesc().mayStore() &&
2246 MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&
2247 MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&
2248 !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();
2249}
2250
2251// Return true if the instruction is a compound branch instruction.
2253 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
2254}
2255
2256// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
2257// isFPImm and later getFPImm as well.
2259 const uint64_t F = MI.getDesc().TSFlags;
2261 if (isExtended) // Instruction must be extended.
2262 return true;
2263
2264 unsigned isExtendable =
2266 if (!isExtendable)
2267 return false;
2268
2269 if (MI.isCall())
2270 return false;
2271
2272 short ExtOpNum = getCExtOpNum(MI);
2273 const MachineOperand &MO = MI.getOperand(ExtOpNum);
2274 // Use MO operand flags to determine if MO
2275 // has the HMOTF_ConstExtended flag set.
2277 return true;
2278 // If this is a Machine BB address we are talking about, and it is
2279 // not marked as extended, say so.
2280 if (MO.isMBB())
2281 return false;
2282
2283 // We could be using an instruction with an extendable immediate and shoehorn
2284 // a global address into it. If it is a global address it will be constant
2285 // extended. We do this for COMBINE.
2286 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
2287 MO.isJTI() || MO.isCPI() || MO.isFPImm())
2288 return true;
2289
2290 // If the extendable operand is not 'Immediate' type, the instruction should
2291 // have 'isExtended' flag set.
2292 assert(MO.isImm() && "Extendable operand must be Immediate type");
2293
2294 int64_t Value = MO.getImm();
2296 int32_t SValue = Value;
2297 int32_t MinValue = getMinValue(MI);
2298 int32_t MaxValue = getMaxValue(MI);
2299 return SValue < MinValue || SValue > MaxValue;
2300 }
2301 uint32_t UValue = Value;
2302 uint32_t MinValue = getMinValue(MI);
2303 uint32_t MaxValue = getMaxValue(MI);
2304 return UValue < MinValue || UValue > MaxValue;
2305}
2306
2308 switch (MI.getOpcode()) {
2309 case Hexagon::L4_return:
2310 case Hexagon::L4_return_t:
2311 case Hexagon::L4_return_f:
2312 case Hexagon::L4_return_tnew_pnt:
2313 case Hexagon::L4_return_fnew_pnt:
2314 case Hexagon::L4_return_tnew_pt:
2315 case Hexagon::L4_return_fnew_pt:
2316 return true;
2317 }
2318 return false;
2319}
2320
2321// Return true when ConsMI uses a register defined by ProdMI.
2323 const MachineInstr &ConsMI) const {
2324 if (!ProdMI.getDesc().getNumDefs())
2325 return false;
2326 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
2327
2332
2333 parseOperands(ProdMI, DefsA, UsesA);
2334 parseOperands(ConsMI, DefsB, UsesB);
2335
2336 for (auto &RegA : DefsA)
2337 for (auto &RegB : UsesB) {
2338 // True data dependency.
2339 if (RegA == RegB)
2340 return true;
2341
2342 if (RegA.isPhysical() && llvm::is_contained(HRI.subregs(RegA), RegB))
2343 return true;
2344
2345 if (RegB.isPhysical() && llvm::is_contained(HRI.subregs(RegB), RegA))
2346 return true;
2347 }
2348
2349 return false;
2350}
2351
2352// Returns true if the instruction is already a .cur.
2354 switch (MI.getOpcode()) {
2355 case Hexagon::V6_vL32b_cur_pi:
2356 case Hexagon::V6_vL32b_cur_ai:
2357 return true;
2358 }
2359 return false;
2360}
2361
2362// Returns true, if any one of the operands is a dot new
2363// insn, whether it is predicated dot new or register dot new.
2366 return true;
2367
2368 return false;
2369}
2370
2371/// Symmetrical. See if these two instructions are fit for duplex pair.
2373 const MachineInstr &MIb) const {
2376 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
2377}
2378
2379bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
2380 return (Opcode == Hexagon::ENDLOOP0 ||
2381 Opcode == Hexagon::ENDLOOP1);
2382}
2383
2384bool HexagonInstrInfo::isExpr(unsigned OpType) const {
2385 switch(OpType) {
2392 return true;
2393 default:
2394 return false;
2395 }
2396}
2397
2399 const MCInstrDesc &MID = MI.getDesc();
2400 const uint64_t F = MID.TSFlags;
2402 return true;
2403
2404 // TODO: This is largely obsolete now. Will need to be removed
2405 // in consecutive patches.
2406 switch (MI.getOpcode()) {
2407 // PS_fi and PS_fia remain special cases.
2408 case Hexagon::PS_fi:
2409 case Hexagon::PS_fia:
2410 return true;
2411 default:
2412 return false;
2413 }
2414 return false;
2415}
2416
2417// This returns true in two cases:
2418// - The OP code itself indicates that this is an extended instruction.
2419// - One of MOs has been marked with HMOTF_ConstExtended flag.
2421 // First check if this is permanently extended op code.
2422 const uint64_t F = MI.getDesc().TSFlags;
2424 return true;
2425 // Use MO operand flags to determine if one of MI's operands
2426 // has HMOTF_ConstExtended flag set.
2427 for (const MachineOperand &MO : MI.operands())
2428 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
2429 return true;
2430 return false;
2431}
2432
2434 unsigned Opcode = MI.getOpcode();
2435 const uint64_t F = get(Opcode).TSFlags;
2436 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
2437}
2438
2439// No V60 HVX VMEM with A_INDIRECT.
2441 const MachineInstr &J) const {
2442 if (!isHVXVec(I))
2443 return false;
2444 if (!I.mayLoad() && !I.mayStore())
2445 return false;
2446 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
2447}
2448
2450 switch (MI.getOpcode()) {
2451 case Hexagon::J2_callr:
2452 case Hexagon::J2_callrf:
2453 case Hexagon::J2_callrt:
2454 case Hexagon::PS_call_nr:
2455 return true;
2456 }
2457 return false;
2458}
2459
2461 switch (MI.getOpcode()) {
2462 case Hexagon::L4_return:
2463 case Hexagon::L4_return_t:
2464 case Hexagon::L4_return_f:
2465 case Hexagon::L4_return_fnew_pnt:
2466 case Hexagon::L4_return_fnew_pt:
2467 case Hexagon::L4_return_tnew_pnt:
2468 case Hexagon::L4_return_tnew_pt:
2469 return true;
2470 }
2471 return false;
2472}
2473
2475 switch (MI.getOpcode()) {
2476 case Hexagon::J2_jumpr:
2477 case Hexagon::J2_jumprt:
2478 case Hexagon::J2_jumprf:
2479 case Hexagon::J2_jumprtnewpt:
2480 case Hexagon::J2_jumprfnewpt:
2481 case Hexagon::J2_jumprtnew:
2482 case Hexagon::J2_jumprfnew:
2483 return true;
2484 }
2485 return false;
2486}
2487
2488// Return true if a given MI can accommodate given offset.
2489// Use abs estimate as oppose to the exact number.
2490// TODO: This will need to be changed to use MC level
2491// definition of instruction extendable field size.
2493 unsigned offset) const {
2494 // This selection of jump instructions matches to that what
2495 // analyzeBranch can parse, plus NVJ.
2496 if (isNewValueJump(MI)) // r9:2
2497 return isInt<11>(offset);
2498
2499 switch (MI.getOpcode()) {
2500 // Still missing Jump to address condition on register value.
2501 default:
2502 return false;
2503 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2504 case Hexagon::J2_call:
2505 case Hexagon::PS_call_nr:
2506 return isInt<24>(offset);
2507 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2508 case Hexagon::J2_jumpf:
2509 case Hexagon::J2_jumptnew:
2510 case Hexagon::J2_jumptnewpt:
2511 case Hexagon::J2_jumpfnew:
2512 case Hexagon::J2_jumpfnewpt:
2513 case Hexagon::J2_callt:
2514 case Hexagon::J2_callf:
2515 return isInt<17>(offset);
2516 case Hexagon::J2_loop0i:
2517 case Hexagon::J2_loop0iext:
2518 case Hexagon::J2_loop0r:
2519 case Hexagon::J2_loop0rext:
2520 case Hexagon::J2_loop1i:
2521 case Hexagon::J2_loop1iext:
2522 case Hexagon::J2_loop1r:
2523 case Hexagon::J2_loop1rext:
2524 return isInt<9>(offset);
2525 // TODO: Add all the compound branches here. Can we do this in Relation model?
2526 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2527 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2528 case Hexagon::J4_cmpeqn1_tp0_jump_nt:
2529 case Hexagon::J4_cmpeqn1_tp1_jump_nt:
2530 return isInt<11>(offset);
2531 }
2532}
2533
2535 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2536 // resource, but all operands can be received late like an ALU instruction.
2538}
2539
2541 unsigned Opcode = MI.getOpcode();
2542 return Opcode == Hexagon::J2_loop0i ||
2543 Opcode == Hexagon::J2_loop0r ||
2544 Opcode == Hexagon::J2_loop0iext ||
2545 Opcode == Hexagon::J2_loop0rext ||
2546 Opcode == Hexagon::J2_loop1i ||
2547 Opcode == Hexagon::J2_loop1r ||
2548 Opcode == Hexagon::J2_loop1iext ||
2549 Opcode == Hexagon::J2_loop1rext;
2550}
2551
2553 switch (MI.getOpcode()) {
2554 default: return false;
2555 case Hexagon::L4_iadd_memopw_io:
2556 case Hexagon::L4_isub_memopw_io:
2557 case Hexagon::L4_add_memopw_io:
2558 case Hexagon::L4_sub_memopw_io:
2559 case Hexagon::L4_and_memopw_io:
2560 case Hexagon::L4_or_memopw_io:
2561 case Hexagon::L4_iadd_memoph_io:
2562 case Hexagon::L4_isub_memoph_io:
2563 case Hexagon::L4_add_memoph_io:
2564 case Hexagon::L4_sub_memoph_io:
2565 case Hexagon::L4_and_memoph_io:
2566 case Hexagon::L4_or_memoph_io:
2567 case Hexagon::L4_iadd_memopb_io:
2568 case Hexagon::L4_isub_memopb_io:
2569 case Hexagon::L4_add_memopb_io:
2570 case Hexagon::L4_sub_memopb_io:
2571 case Hexagon::L4_and_memopb_io:
2572 case Hexagon::L4_or_memopb_io:
2573 case Hexagon::L4_ior_memopb_io:
2574 case Hexagon::L4_ior_memoph_io:
2575 case Hexagon::L4_ior_memopw_io:
2576 case Hexagon::L4_iand_memopb_io:
2577 case Hexagon::L4_iand_memoph_io:
2578 case Hexagon::L4_iand_memopw_io:
2579 return true;
2580 }
2581 return false;
2582}
2583
2585 const uint64_t F = MI.getDesc().TSFlags;
2587}
2588
2589bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2590 const uint64_t F = get(Opcode).TSFlags;
2592}
2593
2597
2599 return isNewValue(MI) && MI.isBranch();
2600}
2601
2602bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2603 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2604}
2605
2607 const uint64_t F = MI.getDesc().TSFlags;
2609}
2610
2611bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2612 const uint64_t F = get(Opcode).TSFlags;
2614}
2615
2616// Returns true if a particular operand is extendable for an instruction.
2618 unsigned OperandNum) const {
2619 const uint64_t F = MI.getDesc().TSFlags;
2621 == OperandNum;
2622}
2623
2625 const uint64_t F = MI.getDesc().TSFlags;
2628}
2629
2630bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2631 const uint64_t F = get(Opcode).TSFlags;
2632 assert(isPredicated(Opcode));
2634}
2635
2637 const uint64_t F = MI.getDesc().TSFlags;
2638 return !((F >> HexagonII::PredicatedFalsePos) &
2640}
2641
2642bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2643 const uint64_t F = get(Opcode).TSFlags;
2644 // Make sure that the instruction is predicated.
2646 return !((F >> HexagonII::PredicatedFalsePos) &
2648}
2649
2650bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2651 const uint64_t F = get(Opcode).TSFlags;
2653}
2654
2655bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2656 const uint64_t F = get(Opcode).TSFlags;
2658}
2659
2660bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2661 const uint64_t F = get(Opcode).TSFlags;
2662 assert(get(Opcode).isBranch() &&
2663 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2665}
2666
2668 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2669 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2670 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2671 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
2672}
2673
2675 switch (MI.getOpcode()) {
2676 // Byte
2677 case Hexagon::L2_loadrb_io:
2678 case Hexagon::L4_loadrb_ur:
2679 case Hexagon::L4_loadrb_ap:
2680 case Hexagon::L2_loadrb_pr:
2681 case Hexagon::L2_loadrb_pbr:
2682 case Hexagon::L2_loadrb_pi:
2683 case Hexagon::L2_loadrb_pci:
2684 case Hexagon::L2_loadrb_pcr:
2685 case Hexagon::L2_loadbsw2_io:
2686 case Hexagon::L4_loadbsw2_ur:
2687 case Hexagon::L4_loadbsw2_ap:
2688 case Hexagon::L2_loadbsw2_pr:
2689 case Hexagon::L2_loadbsw2_pbr:
2690 case Hexagon::L2_loadbsw2_pi:
2691 case Hexagon::L2_loadbsw2_pci:
2692 case Hexagon::L2_loadbsw2_pcr:
2693 case Hexagon::L2_loadbsw4_io:
2694 case Hexagon::L4_loadbsw4_ur:
2695 case Hexagon::L4_loadbsw4_ap:
2696 case Hexagon::L2_loadbsw4_pr:
2697 case Hexagon::L2_loadbsw4_pbr:
2698 case Hexagon::L2_loadbsw4_pi:
2699 case Hexagon::L2_loadbsw4_pci:
2700 case Hexagon::L2_loadbsw4_pcr:
2701 case Hexagon::L4_loadrb_rr:
2702 case Hexagon::L2_ploadrbt_io:
2703 case Hexagon::L2_ploadrbt_pi:
2704 case Hexagon::L2_ploadrbf_io:
2705 case Hexagon::L2_ploadrbf_pi:
2706 case Hexagon::L2_ploadrbtnew_io:
2707 case Hexagon::L2_ploadrbfnew_io:
2708 case Hexagon::L4_ploadrbt_rr:
2709 case Hexagon::L4_ploadrbf_rr:
2710 case Hexagon::L4_ploadrbtnew_rr:
2711 case Hexagon::L4_ploadrbfnew_rr:
2712 case Hexagon::L2_ploadrbtnew_pi:
2713 case Hexagon::L2_ploadrbfnew_pi:
2714 case Hexagon::L4_ploadrbt_abs:
2715 case Hexagon::L4_ploadrbf_abs:
2716 case Hexagon::L4_ploadrbtnew_abs:
2717 case Hexagon::L4_ploadrbfnew_abs:
2718 case Hexagon::L2_loadrbgp:
2719 // Half
2720 case Hexagon::L2_loadrh_io:
2721 case Hexagon::L4_loadrh_ur:
2722 case Hexagon::L4_loadrh_ap:
2723 case Hexagon::L2_loadrh_pr:
2724 case Hexagon::L2_loadrh_pbr:
2725 case Hexagon::L2_loadrh_pi:
2726 case Hexagon::L2_loadrh_pci:
2727 case Hexagon::L2_loadrh_pcr:
2728 case Hexagon::L4_loadrh_rr:
2729 case Hexagon::L2_ploadrht_io:
2730 case Hexagon::L2_ploadrht_pi:
2731 case Hexagon::L2_ploadrhf_io:
2732 case Hexagon::L2_ploadrhf_pi:
2733 case Hexagon::L2_ploadrhtnew_io:
2734 case Hexagon::L2_ploadrhfnew_io:
2735 case Hexagon::L4_ploadrht_rr:
2736 case Hexagon::L4_ploadrhf_rr:
2737 case Hexagon::L4_ploadrhtnew_rr:
2738 case Hexagon::L4_ploadrhfnew_rr:
2739 case Hexagon::L2_ploadrhtnew_pi:
2740 case Hexagon::L2_ploadrhfnew_pi:
2741 case Hexagon::L4_ploadrht_abs:
2742 case Hexagon::L4_ploadrhf_abs:
2743 case Hexagon::L4_ploadrhtnew_abs:
2744 case Hexagon::L4_ploadrhfnew_abs:
2745 case Hexagon::L2_loadrhgp:
2746 return true;
2747 default:
2748 return false;
2749 }
2750}
2751
2753 const uint64_t F = MI.getDesc().TSFlags;
2755}
2756
2758 switch (MI.getOpcode()) {
2759 case Hexagon::STriw_pred:
2760 case Hexagon::LDriw_pred:
2761 return true;
2762 default:
2763 return false;
2764 }
2765}
2766
2768 if (!MI.isBranch())
2769 return false;
2770
2771 for (auto &Op : MI.operands())
2772 if (Op.isGlobal() || Op.isSymbol())
2773 return true;
2774 return false;
2775}
2776
2777// Returns true when SU has a timing class TC1.
2779 unsigned SchedClass = MI.getDesc().getSchedClass();
2780 return is_TC1(SchedClass);
2781}
2782
2784 unsigned SchedClass = MI.getDesc().getSchedClass();
2785 return is_TC2(SchedClass);
2786}
2787
2789 unsigned SchedClass = MI.getDesc().getSchedClass();
2790 return is_TC2early(SchedClass);
2791}
2792
2794 unsigned SchedClass = MI.getDesc().getSchedClass();
2795 return is_TC4x(SchedClass);
2796}
2797
2798// Schedule this ASAP.
2800 const MachineInstr &MI2) const {
2801 if (mayBeCurLoad(MI1)) {
2802 // if (result of SU is used in Next) return true;
2803 Register DstReg = MI1.getOperand(0).getReg();
2804 int N = MI2.getNumOperands();
2805 for (int I = 0; I < N; I++)
2806 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())
2807 return true;
2808 }
2809 if (mayBeNewStore(MI2))
2810 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)
2811 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&
2812 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())
2813 return true;
2814 return false;
2815}
2816
2818 const uint64_t V = getType(MI);
2820}
2821
2823 return (MI.getDesc().TSFlags >> HexagonII::isHLXPos) & HexagonII::isHLXMask;
2824}
2825
2826// Check if the Offset is a valid auto-inc imm by Load/Store Type.
2828 int Size = VT.getSizeInBits() / 8;
2829 if (Offset % Size != 0)
2830 return false;
2831 int Count = Offset / Size;
2832
2833 switch (VT.getSimpleVT().SimpleTy) {
2834 // For scalars the auto-inc is s4
2835 case MVT::i8:
2836 case MVT::i16:
2837 case MVT::i32:
2838 case MVT::i64:
2839 case MVT::f32:
2840 case MVT::f64:
2841 case MVT::v2i16:
2842 case MVT::v2i32:
2843 case MVT::v4i8:
2844 case MVT::v4i16:
2845 case MVT::v8i8:
2846 return isInt<4>(Count);
2847 // For HVX vectors the auto-inc is s3
2848 case MVT::v64i8:
2849 case MVT::v32i16:
2850 case MVT::v16i32:
2851 case MVT::v8i64:
2852 case MVT::v128i8:
2853 case MVT::v64i16:
2854 case MVT::v32i32:
2855 case MVT::v16i64:
2856 return isInt<3>(Count);
2857 default:
2858 break;
2859 }
2860
2861 llvm_unreachable("Not an valid type!");
2862}
2863
2864bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
2865 bool Extend) const {
2866 // This function is to check whether the "Offset" is in the correct range of
2867 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
2868 // inserted to calculate the final address. Due to this reason, the function
2869 // assumes that the "Offset" has correct alignment.
2870 // We used to assert if the offset was not properly aligned, however,
2871 // there are cases where a misaligned pointer recast can cause this
2872 // problem, and we need to allow for it. The front end warns of such
2873 // misaligns with respect to load size.
2874 switch (Opcode) {
2875 case Hexagon::PS_vstorerq_ai:
2876 case Hexagon::PS_vstorerv_ai:
2877 case Hexagon::PS_vstorerw_ai:
2878 case Hexagon::PS_vstorerw_nt_ai:
2879 case Hexagon::PS_vloadrq_ai:
2880 case Hexagon::PS_vloadrv_ai:
2881 case Hexagon::PS_vloadrw_ai:
2882 case Hexagon::PS_vloadrw_nt_ai:
2883 case Hexagon::V6_vL32b_ai:
2884 case Hexagon::V6_vS32b_ai:
2885 case Hexagon::V6_vS32b_pred_ai:
2886 case Hexagon::V6_vS32b_npred_ai:
2887 case Hexagon::V6_vS32b_qpred_ai:
2888 case Hexagon::V6_vS32b_nqpred_ai:
2889 case Hexagon::V6_vS32b_new_ai:
2890 case Hexagon::V6_vS32b_new_pred_ai:
2891 case Hexagon::V6_vS32b_new_npred_ai:
2892 case Hexagon::V6_vS32b_nt_pred_ai:
2893 case Hexagon::V6_vS32b_nt_npred_ai:
2894 case Hexagon::V6_vS32b_nt_new_ai:
2895 case Hexagon::V6_vS32b_nt_new_pred_ai:
2896 case Hexagon::V6_vS32b_nt_new_npred_ai:
2897 case Hexagon::V6_vS32b_nt_qpred_ai:
2898 case Hexagon::V6_vS32b_nt_nqpred_ai:
2899 case Hexagon::V6_vL32b_nt_ai:
2900 case Hexagon::V6_vS32b_nt_ai:
2901 case Hexagon::V6_vL32Ub_ai:
2902 case Hexagon::V6_vS32Ub_ai:
2903 case Hexagon::V6_vL32b_cur_ai:
2904 case Hexagon::V6_vL32b_tmp_ai:
2905 case Hexagon::V6_vL32b_pred_ai:
2906 case Hexagon::V6_vL32b_npred_ai:
2907 case Hexagon::V6_vL32b_cur_pred_ai:
2908 case Hexagon::V6_vL32b_cur_npred_ai:
2909 case Hexagon::V6_vL32b_tmp_pred_ai:
2910 case Hexagon::V6_vL32b_tmp_npred_ai:
2911 case Hexagon::V6_vL32b_nt_cur_ai:
2912 case Hexagon::V6_vL32b_nt_tmp_ai:
2913 case Hexagon::V6_vL32b_nt_pred_ai:
2914 case Hexagon::V6_vL32b_nt_npred_ai:
2915 case Hexagon::V6_vL32b_nt_cur_pred_ai:
2916 case Hexagon::V6_vL32b_nt_cur_npred_ai:
2917 case Hexagon::V6_vL32b_nt_tmp_pred_ai:
2918 case Hexagon::V6_vL32b_nt_tmp_npred_ai:
2919 case Hexagon::V6_vS32Ub_pred_ai:
2920 case Hexagon::V6_vS32Ub_npred_ai:
2921 case Hexagon::V6_vgathermh_pseudo:
2922 case Hexagon::V6_vgather_vscatter_mh_pseudo:
2923 case Hexagon::V6_vgathermw_pseudo:
2924 case Hexagon::V6_vgathermhw_pseudo:
2925 case Hexagon::V6_vgathermhq_pseudo:
2926 case Hexagon::V6_vgathermwq_pseudo:
2927 case Hexagon::V6_vgathermhwq_pseudo: {
2928 unsigned VectorSize = RegInfo.getSpillSize(Hexagon::HvxVRRegClass);
2929 assert(isPowerOf2_32(VectorSize));
2930 if (Offset & (VectorSize-1))
2931 return false;
2932 return isInt<4>(Offset >> Log2_32(VectorSize));
2933 }
2934
2935 case Hexagon::J2_loop0i:
2936 case Hexagon::J2_loop1i:
2937 return isUInt<10>(Offset);
2938
2939 case Hexagon::S4_storeirb_io:
2940 case Hexagon::S4_storeirbt_io:
2941 case Hexagon::S4_storeirbf_io:
2942 return isUInt<6>(Offset);
2943
2944 case Hexagon::S4_storeirh_io:
2945 case Hexagon::S4_storeirht_io:
2946 case Hexagon::S4_storeirhf_io:
2947 return isShiftedUInt<6,1>(Offset);
2948
2949 case Hexagon::S4_storeiri_io:
2950 case Hexagon::S4_storeirit_io:
2951 case Hexagon::S4_storeirif_io:
2952 return isShiftedUInt<6,2>(Offset);
2953 // Handle these two compare instructions that are not extendable.
2954 case Hexagon::A4_cmpbeqi:
2955 return isUInt<8>(Offset);
2956 case Hexagon::A4_cmpbgti:
2957 return isInt<8>(Offset);
2958 }
2959
2960 if (Extend)
2961 return true;
2962
2963 switch (Opcode) {
2964 case Hexagon::L2_loadri_io:
2965 case Hexagon::S2_storeri_io:
2966 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2968
2969 case Hexagon::L2_loadrd_io:
2970 case Hexagon::S2_storerd_io:
2971 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2973
2974 case Hexagon::L2_loadrh_io:
2975 case Hexagon::L2_loadruh_io:
2976 case Hexagon::S2_storerh_io:
2977 case Hexagon::S2_storerf_io:
2978 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2980
2981 case Hexagon::L2_loadrb_io:
2982 case Hexagon::L2_loadrub_io:
2983 case Hexagon::S2_storerb_io:
2984 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2986
2987 case Hexagon::A2_addi:
2988 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2990
2991 case Hexagon::L4_iadd_memopw_io:
2992 case Hexagon::L4_isub_memopw_io:
2993 case Hexagon::L4_add_memopw_io:
2994 case Hexagon::L4_sub_memopw_io:
2995 case Hexagon::L4_iand_memopw_io:
2996 case Hexagon::L4_ior_memopw_io:
2997 case Hexagon::L4_and_memopw_io:
2998 case Hexagon::L4_or_memopw_io:
2999 return (0 <= Offset && Offset <= 255);
3000
3001 case Hexagon::L4_iadd_memoph_io:
3002 case Hexagon::L4_isub_memoph_io:
3003 case Hexagon::L4_add_memoph_io:
3004 case Hexagon::L4_sub_memoph_io:
3005 case Hexagon::L4_iand_memoph_io:
3006 case Hexagon::L4_ior_memoph_io:
3007 case Hexagon::L4_and_memoph_io:
3008 case Hexagon::L4_or_memoph_io:
3009 return (0 <= Offset && Offset <= 127);
3010
3011 case Hexagon::L4_iadd_memopb_io:
3012 case Hexagon::L4_isub_memopb_io:
3013 case Hexagon::L4_add_memopb_io:
3014 case Hexagon::L4_sub_memopb_io:
3015 case Hexagon::L4_iand_memopb_io:
3016 case Hexagon::L4_ior_memopb_io:
3017 case Hexagon::L4_and_memopb_io:
3018 case Hexagon::L4_or_memopb_io:
3019 return (0 <= Offset && Offset <= 63);
3020
3021 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
3022 // any size. Later pass knows how to handle it.
3023 case Hexagon::STriw_pred:
3024 case Hexagon::LDriw_pred:
3025 case Hexagon::STriw_ctr:
3026 case Hexagon::LDriw_ctr:
3027 return true;
3028
3029 case Hexagon::PS_fi:
3030 case Hexagon::PS_fia:
3031 case Hexagon::INLINEASM:
3032 return true;
3033
3034 case Hexagon::L2_ploadrbt_io:
3035 case Hexagon::L2_ploadrbf_io:
3036 case Hexagon::L2_ploadrubt_io:
3037 case Hexagon::L2_ploadrubf_io:
3038 case Hexagon::S2_pstorerbt_io:
3039 case Hexagon::S2_pstorerbf_io:
3040 return isUInt<6>(Offset);
3041
3042 case Hexagon::L2_ploadrht_io:
3043 case Hexagon::L2_ploadrhf_io:
3044 case Hexagon::L2_ploadruht_io:
3045 case Hexagon::L2_ploadruhf_io:
3046 case Hexagon::S2_pstorerht_io:
3047 case Hexagon::S2_pstorerhf_io:
3048 case Hexagon::S2_pstorerft_io:
3049 case Hexagon::S2_pstorerff_io:
3050 return isShiftedUInt<6,1>(Offset);
3051
3052 case Hexagon::L2_ploadrit_io:
3053 case Hexagon::L2_ploadrif_io:
3054 case Hexagon::S2_pstorerit_io:
3055 case Hexagon::S2_pstorerif_io:
3056 return isShiftedUInt<6,2>(Offset);
3057
3058 case Hexagon::L2_ploadrdt_io:
3059 case Hexagon::L2_ploadrdf_io:
3060 case Hexagon::S2_pstorerdt_io:
3061 case Hexagon::S2_pstorerdf_io:
3062 return isShiftedUInt<6,3>(Offset);
3063
3064 case Hexagon::L2_loadbsw2_io:
3065 case Hexagon::L2_loadbzw2_io:
3066 return isShiftedInt<11,1>(Offset);
3067
3068 case Hexagon::L2_loadbsw4_io:
3069 case Hexagon::L2_loadbzw4_io:
3070 return isShiftedInt<11,2>(Offset);
3071 } // switch
3072
3073 dbgs() << "Failed Opcode is : " << Opcode << " (" << getName(Opcode)
3074 << ")\n";
3075 llvm_unreachable("No offset range is defined for this opcode. "
3076 "Please define it in the above switch statement!");
3077}
3078
3080 return isHVXVec(MI) && isAccumulator(MI);
3081}
3082
3084 const uint64_t F = get(MI.getOpcode()).TSFlags;
3085 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
3086 return
3087 V == HexagonII::TypeCVI_VA ||
3089}
3090
3092 const MachineInstr &ConsMI) const {
3093 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
3094 return true;
3095
3096 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
3097 return true;
3098
3099 if (mayBeNewStore(ConsMI))
3100 return true;
3101
3102 return false;
3103}
3104
3106 switch (MI.getOpcode()) {
3107 // Byte
3108 case Hexagon::L2_loadrub_io:
3109 case Hexagon::L4_loadrub_ur:
3110 case Hexagon::L4_loadrub_ap:
3111 case Hexagon::L2_loadrub_pr:
3112 case Hexagon::L2_loadrub_pbr:
3113 case Hexagon::L2_loadrub_pi:
3114 case Hexagon::L2_loadrub_pci:
3115 case Hexagon::L2_loadrub_pcr:
3116 case Hexagon::L2_loadbzw2_io:
3117 case Hexagon::L4_loadbzw2_ur:
3118 case Hexagon::L4_loadbzw2_ap:
3119 case Hexagon::L2_loadbzw2_pr:
3120 case Hexagon::L2_loadbzw2_pbr:
3121 case Hexagon::L2_loadbzw2_pi:
3122 case Hexagon::L2_loadbzw2_pci:
3123 case Hexagon::L2_loadbzw2_pcr:
3124 case Hexagon::L2_loadbzw4_io:
3125 case Hexagon::L4_loadbzw4_ur:
3126 case Hexagon::L4_loadbzw4_ap:
3127 case Hexagon::L2_loadbzw4_pr:
3128 case Hexagon::L2_loadbzw4_pbr:
3129 case Hexagon::L2_loadbzw4_pi:
3130 case Hexagon::L2_loadbzw4_pci:
3131 case Hexagon::L2_loadbzw4_pcr:
3132 case Hexagon::L4_loadrub_rr:
3133 case Hexagon::L2_ploadrubt_io:
3134 case Hexagon::L2_ploadrubt_pi:
3135 case Hexagon::L2_ploadrubf_io:
3136 case Hexagon::L2_ploadrubf_pi:
3137 case Hexagon::L2_ploadrubtnew_io:
3138 case Hexagon::L2_ploadrubfnew_io:
3139 case Hexagon::L4_ploadrubt_rr:
3140 case Hexagon::L4_ploadrubf_rr:
3141 case Hexagon::L4_ploadrubtnew_rr:
3142 case Hexagon::L4_ploadrubfnew_rr:
3143 case Hexagon::L2_ploadrubtnew_pi:
3144 case Hexagon::L2_ploadrubfnew_pi:
3145 case Hexagon::L4_ploadrubt_abs:
3146 case Hexagon::L4_ploadrubf_abs:
3147 case Hexagon::L4_ploadrubtnew_abs:
3148 case Hexagon::L4_ploadrubfnew_abs:
3149 case Hexagon::L2_loadrubgp:
3150 // Half
3151 case Hexagon::L2_loadruh_io:
3152 case Hexagon::L4_loadruh_ur:
3153 case Hexagon::L4_loadruh_ap:
3154 case Hexagon::L2_loadruh_pr:
3155 case Hexagon::L2_loadruh_pbr:
3156 case Hexagon::L2_loadruh_pi:
3157 case Hexagon::L2_loadruh_pci:
3158 case Hexagon::L2_loadruh_pcr:
3159 case Hexagon::L4_loadruh_rr:
3160 case Hexagon::L2_ploadruht_io:
3161 case Hexagon::L2_ploadruht_pi:
3162 case Hexagon::L2_ploadruhf_io:
3163 case Hexagon::L2_ploadruhf_pi:
3164 case Hexagon::L2_ploadruhtnew_io:
3165 case Hexagon::L2_ploadruhfnew_io:
3166 case Hexagon::L4_ploadruht_rr:
3167 case Hexagon::L4_ploadruhf_rr:
3168 case Hexagon::L4_ploadruhtnew_rr:
3169 case Hexagon::L4_ploadruhfnew_rr:
3170 case Hexagon::L2_ploadruhtnew_pi:
3171 case Hexagon::L2_ploadruhfnew_pi:
3172 case Hexagon::L4_ploadruht_abs:
3173 case Hexagon::L4_ploadruhf_abs:
3174 case Hexagon::L4_ploadruhtnew_abs:
3175 case Hexagon::L4_ploadruhfnew_abs:
3176 case Hexagon::L2_loadruhgp:
3177 return true;
3178 default:
3179 return false;
3180 }
3181}
3182
3183// Add latency to instruction.
3185 const MachineInstr &MI2) const {
3186 if (isHVXVec(MI1) && isHVXVec(MI2))
3187 if (!isVecUsableNextPacket(MI1, MI2))
3188 return true;
3189 return false;
3190}
3191
3192/// Get the base register and byte offset of a load/store instr.
3195 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) const {
3196 OffsetIsScalable = false;
3197 const MachineOperand *BaseOp = getBaseAndOffset(LdSt, Offset, Width);
3198 if (!BaseOp || !BaseOp->isReg())
3199 return false;
3200 BaseOps.push_back(BaseOp);
3201 return true;
3202}
3203
3204/// Can these instructions execute at the same time in a bundle.
3206 const MachineInstr &Second) const {
3207 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {
3208 const MachineOperand &Op = Second.getOperand(0);
3209 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)
3210 return true;
3211 }
3213 return false;
3214 if (mayBeNewStore(Second)) {
3215 // Make sure the definition of the first instruction is the value being
3216 // stored.
3217 const MachineOperand &Stored =
3218 Second.getOperand(Second.getNumOperands() - 1);
3219 if (!Stored.isReg())
3220 return false;
3221 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {
3222 const MachineOperand &Op = First.getOperand(i);
3223 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
3224 return true;
3225 }
3226 }
3227 return false;
3228}
3229
3231 unsigned Opc = CallMI.getOpcode();
3232 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;
3233}
3234
3236 for (auto &I : *B)
3237 if (I.isEHLabel())
3238 return true;
3239 return false;
3240}
3241
3242// Returns true if an instruction can be converted into a non-extended
3243// equivalent instruction.
3245 short NonExtOpcode;
3246 // Check if the instruction has a register form that uses register in place
3247 // of the extended operand, if so return that as the non-extended form.
3248 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)
3249 return true;
3250
3251 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
3252 // Check addressing mode and retrieve non-ext equivalent instruction.
3253
3254 switch (getAddrMode(MI)) {
3256 // Load/store with absolute addressing mode can be converted into
3257 // base+offset mode.
3258 NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());
3259 break;
3261 // Load/store with base+offset addressing mode can be converted into
3262 // base+register offset addressing mode. However left shift operand should
3263 // be set to 0.
3264 NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());
3265 break;
3267 NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
3268 break;
3269 default:
3270 return false;
3271 }
3272 if (NonExtOpcode < 0)
3273 return false;
3274 return true;
3275 }
3276 return false;
3277}
3278
3280 const {
3281 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
3282 while (I != E) {
3283 if (I->isBarrier())
3284 return true;
3285 ++I;
3286 }
3287 return false;
3288}
3289
3290// Returns true, if a LD insn can be promoted to a cur load.
3292 const uint64_t F = MI.getDesc().TSFlags;
3294 Subtarget.hasV60Ops();
3295}
3296
3297// Returns true, if a ST insn can be promoted to a new-value store.
3299 if (MI.mayStore() && !Subtarget.useNewValueStores())
3300 return false;
3301
3302 const uint64_t F = MI.getDesc().TSFlags;
3304}
3305
3307 return MI.getOpcode() == Hexagon::LX_L16b_pseudo;
3308}
3309
3311 return MI.getOpcode() == Hexagon::LX_S16b_pseudo;
3312}
3313
3315 const MachineInstr &ConsMI) const {
3316 // There is no stall when ProdMI is not a V60 vector.
3317 if (!isHVXVec(ProdMI))
3318 return false;
3319
3320 // There is no stall when ProdMI and ConsMI are not dependent.
3321 if (!isDependent(ProdMI, ConsMI))
3322 return false;
3323
3324 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
3325 // are scheduled in consecutive packets.
3326 if (isVecUsableNextPacket(ProdMI, ConsMI))
3327 return false;
3328
3329 return true;
3330}
3331
3334 // There is no stall when I is not a V60 vector.
3335 if (!isHVXVec(MI))
3336 return false;
3337
3339 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
3340
3341 if (!MII->isBundle())
3342 return producesStall(*MII, MI);
3343
3344 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
3345 const MachineInstr &J = *MII;
3346 if (producesStall(J, MI))
3347 return true;
3348 }
3349 return false;
3350}
3351
3353 Register PredReg) const {
3354 for (const MachineOperand &MO : MI.operands()) {
3355 // Predicate register must be explicitly defined.
3356 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))
3357 return false;
3358 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
3359 return false;
3360 }
3361
3362 // Instruction that produce late predicate cannot be used as sources of
3363 // dot-new.
3364 switch (MI.getOpcode()) {
3365 case Hexagon::A4_addp_c:
3366 case Hexagon::A4_subp_c:
3367 case Hexagon::A4_tlbmatch:
3368 case Hexagon::A5_ACS:
3369 case Hexagon::F2_sfinvsqrta:
3370 case Hexagon::F2_sfrecipa:
3371 case Hexagon::J2_endloop0:
3372 case Hexagon::J2_endloop01:
3373 case Hexagon::J2_ploop1si:
3374 case Hexagon::J2_ploop1sr:
3375 case Hexagon::J2_ploop2si:
3376 case Hexagon::J2_ploop2sr:
3377 case Hexagon::J2_ploop3si:
3378 case Hexagon::J2_ploop3sr:
3379 case Hexagon::S2_cabacdecbin:
3380 case Hexagon::S2_storew_locked:
3381 case Hexagon::S4_stored_locked:
3382 return false;
3383 }
3384 return true;
3385}
3386
3387bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
3388 return Opcode == Hexagon::J2_jumpt ||
3389 Opcode == Hexagon::J2_jumptpt ||
3390 Opcode == Hexagon::J2_jumpf ||
3391 Opcode == Hexagon::J2_jumpfpt ||
3392 Opcode == Hexagon::J2_jumptnew ||
3393 Opcode == Hexagon::J2_jumpfnew ||
3394 Opcode == Hexagon::J2_jumptnewpt ||
3395 Opcode == Hexagon::J2_jumpfnewpt;
3396}
3397
3399 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
3400 return false;
3401 return !isPredicatedTrue(Cond[0].getImm());
3402}
3403
3405 const uint64_t F = MI.getDesc().TSFlags;
3407}
3408
3409// Returns the base register in a memory access (load/store). The offset is
3410// returned in Offset and the access size is returned in AccessSize.
3411// If the base operand has a subregister or the offset field does not contain
3412// an immediate value, return nullptr.
3415 LocationSize &AccessSize) const {
3416 // Return if it is not a base+offset type instruction or a MemOp.
3420 return nullptr;
3421
3423
3424 unsigned BasePos = 0, OffsetPos = 0;
3425 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
3426 return nullptr;
3427
3428 // Post increment updates its EA after the mem access,
3429 // so we need to treat its offset as zero.
3430 if (isPostIncrement(MI)) {
3431 Offset = 0;
3432 } else {
3433 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
3434 if (!OffsetOp.isImm())
3435 return nullptr;
3436 Offset = OffsetOp.getImm();
3437 }
3438
3439 const MachineOperand &BaseOp = MI.getOperand(BasePos);
3440 if (BaseOp.getSubReg() != 0)
3441 return nullptr;
3442 return &const_cast<MachineOperand&>(BaseOp);
3443}
3444
3445/// Return the position of the base and offset operands for this instruction.
3447 unsigned &BasePos, unsigned &OffsetPos) const {
3449 return false;
3450
3451 // Deal with memops first.
3452 if (isMemOp(MI)) {
3453 BasePos = 0;
3454 OffsetPos = 1;
3455 } else if (MI.mayStore()) {
3456 BasePos = 0;
3457 OffsetPos = 1;
3458 } else if (MI.mayLoad()) {
3459 BasePos = 1;
3460 OffsetPos = 2;
3461 } else
3462 return false;
3463
3464 if (isPredicated(MI)) {
3465 BasePos++;
3466 OffsetPos++;
3467 }
3468 if (isPostIncrement(MI)) {
3469 BasePos++;
3470 OffsetPos++;
3471 }
3472
3473 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
3474 return false;
3475
3476 return true;
3477}
3478
3479// Inserts branching instructions in reverse order of their occurrence.
3480// e.g. jump_t t1 (i1)
3481// jump t2 (i2)
3482// Jumpers = {i2, i1}
3484 MachineBasicBlock& MBB) const {
3486 // If the block has no terminators, it just falls into the block after it.
3488 if (I == MBB.instr_begin())
3489 return Jumpers;
3490
3491 // A basic block may looks like this:
3492 //
3493 // [ insn
3494 // EH_LABEL
3495 // insn
3496 // insn
3497 // insn
3498 // EH_LABEL
3499 // insn ]
3500 //
3501 // It has two succs but does not have a terminator
3502 // Don't know how to handle it.
3503 do {
3504 --I;
3505 if (I->isEHLabel())
3506 return Jumpers;
3507 } while (I != MBB.instr_begin());
3508
3509 I = MBB.instr_end();
3510 --I;
3511
3512 while (I->isDebugInstr()) {
3513 if (I == MBB.instr_begin())
3514 return Jumpers;
3515 --I;
3516 }
3517 if (!isUnpredicatedTerminator(*I))
3518 return Jumpers;
3519
3520 // Get the last instruction in the block.
3521 MachineInstr *LastInst = &*I;
3522 Jumpers.push_back(LastInst);
3523 MachineInstr *SecondLastInst = nullptr;
3524 // Find one more terminator if present.
3525 do {
3526 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
3527 if (!SecondLastInst) {
3528 SecondLastInst = &*I;
3529 Jumpers.push_back(SecondLastInst);
3530 } else // This is a third branch.
3531 return Jumpers;
3532 }
3533 if (I == MBB.instr_begin())
3534 break;
3535 --I;
3536 } while (true);
3537 return Jumpers;
3538}
3539
3540// Returns Operand Index for the constant extended instruction.
3542 const uint64_t F = MI.getDesc().TSFlags;
3544}
3545
3546// See if instruction could potentially be a duplex candidate.
3547// If so, return its group. Zero otherwise.
3549 const MachineInstr &MI) const {
3550 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3551
3552 switch (MI.getOpcode()) {
3553 default:
3554 return HexagonII::HCG_None;
3555 //
3556 // Compound pairs.
3557 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3558 // "Rd16=#U6 ; jump #r9:2"
3559 // "Rd16=Rs16 ; jump #r9:2"
3560 //
3561 case Hexagon::C2_cmpeq:
3562 case Hexagon::C2_cmpgt:
3563 case Hexagon::C2_cmpgtu:
3564 DstReg = MI.getOperand(0).getReg();
3565 Src1Reg = MI.getOperand(1).getReg();
3566 Src2Reg = MI.getOperand(2).getReg();
3567 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3568 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3569 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3570 return HexagonII::HCG_A;
3571 break;
3572 case Hexagon::C2_cmpeqi:
3573 case Hexagon::C2_cmpgti:
3574 case Hexagon::C2_cmpgtui:
3575 // P0 = cmp.eq(Rs,#u2)
3576 DstReg = MI.getOperand(0).getReg();
3577 SrcReg = MI.getOperand(1).getReg();
3578 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3579 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3580 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3581 ((isUInt<5>(MI.getOperand(2).getImm())) ||
3582 (MI.getOperand(2).getImm() == -1)))
3583 return HexagonII::HCG_A;
3584 break;
3585 case Hexagon::A2_tfr:
3586 // Rd = Rs
3587 DstReg = MI.getOperand(0).getReg();
3588 SrcReg = MI.getOperand(1).getReg();
3589 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3590 return HexagonII::HCG_A;
3591 break;
3592 case Hexagon::A2_tfrsi:
3593 // Rd = #u6
3594 // Do not test for #u6 size since the const is getting extended
3595 // regardless and compound could be formed.
3596 DstReg = MI.getOperand(0).getReg();
3597 if (isIntRegForSubInst(DstReg))
3598 return HexagonII::HCG_A;
3599 break;
3600 case Hexagon::S2_tstbit_i:
3601 DstReg = MI.getOperand(0).getReg();
3602 Src1Reg = MI.getOperand(1).getReg();
3603 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3604 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3605 MI.getOperand(2).isImm() &&
3606 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))
3607 return HexagonII::HCG_A;
3608 break;
3609 // The fact that .new form is used pretty much guarantees
3610 // that predicate register will match. Nevertheless,
3611 // there could be some false positives without additional
3612 // checking.
3613 case Hexagon::J2_jumptnew:
3614 case Hexagon::J2_jumpfnew:
3615 case Hexagon::J2_jumptnewpt:
3616 case Hexagon::J2_jumpfnewpt:
3617 Src1Reg = MI.getOperand(0).getReg();
3618 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3619 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3620 return HexagonII::HCG_B;
3621 break;
3622 // Transfer and jump:
3623 // Rd=#U6 ; jump #r9:2
3624 // Rd=Rs ; jump #r9:2
3625 // Do not test for jump range here.
3626 case Hexagon::J2_jump:
3627 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3628 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
3629 return HexagonII::HCG_C;
3630 }
3631
3632 return HexagonII::HCG_None;
3633}
3634
3635// Returns -1 when there is no opcode found.
3637 const MachineInstr &GB) const {
3640 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
3641 (GB.getOpcode() != Hexagon::J2_jumptnew))
3642 return -1u;
3643 Register DestReg = GA.getOperand(0).getReg();
3644 if (!GB.readsRegister(DestReg, /*TRI=*/nullptr))
3645 return -1u;
3646 if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)
3647 return -1u;
3648 // The value compared against must be either u5 or -1.
3649 const MachineOperand &CmpOp = GA.getOperand(2);
3650 if (!CmpOp.isImm())
3651 return -1u;
3652 int V = CmpOp.getImm();
3653 if (V == -1)
3654 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt
3655 : Hexagon::J4_cmpeqn1_tp1_jump_nt;
3656 if (!isUInt<5>(V))
3657 return -1u;
3658 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt
3659 : Hexagon::J4_cmpeqi_tp1_jump_nt;
3660}
3661
3662// Returns -1 if there is no opcode found.
3664 bool ForBigCore) const {
3665 // Static table to switch the opcodes across Tiny Core and Big Core.
3666 // dup_ opcodes are Big core opcodes.
3667 // NOTE: There are special instructions that need to handled later.
3668 // L4_return* instructions, they will only occupy SLOT0 (on big core too).
3669 // PS_jmpret - This pseudo translates to J2_jumpr which occupies only SLOT2.
3670 // The compiler need to base the root instruction to L6_return_map_to_raw
3671 // which can go any slot.
3672 static const std::map<unsigned, unsigned> DupMap = {
3673 {Hexagon::A2_add, Hexagon::dup_A2_add},
3674 {Hexagon::A2_addi, Hexagon::dup_A2_addi},
3675 {Hexagon::A2_andir, Hexagon::dup_A2_andir},
3676 {Hexagon::A2_combineii, Hexagon::dup_A2_combineii},
3677 {Hexagon::A2_sxtb, Hexagon::dup_A2_sxtb},
3678 {Hexagon::A2_sxth, Hexagon::dup_A2_sxth},
3679 {Hexagon::A2_tfr, Hexagon::dup_A2_tfr},
3680 {Hexagon::A2_tfrsi, Hexagon::dup_A2_tfrsi},
3681 {Hexagon::A2_zxtb, Hexagon::dup_A2_zxtb},
3682 {Hexagon::A2_zxth, Hexagon::dup_A2_zxth},
3683 {Hexagon::A4_combineii, Hexagon::dup_A4_combineii},
3684 {Hexagon::A4_combineir, Hexagon::dup_A4_combineir},
3685 {Hexagon::A4_combineri, Hexagon::dup_A4_combineri},
3686 {Hexagon::C2_cmoveif, Hexagon::dup_C2_cmoveif},
3687 {Hexagon::C2_cmoveit, Hexagon::dup_C2_cmoveit},
3688 {Hexagon::C2_cmovenewif, Hexagon::dup_C2_cmovenewif},
3689 {Hexagon::C2_cmovenewit, Hexagon::dup_C2_cmovenewit},
3690 {Hexagon::C2_cmpeqi, Hexagon::dup_C2_cmpeqi},
3691 {Hexagon::L2_deallocframe, Hexagon::dup_L2_deallocframe},
3692 {Hexagon::L2_loadrb_io, Hexagon::dup_L2_loadrb_io},
3693 {Hexagon::L2_loadrd_io, Hexagon::dup_L2_loadrd_io},
3694 {Hexagon::L2_loadrh_io, Hexagon::dup_L2_loadrh_io},
3695 {Hexagon::L2_loadri_io, Hexagon::dup_L2_loadri_io},
3696 {Hexagon::L2_loadrub_io, Hexagon::dup_L2_loadrub_io},
3697 {Hexagon::L2_loadruh_io, Hexagon::dup_L2_loadruh_io},
3698 {Hexagon::S2_allocframe, Hexagon::dup_S2_allocframe},
3699 {Hexagon::S2_storerb_io, Hexagon::dup_S2_storerb_io},
3700 {Hexagon::S2_storerd_io, Hexagon::dup_S2_storerd_io},
3701 {Hexagon::S2_storerh_io, Hexagon::dup_S2_storerh_io},
3702 {Hexagon::S2_storeri_io, Hexagon::dup_S2_storeri_io},
3703 {Hexagon::S4_storeirb_io, Hexagon::dup_S4_storeirb_io},
3704 {Hexagon::S4_storeiri_io, Hexagon::dup_S4_storeiri_io},
3705 };
3706 unsigned OpNum = MI.getOpcode();
3707 // Conversion to Big core.
3708 if (ForBigCore) {
3709 auto Iter = DupMap.find(OpNum);
3710 if (Iter != DupMap.end())
3711 return Iter->second;
3712 } else { // Conversion to Tiny core.
3713 for (const auto &Iter : DupMap)
3714 if (Iter.second == OpNum)
3715 return Iter.first;
3716 }
3717 return -1;
3718}
3719
3720int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3721 enum Hexagon::PredSense inPredSense;
3722 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3723 Hexagon::PredSense_true;
3724 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3725 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3726 return CondOpcode;
3727
3728 llvm_unreachable("Unexpected predicable instruction");
3729}
3730
3731// Return the cur value instruction for a given store.
3733 switch (MI.getOpcode()) {
3734 default: llvm_unreachable("Unknown .cur type");
3735 case Hexagon::V6_vL32b_pi:
3736 return Hexagon::V6_vL32b_cur_pi;
3737 case Hexagon::V6_vL32b_ai:
3738 return Hexagon::V6_vL32b_cur_ai;
3739 case Hexagon::V6_vL32b_nt_pi:
3740 return Hexagon::V6_vL32b_nt_cur_pi;
3741 case Hexagon::V6_vL32b_nt_ai:
3742 return Hexagon::V6_vL32b_nt_cur_ai;
3743 case Hexagon::V6_vL32b_ppu:
3744 return Hexagon::V6_vL32b_cur_ppu;
3745 case Hexagon::V6_vL32b_nt_ppu:
3746 return Hexagon::V6_vL32b_nt_cur_ppu;
3747 }
3748 return 0;
3749}
3750
3751// Return the regular version of the .cur instruction.
3753 switch (MI.getOpcode()) {
3754 default: llvm_unreachable("Unknown .cur type");
3755 case Hexagon::V6_vL32b_cur_pi:
3756 return Hexagon::V6_vL32b_pi;
3757 case Hexagon::V6_vL32b_cur_ai:
3758 return Hexagon::V6_vL32b_ai;
3759 case Hexagon::V6_vL32b_nt_cur_pi:
3760 return Hexagon::V6_vL32b_nt_pi;
3761 case Hexagon::V6_vL32b_nt_cur_ai:
3762 return Hexagon::V6_vL32b_nt_ai;
3763 case Hexagon::V6_vL32b_cur_ppu:
3764 return Hexagon::V6_vL32b_ppu;
3765 case Hexagon::V6_vL32b_nt_cur_ppu:
3766 return Hexagon::V6_vL32b_nt_ppu;
3767 }
3768 return 0;
3769}
3770
3771// The diagram below shows the steps involved in the conversion of a predicated
3772// store instruction to its .new predicated new-value form.
3773//
3774// Note: It doesn't include conditional new-value stores as they can't be
3775// converted to .new predicate.
3776//
3777// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3778// ^ ^
3779// / \ (not OK. it will cause new-value store to be
3780// / X conditional on p0.new while R2 producer is
3781// / \ on p0)
3782// / \.
3783// p.new store p.old NV store
3784// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3785// ^ ^
3786// \ /
3787// \ /
3788// \ /
3789// p.old store
3790// [if (p0)memw(R0+#0)=R2]
3791//
3792// The following set of instructions further explains the scenario where
3793// conditional new-value store becomes invalid when promoted to .new predicate
3794// form.
3795//
3796// { 1) if (p0) r0 = add(r1, r2)
3797// 2) p0 = cmp.eq(r3, #0) }
3798//
3799// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3800// the first two instructions because in instr 1, r0 is conditional on old value
3801// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3802// is not valid for new-value stores.
3803// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3804// from the "Conditional Store" list. Because a predicated new value store
3805// would NOT be promoted to a double dot new store. See diagram below:
3806// This function returns yes for those stores that are predicated but not
3807// yet promoted to predicate dot new instructions.
3808//
3809// +---------------------+
3810// /-----| if (p0) memw(..)=r0 |---------\~
3811// || +---------------------+ ||
3812// promote || /\ /\ || promote
3813// || /||\ /||\ ||
3814// \||/ demote || \||/
3815// \/ || || \/
3816// +-------------------------+ || +-------------------------+
3817// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3818// +-------------------------+ || +-------------------------+
3819// || || ||
3820// || demote \||/
3821// promote || \/ NOT possible
3822// || || /\~
3823// \||/ || /||\~
3824// \/ || ||
3825// +-----------------------------+
3826// | if (p0.new) memw(..)=r0.new |
3827// +-----------------------------+
3828// Double Dot New Store
3829//
3830// Returns the most basic instruction for the .new predicated instructions and
3831// new-value stores.
3832// For example, all of the following instructions will be converted back to the
3833// same instruction:
3834// 1) if (p0.new) memw(R0+#0) = R1.new --->
3835// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3836// 3) if (p0.new) memw(R0+#0) = R1 --->
3837//
3838// To understand the translation of instruction 1 to its original form, consider
3839// a packet with 3 instructions.
3840// { p0 = cmp.eq(R0,R1)
3841// if (p0.new) R2 = add(R3, R4)
3842// R5 = add (R3, R1)
3843// }
3844// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3845//
3846// This instruction can be part of the previous packet only if both p0 and R2
3847// are promoted to .new values. This promotion happens in steps, first
3848// predicate register is promoted to .new and in the next iteration R2 is
3849// promoted. Therefore, in case of dependence check failure (due to R5) during
3850// next iteration, it should be converted back to its most basic form.
3851
3852// Return the new value instruction for a given store.
3854 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());
3855 if (NVOpcode >= 0) // Valid new-value store instruction.
3856 return NVOpcode;
3857
3858 switch (MI.getOpcode()) {
3859 default:
3860 report_fatal_error(Twine("Unknown .new type: ") +
3861 std::to_string(MI.getOpcode()));
3862 case Hexagon::S4_storerb_ur:
3863 return Hexagon::S4_storerbnew_ur;
3864
3865 case Hexagon::S2_storerb_pci:
3866 return Hexagon::S2_storerb_pci;
3867
3868 case Hexagon::S2_storeri_pci:
3869 return Hexagon::S2_storeri_pci;
3870
3871 case Hexagon::S2_storerh_pci:
3872 return Hexagon::S2_storerh_pci;
3873
3874 case Hexagon::S2_storerd_pci:
3875 return Hexagon::S2_storerd_pci;
3876
3877 case Hexagon::S2_storerf_pci:
3878 return Hexagon::S2_storerf_pci;
3879
3880 case Hexagon::V6_vS32b_ai:
3881 return Hexagon::V6_vS32b_new_ai;
3882
3883 case Hexagon::V6_vS32b_pi:
3884 return Hexagon::V6_vS32b_new_pi;
3885 }
3886 return 0;
3887}
3888
3889// Returns the opcode to use when converting MI, which is a conditional jump,
3890// into a conditional instruction which uses the .new value of the predicate.
3891// We also use branch probabilities to add a hint to the jump.
3892// If MBPI is null, all edges will be treated as equally likely for the
3893// purposes of establishing a predication hint.
3895 const MachineBranchProbabilityInfo *MBPI) const {
3896 // We assume that block can have at most two successors.
3897 const MachineBasicBlock *Src = MI.getParent();
3898 const MachineOperand &BrTarget = MI.getOperand(1);
3899 bool Taken = false;
3900 const BranchProbability OneHalf(1, 2);
3901
3902 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
3903 const MachineBasicBlock *Dst) {
3904 if (MBPI)
3905 return MBPI->getEdgeProbability(Src, Dst);
3906 return BranchProbability(1, Src->succ_size());
3907 };
3908
3909 if (BrTarget.isMBB()) {
3910 const MachineBasicBlock *Dst = BrTarget.getMBB();
3911 Taken = getEdgeProbability(Src, Dst) >= OneHalf;
3912 } else {
3913 // The branch target is not a basic block (most likely a function).
3914 // Since BPI only gives probabilities for targets that are basic blocks,
3915 // try to identify another target of this branch (potentially a fall-
3916 // -through) and check the probability of that target.
3917 //
3918 // The only handled branch combinations are:
3919 // - one conditional branch,
3920 // - one conditional branch followed by one unconditional branch.
3921 // Otherwise, assume not-taken.
3922 assert(MI.isConditionalBranch());
3923 const MachineBasicBlock &B = *MI.getParent();
3924 bool SawCond = false, Bad = false;
3925 for (const MachineInstr &I : B) {
3926 if (!I.isBranch())
3927 continue;
3928 if (I.isConditionalBranch()) {
3929 SawCond = true;
3930 if (&I != &MI) {
3931 Bad = true;
3932 break;
3933 }
3934 }
3935 if (I.isUnconditionalBranch() && !SawCond) {
3936 Bad = true;
3937 break;
3938 }
3939 }
3940 if (!Bad) {
3942 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
3943 if (NextIt == B.instr_end()) {
3944 // If this branch is the last, look for the fall-through block.
3945 for (const MachineBasicBlock *SB : B.successors()) {
3946 if (!B.isLayoutSuccessor(SB))
3947 continue;
3948 Taken = getEdgeProbability(Src, SB) < OneHalf;
3949 break;
3950 }
3951 } else {
3952 assert(NextIt->isUnconditionalBranch());
3953 // Find the first MBB operand and assume it's the target.
3954 const MachineBasicBlock *BT = nullptr;
3955 for (const MachineOperand &Op : NextIt->operands()) {
3956 if (!Op.isMBB())
3957 continue;
3958 BT = Op.getMBB();
3959 break;
3960 }
3961 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
3962 }
3963 } // if (!Bad)
3964 }
3965
3966 // The Taken flag should be set to something reasonable by this point.
3967
3968 switch (MI.getOpcode()) {
3969 case Hexagon::J2_jumpt:
3970 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
3971 case Hexagon::J2_jumpf:
3972 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
3973
3974 default:
3975 llvm_unreachable("Unexpected jump instruction.");
3976 }
3977}
3978
3979// Return .new predicate version for an instruction.
3981 const MachineBranchProbabilityInfo *MBPI) const {
3982 switch (MI.getOpcode()) {
3983 // Conditional Jumps
3984 case Hexagon::J2_jumpt:
3985 case Hexagon::J2_jumpf:
3986 return getDotNewPredJumpOp(MI, MBPI);
3987 }
3988
3989 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
3990 if (NewOpcode >= 0)
3991 return NewOpcode;
3992 return 0;
3993}
3994
3996 int NewOp = MI.getOpcode();
3997 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3998 NewOp = Hexagon::getPredOldOpcode(NewOp);
3999 // All Hexagon architectures have prediction bits on dot-new branches,
4000 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure
4001 // to pick the right opcode when converting back to dot-old.
4002 if (!Subtarget.hasFeature(Hexagon::ArchV60)) {
4003 switch (NewOp) {
4004 case Hexagon::J2_jumptpt:
4005 NewOp = Hexagon::J2_jumpt;
4006 break;
4007 case Hexagon::J2_jumpfpt:
4008 NewOp = Hexagon::J2_jumpf;
4009 break;
4010 case Hexagon::J2_jumprtpt:
4011 NewOp = Hexagon::J2_jumprt;
4012 break;
4013 case Hexagon::J2_jumprfpt:
4014 NewOp = Hexagon::J2_jumprf;
4015 break;
4016 }
4017 }
4018 assert(NewOp >= 0 &&
4019 "Couldn't change predicate new instruction to its old form.");
4020 }
4021
4022 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
4023 NewOp = Hexagon::getNonNVStore(NewOp);
4024 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
4025 }
4026
4027 if (Subtarget.hasV60Ops())
4028 return NewOp;
4029
4030 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.
4031 switch (NewOp) {
4032 case Hexagon::J2_jumpfpt:
4033 return Hexagon::J2_jumpf;
4034 case Hexagon::J2_jumptpt:
4035 return Hexagon::J2_jumpt;
4036 case Hexagon::J2_jumprfpt:
4037 return Hexagon::J2_jumprf;
4038 case Hexagon::J2_jumprtpt:
4039 return Hexagon::J2_jumprt;
4040 }
4041 return NewOp;
4042}
4043
4044// See if instruction could potentially be a duplex candidate.
4045// If so, return its group. Zero otherwise.
4047 const MachineInstr &MI) const {
4048 Register DstReg, SrcReg, Src1Reg, Src2Reg;
4049 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4050
4051 switch (MI.getOpcode()) {
4052 default:
4053 return HexagonII::HSIG_None;
4054 //
4055 // Group L1:
4056 //
4057 // Rd = memw(Rs+#u4:2)
4058 // Rd = memub(Rs+#u4:0)
4059 case Hexagon::L2_loadri_io:
4060 case Hexagon::dup_L2_loadri_io:
4061 DstReg = MI.getOperand(0).getReg();
4062 SrcReg = MI.getOperand(1).getReg();
4063 // Special case this one from Group L2.
4064 // Rd = memw(r29+#u5:2)
4065 if (isIntRegForSubInst(DstReg)) {
4066 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
4067 HRI.getStackRegister() == SrcReg &&
4068 MI.getOperand(2).isImm() &&
4069 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))
4070 return HexagonII::HSIG_L2;
4071 // Rd = memw(Rs+#u4:2)
4072 if (isIntRegForSubInst(SrcReg) &&
4073 (MI.getOperand(2).isImm() &&
4074 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))
4075 return HexagonII::HSIG_L1;
4076 }
4077 break;
4078 case Hexagon::L2_loadrub_io:
4079 case Hexagon::dup_L2_loadrub_io:
4080 // Rd = memub(Rs+#u4:0)
4081 DstReg = MI.getOperand(0).getReg();
4082 SrcReg = MI.getOperand(1).getReg();
4083 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4084 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))
4085 return HexagonII::HSIG_L1;
4086 break;
4087 //
4088 // Group L2:
4089 //
4090 // Rd = memh/memuh(Rs+#u3:1)
4091 // Rd = memb(Rs+#u3:0)
4092 // Rd = memw(r29+#u5:2) - Handled above.
4093 // Rdd = memd(r29+#u5:3)
4094 // deallocframe
4095 // [if ([!]p0[.new])] dealloc_return
4096 // [if ([!]p0[.new])] jumpr r31
4097 case Hexagon::L2_loadrh_io:
4098 case Hexagon::L2_loadruh_io:
4099 case Hexagon::dup_L2_loadrh_io:
4100 case Hexagon::dup_L2_loadruh_io:
4101 // Rd = memh/memuh(Rs+#u3:1)
4102 DstReg = MI.getOperand(0).getReg();
4103 SrcReg = MI.getOperand(1).getReg();
4104 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4105 MI.getOperand(2).isImm() &&
4106 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))
4107 return HexagonII::HSIG_L2;
4108 break;
4109 case Hexagon::L2_loadrb_io:
4110 case Hexagon::dup_L2_loadrb_io:
4111 // Rd = memb(Rs+#u3:0)
4112 DstReg = MI.getOperand(0).getReg();
4113 SrcReg = MI.getOperand(1).getReg();
4114 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4115 MI.getOperand(2).isImm() &&
4116 isUInt<3>(MI.getOperand(2).getImm()))
4117 return HexagonII::HSIG_L2;
4118 break;
4119 case Hexagon::L2_loadrd_io:
4120 case Hexagon::dup_L2_loadrd_io:
4121 // Rdd = memd(r29+#u5:3)
4122 DstReg = MI.getOperand(0).getReg();
4123 SrcReg = MI.getOperand(1).getReg();
4124 if (isDblRegForSubInst(DstReg, HRI) &&
4125 Hexagon::IntRegsRegClass.contains(SrcReg) &&
4126 HRI.getStackRegister() == SrcReg &&
4127 MI.getOperand(2).isImm() &&
4128 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4129 return HexagonII::HSIG_L2;
4130 break;
4131 // dealloc_return is not documented in Hexagon Manual, but marked
4132 // with A_SUBINSN attribute in iset_v4classic.py.
4133 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
4134 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
4135 case Hexagon::L4_return:
4136 case Hexagon::L2_deallocframe:
4137 case Hexagon::dup_L2_deallocframe:
4138 return HexagonII::HSIG_L2;
4139 case Hexagon::EH_RETURN_JMPR:
4140 case Hexagon::PS_jmpret:
4141 case Hexagon::SL2_jumpr31:
4142 // jumpr r31
4143 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0
4144 DstReg = MI.getOperand(0).getReg();
4145 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
4146 return HexagonII::HSIG_L2;
4147 break;
4148 case Hexagon::PS_jmprett:
4149 case Hexagon::PS_jmpretf:
4150 case Hexagon::PS_jmprettnewpt:
4151 case Hexagon::PS_jmpretfnewpt:
4152 case Hexagon::PS_jmprettnew:
4153 case Hexagon::PS_jmpretfnew:
4154 case Hexagon::SL2_jumpr31_t:
4155 case Hexagon::SL2_jumpr31_f:
4156 case Hexagon::SL2_jumpr31_tnew:
4157 case Hexagon::SL2_jumpr31_fnew:
4158 DstReg = MI.getOperand(1).getReg();
4159 SrcReg = MI.getOperand(0).getReg();
4160 // [if ([!]p0[.new])] jumpr r31
4161 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
4162 (Hexagon::P0 == SrcReg)) &&
4163 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
4164 return HexagonII::HSIG_L2;
4165 break;
4166 case Hexagon::L4_return_t:
4167 case Hexagon::L4_return_f:
4168 case Hexagon::L4_return_tnew_pnt:
4169 case Hexagon::L4_return_fnew_pnt:
4170 case Hexagon::L4_return_tnew_pt:
4171 case Hexagon::L4_return_fnew_pt:
4172 // [if ([!]p0[.new])] dealloc_return
4173 SrcReg = MI.getOperand(0).getReg();
4174 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
4175 return HexagonII::HSIG_L2;
4176 break;
4177 //
4178 // Group S1:
4179 //
4180 // memw(Rs+#u4:2) = Rt
4181 // memb(Rs+#u4:0) = Rt
4182 case Hexagon::S2_storeri_io:
4183 case Hexagon::dup_S2_storeri_io:
4184 // Special case this one from Group S2.
4185 // memw(r29+#u5:2) = Rt
4186 Src1Reg = MI.getOperand(0).getReg();
4187 Src2Reg = MI.getOperand(2).getReg();
4188 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4189 isIntRegForSubInst(Src2Reg) &&
4190 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4191 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))
4192 return HexagonII::HSIG_S2;
4193 // memw(Rs+#u4:2) = Rt
4194 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4195 MI.getOperand(1).isImm() &&
4196 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))
4197 return HexagonII::HSIG_S1;
4198 break;
4199 case Hexagon::S2_storerb_io:
4200 case Hexagon::dup_S2_storerb_io:
4201 // memb(Rs+#u4:0) = Rt
4202 Src1Reg = MI.getOperand(0).getReg();
4203 Src2Reg = MI.getOperand(2).getReg();
4204 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4205 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))
4206 return HexagonII::HSIG_S1;
4207 break;
4208 //
4209 // Group S2:
4210 //
4211 // memh(Rs+#u3:1) = Rt
4212 // memw(r29+#u5:2) = Rt
4213 // memd(r29+#s6:3) = Rtt
4214 // memw(Rs+#u4:2) = #U1
4215 // memb(Rs+#u4) = #U1
4216 // allocframe(#u5:3)
4217 case Hexagon::S2_storerh_io:
4218 case Hexagon::dup_S2_storerh_io:
4219 // memh(Rs+#u3:1) = Rt
4220 Src1Reg = MI.getOperand(0).getReg();
4221 Src2Reg = MI.getOperand(2).getReg();
4222 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4223 MI.getOperand(1).isImm() &&
4224 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))
4225 return HexagonII::HSIG_S1;
4226 break;
4227 case Hexagon::S2_storerd_io:
4228 case Hexagon::dup_S2_storerd_io:
4229 // memd(r29+#s6:3) = Rtt
4230 Src1Reg = MI.getOperand(0).getReg();
4231 Src2Reg = MI.getOperand(2).getReg();
4232 if (isDblRegForSubInst(Src2Reg, HRI) &&
4233 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4234 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4235 isShiftedInt<6,3>(MI.getOperand(1).getImm()))
4236 return HexagonII::HSIG_S2;
4237 break;
4238 case Hexagon::S4_storeiri_io:
4239 case Hexagon::dup_S4_storeiri_io:
4240 // memw(Rs+#u4:2) = #U1
4241 Src1Reg = MI.getOperand(0).getReg();
4242 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&
4243 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&
4244 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4245 return HexagonII::HSIG_S2;
4246 break;
4247 case Hexagon::S4_storeirb_io:
4248 case Hexagon::dup_S4_storeirb_io:
4249 // memb(Rs+#u4) = #U1
4250 Src1Reg = MI.getOperand(0).getReg();
4251 if (isIntRegForSubInst(Src1Reg) &&
4252 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&
4253 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4254 return HexagonII::HSIG_S2;
4255 break;
4256 case Hexagon::S2_allocframe:
4257 case Hexagon::dup_S2_allocframe:
4258 if (MI.getOperand(2).isImm() &&
4259 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4260 return HexagonII::HSIG_S1;
4261 break;
4262 //
4263 // Group A:
4264 //
4265 // Rx = add(Rx,#s7)
4266 // Rd = Rs
4267 // Rd = #u6
4268 // Rd = #-1
4269 // if ([!]P0[.new]) Rd = #0
4270 // Rd = add(r29,#u6:2)
4271 // Rx = add(Rx,Rs)
4272 // P0 = cmp.eq(Rs,#u2)
4273 // Rdd = combine(#0,Rs)
4274 // Rdd = combine(Rs,#0)
4275 // Rdd = combine(#u2,#U2)
4276 // Rd = add(Rs,#1)
4277 // Rd = add(Rs,#-1)
4278 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4279 // Rd = and(Rs,#1)
4280 case Hexagon::A2_addi:
4281 case Hexagon::dup_A2_addi:
4282 DstReg = MI.getOperand(0).getReg();
4283 SrcReg = MI.getOperand(1).getReg();
4284 if (isIntRegForSubInst(DstReg)) {
4285 // Rd = add(r29,#u6:2)
4286 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
4287 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&
4288 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))
4289 return HexagonII::HSIG_A;
4290 // Rx = add(Rx,#s7)
4291 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&
4292 isInt<7>(MI.getOperand(2).getImm()))
4293 return HexagonII::HSIG_A;
4294 // Rd = add(Rs,#1)
4295 // Rd = add(Rs,#-1)
4296 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
4297 ((MI.getOperand(2).getImm() == 1) ||
4298 (MI.getOperand(2).getImm() == -1)))
4299 return HexagonII::HSIG_A;
4300 }
4301 break;
4302 case Hexagon::A2_add:
4303 case Hexagon::dup_A2_add:
4304 // Rx = add(Rx,Rs)
4305 DstReg = MI.getOperand(0).getReg();
4306 Src1Reg = MI.getOperand(1).getReg();
4307 Src2Reg = MI.getOperand(2).getReg();
4308 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
4309 isIntRegForSubInst(Src2Reg))
4310 return HexagonII::HSIG_A;
4311 break;
4312 case Hexagon::A2_andir:
4313 case Hexagon::dup_A2_andir:
4314 // Same as zxtb.
4315 // Rd16=and(Rs16,#255)
4316 // Rd16=and(Rs16,#1)
4317 DstReg = MI.getOperand(0).getReg();
4318 SrcReg = MI.getOperand(1).getReg();
4319 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4320 MI.getOperand(2).isImm() &&
4321 ((MI.getOperand(2).getImm() == 1) ||
4322 (MI.getOperand(2).getImm() == 255)))
4323 return HexagonII::HSIG_A;
4324 break;
4325 case Hexagon::A2_tfr:
4326 case Hexagon::dup_A2_tfr:
4327 // Rd = Rs
4328 DstReg = MI.getOperand(0).getReg();
4329 SrcReg = MI.getOperand(1).getReg();
4330 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4331 return HexagonII::HSIG_A;
4332 break;
4333 case Hexagon::A2_tfrsi:
4334 case Hexagon::dup_A2_tfrsi:
4335 // Rd = #u6
4336 // Do not test for #u6 size since the const is getting extended
4337 // regardless and compound could be formed.
4338 // Rd = #-1
4339 DstReg = MI.getOperand(0).getReg();
4340 if (isIntRegForSubInst(DstReg))
4341 return HexagonII::HSIG_A;
4342 break;
4343 case Hexagon::C2_cmoveit:
4344 case Hexagon::C2_cmovenewit:
4345 case Hexagon::C2_cmoveif:
4346 case Hexagon::C2_cmovenewif:
4347 case Hexagon::dup_C2_cmoveit:
4348 case Hexagon::dup_C2_cmovenewit:
4349 case Hexagon::dup_C2_cmoveif:
4350 case Hexagon::dup_C2_cmovenewif:
4351 // if ([!]P0[.new]) Rd = #0
4352 // Actual form:
4353 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
4354 DstReg = MI.getOperand(0).getReg();
4355 SrcReg = MI.getOperand(1).getReg();
4356 if (isIntRegForSubInst(DstReg) &&
4357 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
4358 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)
4359 return HexagonII::HSIG_A;
4360 break;
4361 case Hexagon::C2_cmpeqi:
4362 case Hexagon::dup_C2_cmpeqi:
4363 // P0 = cmp.eq(Rs,#u2)
4364 DstReg = MI.getOperand(0).getReg();
4365 SrcReg = MI.getOperand(1).getReg();
4366 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
4367 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
4368 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))
4369 return HexagonII::HSIG_A;
4370 break;
4371 case Hexagon::A2_combineii:
4372 case Hexagon::A4_combineii:
4373 case Hexagon::dup_A2_combineii:
4374 case Hexagon::dup_A4_combineii:
4375 // Rdd = combine(#u2,#U2)
4376 DstReg = MI.getOperand(0).getReg();
4377 if (isDblRegForSubInst(DstReg, HRI) &&
4378 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||
4379 (MI.getOperand(1).isGlobal() &&
4380 isUInt<2>(MI.getOperand(1).getOffset()))) &&
4381 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||
4382 (MI.getOperand(2).isGlobal() &&
4383 isUInt<2>(MI.getOperand(2).getOffset()))))
4384 return HexagonII::HSIG_A;
4385 break;
4386 case Hexagon::A4_combineri:
4387 case Hexagon::dup_A4_combineri:
4388 // Rdd = combine(Rs,#0)
4389 // Rdd = combine(Rs,#0)
4390 DstReg = MI.getOperand(0).getReg();
4391 SrcReg = MI.getOperand(1).getReg();
4392 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4393 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||
4394 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))
4395 return HexagonII::HSIG_A;
4396 break;
4397 case Hexagon::A4_combineir:
4398 case Hexagon::dup_A4_combineir:
4399 // Rdd = combine(#0,Rs)
4400 DstReg = MI.getOperand(0).getReg();
4401 SrcReg = MI.getOperand(2).getReg();
4402 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4403 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||
4404 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))
4405 return HexagonII::HSIG_A;
4406 break;
4407 case Hexagon::A2_sxtb:
4408 case Hexagon::A2_sxth:
4409 case Hexagon::A2_zxtb:
4410 case Hexagon::A2_zxth:
4411 case Hexagon::dup_A2_sxtb:
4412 case Hexagon::dup_A2_sxth:
4413 case Hexagon::dup_A2_zxtb:
4414 case Hexagon::dup_A2_zxth:
4415 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4416 DstReg = MI.getOperand(0).getReg();
4417 SrcReg = MI.getOperand(1).getReg();
4418 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4419 return HexagonII::HSIG_A;
4420 break;
4421 }
4422
4423 return HexagonII::HSIG_None;
4424}
4425
4427 const InstrItineraryData *ItinData, const MachineInstr &MI) const {
4428 // Default to one cycle for no itinerary. However, an "empty" itinerary may
4429 // still have a MinLatency property, which getStageLatency checks.
4430 if (!ItinData)
4431 return getInstrLatency(ItinData, MI);
4432
4433 if (MI.isTransient())
4434 return 0;
4435 return ItinData->getStageLatency(MI.getDesc().getSchedClass());
4436}
4437
4438/// getOperandLatency - Compute and return the use operand latency of a given
4439/// pair of def and use.
4440/// In most cases, the static scheduling itinerary was enough to determine the
4441/// operand latency. But it may not be possible for instructions with variable
4442/// number of defs / uses.
4443///
4444/// This is a raw interface to the itinerary that may be directly overridden by
4445/// a target. Use computeOperandLatency to get the best estimate of latency.
4447 const InstrItineraryData *ItinData, const MachineInstr &DefMI,
4448 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
4449 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4450
4451 // Get DefIdx and UseIdx for super registers.
4452 const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
4453
4454 if (DefMO.isReg() && DefMO.getReg().isPhysical()) {
4455 if (DefMO.isImplicit()) {
4456 for (MCPhysReg SR : HRI.superregs(DefMO.getReg())) {
4457 int Idx = DefMI.findRegisterDefOperandIdx(SR, &HRI, false, false);
4458 if (Idx != -1) {
4459 DefIdx = Idx;
4460 break;
4461 }
4462 }
4463 }
4464
4465 const MachineOperand &UseMO = UseMI.getOperand(UseIdx);
4466 if (UseMO.isImplicit()) {
4467 for (MCPhysReg SR : HRI.superregs(UseMO.getReg())) {
4468 int Idx = UseMI.findRegisterUseOperandIdx(SR, &HRI, false);
4469 if (Idx != -1) {
4470 UseIdx = Idx;
4471 break;
4472 }
4473 }
4474 }
4475 }
4476
4477 std::optional<unsigned> Latency = TargetInstrInfo::getOperandLatency(
4478 ItinData, DefMI, DefIdx, UseMI, UseIdx);
4479 if (Latency == 0)
4480 // We should never have 0 cycle latency between two instructions unless
4481 // they can be packetized together. However, this decision can't be made
4482 // here.
4483 Latency = 1;
4484 return Latency;
4485}
4486
4487// inverts the predication logic.
4488// p -> NotP
4489// NotP -> P
4492 if (Cond.empty())
4493 return false;
4494 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
4495 Cond[0].setImm(Opc);
4496 return true;
4497}
4498
4500 int InvPredOpcode;
4501 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
4502 : Hexagon::getTruePredOpcode(Opc);
4503 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
4504 return InvPredOpcode;
4505
4506 llvm_unreachable("Unexpected predicated instruction");
4507}
4508
4509// Returns the max value that doesn't need to be extended.
4511 const uint64_t F = MI.getDesc().TSFlags;
4512 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4514 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4516
4517 if (isSigned) // if value is signed
4518 return ~(-1U << (bits - 1));
4519 else
4520 return ~(-1U << bits);
4521}
4522
4523
4525 switch (MI.getOpcode()) {
4526 case Hexagon::L2_loadrbgp:
4527 case Hexagon::L2_loadrdgp:
4528 case Hexagon::L2_loadrhgp:
4529 case Hexagon::L2_loadrigp:
4530 case Hexagon::L2_loadrubgp:
4531 case Hexagon::L2_loadruhgp:
4532 case Hexagon::S2_storerbgp:
4533 case Hexagon::S2_storerbnewgp:
4534 case Hexagon::S2_storerhgp:
4535 case Hexagon::S2_storerhnewgp:
4536 case Hexagon::S2_storerigp:
4537 case Hexagon::S2_storerinewgp:
4538 case Hexagon::S2_storerdgp:
4539 case Hexagon::S2_storerfgp:
4540 return true;
4541 }
4542 const uint64_t F = MI.getDesc().TSFlags;
4543 unsigned addrMode =
4545 // Disallow any base+offset instruction. The assembler does not yet reorder
4546 // based up any zero offset instruction.
4547 return (addrMode == HexagonII::BaseRegOffset ||
4548 addrMode == HexagonII::BaseImmOffset ||
4549 addrMode == HexagonII::BaseLongOffset);
4550}
4551
4553 // Workaround for the Global Scheduler. Sometimes, it creates
4554 // A4_ext as a Pseudo instruction and calls this function to see if
4555 // it can be added to an existing bundle. Since the instruction doesn't
4556 // belong to any BB yet, we can't use getUnits API.
4557 if (MI.getOpcode() == Hexagon::A4_ext)
4558 return false;
4559
4560 unsigned FuncUnits = getUnits(MI);
4561 return HexagonFUnits::isSlot0Only(FuncUnits);
4562}
4563
4565 const uint64_t F = MI.getDesc().TSFlags;
4568}
4569
4571 bool ToBigInstrs) const {
4572 int Opcode = -1;
4573 if (ToBigInstrs) { // To BigCore Instr.
4574 // Check if the instruction can form a Duplex.
4575 if (getDuplexCandidateGroup(*MII))
4576 // Get the opcode marked "dup_*" tag.
4577 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4578 } else // To TinyCore Instr.
4579 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4580
4581 // Change the opcode of the instruction.
4582 if (Opcode >= 0)
4583 MII->setDesc(get(Opcode));
4584}
4585
4586// This function is used to translate instructions to facilitate generating
4587// Duplexes on TinyCore.
4589 bool ToBigInstrs) const {
4590 for (auto &MB : MF)
4591 for (MachineBasicBlock::instr_iterator Instr = MB.instr_begin(),
4592 End = MB.instr_end();
4593 Instr != End; ++Instr)
4594 changeDuplexOpcode(Instr, ToBigInstrs);
4595}
4596
4597// This is a specialized form of above function.
4599 MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {
4600 MachineBasicBlock *MBB = MII->getParent();
4601 while ((MII != MBB->instr_end()) && MII->isInsideBundle()) {
4602 changeDuplexOpcode(MII, ToBigInstrs);
4603 ++MII;
4604 }
4605}
4606
4608 using namespace HexagonII;
4609
4610 const uint64_t F = MI.getDesc().TSFlags;
4611 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
4612 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
4613 if (Size != 0)
4614 return Size;
4615 // Y2_dcfetchbo is special
4616 if (MI.getOpcode() == Hexagon::Y2_dcfetchbo)
4618
4619 // Handle vector access sizes.
4620 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4621 switch (S) {
4623 return HRI.getSpillSize(Hexagon::HvxVRRegClass);
4625 return HRI.getSpillSize(Hexagon::HlxLRRegClass);
4626 default:
4627 llvm_unreachable("Unexpected instruction");
4628 }
4629}
4630
4631// Returns the min value that doesn't need to be extended.
4633 const uint64_t F = MI.getDesc().TSFlags;
4634 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4636 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4638
4639 if (isSigned) // if value is signed
4640 return -1U << (bits - 1);
4641 else
4642 return 0;
4643}
4644
4645// Returns opcode of the non-extended equivalent instruction.
4647 // Check if the instruction has a register form that uses register in place
4648 // of the extended operand, if so return that as the non-extended form.
4649 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());
4650 if (NonExtOpcode >= 0)
4651 return NonExtOpcode;
4652
4653 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
4654 // Check addressing mode and retrieve non-ext equivalent instruction.
4655 switch (getAddrMode(MI)) {
4657 return Hexagon::changeAddrMode_abs_io(MI.getOpcode());
4659 return Hexagon::changeAddrMode_io_rr(MI.getOpcode());
4661 return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
4662
4663 default:
4664 return -1;
4665 }
4666 }
4667 return -1;
4668}
4669
4671 Register &PredReg, unsigned &PredRegPos,
4672 RegState &PredRegFlags) const {
4673 if (Cond.empty())
4674 return false;
4675 assert(Cond.size() == 2);
4676 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
4677 LLVM_DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
4678 return false;
4679 }
4680 PredReg = Cond[1].getReg();
4681 PredRegPos = 1;
4682 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
4683 PredRegFlags = {};
4684 if (Cond[1].isImplicit())
4685 PredRegFlags = RegState::Implicit;
4686 if (Cond[1].isUndef())
4687 PredRegFlags |= RegState::Undef;
4688 return true;
4689}
4690
4692 return Hexagon::getRegForm(MI.getOpcode());
4693}
4694
4695// Return the number of bytes required to encode the instruction.
4696// Hexagon instructions are fixed length, 4 bytes, unless they
4697// use a constant extender, which requires another 4 bytes.
4698// For debug instructions and prolog labels, return 0.
4700 if (MI.isDebugInstr() || MI.isPosition())
4701 return 0;
4702
4703 unsigned Size = MI.getDesc().getSize();
4704 if (!Size)
4705 // Assume the default insn size in case it cannot be determined
4706 // for whatever reason.
4708
4711
4712 // Try and compute number of instructions in asm.
4713 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {
4714 const MachineBasicBlock &MBB = *MI.getParent();
4715 const MachineFunction *MF = MBB.getParent();
4716 const MCAsmInfo &MAI = MF->getTarget().getMCAsmInfo();
4717
4718 // Count the number of register definitions to find the asm string.
4719 unsigned NumDefs = 0;
4720 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();
4721 ++NumDefs)
4722 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");
4723
4724 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");
4725 // Disassemble the AsmStr and approximate number of instructions.
4726 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();
4727 Size = getInlineAsmLength(AsmStr, MAI);
4728 }
4729
4730 return Size;
4731}
4732
4734 const uint64_t F = MI.getDesc().TSFlags;
4736}
4737
4739 const InstrItineraryData &II = *Subtarget.getInstrItineraryData();
4740 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());
4741
4742 return IS.getUnits();
4743}
4744
4745// Calculate size of the basic block without debug instructions.
4747 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4748}
4749
4751 MachineBasicBlock::const_iterator BundleHead) const {
4752 assert(BundleHead->isBundle() && "Not a bundle header");
4753 auto MII = BundleHead.getInstrIterator();
4754 // Skip the bundle header.
4755 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));
4756}
4757
4758/// immediateExtend - Changes the instruction in place to one using an immediate
4759/// extender.
4762 "Instruction must be extendable");
4763 // Find which operand is extendable.
4764 short ExtOpNum = getCExtOpNum(MI);
4765 MachineOperand &MO = MI.getOperand(ExtOpNum);
4766 // This needs to be something we understand.
4767 assert((MO.isMBB() || MO.isImm()) &&
4768 "Branch with unknown extendable field type");
4769 // Mark given operand as extended.
4771}
4772
4774 MachineInstr &MI, MachineBasicBlock *NewTarget) const {
4775 LLVM_DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "
4776 << printMBBReference(*NewTarget);
4777 MI.dump(););
4778 assert(MI.isBranch());
4779 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());
4780 int TargetPos = MI.getNumOperands() - 1;
4781 // In general branch target is the last operand,
4782 // but some implicit defs added at the end might change it.
4783 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())
4784 --TargetPos;
4785 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());
4786 MI.getOperand(TargetPos).setMBB(NewTarget);
4788 NewOpcode = reversePrediction(NewOpcode);
4789 }
4790 MI.setDesc(get(NewOpcode));
4791 return true;
4792}
4793
4795 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4797 MachineBasicBlock &B = *A;
4799 DebugLoc DL = I->getDebugLoc();
4800 MachineInstr *NewMI;
4801
4802 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4803 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
4804 NewMI = BuildMI(B, I, DL, get(insn));
4805 LLVM_DEBUG(dbgs() << "\n"
4806 << getName(NewMI->getOpcode())
4807 << " Class: " << NewMI->getDesc().getSchedClass());
4808 NewMI->eraseFromParent();
4809 }
4810 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4811}
4812
4813// inverts the predication logic.
4814// p -> NotP
4815// NotP -> P
4817 LLVM_DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());
4818 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));
4819 return true;
4820}
4821
4822// Reverse the branch prediction.
4823unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4824 int PredRevOpcode = -1;
4825 if (isPredictedTaken(Opcode))
4826 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4827 else
4828 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4829 assert(PredRevOpcode > 0);
4830 return PredRevOpcode;
4831}
4832
4833// TODO: Add more rigorous validation.
4835 const {
4836 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4837}
4838
4841 assert(MIB->isBundle());
4842 MachineOperand &Operand = MIB->getOperand(0);
4843 if (Operand.isImm())
4844 Operand.setImm(Operand.getImm() | memShufDisabledMask);
4845 else
4846 MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));
4847}
4848
4850 assert(MIB.isBundle());
4851 const MachineOperand &Operand = MIB.getOperand(0);
4852 return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);
4853}
4854
4856 return (MI->getOpcode() == Hexagon::V6_vmpy_qf16_hf ||
4857 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||
4858 MI->getOpcode() == Hexagon::V6_vmpy_qf32_hf ||
4859 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||
4860 MI->getOpcode() == Hexagon::V6_vmpy_qf32_sf ||
4861 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||
4862 MI->getOpcode() == Hexagon::V6_vmpy_qf16 ||
4863 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||
4864 MI->getOpcode() == Hexagon::V6_vmpy_qf32_qf16 ||
4865 MI->getOpcode() == Hexagon::V6_vmpy_qf32);
4866}
4867
4868namespace llvm::HexagonII {
4869
4872 RegType In3 = RegType::Unknown) {
4873 RegTypeInfo I;
4874 I.Output = Out;
4875 I.Input1 = In1;
4876 I.Input2 = In2;
4877 I.Input3 = In3;
4878 return I;
4879}
4880
4881RegTypeInfo getRegTypeInfo(unsigned Opcode) {
4882 switch (Opcode) {
4883 default:
4884 return {};
4885
4886 case Hexagon::V6_vabs_qf16_hf:
4887 return make(RegType::QF16);
4888 case Hexagon::V6_vabs_qf16_qf16:
4890 case Hexagon::V6_vabs_qf32_qf32:
4892 case Hexagon::V6_vabs_qf32_sf:
4893 return make(RegType::QF32);
4894 case Hexagon::V6_vadd_hf:
4895 return make(RegType::QF16);
4896 case Hexagon::V6_vadd_qf16:
4898 case Hexagon::V6_vadd_qf16_mix:
4900 case Hexagon::V6_vadd_qf32:
4902 case Hexagon::V6_vadd_qf32_mix:
4904 case Hexagon::V6_vadd_sf:
4905 return make(RegType::QF32);
4906 case Hexagon::V6_vconv_bf_qf32:
4908 case Hexagon::V6_vconv_f8_qf16:
4910 case Hexagon::V6_vconv_hf_qf16:
4912 case Hexagon::V6_vconv_hf_qf32:
4914 case Hexagon::V6_vconv_qf16_f8:
4915 return make(RegType::QF16);
4916 case Hexagon::V6_vconv_qf16_hf:
4917 return make(RegType::QF16);
4918 case Hexagon::V6_vconv_qf16_qf16:
4920 case Hexagon::V6_vconv_qf32_qf32:
4922 case Hexagon::V6_vconv_qf32_sf:
4923 return make(RegType::QF32);
4924 case Hexagon::V6_vconv_sf_qf32:
4926 case Hexagon::V6_vilog2_qf16:
4928 case Hexagon::V6_vilog2_qf32:
4930 case Hexagon::V6_vmpy_qf16:
4932 case Hexagon::V6_vmpy_qf16_hf:
4933 return make(RegType::QF16);
4934 case Hexagon::V6_vmpy_qf16_mix_hf:
4936 case Hexagon::V6_vmpy_qf32:
4938 case Hexagon::V6_vmpy_qf32_hf:
4939 return make(RegType::QF32);
4940 case Hexagon::V6_vmpy_qf32_mix_hf:
4942 case Hexagon::V6_vmpy_qf32_qf16:
4944 case Hexagon::V6_vmpy_qf32_sf:
4945 return make(RegType::QF32);
4946 case Hexagon::V6_vmpy_rt_hf:
4947 return make(RegType::QF16);
4948 case Hexagon::V6_vmpy_rt_qf16:
4950 case Hexagon::V6_vmpy_rt_sf:
4951 return make(RegType::QF32);
4952 case Hexagon::V6_vneg_qf16_hf:
4953 return make(RegType::QF16);
4954 case Hexagon::V6_vneg_qf16_qf16:
4956 case Hexagon::V6_vneg_qf32_qf32:
4958 case Hexagon::V6_vneg_qf32_sf:
4959 return make(RegType::QF32);
4960 case Hexagon::V6_vsub_hf:
4961 return make(RegType::QF16);
4962 case Hexagon::V6_vsub_qf16:
4964 case Hexagon::V6_vsub_qf16_mix:
4966 case Hexagon::V6_vsub_qf32:
4968 case Hexagon::V6_vsub_qf32_mix:
4970 case Hexagon::V6_vsub_sf:
4971 return make(RegType::QF32);
4972 case Hexagon::V6_vsub_sf_mix:
4974 case Hexagon::V6_vsub_hf_mix:
4976 }
4977}
4978
4979} // namespace llvm::HexagonII
4980
4982 auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
4983 switch (Index) {
4984 case 1:
4985 return Info.Input1 == HexagonII::RegType::QF32;
4986 case 2:
4987 return Info.Input2 == HexagonII::RegType::QF32;
4988 case 3:
4989 return Info.Input3 == HexagonII::RegType::QF32;
4990 case 0:
4991 return Info.Input1 == HexagonII::RegType::QF32 ||
4992 Info.Input2 == HexagonII::RegType::QF32 ||
4993 Info.Input3 == HexagonII::RegType::QF32;
4994 default: // No instruction with more than 3 operands uses QF32.
4995 return false;
4996 }
4997 return false;
4998}
4999
5001 auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
5002 switch (Index) {
5003 case 1:
5004 return Info.Input1 == HexagonII::RegType::QF16;
5005 case 2:
5006 return Info.Input2 == HexagonII::RegType::QF16;
5007 case 3:
5008 return Info.Input3 == HexagonII::RegType::QF16;
5009 case 0:
5010 return Info.Input1 == HexagonII::RegType::QF16 ||
5011 Info.Input2 == HexagonII::RegType::QF16 ||
5012 Info.Input3 == HexagonII::RegType::QF16;
5013 default: // No instruction with more than 3 operands uses QF16.
5014 return false;
5015 }
5016 return false;
5017}
5018
5020 return usesQF32Operand(MI, Index) || usesQF16Operand(MI, Index);
5021}
5022
5026
5030
5034
5035// Return true if the function contains any qf-generating instructions.
5037 for (const MachineBasicBlock &MBB : MF)
5038 for (const MachineInstr &MI : MBB)
5039 if (isQFPInstr(const_cast<MachineInstr *>(&MI)))
5040 return true;
5041 return false;
5042}
5043
5044// Returns true if A appears before B within the same basic block.
5046 const MachineInstr *B) const {
5047 if (!A || !B || A->getParent() != B->getParent())
5048 return false;
5049
5050 for (const MachineInstr &MI : *A->getParent()) {
5051 if (&MI == A)
5052 return true;
5053 if (&MI == B)
5054 return false;
5055 }
5056 return false;
5057}
5058
5059// Addressing mode relations.
5061 return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
5062}
5063
5065 return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;
5066}
5067
5069 return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;
5070}
5071
5073 return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;
5074}
5075
5077 return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;
5078}
5079
5081 return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;
5082}
5083
5085 return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;
5086}
5087
5089 return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;
5090}
5091
5093 static const MCInst Nop = MCInstBuilder(Hexagon::A2_nop);
5094
5095 return MCInstBuilder(Hexagon::BUNDLE)
5096 .addImm(0)
5097 .addInst(&Nop);
5098}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool mayAlias(MachineInstr &MIa, SmallVectorImpl< MachineInstr * > &MemInsns, AliasAnalysis *AA)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Imm
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static const Function * getParent(const Value *V)
BitTracker BT
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DXIL Forward Handle Accesses
static bool isSigned(unsigned Opcode)
const HexagonInstrInfo * TII
static void parseOperands(MachineInstr *MI, SmallVector< unsigned, 4 > &Defs, SmallVector< unsigned, 8 > &Uses)
Gather register def/uses from MI.
static cl::opt< bool > DisableNVSchedule("disable-hexagon-nv-schedule", cl::Hidden, cl::desc("Disable schedule adjustment for new value stores."))
const int Hexagon_MEMH_OFFSET_MAX
const int Hexagon_MEMB_OFFSET_MAX
const int Hexagon_MEMH_OFFSET_MIN
const int Hexagon_MEMD_OFFSET_MAX
static cl::opt< bool > EnableTimingClassLatency("enable-timing-class-latency", cl::Hidden, cl::init(false), cl::desc("Enable timing class latency"))
const int Hexagon_MEMD_OFFSET_MIN
const int Hexagon_ADDI_OFFSET_MAX
static cl::opt< bool > EnableACCForwarding("enable-acc-forwarding", cl::Hidden, cl::init(true), cl::desc("Enable vec acc forwarding"))
static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI)
const int Hexagon_MEMW_OFFSET_MAX
Constants for Hexagon instructions.
const int Hexagon_MEMW_OFFSET_MIN
cl::opt< bool > ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden, cl::init(false), cl::desc("Do not consider inline-asm a scheduling/" "packetization boundary."))
const int Hexagon_ADDI_OFFSET_MIN
static cl::opt< bool > BranchRelaxAsmLarge("branch-relax-asm-large", cl::init(true), cl::Hidden, cl::desc("branch relax asm"))
static cl::opt< bool > EnableALUForwarding("enable-alu-forwarding", cl::Hidden, cl::init(true), cl::desc("Enable vec alu forwarding"))
const int Hexagon_MEMB_OFFSET_MIN
static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB, MachineBasicBlock::const_instr_iterator MIE)
Calculate number of instructions excluding the debug instructions.
static cl::opt< bool > EnableBranchPrediction("hexagon-enable-branch-prediction", cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"))
static bool isDblRegForSubInst(Register Reg, const HexagonRegisterInfo &HRI)
static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI)
static cl::opt< bool > UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden, cl::desc("Use the DFA based hazard recognizer."))
static bool isIntRegForSubInst(Register Reg)
static bool isDuplexPairMatch(unsigned Ga, unsigned Gb)
#define HEXAGON_INSTR_SIZE
IRTranslator LLVM IR MI
std::pair< Instruction::BinaryOps, Value * > OffsetOp
Find all possible pairs (BinOp, RHS) that BinOp V, RHS can be simplified.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
static bool isUndef(const MachineInstr &MI)
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define T
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
uint64_t IntrinsicInst * II
PassBuilder PB(Mod->getContext(), Machine, PassOpts->PTO, std::nullopt, &PIC)
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
static bool isBranch(unsigned Opcode)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
Remove Loads Into Fake Uses
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:479
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A debug info location.
Definition DebugLoc.h:126
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isTmpLoadPseudo(const MachineInstr &MI) const
int getDuplexOpcode(const MachineInstr &MI, bool ForBigCore=true) const
bool isHLXVec(const MachineInstr &MI) const
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool isHVXMemWithAIndirect(const MachineInstr &I, const MachineInstr &J) const
short changeAddrMode_abs_io(short Opc) const
bool isRestrictNoSlot1Store(const MachineInstr &MI) const
short getRegForm(const MachineInstr &MI) const
bool isVecALU(const MachineInstr &MI) const
bool isCompoundBranchInstr(const MachineInstr &MI) const
bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const
Symmetrical. See if these two instructions are fit for duplex pair.
bool isJumpR(const MachineInstr &MI) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
Decompose the machine operand's target flags into two values - the direct target flag value and any o...
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) const override
Get the base register and byte offset of a load/store instr.
bool producesStall(const MachineInstr &ProdMI, const MachineInstr &ConsMI) const
bool invertAndChangeJumpTarget(MachineInstr &MI, MachineBasicBlock *NewTarget) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
bool isPredictedTaken(unsigned Opcode) const
bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) const
bool hasQFPInstrs(const MachineFunction &MF) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const
int getDotNewPredOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const
bool isQFP32Instr(MachineInstr *MI) const
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
If the specified instruction defines any predicate or condition code register(s) used for predication...
unsigned getInvertedPredicatedOpcode(const int Opc) const
bool isPureSlot0(const MachineInstr &MI) const
bool doesNotReturn(const MachineInstr &CallMI) const
HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI) const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool usesQF16Operand(MachineInstr *MI, unsigned Index=0) const
bool isPredicatedNew(const MachineInstr &MI) const
bool isSignExtendingLoad(const MachineInstr &MI) const
bool isVecAcc(const MachineInstr &MI) const
bool reversePredSense(MachineInstr &MI) const
bool isPostIncWithImmOffset(const MachineInstr &MI) const
bool isQFPMul(const MachineInstr *MF) const
unsigned getAddrMode(const MachineInstr &MI) const
MCInst getNop() const override
bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const
bool mayBeNewStore(const MachineInstr &MI) const
bool isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const
bool canExecuteInBundle(const MachineInstr &First, const MachineInstr &Second) const
Can these instructions execute at the same time in a bundle.
bool isQFP16Instr(MachineInstr *MI) const
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
getOperandLatency - Compute and return the use operand latency of a given pair of def and use.
bool isAddrModeWithOffset(const MachineInstr &MI) const
bool isBaseImmOffset(const MachineInstr &MI) const
bool isAbsoluteSet(const MachineInstr &MI) const
short changeAddrMode_io_pi(short Opc) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Emit instructions to copy a pair of physical registers.
short changeAddrMode_pi_io(short Opc) const
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
std::unique_ptr< PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
bool isLoopN(const MachineInstr &MI) const
bool isSpillPredRegOp(const MachineInstr &MI) const
bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const override
Check if the instruction or the bundle of instructions has store to stack slots.
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
Return an array that contains the direct target flag values and their names.
bool isIndirectCall(const MachineInstr &MI) const
short changeAddrMode_ur_rr(short Opc) const
bool isValidAutoIncImm(const EVT VT, const int Offset) const
bool hasNonExtEquivalent(const MachineInstr &MI) const
bool isConstExtended(const MachineInstr &MI) const
bool getIncrementValue(const MachineInstr &MI, int &Value) const override
If the instruction is an increment of a constant value, return the amount.
int getCondOpcode(int Opc, bool sense) const
MachineInstr * findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp, MachineBasicBlock *TargetBB, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const
Find the hardware loop instruction used to set-up the specified loop.
unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData, const MachineInstr &MI) const
bool usesQF32Operand(MachineInstr *MI, unsigned Index=0) const
bool isAccumulator(const MachineInstr &MI) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
Compute the instruction latency of a given instruction.
bool PredOpcodeHasJMP_c(unsigned Opcode) const
bool isNewValue(const MachineInstr &MI) const
Register createVR(MachineFunction *MF, MVT VT) const
HexagonInstrInfo specifics.
bool isDotCurInst(const MachineInstr &MI) const
bool validateBranchCond(const ArrayRef< MachineOperand > &Cond) const
bool isExtended(const MachineInstr &MI) const
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Return true if it's profitable to predicate instructions with accumulated instruction latency of "Num...
bool isAsCheapAsAMove(const MachineInstr &MI) const override
int getMaxValue(const MachineInstr &MI) const
bool isPredicateLate(unsigned Opcode) const
short changeAddrMode_rr_ur(short Opc) const
bool isNewValueInst(const MachineInstr &MI) const
unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI, const TargetSubtargetInfo *STI=nullptr) const override
Measure the specified inline asm to determine an approximation of its length.
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
int getNonDotCurOp(const MachineInstr &MI) const
bool isIndirectL4Return(const MachineInstr &MI) const
unsigned reversePrediction(unsigned Opcode) const
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
Return an array that contains the bitmask target flag values and their names.
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
InstrStage::FuncUnits getUnits(const MachineInstr &MI) const
unsigned getMemAccessSize(const MachineInstr &MI) const
bool predOpcodeHasNot(ArrayRef< MachineOperand > Cond) const
bool isComplex(const MachineInstr &MI) const
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
void setBundleNoShuf(MachineBasicBlock::instr_iterator MIB) const
MachineBasicBlock::instr_iterator expandVGatherPseudo(MachineInstr &MI) const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
int getDotNewOp(const MachineInstr &MI) const
void changeDuplexOpcode(MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const
bool isMemOp(const MachineInstr &MI) const
int getDotOldOp(const MachineInstr &MI) const
bool hasUncondBranch(const MachineBasicBlock *B) const
short getNonExtOpcode(const MachineInstr &MI) const
bool isNewStorePseudo(const MachineInstr &MI) const
bool isTailCall(const MachineInstr &MI) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
Insert a noop into the instruction stream at the specified point.
bool isDeallocRet(const MachineInstr &MI) const
HexagonInstrInfo(const HexagonSubtarget &ST)
unsigned getCExtOpNum(const MachineInstr &MI) const
bool isSolo(const MachineInstr &MI) const
DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override
Create machine specific model for scheduling.
bool isLateSourceInstr(const MachineInstr &MI) const
bool isDotNewInst(const MachineInstr &MI) const
void translateInstrsForDup(MachineFunction &MF, bool ToBigInstrs=true) const
bool isTC1(const MachineInstr &MI) const
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
Test if the given instruction should be considered a scheduling boundary.
bool predCanBeUsedAsDotNew(const MachineInstr &MI, Register PredReg) const
unsigned getSize(const MachineInstr &MI) const
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
Return true if it's profitable for if-converter to duplicate instructions of specified accumulated in...
short changeAddrMode_io_abs(short Opc) const
int getDotCurOp(const MachineInstr &MI) const
bool expandPostRAPseudo(MachineInstr &MI) const override
This function is called for all pseudo instructions that remain after register allocation.
bool isMIBefore(const MachineInstr *A, const MachineInstr *B) const
bool isExpr(unsigned OpType) const
void genAllInsnTimingClasses(MachineFunction &MF) const
bool isTC2Early(const MachineInstr &MI) const
bool hasEHLabel(const MachineBasicBlock *B) const
bool shouldSink(const MachineInstr &MI) const override
bool isZeroExtendingLoad(const MachineInstr &MI) const
short changeAddrMode_rr_io(short Opc) const
bool isHVXVec(const MachineInstr &MI) const
bool isDependent(const MachineInstr &ProdMI, const MachineInstr &ConsMI) const
short changeAddrMode_io_rr(short Opc) const
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
Returns true if the first specified predicate subsumes the second, e.g.
bool mayBeCurLoad(const MachineInstr &MI) const
bool getBundleNoShuf(const MachineInstr &MIB) const
bool isNewValueJump(const MachineInstr &MI) const
bool isTC4x(const MachineInstr &MI) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Cond) const override
Convert the instruction into a predicated instruction.
bool getPredReg(ArrayRef< MachineOperand > Cond, Register &PredReg, unsigned &PredRegPos, RegState &PredRegFlags) const
bool isFloat(const MachineInstr &MI) const
bool isQFPInstr(MachineInstr *MI) const
bool isToBeScheduledASAP(const MachineInstr &MI1, const MachineInstr &MI2) const
MachineOperand * getBaseAndOffset(const MachineInstr &MI, int64_t &Offset, LocationSize &AccessSize) const
bool getInvertedPredSense(SmallVectorImpl< MachineOperand > &Cond) const
unsigned nonDbgBBSize(const MachineBasicBlock *BB) const
getInstrTimingClassLatency - Compute the instruction latency of a given instruction using Timing Clas...
uint64_t getType(const MachineInstr &MI) const
bool isEndLoopN(unsigned Opcode) const
bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
For instructions with a base and offset, return the position of the base register and offset operands...
bool isPredicable(const MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
bool isExtendable(const MachineInstr &MI) const
void immediateExtend(MachineInstr &MI) const
immediateExtend - Changes the instruction in place to one using an immediate extender.
bool isValidOffset(unsigned Opcode, int Offset, bool Extend=true) const
HexagonII::CompoundGroup getCompoundCandidateGroup(const MachineInstr &MI) const
bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const override
Check if the instruction or the bundle of instructions has load from stack slots.
SmallVector< MachineInstr *, 2 > getBranchingInstrs(MachineBasicBlock &MBB) const
bool isPredicatedTrue(const MachineInstr &MI) const
bool isNewValueStore(const MachineInstr &MI) const
int getMinValue(const MachineInstr &MI) const
bool isVecUsableNextPacket(const MachineInstr &ProdMI, const MachineInstr &ConsMI) const
unsigned getCompoundOpcode(const MachineInstr &GA, const MachineInstr &GB) const
bool addLatencyToSchedule(const MachineInstr &MI1, const MachineInstr &MI2) const
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
int getDotNewPredJumpOp(const MachineInstr &MI, const MachineBranchProbabilityInfo *MBPI) const
bool usesQFOperand(MachineInstr *MI, unsigned Index=0) const
bool isTC2(const MachineInstr &MI) const
Hexagon target-specific information for each MachineFunction.
Register getFrameRegister(const MachineFunction &MF) const override
Itinerary data supplied by a subtarget to be used by a target.
unsigned getStageLatency(unsigned ItinClassIndx) const
Return the total stage latency of the given class.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
A set of physical registers with utility functions to track liveness when walking backward/forward th...
LLVM_ABI void stepForward(const MachineInstr &MI, SmallVectorImpl< std::pair< MCPhysReg, const MachineOperand * > > &Clobbers)
Simulates liveness when stepping forward over an instruction(bundle).
LLVM_ABI void stepBackward(const MachineInstr &MI)
Simulates liveness when stepping backwards over an instruction(bundle).
LLVM_ABI void addLiveIns(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB.
LLVM_ABI bool available(const MachineRegisterInfo &MRI, MCRegister Reg) const
Returns true if register Reg and no aliasing register is in the set.
LLVM_ABI void addLiveOuts(const MachineBasicBlock &MBB)
Adds all live-out registers of basic block MBB.
bool contains(MCRegister Reg) const
Returns true if register Reg is contained in the set.
static LocationSize precise(uint64_t Value)
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:67
virtual unsigned getMaxInstLength(const MCSubtargetInfo *STI=nullptr) const
Returns the maximum possible encoded instruction size in bytes.
Definition MCAsmInfo.h:548
StringRef getCommentString() const
Definition MCAsmInfo.h:559
const char * getSeparatorString() const
Definition MCAsmInfo.h:554
MCInstBuilder & addInst(const MCInst *Val)
Add a new MCInst operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Machine Value Type.
SimpleValueType SimpleTy
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
Instructions::const_iterator const_instr_iterator
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
const char * createExternalSymbolName(StringRef Name)
Allocate a string and populate it with the given external symbol name.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
bool isBundle() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
void setImm(int64_t immVal)
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
unsigned getTargetFlags() const
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
void addTargetFlag(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Register getReg() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition StringRef.h:471
Object returned by analyzeLoopForPipelining.
virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool hasStoreToStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const
If the specified machine instruction has a store to a stack slot, return true along with the FrameInd...
virtual std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, SDNode *UseNode, unsigned UseIdx) const
virtual bool hasLoadFromStackSlot(const MachineInstr &MI, SmallVectorImpl< const MachineMemOperand * > &Accesses) const
If the specified machine instruction has a load from a stack slot, return true along with the FrameIn...
Primary interface to the complete machine description for the target machine.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const InstrItineraryData * getInstrItineraryData() const
getInstrItineraryData - Returns instruction itinerary data for the target or specific subtarget.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isSlot0Only(unsigned units)
HexagonII - This namespace holds all of the target specific flags that instruction info tracks.
unsigned const TypeCVI_LAST
static constexpr RegTypeInfo make(RegType Out, RegType In1=RegType::Unknown, RegType In2=RegType::Unknown, RegType In3=RegType::Unknown)
unsigned const TypeCVI_FIRST
RegType getOpRegType(unsigned Opcode)
RegTypeInfo getRegTypeInfo(unsigned Opcode)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ InternalRead
Register reads a value that is defined inside the same instruction or bundle.
@ Undef
Value of the register doesn't matter.
@ NoFlags
No Specific Flags.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
bool is_TC1(unsigned SchedClass)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
bool is_TC2(unsigned SchedClass)
bool is_TC2early(unsigned SchedClass)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition MathExtras.h:183
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool isSpace(char C)
Checks whether character C is whitespace in the "C" locale.
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
constexpr RegState getUndefRegState(bool B)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition MathExtras.h:199
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
bool is_TC4x(unsigned SchedClass)
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:411
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:354
These values represent a non-pipelined step in the execution of an instruction.
uint64_t FuncUnits
Bitmask representing a set of functional units.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.