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::HvxQRRegClass.hasSubClassEq(RC)) {
994 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))
995 .addFrameIndex(FI).addImm(0)
996 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
997 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
998 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))
999 .addFrameIndex(FI).addImm(0)
1000 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1001 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1002 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))
1003 .addFrameIndex(FI).addImm(0)
1004 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1005 } else {
1006 llvm_unreachable("Unimplemented");
1007 }
1008}
1009
1012 Register DestReg, int FI,
1013 const TargetRegisterClass *RC,
1014 Register VReg, unsigned SubReg,
1015 MachineInstr::MIFlag Flags) const {
1016 DebugLoc DL = MBB.findDebugLoc(I);
1017 MachineFunction &MF = *MBB.getParent();
1018 MachineFrameInfo &MFI = MF.getFrameInfo();
1019
1022 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
1023
1024 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
1025 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
1026 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1027 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
1028 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
1029 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1030 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
1031 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
1032 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1033 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
1034 BuildMI(MBB, I, DL, get(Hexagon::LDriw_ctr), DestReg)
1035 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1036 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
1037 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
1038 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1039 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
1040 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrv_ai), DestReg)
1041 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1042 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1043 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrw_ai), DestReg)
1044 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
1045 } else {
1046 llvm_unreachable("Can't store this register to stack slot");
1047 }
1048}
1049
1050/// expandPostRAPseudo - This function is called for all pseudo instructions
1051/// that remain after register allocation. Many pseudo instructions are
1052/// created to help register allocation. This is the place to convert them
1053/// into real instructions. The target can edit MI in place, or it can insert
1054/// new instructions and erase MI. The function should return true if
1055/// anything was changed.
1057 MachineBasicBlock &MBB = *MI.getParent();
1058 MachineFunction &MF = *MBB.getParent();
1059 MachineRegisterInfo &MRI = MF.getRegInfo();
1060 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1061 LivePhysRegs LiveIn(HRI), LiveOut(HRI);
1062 DebugLoc DL = MI.getDebugLoc();
1063 unsigned Opc = MI.getOpcode();
1064
1065 auto RealCirc = [&](unsigned Opc, bool HasImm, unsigned MxOp) {
1066 Register Mx = MI.getOperand(MxOp).getReg();
1067 Register CSx = (Mx == Hexagon::M0 ? Hexagon::CS0 : Hexagon::CS1);
1068 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrrcr), CSx)
1069 .add(MI.getOperand((HasImm ? 5 : 4)));
1070 auto MIB = BuildMI(MBB, MI, DL, get(Opc)).add(MI.getOperand(0))
1071 .add(MI.getOperand(1)).add(MI.getOperand(2)).add(MI.getOperand(3));
1072 if (HasImm)
1073 MIB.add(MI.getOperand(4));
1074 MIB.addReg(CSx, RegState::Implicit);
1075 MBB.erase(MI);
1076 return true;
1077 };
1078
1079 auto UseAligned = [&](const MachineInstr &MI, Align NeedAlign) {
1080 if (MI.memoperands().empty())
1081 return false;
1082 return all_of(MI.memoperands(), [NeedAlign](const MachineMemOperand *MMO) {
1083 return MMO->getAlign() >= NeedAlign;
1084 });
1085 };
1086
1087 switch (Opc) {
1088 case Hexagon::PS_call_instrprof_custom: {
1089 auto Op0 = MI.getOperand(0);
1090 assert(Op0.isGlobal() &&
1091 "First operand must be a global containing handler name.");
1092 const GlobalValue *NameVar = Op0.getGlobal();
1093 const GlobalVariable *GV = dyn_cast<GlobalVariable>(NameVar);
1094 auto *Arr = cast<ConstantDataArray>(GV->getInitializer());
1095 StringRef NameStr = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();
1096
1097 MachineOperand &Op1 = MI.getOperand(1);
1098 // Set R0 with the imm value to be passed to the custom profiling handler.
1099 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrsi), Hexagon::R0)
1100 .addImm(Op1.getImm());
1101 // The call to the custom handler is being treated as a special one as the
1102 // callee is responsible for saving and restoring all the registers
1103 // (including caller saved registers) it needs to modify. This is
1104 // done to reduce the impact of instrumentation on the code being
1105 // instrumented/profiled.
1106 // NOTE: R14, R15 and R28 are reserved for PLT handling. These registers
1107 // are in the Def list of the Hexagon::PS_call_instrprof_custom and
1108 // therefore will be handled appropriately duing register allocation.
1109
1110 // TODO: It may be a good idea to add a separate pseudo instruction for
1111 // static relocation which doesn't need to reserve r14, r15 and r28.
1112
1113 auto MIB = BuildMI(MBB, MI, DL, get(Hexagon::J2_call))
1115 .addDef(Hexagon::R29, RegState::ImplicitDefine)
1116 .addDef(Hexagon::R30, RegState::ImplicitDefine)
1117 .addDef(Hexagon::R14, RegState::ImplicitDefine)
1118 .addDef(Hexagon::R15, RegState::ImplicitDefine)
1119 .addDef(Hexagon::R28, RegState::ImplicitDefine);
1120 const char *cstr = MF.createExternalSymbolName(NameStr);
1121 MIB.addExternalSymbol(cstr);
1122 MBB.erase(MI);
1123 return true;
1124 }
1125 case TargetOpcode::COPY: {
1126 MachineOperand &MD = MI.getOperand(0);
1127 MachineOperand &MS = MI.getOperand(1);
1128 MachineBasicBlock::iterator MBBI = MI.getIterator();
1129 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
1130 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
1131 std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);
1132 }
1133 MBB.erase(MBBI);
1134 return true;
1135 }
1136 case Hexagon::PS_aligna:
1137 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())
1138 .addReg(HRI.getFrameRegister())
1139 .addImm(-MI.getOperand(1).getImm());
1140 MBB.erase(MI);
1141 return true;
1142 case Hexagon::V6_vassignp: {
1143 Register SrcReg = MI.getOperand(1).getReg();
1144 Register DstReg = MI.getOperand(0).getReg();
1145 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
1146 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1147 getLiveInRegsAt(LiveIn, MI);
1148 RegState UndefLo = getUndefRegState(!LiveIn.contains(SrcLo));
1149 RegState UndefHi = getUndefRegState(!LiveIn.contains(SrcHi));
1150 RegState Kill = getKillRegState(MI.getOperand(1).isKill());
1151 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)
1152 .addReg(SrcHi, UndefHi)
1153 .addReg(SrcLo, Kill | UndefLo);
1154 MBB.erase(MI);
1155 return true;
1156 }
1157 case Hexagon::V6_lo: {
1158 Register SrcReg = MI.getOperand(1).getReg();
1159 Register DstReg = MI.getOperand(0).getReg();
1160 Register SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
1161 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());
1162 MBB.erase(MI);
1163 MRI.clearKillFlags(SrcSubLo);
1164 return true;
1165 }
1166 case Hexagon::V6_hi: {
1167 Register SrcReg = MI.getOperand(1).getReg();
1168 Register DstReg = MI.getOperand(0).getReg();
1169 Register SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1170 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());
1171 MBB.erase(MI);
1172 MRI.clearKillFlags(SrcSubHi);
1173 return true;
1174 }
1175 case Hexagon::PS_vloadrv_ai: {
1176 Register DstReg = MI.getOperand(0).getReg();
1177 const MachineOperand &BaseOp = MI.getOperand(1);
1178 assert(BaseOp.getSubReg() == 0);
1179 int Offset = MI.getOperand(2).getImm();
1180 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1181 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
1182 : Hexagon::V6_vL32Ub_ai;
1183 BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
1184 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1185 .addImm(Offset)
1186 .cloneMemRefs(MI);
1187 MBB.erase(MI);
1188 return true;
1189 }
1190 case Hexagon::PS_vloadrw_ai: {
1191 Register DstReg = MI.getOperand(0).getReg();
1192 const MachineOperand &BaseOp = MI.getOperand(1);
1193 assert(BaseOp.getSubReg() == 0);
1194 int Offset = MI.getOperand(2).getImm();
1195 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1196 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1197 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vL32b_ai
1198 : Hexagon::V6_vL32Ub_ai;
1199 BuildMI(MBB, MI, DL, get(NewOpc),
1200 HRI.getSubReg(DstReg, Hexagon::vsub_lo))
1201 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
1202 .addImm(Offset)
1203 .cloneMemRefs(MI);
1204 BuildMI(MBB, MI, DL, get(NewOpc),
1205 HRI.getSubReg(DstReg, Hexagon::vsub_hi))
1206 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1207 .addImm(Offset + VecOffset)
1208 .cloneMemRefs(MI);
1209 MBB.erase(MI);
1210 return true;
1211 }
1212 case Hexagon::PS_vstorerv_ai: {
1213 const MachineOperand &SrcOp = MI.getOperand(2);
1214 assert(SrcOp.getSubReg() == 0);
1215 const MachineOperand &BaseOp = MI.getOperand(0);
1216 assert(BaseOp.getSubReg() == 0);
1217 int Offset = MI.getOperand(1).getImm();
1218 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1219 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
1220 : Hexagon::V6_vS32Ub_ai;
1221 BuildMI(MBB, MI, DL, get(NewOpc))
1222 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1223 .addImm(Offset)
1225 .cloneMemRefs(MI);
1226 MBB.erase(MI);
1227 return true;
1228 }
1229 case Hexagon::PS_vstorerw_ai: {
1230 Register SrcReg = MI.getOperand(2).getReg();
1231 const MachineOperand &BaseOp = MI.getOperand(0);
1232 assert(BaseOp.getSubReg() == 0);
1233 int Offset = MI.getOperand(1).getImm();
1234 unsigned VecOffset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1235 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
1236 unsigned NewOpc = UseAligned(MI, NeedAlign) ? Hexagon::V6_vS32b_ai
1237 : Hexagon::V6_vS32Ub_ai;
1238 BuildMI(MBB, MI, DL, get(NewOpc))
1239 .addReg(BaseOp.getReg(), getRegState(BaseOp) & ~RegState::Kill)
1240 .addImm(Offset)
1241 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo))
1242 .cloneMemRefs(MI);
1243 BuildMI(MBB, MI, DL, get(NewOpc))
1244 .addReg(BaseOp.getReg(), getRegState(BaseOp))
1245 .addImm(Offset + VecOffset)
1246 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi))
1247 .cloneMemRefs(MI);
1248 MBB.erase(MI);
1249 return true;
1250 }
1251 case Hexagon::PS_true: {
1252 Register Reg = MI.getOperand(0).getReg();
1253 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1254 .addReg(Reg, RegState::Undef)
1255 .addReg(Reg, RegState::Undef);
1256 MBB.erase(MI);
1257 return true;
1258 }
1259 case Hexagon::PS_false: {
1260 Register Reg = MI.getOperand(0).getReg();
1261 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1262 .addReg(Reg, RegState::Undef)
1263 .addReg(Reg, RegState::Undef);
1264 MBB.erase(MI);
1265 return true;
1266 }
1267 case Hexagon::PS_qtrue: {
1268 BuildMI(MBB, MI, DL, get(Hexagon::V6_veqw), MI.getOperand(0).getReg())
1269 .addReg(Hexagon::V0, RegState::Undef)
1270 .addReg(Hexagon::V0, RegState::Undef);
1271 MBB.erase(MI);
1272 return true;
1273 }
1274 case Hexagon::PS_qfalse: {
1275 BuildMI(MBB, MI, DL, get(Hexagon::V6_vgtw), MI.getOperand(0).getReg())
1276 .addReg(Hexagon::V0, RegState::Undef)
1277 .addReg(Hexagon::V0, RegState::Undef);
1278 MBB.erase(MI);
1279 return true;
1280 }
1281 case Hexagon::PS_vdd0: {
1282 Register Vd = MI.getOperand(0).getReg();
1283 BuildMI(MBB, MI, DL, get(Hexagon::V6_vsubw_dv), Vd)
1285 .addReg(Vd, RegState::Undef);
1286 MBB.erase(MI);
1287 return true;
1288 }
1289 case Hexagon::PS_vmulw: {
1290 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
1291 Register DstReg = MI.getOperand(0).getReg();
1292 Register Src1Reg = MI.getOperand(1).getReg();
1293 Register Src2Reg = MI.getOperand(2).getReg();
1294 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1295 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1296 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1297 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1298 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1299 HRI.getSubReg(DstReg, Hexagon::isub_hi))
1300 .addReg(Src1SubHi)
1301 .addReg(Src2SubHi);
1302 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1303 HRI.getSubReg(DstReg, Hexagon::isub_lo))
1304 .addReg(Src1SubLo)
1305 .addReg(Src2SubLo);
1306 MBB.erase(MI);
1307 MRI.clearKillFlags(Src1SubHi);
1308 MRI.clearKillFlags(Src1SubLo);
1309 MRI.clearKillFlags(Src2SubHi);
1310 MRI.clearKillFlags(Src2SubLo);
1311 return true;
1312 }
1313 case Hexagon::PS_vmulw_acc: {
1314 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
1315 Register DstReg = MI.getOperand(0).getReg();
1316 Register Src1Reg = MI.getOperand(1).getReg();
1317 Register Src2Reg = MI.getOperand(2).getReg();
1318 Register Src3Reg = MI.getOperand(3).getReg();
1319 Register Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1320 Register Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1321 Register Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1322 Register Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1323 Register Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);
1324 Register Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);
1325 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1326 HRI.getSubReg(DstReg, Hexagon::isub_hi))
1327 .addReg(Src1SubHi)
1328 .addReg(Src2SubHi)
1329 .addReg(Src3SubHi);
1330 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1331 HRI.getSubReg(DstReg, Hexagon::isub_lo))
1332 .addReg(Src1SubLo)
1333 .addReg(Src2SubLo)
1334 .addReg(Src3SubLo);
1335 MBB.erase(MI);
1336 MRI.clearKillFlags(Src1SubHi);
1337 MRI.clearKillFlags(Src1SubLo);
1338 MRI.clearKillFlags(Src2SubHi);
1339 MRI.clearKillFlags(Src2SubLo);
1340 MRI.clearKillFlags(Src3SubHi);
1341 MRI.clearKillFlags(Src3SubLo);
1342 return true;
1343 }
1344 case Hexagon::PS_pselect: {
1345 const MachineOperand &Op0 = MI.getOperand(0);
1346 const MachineOperand &Op1 = MI.getOperand(1);
1347 const MachineOperand &Op2 = MI.getOperand(2);
1348 const MachineOperand &Op3 = MI.getOperand(3);
1349 Register Rd = Op0.getReg();
1350 Register Pu = Op1.getReg();
1351 Register Rs = Op2.getReg();
1352 Register Rt = Op3.getReg();
1353 DebugLoc DL = MI.getDebugLoc();
1354 RegState K1 = getKillRegState(Op1.isKill());
1355 RegState K2 = getKillRegState(Op2.isKill());
1356 RegState K3 = getKillRegState(Op3.isKill());
1357 if (Rd != Rs)
1358 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1359 .addReg(Pu, (Rd == Rt) ? K1 : RegState::NoFlags)
1360 .addReg(Rs, K2);
1361 if (Rd != Rt)
1362 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1363 .addReg(Pu, K1)
1364 .addReg(Rt, K3);
1365 MBB.erase(MI);
1366 return true;
1367 }
1368 case Hexagon::PS_vselect: {
1369 const MachineOperand &Op0 = MI.getOperand(0);
1370 const MachineOperand &Op1 = MI.getOperand(1);
1371 const MachineOperand &Op2 = MI.getOperand(2);
1372 const MachineOperand &Op3 = MI.getOperand(3);
1373 getLiveOutRegsAt(LiveOut, MI);
1374 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());
1375 Register PReg = Op1.getReg();
1376 assert(Op1.getSubReg() == 0);
1377 RegState PState = getRegState(Op1);
1378
1379 if (Op0.getReg() != Op2.getReg()) {
1380 RegState S =
1381 Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill : PState;
1382 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
1383 .add(Op0)
1384 .addReg(PReg, S)
1385 .add(Op2);
1386 if (IsDestLive)
1387 T.addReg(Op0.getReg(), RegState::Implicit);
1388 IsDestLive = true;
1389 }
1390 if (Op0.getReg() != Op3.getReg()) {
1391 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
1392 .add(Op0)
1393 .addReg(PReg, PState)
1394 .add(Op3);
1395 if (IsDestLive)
1396 T.addReg(Op0.getReg(), RegState::Implicit);
1397 }
1398 MBB.erase(MI);
1399 return true;
1400 }
1401 case Hexagon::PS_wselect: {
1402 MachineOperand &Op0 = MI.getOperand(0);
1403 MachineOperand &Op1 = MI.getOperand(1);
1404 MachineOperand &Op2 = MI.getOperand(2);
1405 MachineOperand &Op3 = MI.getOperand(3);
1406 getLiveOutRegsAt(LiveOut, MI);
1407 bool IsDestLive = !LiveOut.available(MRI, Op0.getReg());
1408 Register PReg = Op1.getReg();
1409 assert(Op1.getSubReg() == 0);
1410 RegState PState = getRegState(Op1);
1411
1412 if (Op0.getReg() != Op2.getReg()) {
1413 RegState S =
1414 Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill : PState;
1415 Register SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);
1416 Register SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);
1417 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
1418 .add(Op0)
1419 .addReg(PReg, S)
1420 .addReg(SrcHi)
1421 .addReg(SrcLo);
1422 if (IsDestLive)
1423 T.addReg(Op0.getReg(), RegState::Implicit);
1424 IsDestLive = true;
1425 }
1426 if (Op0.getReg() != Op3.getReg()) {
1427 Register SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);
1428 Register SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);
1429 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
1430 .add(Op0)
1431 .addReg(PReg, PState)
1432 .addReg(SrcHi)
1433 .addReg(SrcLo);
1434 if (IsDestLive)
1435 T.addReg(Op0.getReg(), RegState::Implicit);
1436 }
1437 MBB.erase(MI);
1438 return true;
1439 }
1440
1441 case Hexagon::PS_crash: {
1442 // Generate a misaligned load that is guaranteed to cause a crash.
1443 class CrashPseudoSourceValue : public PseudoSourceValue {
1444 public:
1445 CrashPseudoSourceValue(const TargetMachine &TM)
1446 : PseudoSourceValue(TargetCustom, TM) {}
1447
1448 bool isConstant(const MachineFrameInfo *) const override {
1449 return false;
1450 }
1451 bool isAliased(const MachineFrameInfo *) const override {
1452 return false;
1453 }
1454 bool mayAlias(const MachineFrameInfo *) const override {
1455 return false;
1456 }
1457 void printCustom(raw_ostream &OS) const override {
1458 OS << "MisalignedCrash";
1459 }
1460 };
1461
1462 static const CrashPseudoSourceValue CrashPSV(MF.getTarget());
1464 MachinePointerInfo(&CrashPSV),
1466 Align(1));
1467 BuildMI(MBB, MI, DL, get(Hexagon::PS_loadrdabs), Hexagon::D13)
1468 .addImm(0xBADC0FEE) // Misaligned load.
1469 .addMemOperand(MMO);
1470 MBB.erase(MI);
1471 return true;
1472 }
1473
1474 case Hexagon::PS_tailcall_i:
1475 MI.setDesc(get(Hexagon::J2_jump));
1476 return true;
1477 case Hexagon::PS_tailcall_r:
1478 case Hexagon::PS_jmpret:
1479 MI.setDesc(get(Hexagon::J2_jumpr));
1480 return true;
1481 case Hexagon::PS_jmprett:
1482 MI.setDesc(get(Hexagon::J2_jumprt));
1483 return true;
1484 case Hexagon::PS_jmpretf:
1485 MI.setDesc(get(Hexagon::J2_jumprf));
1486 return true;
1487 case Hexagon::PS_jmprettnewpt:
1488 MI.setDesc(get(Hexagon::J2_jumprtnewpt));
1489 return true;
1490 case Hexagon::PS_jmpretfnewpt:
1491 MI.setDesc(get(Hexagon::J2_jumprfnewpt));
1492 return true;
1493 case Hexagon::PS_jmprettnew:
1494 MI.setDesc(get(Hexagon::J2_jumprtnew));
1495 return true;
1496 case Hexagon::PS_jmpretfnew:
1497 MI.setDesc(get(Hexagon::J2_jumprfnew));
1498 return true;
1499
1500 case Hexagon::PS_loadrub_pci:
1501 return RealCirc(Hexagon::L2_loadrub_pci, /*HasImm*/true, /*MxOp*/4);
1502 case Hexagon::PS_loadrb_pci:
1503 return RealCirc(Hexagon::L2_loadrb_pci, /*HasImm*/true, /*MxOp*/4);
1504 case Hexagon::PS_loadruh_pci:
1505 return RealCirc(Hexagon::L2_loadruh_pci, /*HasImm*/true, /*MxOp*/4);
1506 case Hexagon::PS_loadrh_pci:
1507 return RealCirc(Hexagon::L2_loadrh_pci, /*HasImm*/true, /*MxOp*/4);
1508 case Hexagon::PS_loadri_pci:
1509 return RealCirc(Hexagon::L2_loadri_pci, /*HasImm*/true, /*MxOp*/4);
1510 case Hexagon::PS_loadrd_pci:
1511 return RealCirc(Hexagon::L2_loadrd_pci, /*HasImm*/true, /*MxOp*/4);
1512 case Hexagon::PS_loadrub_pcr:
1513 return RealCirc(Hexagon::L2_loadrub_pcr, /*HasImm*/false, /*MxOp*/3);
1514 case Hexagon::PS_loadrb_pcr:
1515 return RealCirc(Hexagon::L2_loadrb_pcr, /*HasImm*/false, /*MxOp*/3);
1516 case Hexagon::PS_loadruh_pcr:
1517 return RealCirc(Hexagon::L2_loadruh_pcr, /*HasImm*/false, /*MxOp*/3);
1518 case Hexagon::PS_loadrh_pcr:
1519 return RealCirc(Hexagon::L2_loadrh_pcr, /*HasImm*/false, /*MxOp*/3);
1520 case Hexagon::PS_loadri_pcr:
1521 return RealCirc(Hexagon::L2_loadri_pcr, /*HasImm*/false, /*MxOp*/3);
1522 case Hexagon::PS_loadrd_pcr:
1523 return RealCirc(Hexagon::L2_loadrd_pcr, /*HasImm*/false, /*MxOp*/3);
1524 case Hexagon::PS_storerb_pci:
1525 return RealCirc(Hexagon::S2_storerb_pci, /*HasImm*/true, /*MxOp*/3);
1526 case Hexagon::PS_storerh_pci:
1527 return RealCirc(Hexagon::S2_storerh_pci, /*HasImm*/true, /*MxOp*/3);
1528 case Hexagon::PS_storerf_pci:
1529 return RealCirc(Hexagon::S2_storerf_pci, /*HasImm*/true, /*MxOp*/3);
1530 case Hexagon::PS_storeri_pci:
1531 return RealCirc(Hexagon::S2_storeri_pci, /*HasImm*/true, /*MxOp*/3);
1532 case Hexagon::PS_storerd_pci:
1533 return RealCirc(Hexagon::S2_storerd_pci, /*HasImm*/true, /*MxOp*/3);
1534 case Hexagon::PS_storerb_pcr:
1535 return RealCirc(Hexagon::S2_storerb_pcr, /*HasImm*/false, /*MxOp*/2);
1536 case Hexagon::PS_storerh_pcr:
1537 return RealCirc(Hexagon::S2_storerh_pcr, /*HasImm*/false, /*MxOp*/2);
1538 case Hexagon::PS_storerf_pcr:
1539 return RealCirc(Hexagon::S2_storerf_pcr, /*HasImm*/false, /*MxOp*/2);
1540 case Hexagon::PS_storeri_pcr:
1541 return RealCirc(Hexagon::S2_storeri_pcr, /*HasImm*/false, /*MxOp*/2);
1542 case Hexagon::PS_storerd_pcr:
1543 return RealCirc(Hexagon::S2_storerd_pcr, /*HasImm*/false, /*MxOp*/2);
1544 }
1545
1546 return false;
1547}
1548
1551 MachineBasicBlock &MBB = *MI.getParent();
1552 const DebugLoc &DL = MI.getDebugLoc();
1553 unsigned Opc = MI.getOpcode();
1555
1556 switch (Opc) {
1557 case Hexagon::V6_vgather_vscatter_mh_pseudo:
1558 // This is mainly a place holder. It will be extended.
1559 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
1560 .add(MI.getOperand(2))
1561 .add(MI.getOperand(3))
1562 .add(MI.getOperand(4));
1563 BuildMI(MBB, MI, DL, get(Hexagon::V6_vscattermh))
1564 .add(MI.getOperand(2))
1565 .add(MI.getOperand(3))
1566 .add(MI.getOperand(4))
1567 .addReg(Hexagon::VTMP);
1568 MBB.erase(MI);
1569 return First.getInstrIterator();
1570 case Hexagon::V6_vgathermh_pseudo:
1571 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermh))
1572 .add(MI.getOperand(2))
1573 .add(MI.getOperand(3))
1574 .add(MI.getOperand(4));
1575 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1576 .add(MI.getOperand(0))
1577 .addImm(MI.getOperand(1).getImm())
1578 .addReg(Hexagon::VTMP);
1579 MBB.erase(MI);
1580 return First.getInstrIterator();
1581
1582 case Hexagon::V6_vgathermw_pseudo:
1583 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermw))
1584 .add(MI.getOperand(2))
1585 .add(MI.getOperand(3))
1586 .add(MI.getOperand(4));
1587 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1588 .add(MI.getOperand(0))
1589 .addImm(MI.getOperand(1).getImm())
1590 .addReg(Hexagon::VTMP);
1591 MBB.erase(MI);
1592 return First.getInstrIterator();
1593
1594 case Hexagon::V6_vgathermhw_pseudo:
1595 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhw))
1596 .add(MI.getOperand(2))
1597 .add(MI.getOperand(3))
1598 .add(MI.getOperand(4));
1599 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1600 .add(MI.getOperand(0))
1601 .addImm(MI.getOperand(1).getImm())
1602 .addReg(Hexagon::VTMP);
1603 MBB.erase(MI);
1604 return First.getInstrIterator();
1605
1606 case Hexagon::V6_vgathermhq_pseudo:
1607 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhq))
1608 .add(MI.getOperand(2))
1609 .add(MI.getOperand(3))
1610 .add(MI.getOperand(4))
1611 .add(MI.getOperand(5));
1612 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1613 .add(MI.getOperand(0))
1614 .addImm(MI.getOperand(1).getImm())
1615 .addReg(Hexagon::VTMP);
1616 MBB.erase(MI);
1617 return First.getInstrIterator();
1618
1619 case Hexagon::V6_vgathermwq_pseudo:
1620 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermwq))
1621 .add(MI.getOperand(2))
1622 .add(MI.getOperand(3))
1623 .add(MI.getOperand(4))
1624 .add(MI.getOperand(5));
1625 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1626 .add(MI.getOperand(0))
1627 .addImm(MI.getOperand(1).getImm())
1628 .addReg(Hexagon::VTMP);
1629 MBB.erase(MI);
1630 return First.getInstrIterator();
1631
1632 case Hexagon::V6_vgathermhwq_pseudo:
1633 First = BuildMI(MBB, MI, DL, get(Hexagon::V6_vgathermhwq))
1634 .add(MI.getOperand(2))
1635 .add(MI.getOperand(3))
1636 .add(MI.getOperand(4))
1637 .add(MI.getOperand(5));
1638 BuildMI(MBB, MI, DL, get(Hexagon::V6_vS32b_new_ai))
1639 .add(MI.getOperand(0))
1640 .addImm(MI.getOperand(1).getImm())
1641 .addReg(Hexagon::VTMP);
1642 MBB.erase(MI);
1643 return First.getInstrIterator();
1644 }
1645
1646 return MI.getIterator();
1647}
1648
1649// We indicate that we want to reverse the branch by
1650// inserting the reversed branching opcode.
1653 if (Cond.empty())
1654 return true;
1655 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1656 unsigned opcode = Cond[0].getImm();
1657 //unsigned temp;
1658 assert(get(opcode).isBranch() && "Should be a branching condition.");
1659 if (isEndLoopN(opcode))
1660 return true;
1661 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1662 Cond[0].setImm(NewOpcode);
1663 return false;
1664}
1665
1671
1675
1677 unsigned BasePos, OffsetPos;
1678 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
1679 return false;
1680 return isPostIncrement(MI) && MI.getOperand(OffsetPos).isImm();
1681}
1682
1683// Returns true if an instruction is predicated irrespective of the predicate
1684// sense. For example, all of the following will return true.
1685// if (p0) R1 = add(R2, R3)
1686// if (!p0) R1 = add(R2, R3)
1687// if (p0.new) R1 = add(R2, R3)
1688// if (!p0.new) R1 = add(R2, R3)
1689// Note: New-value stores are not included here as in the current
1690// implementation, we don't need to check their predicate sense.
1692 const uint64_t F = MI.getDesc().TSFlags;
1694}
1695
1698 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1699 isEndLoopN(Cond[0].getImm())) {
1700 LLVM_DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
1701 return false;
1702 }
1703 int Opc = MI.getOpcode();
1704 assert (isPredicable(MI) && "Expected predicable instruction");
1705 bool invertJump = predOpcodeHasNot(Cond);
1706
1707 // We have to predicate MI "in place", i.e. after this function returns,
1708 // MI will need to be transformed into a predicated form. To avoid com-
1709 // plicated manipulations with the operands (handling tied operands,
1710 // etc.), build a new temporary instruction, then overwrite MI with it.
1711
1712 MachineBasicBlock &B = *MI.getParent();
1713 DebugLoc DL = MI.getDebugLoc();
1714 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1715 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
1716 unsigned NOp = 0, NumOps = MI.getNumOperands();
1717 while (NOp < NumOps) {
1718 MachineOperand &Op = MI.getOperand(NOp);
1719 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1720 break;
1721 T.add(Op);
1722 NOp++;
1723 }
1724
1725 Register PredReg;
1726 unsigned PredRegPos;
1727 RegState PredRegFlags = {};
1728 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1729 (void)GotPredReg;
1730 assert(GotPredReg);
1731 T.addReg(PredReg, PredRegFlags);
1732 while (NOp < NumOps)
1733 T.add(MI.getOperand(NOp++));
1734
1735 MI.setDesc(get(PredOpc));
1736 while (unsigned n = MI.getNumOperands())
1737 MI.removeOperand(n-1);
1738 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
1739 MI.addOperand(T->getOperand(i));
1740
1741 MachineBasicBlock::instr_iterator TI = T->getIterator();
1742 B.erase(TI);
1743
1744 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1745 MRI.clearKillFlags(PredReg);
1746 return true;
1747}
1748
1750 ArrayRef<MachineOperand> Pred2) const {
1751 // TODO: Fix this
1752 return false;
1753}
1754
1756 std::vector<MachineOperand> &Pred,
1757 bool SkipDead) const {
1758 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1759
1760 for (const MachineOperand &MO : MI.operands()) {
1761 if (MO.isReg()) {
1762 if (!MO.isDef())
1763 continue;
1764 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1765 if (RC == &Hexagon::PredRegsRegClass) {
1766 Pred.push_back(MO);
1767 return true;
1768 }
1769 continue;
1770 } else if (MO.isRegMask()) {
1771 for (Register PR : Hexagon::PredRegsRegClass) {
1772 if (!MI.modifiesRegister(PR, &HRI))
1773 continue;
1774 Pred.push_back(MO);
1775 return true;
1776 }
1777 }
1778 }
1779 return false;
1780}
1781
1783 if (!MI.getDesc().isPredicable())
1784 return false;
1785
1786 if (MI.isCall() || isTailCall(MI)) {
1787 if (!Subtarget.usePredicatedCalls())
1788 return false;
1789 }
1790
1791 // HVX loads are not predicable on v60, but are on v62.
1792 if (!Subtarget.hasV62Ops()) {
1793 switch (MI.getOpcode()) {
1794 case Hexagon::V6_vL32b_ai:
1795 case Hexagon::V6_vL32b_pi:
1796 case Hexagon::V6_vL32b_ppu:
1797 case Hexagon::V6_vL32b_cur_ai:
1798 case Hexagon::V6_vL32b_cur_pi:
1799 case Hexagon::V6_vL32b_cur_ppu:
1800 case Hexagon::V6_vL32b_nt_ai:
1801 case Hexagon::V6_vL32b_nt_pi:
1802 case Hexagon::V6_vL32b_nt_ppu:
1803 case Hexagon::V6_vL32b_tmp_ai:
1804 case Hexagon::V6_vL32b_tmp_pi:
1805 case Hexagon::V6_vL32b_tmp_ppu:
1806 case Hexagon::V6_vL32b_nt_cur_ai:
1807 case Hexagon::V6_vL32b_nt_cur_pi:
1808 case Hexagon::V6_vL32b_nt_cur_ppu:
1809 case Hexagon::V6_vL32b_nt_tmp_ai:
1810 case Hexagon::V6_vL32b_nt_tmp_pi:
1811 case Hexagon::V6_vL32b_nt_tmp_ppu:
1812 return false;
1813 }
1814 }
1815 return true;
1816}
1817
1819 bool Invert) const {
1820 if (Invert)
1821 return false;
1822
1823 switch (Inst.getOpcode()) {
1824 // TODO: Add more instructions to be handled by MachineCombiner.
1825 case Hexagon::F2_sfadd:
1827 default:
1828 return false;
1829 }
1830}
1831
1833 const MachineBasicBlock *MBB,
1834 const MachineFunction &MF) const {
1835 // Debug info is never a scheduling boundary. It's necessary to be explicit
1836 // due to the special treatment of IT instructions below, otherwise a
1837 // dbg_value followed by an IT will result in the IT instruction being
1838 // considered a scheduling hazard, which is wrong. It should be the actual
1839 // instruction preceding the dbg_value instruction(s), just like it is
1840 // when debug info is not present.
1841 if (MI.isDebugInstr())
1842 return false;
1843
1844 // Throwing call is a boundary.
1845 if (MI.isCall()) {
1846 // Don't mess around with no return calls.
1847 if (doesNotReturn(MI))
1848 return true;
1849 // If any of the block's successors is a landing pad, this could be a
1850 // throwing call.
1851 for (auto *I : MBB->successors())
1852 if (I->isEHPad())
1853 return true;
1854 }
1855
1856 // Terminators and labels can't be scheduled around.
1857 if (MI.getDesc().isTerminator() || MI.isPosition())
1858 return true;
1859
1860 // INLINEASM_BR can jump to another block
1861 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
1862 return true;
1863
1864 if (MI.isInlineAsm() && !ScheduleInlineAsm)
1865 return true;
1866
1867 return false;
1868}
1869
1870/// Measure the specified inline asm to determine an approximation of its
1871/// length.
1872/// Comments (which run till the next SeparatorString or newline) do not
1873/// count as an instruction.
1874/// Any other non-whitespace text is considered an instruction, with
1875/// multiple instructions separated by SeparatorString or newlines.
1876/// Variable-length instructions are not handled here; this function
1877/// may be overloaded in the target code to do that.
1878/// Hexagon counts the number of ##'s and adjust for that many
1879/// constant exenders.
1881 const MCAsmInfo &MAI,
1882 const TargetSubtargetInfo *STI) const {
1883 StringRef AStr(Str);
1884 // Count the number of instructions in the asm.
1885 bool atInsnStart = true;
1886 unsigned Length = 0;
1887 const unsigned MaxInstLength = MAI.getMaxInstLength(STI);
1888 for (; *Str; ++Str) {
1889 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1890 strlen(MAI.getSeparatorString())) == 0)
1891 atInsnStart = true;
1892 if (atInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {
1893 Length += MaxInstLength;
1894 atInsnStart = false;
1895 }
1896 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
1897 MAI.getCommentString().size()) == 0)
1898 atInsnStart = false;
1899 }
1900
1901 // Add to size number of constant extenders seen * 4.
1902 StringRef Occ("##");
1903 Length += AStr.count(Occ)*4;
1904 return Length;
1905}
1906
1914
1915/// For a comparison instruction, return the source registers in
1916/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1917/// compares against in CmpValue. Return true if the comparison instruction
1918/// can be analyzed.
1920 Register &SrcReg2, int64_t &Mask,
1921 int64_t &Value) const {
1922 unsigned Opc = MI.getOpcode();
1923
1924 // Set mask and the first source register.
1925 switch (Opc) {
1926 case Hexagon::C2_cmpeq:
1927 case Hexagon::C2_cmpeqp:
1928 case Hexagon::C2_cmpgt:
1929 case Hexagon::C2_cmpgtp:
1930 case Hexagon::C2_cmpgtu:
1931 case Hexagon::C2_cmpgtup:
1932 case Hexagon::C4_cmpneq:
1933 case Hexagon::C4_cmplte:
1934 case Hexagon::C4_cmplteu:
1935 case Hexagon::C2_cmpeqi:
1936 case Hexagon::C2_cmpgti:
1937 case Hexagon::C2_cmpgtui:
1938 case Hexagon::C4_cmpneqi:
1939 case Hexagon::C4_cmplteui:
1940 case Hexagon::C4_cmpltei:
1941 SrcReg = MI.getOperand(1).getReg();
1942 Mask = ~0;
1943 break;
1944 case Hexagon::A4_cmpbeq:
1945 case Hexagon::A4_cmpbgt:
1946 case Hexagon::A4_cmpbgtu:
1947 case Hexagon::A4_cmpbeqi:
1948 case Hexagon::A4_cmpbgti:
1949 case Hexagon::A4_cmpbgtui:
1950 SrcReg = MI.getOperand(1).getReg();
1951 Mask = 0xFF;
1952 break;
1953 case Hexagon::A4_cmpheq:
1954 case Hexagon::A4_cmphgt:
1955 case Hexagon::A4_cmphgtu:
1956 case Hexagon::A4_cmpheqi:
1957 case Hexagon::A4_cmphgti:
1958 case Hexagon::A4_cmphgtui:
1959 SrcReg = MI.getOperand(1).getReg();
1960 Mask = 0xFFFF;
1961 break;
1962 }
1963
1964 // Set the value/second source register.
1965 switch (Opc) {
1966 case Hexagon::C2_cmpeq:
1967 case Hexagon::C2_cmpeqp:
1968 case Hexagon::C2_cmpgt:
1969 case Hexagon::C2_cmpgtp:
1970 case Hexagon::C2_cmpgtu:
1971 case Hexagon::C2_cmpgtup:
1972 case Hexagon::A4_cmpbeq:
1973 case Hexagon::A4_cmpbgt:
1974 case Hexagon::A4_cmpbgtu:
1975 case Hexagon::A4_cmpheq:
1976 case Hexagon::A4_cmphgt:
1977 case Hexagon::A4_cmphgtu:
1978 case Hexagon::C4_cmpneq:
1979 case Hexagon::C4_cmplte:
1980 case Hexagon::C4_cmplteu:
1981 SrcReg2 = MI.getOperand(2).getReg();
1982 Value = 0;
1983 return true;
1984
1985 case Hexagon::C2_cmpeqi:
1986 case Hexagon::C2_cmpgtui:
1987 case Hexagon::C2_cmpgti:
1988 case Hexagon::C4_cmpneqi:
1989 case Hexagon::C4_cmplteui:
1990 case Hexagon::C4_cmpltei:
1991 case Hexagon::A4_cmpbeqi:
1992 case Hexagon::A4_cmpbgti:
1993 case Hexagon::A4_cmpbgtui:
1994 case Hexagon::A4_cmpheqi:
1995 case Hexagon::A4_cmphgti:
1996 case Hexagon::A4_cmphgtui: {
1997 SrcReg2 = 0;
1998 const MachineOperand &Op2 = MI.getOperand(2);
1999 if (!Op2.isImm())
2000 return false;
2001 Value = MI.getOperand(2).getImm();
2002 return true;
2003 }
2004 }
2005
2006 return false;
2007}
2008
2010 const MachineInstr &MI,
2011 unsigned *PredCost) const {
2012 return getInstrTimingClassLatency(ItinData, MI);
2013}
2014
2016 const TargetSubtargetInfo &STI) const {
2018 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
2019}
2020
2021// Inspired by this pair:
2022// %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]
2023// S2_storeri_io %r29, 132, killed %r1; flags: mem:ST4[FixedStack1]
2024// Currently AA considers the addresses in these instructions to be aliasing.
2026 const MachineInstr &MIa, const MachineInstr &MIb) const {
2029 return false;
2030
2031 // Instructions that are pure loads, not loads and stores like memops are not
2032 // dependent.
2033 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))
2034 return true;
2035
2036 // Get the base register in MIa.
2037 unsigned BasePosA, OffsetPosA;
2038 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))
2039 return false;
2040 const MachineOperand &BaseA = MIa.getOperand(BasePosA);
2041 Register BaseRegA = BaseA.getReg();
2042 unsigned BaseSubA = BaseA.getSubReg();
2043
2044 // Get the base register in MIb.
2045 unsigned BasePosB, OffsetPosB;
2046 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))
2047 return false;
2048 const MachineOperand &BaseB = MIb.getOperand(BasePosB);
2049 Register BaseRegB = BaseB.getReg();
2050 unsigned BaseSubB = BaseB.getSubReg();
2051
2052 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)
2053 return false;
2054
2055 // Get the access sizes.
2056 unsigned SizeA = getMemAccessSize(MIa);
2057 unsigned SizeB = getMemAccessSize(MIb);
2058
2059 // Get the offsets. Handle immediates only for now.
2060 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);
2061 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);
2062 if (!MIa.getOperand(OffsetPosA).isImm() ||
2063 !MIb.getOperand(OffsetPosB).isImm())
2064 return false;
2065 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();
2066 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();
2067
2068 // This is a mem access with the same base register and known offsets from it.
2069 // Reason about it.
2070 if (OffsetA > OffsetB) {
2071 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
2072 return SizeB <= OffDiff;
2073 }
2074 if (OffsetA < OffsetB) {
2075 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
2076 return SizeA <= OffDiff;
2077 }
2078
2079 return false;
2080}
2081
2082/// If the instruction is an increment of a constant value, return the amount.
2084 int &Value) const {
2085 if (isPostIncrement(MI)) {
2086 unsigned BasePos = 0, OffsetPos = 0;
2087 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
2088 return false;
2089 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
2090 if (OffsetOp.isImm()) {
2091 Value = OffsetOp.getImm();
2092 return true;
2093 }
2094 } else if (MI.getOpcode() == Hexagon::A2_addi) {
2095 const MachineOperand &AddOp = MI.getOperand(2);
2096 if (AddOp.isImm()) {
2097 Value = AddOp.getImm();
2098 return true;
2099 }
2100 }
2101
2102 return false;
2103}
2104
2105std::pair<unsigned, unsigned>
2107 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,
2109}
2110
2113 using namespace HexagonII;
2114
2115 static const std::pair<unsigned, const char*> Flags[] = {
2116 {MO_PCREL, "hexagon-pcrel"},
2117 {MO_GOT, "hexagon-got"},
2118 {MO_LO16, "hexagon-lo16"},
2119 {MO_HI16, "hexagon-hi16"},
2120 {MO_GPREL, "hexagon-gprel"},
2121 {MO_GDGOT, "hexagon-gdgot"},
2122 {MO_GDPLT, "hexagon-gdplt"},
2123 {MO_IE, "hexagon-ie"},
2124 {MO_IEGOT, "hexagon-iegot"},
2125 {MO_TPREL, "hexagon-tprel"}
2126 };
2127 return ArrayRef(Flags);
2128}
2129
2132 using namespace HexagonII;
2133
2134 static const std::pair<unsigned, const char*> Flags[] = {
2135 {HMOTF_ConstExtended, "hexagon-ext"}
2136 };
2137 return ArrayRef(Flags);
2138}
2139
2141 MachineRegisterInfo &MRI = MF->getRegInfo();
2142 const TargetRegisterClass *TRC;
2143 if (VT == MVT::i1) {
2144 TRC = &Hexagon::PredRegsRegClass;
2145 } else if (VT == MVT::i32 || VT == MVT::f32) {
2146 TRC = &Hexagon::IntRegsRegClass;
2147 } else if (VT == MVT::i64 || VT == MVT::f64) {
2148 TRC = &Hexagon::DoubleRegsRegClass;
2149 } else {
2150 llvm_unreachable("Cannot handle this register class");
2151 }
2152
2153 Register NewReg = MRI.createVirtualRegister(TRC);
2154 return NewReg;
2155}
2156
2160
2162 const uint64_t F = MI.getDesc().TSFlags;
2164}
2165
2169
2171 return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&
2172 !MI.getDesc().mayStore() &&
2173 MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&
2174 MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&
2175 !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();
2176}
2177
2178// Return true if the instruction is a compound branch instruction.
2180 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
2181}
2182
2183// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
2184// isFPImm and later getFPImm as well.
2186 const uint64_t F = MI.getDesc().TSFlags;
2188 if (isExtended) // Instruction must be extended.
2189 return true;
2190
2191 unsigned isExtendable =
2193 if (!isExtendable)
2194 return false;
2195
2196 if (MI.isCall())
2197 return false;
2198
2199 short ExtOpNum = getCExtOpNum(MI);
2200 const MachineOperand &MO = MI.getOperand(ExtOpNum);
2201 // Use MO operand flags to determine if MO
2202 // has the HMOTF_ConstExtended flag set.
2204 return true;
2205 // If this is a Machine BB address we are talking about, and it is
2206 // not marked as extended, say so.
2207 if (MO.isMBB())
2208 return false;
2209
2210 // We could be using an instruction with an extendable immediate and shoehorn
2211 // a global address into it. If it is a global address it will be constant
2212 // extended. We do this for COMBINE.
2213 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
2214 MO.isJTI() || MO.isCPI() || MO.isFPImm())
2215 return true;
2216
2217 // If the extendable operand is not 'Immediate' type, the instruction should
2218 // have 'isExtended' flag set.
2219 assert(MO.isImm() && "Extendable operand must be Immediate type");
2220
2221 int64_t Value = MO.getImm();
2223 int32_t SValue = Value;
2224 int32_t MinValue = getMinValue(MI);
2225 int32_t MaxValue = getMaxValue(MI);
2226 return SValue < MinValue || SValue > MaxValue;
2227 }
2228 uint32_t UValue = Value;
2229 uint32_t MinValue = getMinValue(MI);
2230 uint32_t MaxValue = getMaxValue(MI);
2231 return UValue < MinValue || UValue > MaxValue;
2232}
2233
2235 switch (MI.getOpcode()) {
2236 case Hexagon::L4_return:
2237 case Hexagon::L4_return_t:
2238 case Hexagon::L4_return_f:
2239 case Hexagon::L4_return_tnew_pnt:
2240 case Hexagon::L4_return_fnew_pnt:
2241 case Hexagon::L4_return_tnew_pt:
2242 case Hexagon::L4_return_fnew_pt:
2243 return true;
2244 }
2245 return false;
2246}
2247
2248// Return true when ConsMI uses a register defined by ProdMI.
2250 const MachineInstr &ConsMI) const {
2251 if (!ProdMI.getDesc().getNumDefs())
2252 return false;
2253 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
2254
2259
2260 parseOperands(ProdMI, DefsA, UsesA);
2261 parseOperands(ConsMI, DefsB, UsesB);
2262
2263 for (auto &RegA : DefsA)
2264 for (auto &RegB : UsesB) {
2265 // True data dependency.
2266 if (RegA == RegB)
2267 return true;
2268
2269 if (RegA.isPhysical() && llvm::is_contained(HRI.subregs(RegA), RegB))
2270 return true;
2271
2272 if (RegB.isPhysical() && llvm::is_contained(HRI.subregs(RegB), RegA))
2273 return true;
2274 }
2275
2276 return false;
2277}
2278
2279// Returns true if the instruction is already a .cur.
2281 switch (MI.getOpcode()) {
2282 case Hexagon::V6_vL32b_cur_pi:
2283 case Hexagon::V6_vL32b_cur_ai:
2284 return true;
2285 }
2286 return false;
2287}
2288
2289// Returns true, if any one of the operands is a dot new
2290// insn, whether it is predicated dot new or register dot new.
2293 return true;
2294
2295 return false;
2296}
2297
2298/// Symmetrical. See if these two instructions are fit for duplex pair.
2300 const MachineInstr &MIb) const {
2303 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
2304}
2305
2306bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
2307 return (Opcode == Hexagon::ENDLOOP0 ||
2308 Opcode == Hexagon::ENDLOOP1);
2309}
2310
2311bool HexagonInstrInfo::isExpr(unsigned OpType) const {
2312 switch(OpType) {
2319 return true;
2320 default:
2321 return false;
2322 }
2323}
2324
2326 const MCInstrDesc &MID = MI.getDesc();
2327 const uint64_t F = MID.TSFlags;
2329 return true;
2330
2331 // TODO: This is largely obsolete now. Will need to be removed
2332 // in consecutive patches.
2333 switch (MI.getOpcode()) {
2334 // PS_fi and PS_fia remain special cases.
2335 case Hexagon::PS_fi:
2336 case Hexagon::PS_fia:
2337 return true;
2338 default:
2339 return false;
2340 }
2341 return false;
2342}
2343
2344// This returns true in two cases:
2345// - The OP code itself indicates that this is an extended instruction.
2346// - One of MOs has been marked with HMOTF_ConstExtended flag.
2348 // First check if this is permanently extended op code.
2349 const uint64_t F = MI.getDesc().TSFlags;
2351 return true;
2352 // Use MO operand flags to determine if one of MI's operands
2353 // has HMOTF_ConstExtended flag set.
2354 for (const MachineOperand &MO : MI.operands())
2355 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
2356 return true;
2357 return false;
2358}
2359
2361 unsigned Opcode = MI.getOpcode();
2362 const uint64_t F = get(Opcode).TSFlags;
2363 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
2364}
2365
2366// No V60 HVX VMEM with A_INDIRECT.
2368 const MachineInstr &J) const {
2369 if (!isHVXVec(I))
2370 return false;
2371 if (!I.mayLoad() && !I.mayStore())
2372 return false;
2373 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
2374}
2375
2377 switch (MI.getOpcode()) {
2378 case Hexagon::J2_callr:
2379 case Hexagon::J2_callrf:
2380 case Hexagon::J2_callrt:
2381 case Hexagon::PS_call_nr:
2382 return true;
2383 }
2384 return false;
2385}
2386
2388 switch (MI.getOpcode()) {
2389 case Hexagon::L4_return:
2390 case Hexagon::L4_return_t:
2391 case Hexagon::L4_return_f:
2392 case Hexagon::L4_return_fnew_pnt:
2393 case Hexagon::L4_return_fnew_pt:
2394 case Hexagon::L4_return_tnew_pnt:
2395 case Hexagon::L4_return_tnew_pt:
2396 return true;
2397 }
2398 return false;
2399}
2400
2402 switch (MI.getOpcode()) {
2403 case Hexagon::J2_jumpr:
2404 case Hexagon::J2_jumprt:
2405 case Hexagon::J2_jumprf:
2406 case Hexagon::J2_jumprtnewpt:
2407 case Hexagon::J2_jumprfnewpt:
2408 case Hexagon::J2_jumprtnew:
2409 case Hexagon::J2_jumprfnew:
2410 return true;
2411 }
2412 return false;
2413}
2414
2415// Return true if a given MI can accommodate given offset.
2416// Use abs estimate as oppose to the exact number.
2417// TODO: This will need to be changed to use MC level
2418// definition of instruction extendable field size.
2420 unsigned offset) const {
2421 // This selection of jump instructions matches to that what
2422 // analyzeBranch can parse, plus NVJ.
2423 if (isNewValueJump(MI)) // r9:2
2424 return isInt<11>(offset);
2425
2426 switch (MI.getOpcode()) {
2427 // Still missing Jump to address condition on register value.
2428 default:
2429 return false;
2430 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2431 case Hexagon::J2_call:
2432 case Hexagon::PS_call_nr:
2433 return isInt<24>(offset);
2434 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2435 case Hexagon::J2_jumpf:
2436 case Hexagon::J2_jumptnew:
2437 case Hexagon::J2_jumptnewpt:
2438 case Hexagon::J2_jumpfnew:
2439 case Hexagon::J2_jumpfnewpt:
2440 case Hexagon::J2_callt:
2441 case Hexagon::J2_callf:
2442 return isInt<17>(offset);
2443 case Hexagon::J2_loop0i:
2444 case Hexagon::J2_loop0iext:
2445 case Hexagon::J2_loop0r:
2446 case Hexagon::J2_loop0rext:
2447 case Hexagon::J2_loop1i:
2448 case Hexagon::J2_loop1iext:
2449 case Hexagon::J2_loop1r:
2450 case Hexagon::J2_loop1rext:
2451 return isInt<9>(offset);
2452 // TODO: Add all the compound branches here. Can we do this in Relation model?
2453 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2454 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2455 case Hexagon::J4_cmpeqn1_tp0_jump_nt:
2456 case Hexagon::J4_cmpeqn1_tp1_jump_nt:
2457 return isInt<11>(offset);
2458 }
2459}
2460
2462 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2463 // resource, but all operands can be received late like an ALU instruction.
2465}
2466
2468 unsigned Opcode = MI.getOpcode();
2469 return Opcode == Hexagon::J2_loop0i ||
2470 Opcode == Hexagon::J2_loop0r ||
2471 Opcode == Hexagon::J2_loop0iext ||
2472 Opcode == Hexagon::J2_loop0rext ||
2473 Opcode == Hexagon::J2_loop1i ||
2474 Opcode == Hexagon::J2_loop1r ||
2475 Opcode == Hexagon::J2_loop1iext ||
2476 Opcode == Hexagon::J2_loop1rext;
2477}
2478
2480 switch (MI.getOpcode()) {
2481 default: return false;
2482 case Hexagon::L4_iadd_memopw_io:
2483 case Hexagon::L4_isub_memopw_io:
2484 case Hexagon::L4_add_memopw_io:
2485 case Hexagon::L4_sub_memopw_io:
2486 case Hexagon::L4_and_memopw_io:
2487 case Hexagon::L4_or_memopw_io:
2488 case Hexagon::L4_iadd_memoph_io:
2489 case Hexagon::L4_isub_memoph_io:
2490 case Hexagon::L4_add_memoph_io:
2491 case Hexagon::L4_sub_memoph_io:
2492 case Hexagon::L4_and_memoph_io:
2493 case Hexagon::L4_or_memoph_io:
2494 case Hexagon::L4_iadd_memopb_io:
2495 case Hexagon::L4_isub_memopb_io:
2496 case Hexagon::L4_add_memopb_io:
2497 case Hexagon::L4_sub_memopb_io:
2498 case Hexagon::L4_and_memopb_io:
2499 case Hexagon::L4_or_memopb_io:
2500 case Hexagon::L4_ior_memopb_io:
2501 case Hexagon::L4_ior_memoph_io:
2502 case Hexagon::L4_ior_memopw_io:
2503 case Hexagon::L4_iand_memopb_io:
2504 case Hexagon::L4_iand_memoph_io:
2505 case Hexagon::L4_iand_memopw_io:
2506 return true;
2507 }
2508 return false;
2509}
2510
2512 const uint64_t F = MI.getDesc().TSFlags;
2514}
2515
2516bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2517 const uint64_t F = get(Opcode).TSFlags;
2519}
2520
2524
2526 return isNewValue(MI) && MI.isBranch();
2527}
2528
2529bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2530 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2531}
2532
2534 const uint64_t F = MI.getDesc().TSFlags;
2536}
2537
2538bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2539 const uint64_t F = get(Opcode).TSFlags;
2541}
2542
2543// Returns true if a particular operand is extendable for an instruction.
2545 unsigned OperandNum) const {
2546 const uint64_t F = MI.getDesc().TSFlags;
2548 == OperandNum;
2549}
2550
2552 const uint64_t F = MI.getDesc().TSFlags;
2555}
2556
2557bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2558 const uint64_t F = get(Opcode).TSFlags;
2559 assert(isPredicated(Opcode));
2561}
2562
2564 const uint64_t F = MI.getDesc().TSFlags;
2565 return !((F >> HexagonII::PredicatedFalsePos) &
2567}
2568
2569bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2570 const uint64_t F = get(Opcode).TSFlags;
2571 // Make sure that the instruction is predicated.
2573 return !((F >> HexagonII::PredicatedFalsePos) &
2575}
2576
2577bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2578 const uint64_t F = get(Opcode).TSFlags;
2580}
2581
2582bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2583 const uint64_t F = get(Opcode).TSFlags;
2585}
2586
2587bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2588 const uint64_t F = get(Opcode).TSFlags;
2589 assert(get(Opcode).isBranch() &&
2590 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2592}
2593
2595 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2596 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2597 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2598 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
2599}
2600
2602 switch (MI.getOpcode()) {
2603 // Byte
2604 case Hexagon::L2_loadrb_io:
2605 case Hexagon::L4_loadrb_ur:
2606 case Hexagon::L4_loadrb_ap:
2607 case Hexagon::L2_loadrb_pr:
2608 case Hexagon::L2_loadrb_pbr:
2609 case Hexagon::L2_loadrb_pi:
2610 case Hexagon::L2_loadrb_pci:
2611 case Hexagon::L2_loadrb_pcr:
2612 case Hexagon::L2_loadbsw2_io:
2613 case Hexagon::L4_loadbsw2_ur:
2614 case Hexagon::L4_loadbsw2_ap:
2615 case Hexagon::L2_loadbsw2_pr:
2616 case Hexagon::L2_loadbsw2_pbr:
2617 case Hexagon::L2_loadbsw2_pi:
2618 case Hexagon::L2_loadbsw2_pci:
2619 case Hexagon::L2_loadbsw2_pcr:
2620 case Hexagon::L2_loadbsw4_io:
2621 case Hexagon::L4_loadbsw4_ur:
2622 case Hexagon::L4_loadbsw4_ap:
2623 case Hexagon::L2_loadbsw4_pr:
2624 case Hexagon::L2_loadbsw4_pbr:
2625 case Hexagon::L2_loadbsw4_pi:
2626 case Hexagon::L2_loadbsw4_pci:
2627 case Hexagon::L2_loadbsw4_pcr:
2628 case Hexagon::L4_loadrb_rr:
2629 case Hexagon::L2_ploadrbt_io:
2630 case Hexagon::L2_ploadrbt_pi:
2631 case Hexagon::L2_ploadrbf_io:
2632 case Hexagon::L2_ploadrbf_pi:
2633 case Hexagon::L2_ploadrbtnew_io:
2634 case Hexagon::L2_ploadrbfnew_io:
2635 case Hexagon::L4_ploadrbt_rr:
2636 case Hexagon::L4_ploadrbf_rr:
2637 case Hexagon::L4_ploadrbtnew_rr:
2638 case Hexagon::L4_ploadrbfnew_rr:
2639 case Hexagon::L2_ploadrbtnew_pi:
2640 case Hexagon::L2_ploadrbfnew_pi:
2641 case Hexagon::L4_ploadrbt_abs:
2642 case Hexagon::L4_ploadrbf_abs:
2643 case Hexagon::L4_ploadrbtnew_abs:
2644 case Hexagon::L4_ploadrbfnew_abs:
2645 case Hexagon::L2_loadrbgp:
2646 // Half
2647 case Hexagon::L2_loadrh_io:
2648 case Hexagon::L4_loadrh_ur:
2649 case Hexagon::L4_loadrh_ap:
2650 case Hexagon::L2_loadrh_pr:
2651 case Hexagon::L2_loadrh_pbr:
2652 case Hexagon::L2_loadrh_pi:
2653 case Hexagon::L2_loadrh_pci:
2654 case Hexagon::L2_loadrh_pcr:
2655 case Hexagon::L4_loadrh_rr:
2656 case Hexagon::L2_ploadrht_io:
2657 case Hexagon::L2_ploadrht_pi:
2658 case Hexagon::L2_ploadrhf_io:
2659 case Hexagon::L2_ploadrhf_pi:
2660 case Hexagon::L2_ploadrhtnew_io:
2661 case Hexagon::L2_ploadrhfnew_io:
2662 case Hexagon::L4_ploadrht_rr:
2663 case Hexagon::L4_ploadrhf_rr:
2664 case Hexagon::L4_ploadrhtnew_rr:
2665 case Hexagon::L4_ploadrhfnew_rr:
2666 case Hexagon::L2_ploadrhtnew_pi:
2667 case Hexagon::L2_ploadrhfnew_pi:
2668 case Hexagon::L4_ploadrht_abs:
2669 case Hexagon::L4_ploadrhf_abs:
2670 case Hexagon::L4_ploadrhtnew_abs:
2671 case Hexagon::L4_ploadrhfnew_abs:
2672 case Hexagon::L2_loadrhgp:
2673 return true;
2674 default:
2675 return false;
2676 }
2677}
2678
2680 const uint64_t F = MI.getDesc().TSFlags;
2682}
2683
2685 switch (MI.getOpcode()) {
2686 case Hexagon::STriw_pred:
2687 case Hexagon::LDriw_pred:
2688 return true;
2689 default:
2690 return false;
2691 }
2692}
2693
2695 if (!MI.isBranch())
2696 return false;
2697
2698 for (auto &Op : MI.operands())
2699 if (Op.isGlobal() || Op.isSymbol())
2700 return true;
2701 return false;
2702}
2703
2704// Returns true when SU has a timing class TC1.
2706 unsigned SchedClass = MI.getDesc().getSchedClass();
2707 return is_TC1(SchedClass);
2708}
2709
2711 unsigned SchedClass = MI.getDesc().getSchedClass();
2712 return is_TC2(SchedClass);
2713}
2714
2716 unsigned SchedClass = MI.getDesc().getSchedClass();
2717 return is_TC2early(SchedClass);
2718}
2719
2721 unsigned SchedClass = MI.getDesc().getSchedClass();
2722 return is_TC4x(SchedClass);
2723}
2724
2725// Schedule this ASAP.
2727 const MachineInstr &MI2) const {
2728 if (mayBeCurLoad(MI1)) {
2729 // if (result of SU is used in Next) return true;
2730 Register DstReg = MI1.getOperand(0).getReg();
2731 int N = MI2.getNumOperands();
2732 for (int I = 0; I < N; I++)
2733 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())
2734 return true;
2735 }
2736 if (mayBeNewStore(MI2))
2737 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)
2738 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&
2739 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())
2740 return true;
2741 return false;
2742}
2743
2745 const uint64_t V = getType(MI);
2747}
2748
2749// Check if the Offset is a valid auto-inc imm by Load/Store Type.
2751 int Size = VT.getSizeInBits() / 8;
2752 if (Offset % Size != 0)
2753 return false;
2754 int Count = Offset / Size;
2755
2756 switch (VT.getSimpleVT().SimpleTy) {
2757 // For scalars the auto-inc is s4
2758 case MVT::i8:
2759 case MVT::i16:
2760 case MVT::i32:
2761 case MVT::i64:
2762 case MVT::f32:
2763 case MVT::f64:
2764 case MVT::v2i16:
2765 case MVT::v2i32:
2766 case MVT::v4i8:
2767 case MVT::v4i16:
2768 case MVT::v8i8:
2769 return isInt<4>(Count);
2770 // For HVX vectors the auto-inc is s3
2771 case MVT::v64i8:
2772 case MVT::v32i16:
2773 case MVT::v16i32:
2774 case MVT::v8i64:
2775 case MVT::v128i8:
2776 case MVT::v64i16:
2777 case MVT::v32i32:
2778 case MVT::v16i64:
2779 return isInt<3>(Count);
2780 default:
2781 break;
2782 }
2783
2784 llvm_unreachable("Not an valid type!");
2785}
2786
2787bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
2788 const TargetRegisterInfo *TRI, bool Extend) const {
2789 // This function is to check whether the "Offset" is in the correct range of
2790 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
2791 // inserted to calculate the final address. Due to this reason, the function
2792 // assumes that the "Offset" has correct alignment.
2793 // We used to assert if the offset was not properly aligned, however,
2794 // there are cases where a misaligned pointer recast can cause this
2795 // problem, and we need to allow for it. The front end warns of such
2796 // misaligns with respect to load size.
2797 switch (Opcode) {
2798 case Hexagon::PS_vstorerq_ai:
2799 case Hexagon::PS_vstorerv_ai:
2800 case Hexagon::PS_vstorerw_ai:
2801 case Hexagon::PS_vstorerw_nt_ai:
2802 case Hexagon::PS_vloadrq_ai:
2803 case Hexagon::PS_vloadrv_ai:
2804 case Hexagon::PS_vloadrw_ai:
2805 case Hexagon::PS_vloadrw_nt_ai:
2806 case Hexagon::V6_vL32b_ai:
2807 case Hexagon::V6_vS32b_ai:
2808 case Hexagon::V6_vS32b_pred_ai:
2809 case Hexagon::V6_vS32b_npred_ai:
2810 case Hexagon::V6_vS32b_qpred_ai:
2811 case Hexagon::V6_vS32b_nqpred_ai:
2812 case Hexagon::V6_vS32b_new_ai:
2813 case Hexagon::V6_vS32b_new_pred_ai:
2814 case Hexagon::V6_vS32b_new_npred_ai:
2815 case Hexagon::V6_vS32b_nt_pred_ai:
2816 case Hexagon::V6_vS32b_nt_npred_ai:
2817 case Hexagon::V6_vS32b_nt_new_ai:
2818 case Hexagon::V6_vS32b_nt_new_pred_ai:
2819 case Hexagon::V6_vS32b_nt_new_npred_ai:
2820 case Hexagon::V6_vS32b_nt_qpred_ai:
2821 case Hexagon::V6_vS32b_nt_nqpred_ai:
2822 case Hexagon::V6_vL32b_nt_ai:
2823 case Hexagon::V6_vS32b_nt_ai:
2824 case Hexagon::V6_vL32Ub_ai:
2825 case Hexagon::V6_vS32Ub_ai:
2826 case Hexagon::V6_vL32b_cur_ai:
2827 case Hexagon::V6_vL32b_tmp_ai:
2828 case Hexagon::V6_vL32b_pred_ai:
2829 case Hexagon::V6_vL32b_npred_ai:
2830 case Hexagon::V6_vL32b_cur_pred_ai:
2831 case Hexagon::V6_vL32b_cur_npred_ai:
2832 case Hexagon::V6_vL32b_tmp_pred_ai:
2833 case Hexagon::V6_vL32b_tmp_npred_ai:
2834 case Hexagon::V6_vL32b_nt_cur_ai:
2835 case Hexagon::V6_vL32b_nt_tmp_ai:
2836 case Hexagon::V6_vL32b_nt_pred_ai:
2837 case Hexagon::V6_vL32b_nt_npred_ai:
2838 case Hexagon::V6_vL32b_nt_cur_pred_ai:
2839 case Hexagon::V6_vL32b_nt_cur_npred_ai:
2840 case Hexagon::V6_vL32b_nt_tmp_pred_ai:
2841 case Hexagon::V6_vL32b_nt_tmp_npred_ai:
2842 case Hexagon::V6_vS32Ub_pred_ai:
2843 case Hexagon::V6_vS32Ub_npred_ai:
2844 case Hexagon::V6_vgathermh_pseudo:
2845 case Hexagon::V6_vgather_vscatter_mh_pseudo:
2846 case Hexagon::V6_vgathermw_pseudo:
2847 case Hexagon::V6_vgathermhw_pseudo:
2848 case Hexagon::V6_vgathermhq_pseudo:
2849 case Hexagon::V6_vgathermwq_pseudo:
2850 case Hexagon::V6_vgathermhwq_pseudo: {
2851 unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);
2852 assert(isPowerOf2_32(VectorSize));
2853 if (Offset & (VectorSize-1))
2854 return false;
2855 return isInt<4>(Offset >> Log2_32(VectorSize));
2856 }
2857
2858 case Hexagon::J2_loop0i:
2859 case Hexagon::J2_loop1i:
2860 return isUInt<10>(Offset);
2861
2862 case Hexagon::S4_storeirb_io:
2863 case Hexagon::S4_storeirbt_io:
2864 case Hexagon::S4_storeirbf_io:
2865 return isUInt<6>(Offset);
2866
2867 case Hexagon::S4_storeirh_io:
2868 case Hexagon::S4_storeirht_io:
2869 case Hexagon::S4_storeirhf_io:
2870 return isShiftedUInt<6,1>(Offset);
2871
2872 case Hexagon::S4_storeiri_io:
2873 case Hexagon::S4_storeirit_io:
2874 case Hexagon::S4_storeirif_io:
2875 return isShiftedUInt<6,2>(Offset);
2876 // Handle these two compare instructions that are not extendable.
2877 case Hexagon::A4_cmpbeqi:
2878 return isUInt<8>(Offset);
2879 case Hexagon::A4_cmpbgti:
2880 return isInt<8>(Offset);
2881 }
2882
2883 if (Extend)
2884 return true;
2885
2886 switch (Opcode) {
2887 case Hexagon::L2_loadri_io:
2888 case Hexagon::S2_storeri_io:
2889 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2891
2892 case Hexagon::L2_loadrd_io:
2893 case Hexagon::S2_storerd_io:
2894 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2896
2897 case Hexagon::L2_loadrh_io:
2898 case Hexagon::L2_loadruh_io:
2899 case Hexagon::S2_storerh_io:
2900 case Hexagon::S2_storerf_io:
2901 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2903
2904 case Hexagon::L2_loadrb_io:
2905 case Hexagon::L2_loadrub_io:
2906 case Hexagon::S2_storerb_io:
2907 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2909
2910 case Hexagon::A2_addi:
2911 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2913
2914 case Hexagon::L4_iadd_memopw_io:
2915 case Hexagon::L4_isub_memopw_io:
2916 case Hexagon::L4_add_memopw_io:
2917 case Hexagon::L4_sub_memopw_io:
2918 case Hexagon::L4_iand_memopw_io:
2919 case Hexagon::L4_ior_memopw_io:
2920 case Hexagon::L4_and_memopw_io:
2921 case Hexagon::L4_or_memopw_io:
2922 return (0 <= Offset && Offset <= 255);
2923
2924 case Hexagon::L4_iadd_memoph_io:
2925 case Hexagon::L4_isub_memoph_io:
2926 case Hexagon::L4_add_memoph_io:
2927 case Hexagon::L4_sub_memoph_io:
2928 case Hexagon::L4_iand_memoph_io:
2929 case Hexagon::L4_ior_memoph_io:
2930 case Hexagon::L4_and_memoph_io:
2931 case Hexagon::L4_or_memoph_io:
2932 return (0 <= Offset && Offset <= 127);
2933
2934 case Hexagon::L4_iadd_memopb_io:
2935 case Hexagon::L4_isub_memopb_io:
2936 case Hexagon::L4_add_memopb_io:
2937 case Hexagon::L4_sub_memopb_io:
2938 case Hexagon::L4_iand_memopb_io:
2939 case Hexagon::L4_ior_memopb_io:
2940 case Hexagon::L4_and_memopb_io:
2941 case Hexagon::L4_or_memopb_io:
2942 return (0 <= Offset && Offset <= 63);
2943
2944 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
2945 // any size. Later pass knows how to handle it.
2946 case Hexagon::STriw_pred:
2947 case Hexagon::LDriw_pred:
2948 case Hexagon::STriw_ctr:
2949 case Hexagon::LDriw_ctr:
2950 return true;
2951
2952 case Hexagon::PS_fi:
2953 case Hexagon::PS_fia:
2954 case Hexagon::INLINEASM:
2955 return true;
2956
2957 case Hexagon::L2_ploadrbt_io:
2958 case Hexagon::L2_ploadrbf_io:
2959 case Hexagon::L2_ploadrubt_io:
2960 case Hexagon::L2_ploadrubf_io:
2961 case Hexagon::S2_pstorerbt_io:
2962 case Hexagon::S2_pstorerbf_io:
2963 return isUInt<6>(Offset);
2964
2965 case Hexagon::L2_ploadrht_io:
2966 case Hexagon::L2_ploadrhf_io:
2967 case Hexagon::L2_ploadruht_io:
2968 case Hexagon::L2_ploadruhf_io:
2969 case Hexagon::S2_pstorerht_io:
2970 case Hexagon::S2_pstorerhf_io:
2971 case Hexagon::S2_pstorerft_io:
2972 case Hexagon::S2_pstorerff_io:
2973 return isShiftedUInt<6,1>(Offset);
2974
2975 case Hexagon::L2_ploadrit_io:
2976 case Hexagon::L2_ploadrif_io:
2977 case Hexagon::S2_pstorerit_io:
2978 case Hexagon::S2_pstorerif_io:
2979 return isShiftedUInt<6,2>(Offset);
2980
2981 case Hexagon::L2_ploadrdt_io:
2982 case Hexagon::L2_ploadrdf_io:
2983 case Hexagon::S2_pstorerdt_io:
2984 case Hexagon::S2_pstorerdf_io:
2985 return isShiftedUInt<6,3>(Offset);
2986
2987 case Hexagon::L2_loadbsw2_io:
2988 case Hexagon::L2_loadbzw2_io:
2989 return isShiftedInt<11,1>(Offset);
2990
2991 case Hexagon::L2_loadbsw4_io:
2992 case Hexagon::L2_loadbzw4_io:
2993 return isShiftedInt<11,2>(Offset);
2994 } // switch
2995
2996 dbgs() << "Failed Opcode is : " << Opcode << " (" << getName(Opcode)
2997 << ")\n";
2998 llvm_unreachable("No offset range is defined for this opcode. "
2999 "Please define it in the above switch statement!");
3000}
3001
3003 return isHVXVec(MI) && isAccumulator(MI);
3004}
3005
3007 const uint64_t F = get(MI.getOpcode()).TSFlags;
3008 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
3009 return
3010 V == HexagonII::TypeCVI_VA ||
3012}
3013
3015 const MachineInstr &ConsMI) const {
3016 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
3017 return true;
3018
3019 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
3020 return true;
3021
3022 if (mayBeNewStore(ConsMI))
3023 return true;
3024
3025 return false;
3026}
3027
3029 switch (MI.getOpcode()) {
3030 // Byte
3031 case Hexagon::L2_loadrub_io:
3032 case Hexagon::L4_loadrub_ur:
3033 case Hexagon::L4_loadrub_ap:
3034 case Hexagon::L2_loadrub_pr:
3035 case Hexagon::L2_loadrub_pbr:
3036 case Hexagon::L2_loadrub_pi:
3037 case Hexagon::L2_loadrub_pci:
3038 case Hexagon::L2_loadrub_pcr:
3039 case Hexagon::L2_loadbzw2_io:
3040 case Hexagon::L4_loadbzw2_ur:
3041 case Hexagon::L4_loadbzw2_ap:
3042 case Hexagon::L2_loadbzw2_pr:
3043 case Hexagon::L2_loadbzw2_pbr:
3044 case Hexagon::L2_loadbzw2_pi:
3045 case Hexagon::L2_loadbzw2_pci:
3046 case Hexagon::L2_loadbzw2_pcr:
3047 case Hexagon::L2_loadbzw4_io:
3048 case Hexagon::L4_loadbzw4_ur:
3049 case Hexagon::L4_loadbzw4_ap:
3050 case Hexagon::L2_loadbzw4_pr:
3051 case Hexagon::L2_loadbzw4_pbr:
3052 case Hexagon::L2_loadbzw4_pi:
3053 case Hexagon::L2_loadbzw4_pci:
3054 case Hexagon::L2_loadbzw4_pcr:
3055 case Hexagon::L4_loadrub_rr:
3056 case Hexagon::L2_ploadrubt_io:
3057 case Hexagon::L2_ploadrubt_pi:
3058 case Hexagon::L2_ploadrubf_io:
3059 case Hexagon::L2_ploadrubf_pi:
3060 case Hexagon::L2_ploadrubtnew_io:
3061 case Hexagon::L2_ploadrubfnew_io:
3062 case Hexagon::L4_ploadrubt_rr:
3063 case Hexagon::L4_ploadrubf_rr:
3064 case Hexagon::L4_ploadrubtnew_rr:
3065 case Hexagon::L4_ploadrubfnew_rr:
3066 case Hexagon::L2_ploadrubtnew_pi:
3067 case Hexagon::L2_ploadrubfnew_pi:
3068 case Hexagon::L4_ploadrubt_abs:
3069 case Hexagon::L4_ploadrubf_abs:
3070 case Hexagon::L4_ploadrubtnew_abs:
3071 case Hexagon::L4_ploadrubfnew_abs:
3072 case Hexagon::L2_loadrubgp:
3073 // Half
3074 case Hexagon::L2_loadruh_io:
3075 case Hexagon::L4_loadruh_ur:
3076 case Hexagon::L4_loadruh_ap:
3077 case Hexagon::L2_loadruh_pr:
3078 case Hexagon::L2_loadruh_pbr:
3079 case Hexagon::L2_loadruh_pi:
3080 case Hexagon::L2_loadruh_pci:
3081 case Hexagon::L2_loadruh_pcr:
3082 case Hexagon::L4_loadruh_rr:
3083 case Hexagon::L2_ploadruht_io:
3084 case Hexagon::L2_ploadruht_pi:
3085 case Hexagon::L2_ploadruhf_io:
3086 case Hexagon::L2_ploadruhf_pi:
3087 case Hexagon::L2_ploadruhtnew_io:
3088 case Hexagon::L2_ploadruhfnew_io:
3089 case Hexagon::L4_ploadruht_rr:
3090 case Hexagon::L4_ploadruhf_rr:
3091 case Hexagon::L4_ploadruhtnew_rr:
3092 case Hexagon::L4_ploadruhfnew_rr:
3093 case Hexagon::L2_ploadruhtnew_pi:
3094 case Hexagon::L2_ploadruhfnew_pi:
3095 case Hexagon::L4_ploadruht_abs:
3096 case Hexagon::L4_ploadruhf_abs:
3097 case Hexagon::L4_ploadruhtnew_abs:
3098 case Hexagon::L4_ploadruhfnew_abs:
3099 case Hexagon::L2_loadruhgp:
3100 return true;
3101 default:
3102 return false;
3103 }
3104}
3105
3106// Add latency to instruction.
3108 const MachineInstr &MI2) const {
3109 if (isHVXVec(MI1) && isHVXVec(MI2))
3110 if (!isVecUsableNextPacket(MI1, MI2))
3111 return true;
3112 return false;
3113}
3114
3115/// Get the base register and byte offset of a load/store instr.
3118 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
3119 const TargetRegisterInfo *TRI) const {
3120 OffsetIsScalable = false;
3121 const MachineOperand *BaseOp = getBaseAndOffset(LdSt, Offset, Width);
3122 if (!BaseOp || !BaseOp->isReg())
3123 return false;
3124 BaseOps.push_back(BaseOp);
3125 return true;
3126}
3127
3128/// Can these instructions execute at the same time in a bundle.
3130 const MachineInstr &Second) const {
3131 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {
3132 const MachineOperand &Op = Second.getOperand(0);
3133 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)
3134 return true;
3135 }
3137 return false;
3138 if (mayBeNewStore(Second)) {
3139 // Make sure the definition of the first instruction is the value being
3140 // stored.
3141 const MachineOperand &Stored =
3142 Second.getOperand(Second.getNumOperands() - 1);
3143 if (!Stored.isReg())
3144 return false;
3145 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {
3146 const MachineOperand &Op = First.getOperand(i);
3147 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
3148 return true;
3149 }
3150 }
3151 return false;
3152}
3153
3155 unsigned Opc = CallMI.getOpcode();
3156 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;
3157}
3158
3160 for (auto &I : *B)
3161 if (I.isEHLabel())
3162 return true;
3163 return false;
3164}
3165
3166// Returns true if an instruction can be converted into a non-extended
3167// equivalent instruction.
3169 short NonExtOpcode;
3170 // Check if the instruction has a register form that uses register in place
3171 // of the extended operand, if so return that as the non-extended form.
3172 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)
3173 return true;
3174
3175 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
3176 // Check addressing mode and retrieve non-ext equivalent instruction.
3177
3178 switch (getAddrMode(MI)) {
3180 // Load/store with absolute addressing mode can be converted into
3181 // base+offset mode.
3182 NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());
3183 break;
3185 // Load/store with base+offset addressing mode can be converted into
3186 // base+register offset addressing mode. However left shift operand should
3187 // be set to 0.
3188 NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());
3189 break;
3191 NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
3192 break;
3193 default:
3194 return false;
3195 }
3196 if (NonExtOpcode < 0)
3197 return false;
3198 return true;
3199 }
3200 return false;
3201}
3202
3204 return Hexagon::getRealHWInstr(MI.getOpcode(),
3205 Hexagon::InstrType_Pseudo) >= 0;
3206}
3207
3209 const {
3210 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
3211 while (I != E) {
3212 if (I->isBarrier())
3213 return true;
3214 ++I;
3215 }
3216 return false;
3217}
3218
3219// Returns true, if a LD insn can be promoted to a cur load.
3221 const uint64_t F = MI.getDesc().TSFlags;
3223 Subtarget.hasV60Ops();
3224}
3225
3226// Returns true, if a ST insn can be promoted to a new-value store.
3228 if (MI.mayStore() && !Subtarget.useNewValueStores())
3229 return false;
3230
3231 const uint64_t F = MI.getDesc().TSFlags;
3233}
3234
3236 const MachineInstr &ConsMI) const {
3237 // There is no stall when ProdMI is not a V60 vector.
3238 if (!isHVXVec(ProdMI))
3239 return false;
3240
3241 // There is no stall when ProdMI and ConsMI are not dependent.
3242 if (!isDependent(ProdMI, ConsMI))
3243 return false;
3244
3245 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
3246 // are scheduled in consecutive packets.
3247 if (isVecUsableNextPacket(ProdMI, ConsMI))
3248 return false;
3249
3250 return true;
3251}
3252
3255 // There is no stall when I is not a V60 vector.
3256 if (!isHVXVec(MI))
3257 return false;
3258
3260 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
3261
3262 if (!MII->isBundle())
3263 return producesStall(*MII, MI);
3264
3265 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
3266 const MachineInstr &J = *MII;
3267 if (producesStall(J, MI))
3268 return true;
3269 }
3270 return false;
3271}
3272
3274 Register PredReg) const {
3275 for (const MachineOperand &MO : MI.operands()) {
3276 // Predicate register must be explicitly defined.
3277 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))
3278 return false;
3279 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
3280 return false;
3281 }
3282
3283 // Instruction that produce late predicate cannot be used as sources of
3284 // dot-new.
3285 switch (MI.getOpcode()) {
3286 case Hexagon::A4_addp_c:
3287 case Hexagon::A4_subp_c:
3288 case Hexagon::A4_tlbmatch:
3289 case Hexagon::A5_ACS:
3290 case Hexagon::F2_sfinvsqrta:
3291 case Hexagon::F2_sfrecipa:
3292 case Hexagon::J2_endloop0:
3293 case Hexagon::J2_endloop01:
3294 case Hexagon::J2_ploop1si:
3295 case Hexagon::J2_ploop1sr:
3296 case Hexagon::J2_ploop2si:
3297 case Hexagon::J2_ploop2sr:
3298 case Hexagon::J2_ploop3si:
3299 case Hexagon::J2_ploop3sr:
3300 case Hexagon::S2_cabacdecbin:
3301 case Hexagon::S2_storew_locked:
3302 case Hexagon::S4_stored_locked:
3303 return false;
3304 }
3305 return true;
3306}
3307
3308bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
3309 return Opcode == Hexagon::J2_jumpt ||
3310 Opcode == Hexagon::J2_jumptpt ||
3311 Opcode == Hexagon::J2_jumpf ||
3312 Opcode == Hexagon::J2_jumpfpt ||
3313 Opcode == Hexagon::J2_jumptnew ||
3314 Opcode == Hexagon::J2_jumpfnew ||
3315 Opcode == Hexagon::J2_jumptnewpt ||
3316 Opcode == Hexagon::J2_jumpfnewpt;
3317}
3318
3320 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
3321 return false;
3322 return !isPredicatedTrue(Cond[0].getImm());
3323}
3324
3326 const uint64_t F = MI.getDesc().TSFlags;
3328}
3329
3330// Returns the base register in a memory access (load/store). The offset is
3331// returned in Offset and the access size is returned in AccessSize.
3332// If the base operand has a subregister or the offset field does not contain
3333// an immediate value, return nullptr.
3336 LocationSize &AccessSize) const {
3337 // Return if it is not a base+offset type instruction or a MemOp.
3341 return nullptr;
3342
3344
3345 unsigned BasePos = 0, OffsetPos = 0;
3346 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
3347 return nullptr;
3348
3349 // Post increment updates its EA after the mem access,
3350 // so we need to treat its offset as zero.
3351 if (isPostIncrement(MI)) {
3352 Offset = 0;
3353 } else {
3354 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
3355 if (!OffsetOp.isImm())
3356 return nullptr;
3357 Offset = OffsetOp.getImm();
3358 }
3359
3360 const MachineOperand &BaseOp = MI.getOperand(BasePos);
3361 if (BaseOp.getSubReg() != 0)
3362 return nullptr;
3363 return &const_cast<MachineOperand&>(BaseOp);
3364}
3365
3366/// Return the position of the base and offset operands for this instruction.
3368 unsigned &BasePos, unsigned &OffsetPos) const {
3370 return false;
3371
3372 // Deal with memops first.
3373 if (isMemOp(MI)) {
3374 BasePos = 0;
3375 OffsetPos = 1;
3376 } else if (MI.mayStore()) {
3377 BasePos = 0;
3378 OffsetPos = 1;
3379 } else if (MI.mayLoad()) {
3380 BasePos = 1;
3381 OffsetPos = 2;
3382 } else
3383 return false;
3384
3385 if (isPredicated(MI)) {
3386 BasePos++;
3387 OffsetPos++;
3388 }
3389 if (isPostIncrement(MI)) {
3390 BasePos++;
3391 OffsetPos++;
3392 }
3393
3394 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
3395 return false;
3396
3397 return true;
3398}
3399
3400// Inserts branching instructions in reverse order of their occurrence.
3401// e.g. jump_t t1 (i1)
3402// jump t2 (i2)
3403// Jumpers = {i2, i1}
3405 MachineBasicBlock& MBB) const {
3407 // If the block has no terminators, it just falls into the block after it.
3409 if (I == MBB.instr_begin())
3410 return Jumpers;
3411
3412 // A basic block may looks like this:
3413 //
3414 // [ insn
3415 // EH_LABEL
3416 // insn
3417 // insn
3418 // insn
3419 // EH_LABEL
3420 // insn ]
3421 //
3422 // It has two succs but does not have a terminator
3423 // Don't know how to handle it.
3424 do {
3425 --I;
3426 if (I->isEHLabel())
3427 return Jumpers;
3428 } while (I != MBB.instr_begin());
3429
3430 I = MBB.instr_end();
3431 --I;
3432
3433 while (I->isDebugInstr()) {
3434 if (I == MBB.instr_begin())
3435 return Jumpers;
3436 --I;
3437 }
3438 if (!isUnpredicatedTerminator(*I))
3439 return Jumpers;
3440
3441 // Get the last instruction in the block.
3442 MachineInstr *LastInst = &*I;
3443 Jumpers.push_back(LastInst);
3444 MachineInstr *SecondLastInst = nullptr;
3445 // Find one more terminator if present.
3446 do {
3447 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
3448 if (!SecondLastInst) {
3449 SecondLastInst = &*I;
3450 Jumpers.push_back(SecondLastInst);
3451 } else // This is a third branch.
3452 return Jumpers;
3453 }
3454 if (I == MBB.instr_begin())
3455 break;
3456 --I;
3457 } while (true);
3458 return Jumpers;
3459}
3460
3461// Returns Operand Index for the constant extended instruction.
3463 const uint64_t F = MI.getDesc().TSFlags;
3465}
3466
3467// See if instruction could potentially be a duplex candidate.
3468// If so, return its group. Zero otherwise.
3470 const MachineInstr &MI) const {
3471 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3472
3473 switch (MI.getOpcode()) {
3474 default:
3475 return HexagonII::HCG_None;
3476 //
3477 // Compound pairs.
3478 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3479 // "Rd16=#U6 ; jump #r9:2"
3480 // "Rd16=Rs16 ; jump #r9:2"
3481 //
3482 case Hexagon::C2_cmpeq:
3483 case Hexagon::C2_cmpgt:
3484 case Hexagon::C2_cmpgtu:
3485 DstReg = MI.getOperand(0).getReg();
3486 Src1Reg = MI.getOperand(1).getReg();
3487 Src2Reg = MI.getOperand(2).getReg();
3488 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3489 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3490 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3491 return HexagonII::HCG_A;
3492 break;
3493 case Hexagon::C2_cmpeqi:
3494 case Hexagon::C2_cmpgti:
3495 case Hexagon::C2_cmpgtui:
3496 // P0 = cmp.eq(Rs,#u2)
3497 DstReg = MI.getOperand(0).getReg();
3498 SrcReg = MI.getOperand(1).getReg();
3499 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3500 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3501 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3502 ((isUInt<5>(MI.getOperand(2).getImm())) ||
3503 (MI.getOperand(2).getImm() == -1)))
3504 return HexagonII::HCG_A;
3505 break;
3506 case Hexagon::A2_tfr:
3507 // Rd = Rs
3508 DstReg = MI.getOperand(0).getReg();
3509 SrcReg = MI.getOperand(1).getReg();
3510 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3511 return HexagonII::HCG_A;
3512 break;
3513 case Hexagon::A2_tfrsi:
3514 // Rd = #u6
3515 // Do not test for #u6 size since the const is getting extended
3516 // regardless and compound could be formed.
3517 DstReg = MI.getOperand(0).getReg();
3518 if (isIntRegForSubInst(DstReg))
3519 return HexagonII::HCG_A;
3520 break;
3521 case Hexagon::S2_tstbit_i:
3522 DstReg = MI.getOperand(0).getReg();
3523 Src1Reg = MI.getOperand(1).getReg();
3524 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3525 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3526 MI.getOperand(2).isImm() &&
3527 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))
3528 return HexagonII::HCG_A;
3529 break;
3530 // The fact that .new form is used pretty much guarantees
3531 // that predicate register will match. Nevertheless,
3532 // there could be some false positives without additional
3533 // checking.
3534 case Hexagon::J2_jumptnew:
3535 case Hexagon::J2_jumpfnew:
3536 case Hexagon::J2_jumptnewpt:
3537 case Hexagon::J2_jumpfnewpt:
3538 Src1Reg = MI.getOperand(0).getReg();
3539 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3540 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3541 return HexagonII::HCG_B;
3542 break;
3543 // Transfer and jump:
3544 // Rd=#U6 ; jump #r9:2
3545 // Rd=Rs ; jump #r9:2
3546 // Do not test for jump range here.
3547 case Hexagon::J2_jump:
3548 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3549 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
3550 return HexagonII::HCG_C;
3551 }
3552
3553 return HexagonII::HCG_None;
3554}
3555
3556// Returns -1 when there is no opcode found.
3558 const MachineInstr &GB) const {
3561 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
3562 (GB.getOpcode() != Hexagon::J2_jumptnew))
3563 return -1u;
3564 Register DestReg = GA.getOperand(0).getReg();
3565 if (!GB.readsRegister(DestReg, /*TRI=*/nullptr))
3566 return -1u;
3567 if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)
3568 return -1u;
3569 // The value compared against must be either u5 or -1.
3570 const MachineOperand &CmpOp = GA.getOperand(2);
3571 if (!CmpOp.isImm())
3572 return -1u;
3573 int V = CmpOp.getImm();
3574 if (V == -1)
3575 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt
3576 : Hexagon::J4_cmpeqn1_tp1_jump_nt;
3577 if (!isUInt<5>(V))
3578 return -1u;
3579 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt
3580 : Hexagon::J4_cmpeqi_tp1_jump_nt;
3581}
3582
3583// Returns -1 if there is no opcode found.
3585 bool ForBigCore) const {
3586 // Static table to switch the opcodes across Tiny Core and Big Core.
3587 // dup_ opcodes are Big core opcodes.
3588 // NOTE: There are special instructions that need to handled later.
3589 // L4_return* instructions, they will only occupy SLOT0 (on big core too).
3590 // PS_jmpret - This pseudo translates to J2_jumpr which occupies only SLOT2.
3591 // The compiler need to base the root instruction to L6_return_map_to_raw
3592 // which can go any slot.
3593 static const std::map<unsigned, unsigned> DupMap = {
3594 {Hexagon::A2_add, Hexagon::dup_A2_add},
3595 {Hexagon::A2_addi, Hexagon::dup_A2_addi},
3596 {Hexagon::A2_andir, Hexagon::dup_A2_andir},
3597 {Hexagon::A2_combineii, Hexagon::dup_A2_combineii},
3598 {Hexagon::A2_sxtb, Hexagon::dup_A2_sxtb},
3599 {Hexagon::A2_sxth, Hexagon::dup_A2_sxth},
3600 {Hexagon::A2_tfr, Hexagon::dup_A2_tfr},
3601 {Hexagon::A2_tfrsi, Hexagon::dup_A2_tfrsi},
3602 {Hexagon::A2_zxtb, Hexagon::dup_A2_zxtb},
3603 {Hexagon::A2_zxth, Hexagon::dup_A2_zxth},
3604 {Hexagon::A4_combineii, Hexagon::dup_A4_combineii},
3605 {Hexagon::A4_combineir, Hexagon::dup_A4_combineir},
3606 {Hexagon::A4_combineri, Hexagon::dup_A4_combineri},
3607 {Hexagon::C2_cmoveif, Hexagon::dup_C2_cmoveif},
3608 {Hexagon::C2_cmoveit, Hexagon::dup_C2_cmoveit},
3609 {Hexagon::C2_cmovenewif, Hexagon::dup_C2_cmovenewif},
3610 {Hexagon::C2_cmovenewit, Hexagon::dup_C2_cmovenewit},
3611 {Hexagon::C2_cmpeqi, Hexagon::dup_C2_cmpeqi},
3612 {Hexagon::L2_deallocframe, Hexagon::dup_L2_deallocframe},
3613 {Hexagon::L2_loadrb_io, Hexagon::dup_L2_loadrb_io},
3614 {Hexagon::L2_loadrd_io, Hexagon::dup_L2_loadrd_io},
3615 {Hexagon::L2_loadrh_io, Hexagon::dup_L2_loadrh_io},
3616 {Hexagon::L2_loadri_io, Hexagon::dup_L2_loadri_io},
3617 {Hexagon::L2_loadrub_io, Hexagon::dup_L2_loadrub_io},
3618 {Hexagon::L2_loadruh_io, Hexagon::dup_L2_loadruh_io},
3619 {Hexagon::S2_allocframe, Hexagon::dup_S2_allocframe},
3620 {Hexagon::S2_storerb_io, Hexagon::dup_S2_storerb_io},
3621 {Hexagon::S2_storerd_io, Hexagon::dup_S2_storerd_io},
3622 {Hexagon::S2_storerh_io, Hexagon::dup_S2_storerh_io},
3623 {Hexagon::S2_storeri_io, Hexagon::dup_S2_storeri_io},
3624 {Hexagon::S4_storeirb_io, Hexagon::dup_S4_storeirb_io},
3625 {Hexagon::S4_storeiri_io, Hexagon::dup_S4_storeiri_io},
3626 };
3627 unsigned OpNum = MI.getOpcode();
3628 // Conversion to Big core.
3629 if (ForBigCore) {
3630 auto Iter = DupMap.find(OpNum);
3631 if (Iter != DupMap.end())
3632 return Iter->second;
3633 } else { // Conversion to Tiny core.
3634 for (const auto &Iter : DupMap)
3635 if (Iter.second == OpNum)
3636 return Iter.first;
3637 }
3638 return -1;
3639}
3640
3641int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3642 enum Hexagon::PredSense inPredSense;
3643 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3644 Hexagon::PredSense_true;
3645 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3646 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3647 return CondOpcode;
3648
3649 llvm_unreachable("Unexpected predicable instruction");
3650}
3651
3652// Return the cur value instruction for a given store.
3654 switch (MI.getOpcode()) {
3655 default: llvm_unreachable("Unknown .cur type");
3656 case Hexagon::V6_vL32b_pi:
3657 return Hexagon::V6_vL32b_cur_pi;
3658 case Hexagon::V6_vL32b_ai:
3659 return Hexagon::V6_vL32b_cur_ai;
3660 case Hexagon::V6_vL32b_nt_pi:
3661 return Hexagon::V6_vL32b_nt_cur_pi;
3662 case Hexagon::V6_vL32b_nt_ai:
3663 return Hexagon::V6_vL32b_nt_cur_ai;
3664 case Hexagon::V6_vL32b_ppu:
3665 return Hexagon::V6_vL32b_cur_ppu;
3666 case Hexagon::V6_vL32b_nt_ppu:
3667 return Hexagon::V6_vL32b_nt_cur_ppu;
3668 }
3669 return 0;
3670}
3671
3672// Return the regular version of the .cur instruction.
3674 switch (MI.getOpcode()) {
3675 default: llvm_unreachable("Unknown .cur type");
3676 case Hexagon::V6_vL32b_cur_pi:
3677 return Hexagon::V6_vL32b_pi;
3678 case Hexagon::V6_vL32b_cur_ai:
3679 return Hexagon::V6_vL32b_ai;
3680 case Hexagon::V6_vL32b_nt_cur_pi:
3681 return Hexagon::V6_vL32b_nt_pi;
3682 case Hexagon::V6_vL32b_nt_cur_ai:
3683 return Hexagon::V6_vL32b_nt_ai;
3684 case Hexagon::V6_vL32b_cur_ppu:
3685 return Hexagon::V6_vL32b_ppu;
3686 case Hexagon::V6_vL32b_nt_cur_ppu:
3687 return Hexagon::V6_vL32b_nt_ppu;
3688 }
3689 return 0;
3690}
3691
3692// The diagram below shows the steps involved in the conversion of a predicated
3693// store instruction to its .new predicated new-value form.
3694//
3695// Note: It doesn't include conditional new-value stores as they can't be
3696// converted to .new predicate.
3697//
3698// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3699// ^ ^
3700// / \ (not OK. it will cause new-value store to be
3701// / X conditional on p0.new while R2 producer is
3702// / \ on p0)
3703// / \.
3704// p.new store p.old NV store
3705// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3706// ^ ^
3707// \ /
3708// \ /
3709// \ /
3710// p.old store
3711// [if (p0)memw(R0+#0)=R2]
3712//
3713// The following set of instructions further explains the scenario where
3714// conditional new-value store becomes invalid when promoted to .new predicate
3715// form.
3716//
3717// { 1) if (p0) r0 = add(r1, r2)
3718// 2) p0 = cmp.eq(r3, #0) }
3719//
3720// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3721// the first two instructions because in instr 1, r0 is conditional on old value
3722// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3723// is not valid for new-value stores.
3724// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3725// from the "Conditional Store" list. Because a predicated new value store
3726// would NOT be promoted to a double dot new store. See diagram below:
3727// This function returns yes for those stores that are predicated but not
3728// yet promoted to predicate dot new instructions.
3729//
3730// +---------------------+
3731// /-----| if (p0) memw(..)=r0 |---------\~
3732// || +---------------------+ ||
3733// promote || /\ /\ || promote
3734// || /||\ /||\ ||
3735// \||/ demote || \||/
3736// \/ || || \/
3737// +-------------------------+ || +-------------------------+
3738// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3739// +-------------------------+ || +-------------------------+
3740// || || ||
3741// || demote \||/
3742// promote || \/ NOT possible
3743// || || /\~
3744// \||/ || /||\~
3745// \/ || ||
3746// +-----------------------------+
3747// | if (p0.new) memw(..)=r0.new |
3748// +-----------------------------+
3749// Double Dot New Store
3750//
3751// Returns the most basic instruction for the .new predicated instructions and
3752// new-value stores.
3753// For example, all of the following instructions will be converted back to the
3754// same instruction:
3755// 1) if (p0.new) memw(R0+#0) = R1.new --->
3756// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3757// 3) if (p0.new) memw(R0+#0) = R1 --->
3758//
3759// To understand the translation of instruction 1 to its original form, consider
3760// a packet with 3 instructions.
3761// { p0 = cmp.eq(R0,R1)
3762// if (p0.new) R2 = add(R3, R4)
3763// R5 = add (R3, R1)
3764// }
3765// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3766//
3767// This instruction can be part of the previous packet only if both p0 and R2
3768// are promoted to .new values. This promotion happens in steps, first
3769// predicate register is promoted to .new and in the next iteration R2 is
3770// promoted. Therefore, in case of dependence check failure (due to R5) during
3771// next iteration, it should be converted back to its most basic form.
3772
3773// Return the new value instruction for a given store.
3775 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());
3776 if (NVOpcode >= 0) // Valid new-value store instruction.
3777 return NVOpcode;
3778
3779 switch (MI.getOpcode()) {
3780 default:
3781 report_fatal_error(Twine("Unknown .new type: ") +
3782 std::to_string(MI.getOpcode()));
3783 case Hexagon::S4_storerb_ur:
3784 return Hexagon::S4_storerbnew_ur;
3785
3786 case Hexagon::S2_storerb_pci:
3787 return Hexagon::S2_storerb_pci;
3788
3789 case Hexagon::S2_storeri_pci:
3790 return Hexagon::S2_storeri_pci;
3791
3792 case Hexagon::S2_storerh_pci:
3793 return Hexagon::S2_storerh_pci;
3794
3795 case Hexagon::S2_storerd_pci:
3796 return Hexagon::S2_storerd_pci;
3797
3798 case Hexagon::S2_storerf_pci:
3799 return Hexagon::S2_storerf_pci;
3800
3801 case Hexagon::V6_vS32b_ai:
3802 return Hexagon::V6_vS32b_new_ai;
3803
3804 case Hexagon::V6_vS32b_pi:
3805 return Hexagon::V6_vS32b_new_pi;
3806 }
3807 return 0;
3808}
3809
3810// Returns the opcode to use when converting MI, which is a conditional jump,
3811// into a conditional instruction which uses the .new value of the predicate.
3812// We also use branch probabilities to add a hint to the jump.
3813// If MBPI is null, all edges will be treated as equally likely for the
3814// purposes of establishing a predication hint.
3816 const MachineBranchProbabilityInfo *MBPI) const {
3817 // We assume that block can have at most two successors.
3818 const MachineBasicBlock *Src = MI.getParent();
3819 const MachineOperand &BrTarget = MI.getOperand(1);
3820 bool Taken = false;
3821 const BranchProbability OneHalf(1, 2);
3822
3823 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
3824 const MachineBasicBlock *Dst) {
3825 if (MBPI)
3826 return MBPI->getEdgeProbability(Src, Dst);
3827 return BranchProbability(1, Src->succ_size());
3828 };
3829
3830 if (BrTarget.isMBB()) {
3831 const MachineBasicBlock *Dst = BrTarget.getMBB();
3832 Taken = getEdgeProbability(Src, Dst) >= OneHalf;
3833 } else {
3834 // The branch target is not a basic block (most likely a function).
3835 // Since BPI only gives probabilities for targets that are basic blocks,
3836 // try to identify another target of this branch (potentially a fall-
3837 // -through) and check the probability of that target.
3838 //
3839 // The only handled branch combinations are:
3840 // - one conditional branch,
3841 // - one conditional branch followed by one unconditional branch.
3842 // Otherwise, assume not-taken.
3843 assert(MI.isConditionalBranch());
3844 const MachineBasicBlock &B = *MI.getParent();
3845 bool SawCond = false, Bad = false;
3846 for (const MachineInstr &I : B) {
3847 if (!I.isBranch())
3848 continue;
3849 if (I.isConditionalBranch()) {
3850 SawCond = true;
3851 if (&I != &MI) {
3852 Bad = true;
3853 break;
3854 }
3855 }
3856 if (I.isUnconditionalBranch() && !SawCond) {
3857 Bad = true;
3858 break;
3859 }
3860 }
3861 if (!Bad) {
3863 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
3864 if (NextIt == B.instr_end()) {
3865 // If this branch is the last, look for the fall-through block.
3866 for (const MachineBasicBlock *SB : B.successors()) {
3867 if (!B.isLayoutSuccessor(SB))
3868 continue;
3869 Taken = getEdgeProbability(Src, SB) < OneHalf;
3870 break;
3871 }
3872 } else {
3873 assert(NextIt->isUnconditionalBranch());
3874 // Find the first MBB operand and assume it's the target.
3875 const MachineBasicBlock *BT = nullptr;
3876 for (const MachineOperand &Op : NextIt->operands()) {
3877 if (!Op.isMBB())
3878 continue;
3879 BT = Op.getMBB();
3880 break;
3881 }
3882 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
3883 }
3884 } // if (!Bad)
3885 }
3886
3887 // The Taken flag should be set to something reasonable by this point.
3888
3889 switch (MI.getOpcode()) {
3890 case Hexagon::J2_jumpt:
3891 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
3892 case Hexagon::J2_jumpf:
3893 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
3894
3895 default:
3896 llvm_unreachable("Unexpected jump instruction.");
3897 }
3898}
3899
3900// Return .new predicate version for an instruction.
3902 const MachineBranchProbabilityInfo *MBPI) const {
3903 switch (MI.getOpcode()) {
3904 // Conditional Jumps
3905 case Hexagon::J2_jumpt:
3906 case Hexagon::J2_jumpf:
3907 return getDotNewPredJumpOp(MI, MBPI);
3908 }
3909
3910 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
3911 if (NewOpcode >= 0)
3912 return NewOpcode;
3913 return 0;
3914}
3915
3917 int NewOp = MI.getOpcode();
3918 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3919 NewOp = Hexagon::getPredOldOpcode(NewOp);
3920 // All Hexagon architectures have prediction bits on dot-new branches,
3921 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure
3922 // to pick the right opcode when converting back to dot-old.
3923 if (!Subtarget.hasFeature(Hexagon::ArchV60)) {
3924 switch (NewOp) {
3925 case Hexagon::J2_jumptpt:
3926 NewOp = Hexagon::J2_jumpt;
3927 break;
3928 case Hexagon::J2_jumpfpt:
3929 NewOp = Hexagon::J2_jumpf;
3930 break;
3931 case Hexagon::J2_jumprtpt:
3932 NewOp = Hexagon::J2_jumprt;
3933 break;
3934 case Hexagon::J2_jumprfpt:
3935 NewOp = Hexagon::J2_jumprf;
3936 break;
3937 }
3938 }
3939 assert(NewOp >= 0 &&
3940 "Couldn't change predicate new instruction to its old form.");
3941 }
3942
3943 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3944 NewOp = Hexagon::getNonNVStore(NewOp);
3945 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3946 }
3947
3948 if (Subtarget.hasV60Ops())
3949 return NewOp;
3950
3951 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.
3952 switch (NewOp) {
3953 case Hexagon::J2_jumpfpt:
3954 return Hexagon::J2_jumpf;
3955 case Hexagon::J2_jumptpt:
3956 return Hexagon::J2_jumpt;
3957 case Hexagon::J2_jumprfpt:
3958 return Hexagon::J2_jumprf;
3959 case Hexagon::J2_jumprtpt:
3960 return Hexagon::J2_jumprt;
3961 }
3962 return NewOp;
3963}
3964
3965// See if instruction could potentially be a duplex candidate.
3966// If so, return its group. Zero otherwise.
3968 const MachineInstr &MI) const {
3969 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3970 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
3971
3972 switch (MI.getOpcode()) {
3973 default:
3974 return HexagonII::HSIG_None;
3975 //
3976 // Group L1:
3977 //
3978 // Rd = memw(Rs+#u4:2)
3979 // Rd = memub(Rs+#u4:0)
3980 case Hexagon::L2_loadri_io:
3981 case Hexagon::dup_L2_loadri_io:
3982 DstReg = MI.getOperand(0).getReg();
3983 SrcReg = MI.getOperand(1).getReg();
3984 // Special case this one from Group L2.
3985 // Rd = memw(r29+#u5:2)
3986 if (isIntRegForSubInst(DstReg)) {
3987 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3988 HRI.getStackRegister() == SrcReg &&
3989 MI.getOperand(2).isImm() &&
3990 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))
3991 return HexagonII::HSIG_L2;
3992 // Rd = memw(Rs+#u4:2)
3993 if (isIntRegForSubInst(SrcReg) &&
3994 (MI.getOperand(2).isImm() &&
3995 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))
3996 return HexagonII::HSIG_L1;
3997 }
3998 break;
3999 case Hexagon::L2_loadrub_io:
4000 case Hexagon::dup_L2_loadrub_io:
4001 // Rd = memub(Rs+#u4:0)
4002 DstReg = MI.getOperand(0).getReg();
4003 SrcReg = MI.getOperand(1).getReg();
4004 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4005 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))
4006 return HexagonII::HSIG_L1;
4007 break;
4008 //
4009 // Group L2:
4010 //
4011 // Rd = memh/memuh(Rs+#u3:1)
4012 // Rd = memb(Rs+#u3:0)
4013 // Rd = memw(r29+#u5:2) - Handled above.
4014 // Rdd = memd(r29+#u5:3)
4015 // deallocframe
4016 // [if ([!]p0[.new])] dealloc_return
4017 // [if ([!]p0[.new])] jumpr r31
4018 case Hexagon::L2_loadrh_io:
4019 case Hexagon::L2_loadruh_io:
4020 case Hexagon::dup_L2_loadrh_io:
4021 case Hexagon::dup_L2_loadruh_io:
4022 // Rd = memh/memuh(Rs+#u3:1)
4023 DstReg = MI.getOperand(0).getReg();
4024 SrcReg = MI.getOperand(1).getReg();
4025 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4026 MI.getOperand(2).isImm() &&
4027 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))
4028 return HexagonII::HSIG_L2;
4029 break;
4030 case Hexagon::L2_loadrb_io:
4031 case Hexagon::dup_L2_loadrb_io:
4032 // Rd = memb(Rs+#u3:0)
4033 DstReg = MI.getOperand(0).getReg();
4034 SrcReg = MI.getOperand(1).getReg();
4035 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4036 MI.getOperand(2).isImm() &&
4037 isUInt<3>(MI.getOperand(2).getImm()))
4038 return HexagonII::HSIG_L2;
4039 break;
4040 case Hexagon::L2_loadrd_io:
4041 case Hexagon::dup_L2_loadrd_io:
4042 // Rdd = memd(r29+#u5:3)
4043 DstReg = MI.getOperand(0).getReg();
4044 SrcReg = MI.getOperand(1).getReg();
4045 if (isDblRegForSubInst(DstReg, HRI) &&
4046 Hexagon::IntRegsRegClass.contains(SrcReg) &&
4047 HRI.getStackRegister() == SrcReg &&
4048 MI.getOperand(2).isImm() &&
4049 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4050 return HexagonII::HSIG_L2;
4051 break;
4052 // dealloc_return is not documented in Hexagon Manual, but marked
4053 // with A_SUBINSN attribute in iset_v4classic.py.
4054 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
4055 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
4056 case Hexagon::L4_return:
4057 case Hexagon::L2_deallocframe:
4058 case Hexagon::dup_L2_deallocframe:
4059 return HexagonII::HSIG_L2;
4060 case Hexagon::EH_RETURN_JMPR:
4061 case Hexagon::PS_jmpret:
4062 case Hexagon::SL2_jumpr31:
4063 // jumpr r31
4064 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0
4065 DstReg = MI.getOperand(0).getReg();
4066 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
4067 return HexagonII::HSIG_L2;
4068 break;
4069 case Hexagon::PS_jmprett:
4070 case Hexagon::PS_jmpretf:
4071 case Hexagon::PS_jmprettnewpt:
4072 case Hexagon::PS_jmpretfnewpt:
4073 case Hexagon::PS_jmprettnew:
4074 case Hexagon::PS_jmpretfnew:
4075 case Hexagon::SL2_jumpr31_t:
4076 case Hexagon::SL2_jumpr31_f:
4077 case Hexagon::SL2_jumpr31_tnew:
4078 case Hexagon::SL2_jumpr31_fnew:
4079 DstReg = MI.getOperand(1).getReg();
4080 SrcReg = MI.getOperand(0).getReg();
4081 // [if ([!]p0[.new])] jumpr r31
4082 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
4083 (Hexagon::P0 == SrcReg)) &&
4084 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
4085 return HexagonII::HSIG_L2;
4086 break;
4087 case Hexagon::L4_return_t:
4088 case Hexagon::L4_return_f:
4089 case Hexagon::L4_return_tnew_pnt:
4090 case Hexagon::L4_return_fnew_pnt:
4091 case Hexagon::L4_return_tnew_pt:
4092 case Hexagon::L4_return_fnew_pt:
4093 // [if ([!]p0[.new])] dealloc_return
4094 SrcReg = MI.getOperand(0).getReg();
4095 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
4096 return HexagonII::HSIG_L2;
4097 break;
4098 //
4099 // Group S1:
4100 //
4101 // memw(Rs+#u4:2) = Rt
4102 // memb(Rs+#u4:0) = Rt
4103 case Hexagon::S2_storeri_io:
4104 case Hexagon::dup_S2_storeri_io:
4105 // Special case this one from Group S2.
4106 // memw(r29+#u5:2) = Rt
4107 Src1Reg = MI.getOperand(0).getReg();
4108 Src2Reg = MI.getOperand(2).getReg();
4109 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4110 isIntRegForSubInst(Src2Reg) &&
4111 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4112 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))
4113 return HexagonII::HSIG_S2;
4114 // memw(Rs+#u4:2) = Rt
4115 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4116 MI.getOperand(1).isImm() &&
4117 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))
4118 return HexagonII::HSIG_S1;
4119 break;
4120 case Hexagon::S2_storerb_io:
4121 case Hexagon::dup_S2_storerb_io:
4122 // memb(Rs+#u4:0) = Rt
4123 Src1Reg = MI.getOperand(0).getReg();
4124 Src2Reg = MI.getOperand(2).getReg();
4125 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4126 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))
4127 return HexagonII::HSIG_S1;
4128 break;
4129 //
4130 // Group S2:
4131 //
4132 // memh(Rs+#u3:1) = Rt
4133 // memw(r29+#u5:2) = Rt
4134 // memd(r29+#s6:3) = Rtt
4135 // memw(Rs+#u4:2) = #U1
4136 // memb(Rs+#u4) = #U1
4137 // allocframe(#u5:3)
4138 case Hexagon::S2_storerh_io:
4139 case Hexagon::dup_S2_storerh_io:
4140 // memh(Rs+#u3:1) = Rt
4141 Src1Reg = MI.getOperand(0).getReg();
4142 Src2Reg = MI.getOperand(2).getReg();
4143 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4144 MI.getOperand(1).isImm() &&
4145 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))
4146 return HexagonII::HSIG_S1;
4147 break;
4148 case Hexagon::S2_storerd_io:
4149 case Hexagon::dup_S2_storerd_io:
4150 // memd(r29+#s6:3) = Rtt
4151 Src1Reg = MI.getOperand(0).getReg();
4152 Src2Reg = MI.getOperand(2).getReg();
4153 if (isDblRegForSubInst(Src2Reg, HRI) &&
4154 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4155 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4156 isShiftedInt<6,3>(MI.getOperand(1).getImm()))
4157 return HexagonII::HSIG_S2;
4158 break;
4159 case Hexagon::S4_storeiri_io:
4160 case Hexagon::dup_S4_storeiri_io:
4161 // memw(Rs+#u4:2) = #U1
4162 Src1Reg = MI.getOperand(0).getReg();
4163 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&
4164 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&
4165 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4166 return HexagonII::HSIG_S2;
4167 break;
4168 case Hexagon::S4_storeirb_io:
4169 case Hexagon::dup_S4_storeirb_io:
4170 // memb(Rs+#u4) = #U1
4171 Src1Reg = MI.getOperand(0).getReg();
4172 if (isIntRegForSubInst(Src1Reg) &&
4173 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&
4174 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4175 return HexagonII::HSIG_S2;
4176 break;
4177 case Hexagon::S2_allocframe:
4178 case Hexagon::dup_S2_allocframe:
4179 if (MI.getOperand(2).isImm() &&
4180 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4181 return HexagonII::HSIG_S1;
4182 break;
4183 //
4184 // Group A:
4185 //
4186 // Rx = add(Rx,#s7)
4187 // Rd = Rs
4188 // Rd = #u6
4189 // Rd = #-1
4190 // if ([!]P0[.new]) Rd = #0
4191 // Rd = add(r29,#u6:2)
4192 // Rx = add(Rx,Rs)
4193 // P0 = cmp.eq(Rs,#u2)
4194 // Rdd = combine(#0,Rs)
4195 // Rdd = combine(Rs,#0)
4196 // Rdd = combine(#u2,#U2)
4197 // Rd = add(Rs,#1)
4198 // Rd = add(Rs,#-1)
4199 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4200 // Rd = and(Rs,#1)
4201 case Hexagon::A2_addi:
4202 case Hexagon::dup_A2_addi:
4203 DstReg = MI.getOperand(0).getReg();
4204 SrcReg = MI.getOperand(1).getReg();
4205 if (isIntRegForSubInst(DstReg)) {
4206 // Rd = add(r29,#u6:2)
4207 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
4208 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&
4209 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))
4210 return HexagonII::HSIG_A;
4211 // Rx = add(Rx,#s7)
4212 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&
4213 isInt<7>(MI.getOperand(2).getImm()))
4214 return HexagonII::HSIG_A;
4215 // Rd = add(Rs,#1)
4216 // Rd = add(Rs,#-1)
4217 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
4218 ((MI.getOperand(2).getImm() == 1) ||
4219 (MI.getOperand(2).getImm() == -1)))
4220 return HexagonII::HSIG_A;
4221 }
4222 break;
4223 case Hexagon::A2_add:
4224 case Hexagon::dup_A2_add:
4225 // Rx = add(Rx,Rs)
4226 DstReg = MI.getOperand(0).getReg();
4227 Src1Reg = MI.getOperand(1).getReg();
4228 Src2Reg = MI.getOperand(2).getReg();
4229 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
4230 isIntRegForSubInst(Src2Reg))
4231 return HexagonII::HSIG_A;
4232 break;
4233 case Hexagon::A2_andir:
4234 case Hexagon::dup_A2_andir:
4235 // Same as zxtb.
4236 // Rd16=and(Rs16,#255)
4237 // Rd16=and(Rs16,#1)
4238 DstReg = MI.getOperand(0).getReg();
4239 SrcReg = MI.getOperand(1).getReg();
4240 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4241 MI.getOperand(2).isImm() &&
4242 ((MI.getOperand(2).getImm() == 1) ||
4243 (MI.getOperand(2).getImm() == 255)))
4244 return HexagonII::HSIG_A;
4245 break;
4246 case Hexagon::A2_tfr:
4247 case Hexagon::dup_A2_tfr:
4248 // Rd = Rs
4249 DstReg = MI.getOperand(0).getReg();
4250 SrcReg = MI.getOperand(1).getReg();
4251 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4252 return HexagonII::HSIG_A;
4253 break;
4254 case Hexagon::A2_tfrsi:
4255 case Hexagon::dup_A2_tfrsi:
4256 // Rd = #u6
4257 // Do not test for #u6 size since the const is getting extended
4258 // regardless and compound could be formed.
4259 // Rd = #-1
4260 DstReg = MI.getOperand(0).getReg();
4261 if (isIntRegForSubInst(DstReg))
4262 return HexagonII::HSIG_A;
4263 break;
4264 case Hexagon::C2_cmoveit:
4265 case Hexagon::C2_cmovenewit:
4266 case Hexagon::C2_cmoveif:
4267 case Hexagon::C2_cmovenewif:
4268 case Hexagon::dup_C2_cmoveit:
4269 case Hexagon::dup_C2_cmovenewit:
4270 case Hexagon::dup_C2_cmoveif:
4271 case Hexagon::dup_C2_cmovenewif:
4272 // if ([!]P0[.new]) Rd = #0
4273 // Actual form:
4274 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
4275 DstReg = MI.getOperand(0).getReg();
4276 SrcReg = MI.getOperand(1).getReg();
4277 if (isIntRegForSubInst(DstReg) &&
4278 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
4279 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)
4280 return HexagonII::HSIG_A;
4281 break;
4282 case Hexagon::C2_cmpeqi:
4283 case Hexagon::dup_C2_cmpeqi:
4284 // P0 = cmp.eq(Rs,#u2)
4285 DstReg = MI.getOperand(0).getReg();
4286 SrcReg = MI.getOperand(1).getReg();
4287 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
4288 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
4289 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))
4290 return HexagonII::HSIG_A;
4291 break;
4292 case Hexagon::A2_combineii:
4293 case Hexagon::A4_combineii:
4294 case Hexagon::dup_A2_combineii:
4295 case Hexagon::dup_A4_combineii:
4296 // Rdd = combine(#u2,#U2)
4297 DstReg = MI.getOperand(0).getReg();
4298 if (isDblRegForSubInst(DstReg, HRI) &&
4299 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||
4300 (MI.getOperand(1).isGlobal() &&
4301 isUInt<2>(MI.getOperand(1).getOffset()))) &&
4302 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||
4303 (MI.getOperand(2).isGlobal() &&
4304 isUInt<2>(MI.getOperand(2).getOffset()))))
4305 return HexagonII::HSIG_A;
4306 break;
4307 case Hexagon::A4_combineri:
4308 case Hexagon::dup_A4_combineri:
4309 // Rdd = combine(Rs,#0)
4310 // Rdd = combine(Rs,#0)
4311 DstReg = MI.getOperand(0).getReg();
4312 SrcReg = MI.getOperand(1).getReg();
4313 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4314 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||
4315 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))
4316 return HexagonII::HSIG_A;
4317 break;
4318 case Hexagon::A4_combineir:
4319 case Hexagon::dup_A4_combineir:
4320 // Rdd = combine(#0,Rs)
4321 DstReg = MI.getOperand(0).getReg();
4322 SrcReg = MI.getOperand(2).getReg();
4323 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4324 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||
4325 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))
4326 return HexagonII::HSIG_A;
4327 break;
4328 case Hexagon::A2_sxtb:
4329 case Hexagon::A2_sxth:
4330 case Hexagon::A2_zxtb:
4331 case Hexagon::A2_zxth:
4332 case Hexagon::dup_A2_sxtb:
4333 case Hexagon::dup_A2_sxth:
4334 case Hexagon::dup_A2_zxtb:
4335 case Hexagon::dup_A2_zxth:
4336 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4337 DstReg = MI.getOperand(0).getReg();
4338 SrcReg = MI.getOperand(1).getReg();
4339 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4340 return HexagonII::HSIG_A;
4341 break;
4342 }
4343
4344 return HexagonII::HSIG_None;
4345}
4346
4348 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real);
4349}
4350
4352 const InstrItineraryData *ItinData, const MachineInstr &MI) const {
4353 // Default to one cycle for no itinerary. However, an "empty" itinerary may
4354 // still have a MinLatency property, which getStageLatency checks.
4355 if (!ItinData)
4356 return getInstrLatency(ItinData, MI);
4357
4358 if (MI.isTransient())
4359 return 0;
4360 return ItinData->getStageLatency(MI.getDesc().getSchedClass());
4361}
4362
4363/// getOperandLatency - Compute and return the use operand latency of a given
4364/// pair of def and use.
4365/// In most cases, the static scheduling itinerary was enough to determine the
4366/// operand latency. But it may not be possible for instructions with variable
4367/// number of defs / uses.
4368///
4369/// This is a raw interface to the itinerary that may be directly overridden by
4370/// a target. Use computeOperandLatency to get the best estimate of latency.
4372 const InstrItineraryData *ItinData, const MachineInstr &DefMI,
4373 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
4374 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4375
4376 // Get DefIdx and UseIdx for super registers.
4377 const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
4378
4379 if (DefMO.isReg() && DefMO.getReg().isPhysical()) {
4380 if (DefMO.isImplicit()) {
4381 for (MCPhysReg SR : HRI.superregs(DefMO.getReg())) {
4382 int Idx = DefMI.findRegisterDefOperandIdx(SR, &HRI, false, false);
4383 if (Idx != -1) {
4384 DefIdx = Idx;
4385 break;
4386 }
4387 }
4388 }
4389
4390 const MachineOperand &UseMO = UseMI.getOperand(UseIdx);
4391 if (UseMO.isImplicit()) {
4392 for (MCPhysReg SR : HRI.superregs(UseMO.getReg())) {
4393 int Idx = UseMI.findRegisterUseOperandIdx(SR, &HRI, false);
4394 if (Idx != -1) {
4395 UseIdx = Idx;
4396 break;
4397 }
4398 }
4399 }
4400 }
4401
4402 std::optional<unsigned> Latency = TargetInstrInfo::getOperandLatency(
4403 ItinData, DefMI, DefIdx, UseMI, UseIdx);
4404 if (Latency == 0)
4405 // We should never have 0 cycle latency between two instructions unless
4406 // they can be packetized together. However, this decision can't be made
4407 // here.
4408 Latency = 1;
4409 return Latency;
4410}
4411
4412// inverts the predication logic.
4413// p -> NotP
4414// NotP -> P
4417 if (Cond.empty())
4418 return false;
4419 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
4420 Cond[0].setImm(Opc);
4421 return true;
4422}
4423
4425 int InvPredOpcode;
4426 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
4427 : Hexagon::getTruePredOpcode(Opc);
4428 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
4429 return InvPredOpcode;
4430
4431 llvm_unreachable("Unexpected predicated instruction");
4432}
4433
4434// Returns the max value that doesn't need to be extended.
4436 const uint64_t F = MI.getDesc().TSFlags;
4437 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4439 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4441
4442 if (isSigned) // if value is signed
4443 return ~(-1U << (bits - 1));
4444 else
4445 return ~(-1U << bits);
4446}
4447
4448
4450 switch (MI.getOpcode()) {
4451 case Hexagon::L2_loadrbgp:
4452 case Hexagon::L2_loadrdgp:
4453 case Hexagon::L2_loadrhgp:
4454 case Hexagon::L2_loadrigp:
4455 case Hexagon::L2_loadrubgp:
4456 case Hexagon::L2_loadruhgp:
4457 case Hexagon::S2_storerbgp:
4458 case Hexagon::S2_storerbnewgp:
4459 case Hexagon::S2_storerhgp:
4460 case Hexagon::S2_storerhnewgp:
4461 case Hexagon::S2_storerigp:
4462 case Hexagon::S2_storerinewgp:
4463 case Hexagon::S2_storerdgp:
4464 case Hexagon::S2_storerfgp:
4465 return true;
4466 }
4467 const uint64_t F = MI.getDesc().TSFlags;
4468 unsigned addrMode =
4470 // Disallow any base+offset instruction. The assembler does not yet reorder
4471 // based up any zero offset instruction.
4472 return (addrMode == HexagonII::BaseRegOffset ||
4473 addrMode == HexagonII::BaseImmOffset ||
4474 addrMode == HexagonII::BaseLongOffset);
4475}
4476
4478 // Workaround for the Global Scheduler. Sometimes, it creates
4479 // A4_ext as a Pseudo instruction and calls this function to see if
4480 // it can be added to an existing bundle. Since the instruction doesn't
4481 // belong to any BB yet, we can't use getUnits API.
4482 if (MI.getOpcode() == Hexagon::A4_ext)
4483 return false;
4484
4485 unsigned FuncUnits = getUnits(MI);
4486 return HexagonFUnits::isSlot0Only(FuncUnits);
4487}
4488
4490 const uint64_t F = MI.getDesc().TSFlags;
4493}
4494
4496 bool ToBigInstrs) const {
4497 int Opcode = -1;
4498 if (ToBigInstrs) { // To BigCore Instr.
4499 // Check if the instruction can form a Duplex.
4500 if (getDuplexCandidateGroup(*MII))
4501 // Get the opcode marked "dup_*" tag.
4502 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4503 } else // To TinyCore Instr.
4504 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4505
4506 // Change the opcode of the instruction.
4507 if (Opcode >= 0)
4508 MII->setDesc(get(Opcode));
4509}
4510
4511// This function is used to translate instructions to facilitate generating
4512// Duplexes on TinyCore.
4514 bool ToBigInstrs) const {
4515 for (auto &MB : MF)
4516 for (MachineBasicBlock::instr_iterator Instr = MB.instr_begin(),
4517 End = MB.instr_end();
4518 Instr != End; ++Instr)
4519 changeDuplexOpcode(Instr, ToBigInstrs);
4520}
4521
4522// This is a specialized form of above function.
4524 MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {
4525 MachineBasicBlock *MBB = MII->getParent();
4526 while ((MII != MBB->instr_end()) && MII->isInsideBundle()) {
4527 changeDuplexOpcode(MII, ToBigInstrs);
4528 ++MII;
4529 }
4530}
4531
4533 using namespace HexagonII;
4534
4535 const uint64_t F = MI.getDesc().TSFlags;
4536 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
4537 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
4538 if (Size != 0)
4539 return Size;
4540 // Y2_dcfetchbo is special
4541 if (MI.getOpcode() == Hexagon::Y2_dcfetchbo)
4543
4544 // Handle vector access sizes.
4545 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4546 switch (S) {
4548 return HRI.getSpillSize(Hexagon::HvxVRRegClass);
4549 default:
4550 llvm_unreachable("Unexpected instruction");
4551 }
4552}
4553
4554// Returns the min value that doesn't need to be extended.
4556 const uint64_t F = MI.getDesc().TSFlags;
4557 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4559 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4561
4562 if (isSigned) // if value is signed
4563 return -1U << (bits - 1);
4564 else
4565 return 0;
4566}
4567
4568// Returns opcode of the non-extended equivalent instruction.
4570 // Check if the instruction has a register form that uses register in place
4571 // of the extended operand, if so return that as the non-extended form.
4572 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());
4573 if (NonExtOpcode >= 0)
4574 return NonExtOpcode;
4575
4576 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
4577 // Check addressing mode and retrieve non-ext equivalent instruction.
4578 switch (getAddrMode(MI)) {
4580 return Hexagon::changeAddrMode_abs_io(MI.getOpcode());
4582 return Hexagon::changeAddrMode_io_rr(MI.getOpcode());
4584 return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
4585
4586 default:
4587 return -1;
4588 }
4589 }
4590 return -1;
4591}
4592
4594 Register &PredReg, unsigned &PredRegPos,
4595 RegState &PredRegFlags) const {
4596 if (Cond.empty())
4597 return false;
4598 assert(Cond.size() == 2);
4599 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
4600 LLVM_DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
4601 return false;
4602 }
4603 PredReg = Cond[1].getReg();
4604 PredRegPos = 1;
4605 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
4606 PredRegFlags = {};
4607 if (Cond[1].isImplicit())
4608 PredRegFlags = RegState::Implicit;
4609 if (Cond[1].isUndef())
4610 PredRegFlags |= RegState::Undef;
4611 return true;
4612}
4613
4615 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo);
4616}
4617
4619 return Hexagon::getRegForm(MI.getOpcode());
4620}
4621
4622// Return the number of bytes required to encode the instruction.
4623// Hexagon instructions are fixed length, 4 bytes, unless they
4624// use a constant extender, which requires another 4 bytes.
4625// For debug instructions and prolog labels, return 0.
4627 if (MI.isDebugInstr() || MI.isPosition())
4628 return 0;
4629
4630 unsigned Size = MI.getDesc().getSize();
4631 if (!Size)
4632 // Assume the default insn size in case it cannot be determined
4633 // for whatever reason.
4635
4638
4639 // Try and compute number of instructions in asm.
4640 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {
4641 const MachineBasicBlock &MBB = *MI.getParent();
4642 const MachineFunction *MF = MBB.getParent();
4643 const MCAsmInfo &MAI = MF->getTarget().getMCAsmInfo();
4644
4645 // Count the number of register definitions to find the asm string.
4646 unsigned NumDefs = 0;
4647 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();
4648 ++NumDefs)
4649 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");
4650
4651 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");
4652 // Disassemble the AsmStr and approximate number of instructions.
4653 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();
4654 Size = getInlineAsmLength(AsmStr, MAI);
4655 }
4656
4657 return Size;
4658}
4659
4661 const uint64_t F = MI.getDesc().TSFlags;
4663}
4664
4666 const InstrItineraryData &II = *Subtarget.getInstrItineraryData();
4667 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());
4668
4669 return IS.getUnits();
4670}
4671
4672// Calculate size of the basic block without debug instructions.
4674 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4675}
4676
4678 MachineBasicBlock::const_iterator BundleHead) const {
4679 assert(BundleHead->isBundle() && "Not a bundle header");
4680 auto MII = BundleHead.getInstrIterator();
4681 // Skip the bundle header.
4682 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));
4683}
4684
4685/// immediateExtend - Changes the instruction in place to one using an immediate
4686/// extender.
4689 "Instruction must be extendable");
4690 // Find which operand is extendable.
4691 short ExtOpNum = getCExtOpNum(MI);
4692 MachineOperand &MO = MI.getOperand(ExtOpNum);
4693 // This needs to be something we understand.
4694 assert((MO.isMBB() || MO.isImm()) &&
4695 "Branch with unknown extendable field type");
4696 // Mark given operand as extended.
4698}
4699
4701 MachineInstr &MI, MachineBasicBlock *NewTarget) const {
4702 LLVM_DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "
4703 << printMBBReference(*NewTarget);
4704 MI.dump(););
4705 assert(MI.isBranch());
4706 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());
4707 int TargetPos = MI.getNumOperands() - 1;
4708 // In general branch target is the last operand,
4709 // but some implicit defs added at the end might change it.
4710 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())
4711 --TargetPos;
4712 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());
4713 MI.getOperand(TargetPos).setMBB(NewTarget);
4715 NewOpcode = reversePrediction(NewOpcode);
4716 }
4717 MI.setDesc(get(NewOpcode));
4718 return true;
4719}
4720
4722 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4724 MachineBasicBlock &B = *A;
4726 DebugLoc DL = I->getDebugLoc();
4727 MachineInstr *NewMI;
4728
4729 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4730 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
4731 NewMI = BuildMI(B, I, DL, get(insn));
4732 LLVM_DEBUG(dbgs() << "\n"
4733 << getName(NewMI->getOpcode())
4734 << " Class: " << NewMI->getDesc().getSchedClass());
4735 NewMI->eraseFromParent();
4736 }
4737 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4738}
4739
4740// inverts the predication logic.
4741// p -> NotP
4742// NotP -> P
4744 LLVM_DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());
4745 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));
4746 return true;
4747}
4748
4749// Reverse the branch prediction.
4750unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4751 int PredRevOpcode = -1;
4752 if (isPredictedTaken(Opcode))
4753 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4754 else
4755 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4756 assert(PredRevOpcode > 0);
4757 return PredRevOpcode;
4758}
4759
4760// TODO: Add more rigorous validation.
4762 const {
4763 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4764}
4765
4768 assert(MIB->isBundle());
4769 MachineOperand &Operand = MIB->getOperand(0);
4770 if (Operand.isImm())
4771 Operand.setImm(Operand.getImm() | memShufDisabledMask);
4772 else
4773 MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));
4774}
4775
4777 assert(MIB.isBundle());
4778 const MachineOperand &Operand = MIB.getOperand(0);
4779 return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);
4780}
4781
4783 return (MI->getOpcode() == Hexagon::V6_vmpy_qf16_hf ||
4784 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||
4785 MI->getOpcode() == Hexagon::V6_vmpy_qf32_hf ||
4786 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||
4787 MI->getOpcode() == Hexagon::V6_vmpy_qf32_sf ||
4788 MI->getOpcode() == Hexagon::V6_vmpy_qf16_mix_hf ||
4789 MI->getOpcode() == Hexagon::V6_vmpy_qf16 ||
4790 MI->getOpcode() == Hexagon::V6_vmpy_qf32_mix_hf ||
4791 MI->getOpcode() == Hexagon::V6_vmpy_qf32_qf16 ||
4792 MI->getOpcode() == Hexagon::V6_vmpy_qf32);
4793}
4794
4795namespace llvm::HexagonII {
4796
4799 RegType In3 = RegType::Unknown) {
4800 RegTypeInfo I;
4801 I.Output = Out;
4802 I.Input1 = In1;
4803 I.Input2 = In2;
4804 I.Input3 = In3;
4805 return I;
4806}
4807
4808RegTypeInfo getRegTypeInfo(unsigned Opcode) {
4809 switch (Opcode) {
4810 default:
4811 return {};
4812
4813 case Hexagon::V6_vabs_qf16_hf:
4814 return make(RegType::QF16);
4815 case Hexagon::V6_vabs_qf16_qf16:
4817 case Hexagon::V6_vabs_qf32_qf32:
4819 case Hexagon::V6_vabs_qf32_sf:
4820 return make(RegType::QF32);
4821 case Hexagon::V6_vadd_hf:
4822 return make(RegType::QF16);
4823 case Hexagon::V6_vadd_qf16:
4825 case Hexagon::V6_vadd_qf16_mix:
4827 case Hexagon::V6_vadd_qf32:
4829 case Hexagon::V6_vadd_qf32_mix:
4831 case Hexagon::V6_vadd_sf:
4832 return make(RegType::QF32);
4833 case Hexagon::V6_vconv_bf_qf32:
4835 case Hexagon::V6_vconv_f8_qf16:
4837 case Hexagon::V6_vconv_hf_qf16:
4839 case Hexagon::V6_vconv_hf_qf32:
4841 case Hexagon::V6_vconv_qf16_f8:
4842 return make(RegType::QF16);
4843 case Hexagon::V6_vconv_qf16_hf:
4844 return make(RegType::QF16);
4845 case Hexagon::V6_vconv_qf16_qf16:
4847 case Hexagon::V6_vconv_qf32_qf32:
4849 case Hexagon::V6_vconv_qf32_sf:
4850 return make(RegType::QF32);
4851 case Hexagon::V6_vconv_sf_qf32:
4853 case Hexagon::V6_vilog2_qf16:
4855 case Hexagon::V6_vilog2_qf32:
4857 case Hexagon::V6_vmpy_qf16:
4859 case Hexagon::V6_vmpy_qf16_hf:
4860 return make(RegType::QF16);
4861 case Hexagon::V6_vmpy_qf16_mix_hf:
4863 case Hexagon::V6_vmpy_qf32:
4865 case Hexagon::V6_vmpy_qf32_hf:
4866 return make(RegType::QF32);
4867 case Hexagon::V6_vmpy_qf32_mix_hf:
4869 case Hexagon::V6_vmpy_qf32_qf16:
4871 case Hexagon::V6_vmpy_qf32_sf:
4872 return make(RegType::QF32);
4873 case Hexagon::V6_vmpy_rt_hf:
4874 return make(RegType::QF16);
4875 case Hexagon::V6_vmpy_rt_qf16:
4877 case Hexagon::V6_vmpy_rt_sf:
4878 return make(RegType::QF32);
4879 case Hexagon::V6_vneg_qf16_hf:
4880 return make(RegType::QF16);
4881 case Hexagon::V6_vneg_qf16_qf16:
4883 case Hexagon::V6_vneg_qf32_qf32:
4885 case Hexagon::V6_vneg_qf32_sf:
4886 return make(RegType::QF32);
4887 case Hexagon::V6_vsub_hf:
4888 return make(RegType::QF16);
4889 case Hexagon::V6_vsub_qf16:
4891 case Hexagon::V6_vsub_qf16_mix:
4893 case Hexagon::V6_vsub_qf32:
4895 case Hexagon::V6_vsub_qf32_mix:
4897 case Hexagon::V6_vsub_sf:
4898 return make(RegType::QF32);
4899 case Hexagon::V6_vsub_sf_mix:
4901 case Hexagon::V6_vsub_hf_mix:
4903 }
4904}
4905
4906} // namespace llvm::HexagonII
4907
4909 auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
4910 switch (Index) {
4911 case 1:
4912 return Info.Input1 == HexagonII::RegType::QF32;
4913 case 2:
4914 return Info.Input2 == HexagonII::RegType::QF32;
4915 case 3:
4916 return Info.Input3 == HexagonII::RegType::QF32;
4917 case 0:
4918 return Info.Input1 == HexagonII::RegType::QF32 ||
4919 Info.Input2 == HexagonII::RegType::QF32 ||
4920 Info.Input3 == HexagonII::RegType::QF32;
4921 default: // No instruction with more than 3 operands uses QF32.
4922 return false;
4923 }
4924 return false;
4925}
4926
4928 auto Info = HexagonII::getRegTypeInfo(MI->getOpcode());
4929 switch (Index) {
4930 case 1:
4931 return Info.Input1 == HexagonII::RegType::QF16;
4932 case 2:
4933 return Info.Input2 == HexagonII::RegType::QF16;
4934 case 3:
4935 return Info.Input3 == HexagonII::RegType::QF16;
4936 case 0:
4937 return Info.Input1 == HexagonII::RegType::QF16 ||
4938 Info.Input2 == HexagonII::RegType::QF16 ||
4939 Info.Input3 == HexagonII::RegType::QF16;
4940 default: // No instruction with more than 3 operands uses QF16.
4941 return false;
4942 }
4943 return false;
4944}
4945
4947 return usesQF32Operand(MI, Index) || usesQF16Operand(MI, Index);
4948}
4949
4953
4957
4961
4962// Return true if the function contains any qf-generating instructions.
4964 for (const MachineBasicBlock &MBB : MF)
4965 for (const MachineInstr &MI : MBB)
4966 if (isQFPInstr(const_cast<MachineInstr *>(&MI)))
4967 return true;
4968 return false;
4969}
4970
4971// Returns true if A appears before B within the same basic block.
4973 const MachineInstr *B) const {
4974 if (!A || !B || A->getParent() != B->getParent())
4975 return false;
4976
4977 for (const MachineInstr &MI : *A->getParent()) {
4978 if (&MI == A)
4979 return true;
4980 if (&MI == B)
4981 return false;
4982 }
4983 return false;
4984}
4985
4986// Addressing mode relations.
4988 return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
4989}
4990
4992 return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;
4993}
4994
4996 return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;
4997}
4998
5000 return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;
5001}
5002
5004 return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;
5005}
5006
5008 return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;
5009}
5010
5012 return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;
5013}
5014
5016 return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;
5017}
5018
5020 static const MCInst Nop = MCInstBuilder(Hexagon::A2_nop);
5021
5022 return MCInstBuilder(Hexagon::BUNDLE)
5023 .addImm(0)
5024 .addInst(&Nop);
5025}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool mayAlias(MachineInstr &MIa, SmallVectorImpl< MachineInstr * > &MemInsns, AliasAnalysis *AA)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned 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
Register const TargetRegisterInfo * TRI
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
if(PassOpts->AAPipeline)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
static StringRef getName(Value *V)
static bool isBranch(unsigned Opcode)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
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.
short getEquivalentHWInstr(const MachineInstr &MI) const
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 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 getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
Get the base register and byte offset of a load/store instr.
bool isValidOffset(unsigned Opcode, int Offset, const TargetRegisterInfo *TRI, bool Extend=true) 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 hasPseudoInstrPair(const MachineInstr &MI) 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
short getPseudoInstrPair(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.
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:545
StringRef getCommentString() const
Definition MCAsmInfo.h:556
const char * getSeparatorString() const
Definition MCAsmInfo.h:551
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,...
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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.
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.