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