LLVM 22.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 <cctype>
57#include <cstdint>
58#include <cstring>
59#include <iterator>
60#include <optional>
61#include <string>
62#include <utility>
63
64using namespace llvm;
65
66#define DEBUG_TYPE "hexagon-instrinfo"
67
68#define GET_INSTRINFO_CTOR_DTOR
69#define GET_INSTRMAP_INFO
71#include "HexagonGenDFAPacketizer.inc"
72#include "HexagonGenInstrInfo.inc"
73
74cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
75 cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
76 "packetization boundary."));
77
78static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
79 cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));
80
82 "disable-hexagon-nv-schedule", cl::Hidden,
83 cl::desc("Disable schedule adjustment for new value stores."));
84
86 "enable-timing-class-latency", cl::Hidden, cl::init(false),
87 cl::desc("Enable timing class latency"));
88
90 "enable-alu-forwarding", cl::Hidden, cl::init(true),
91 cl::desc("Enable vec alu forwarding"));
92
94 "enable-acc-forwarding", cl::Hidden, cl::init(true),
95 cl::desc("Enable vec acc forwarding"));
96
97static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
98 cl::init(true), cl::Hidden,
99 cl::desc("branch relax asm"));
100
101static cl::opt<bool>
102 UseDFAHazardRec("dfa-hazard-rec", cl::init(true), cl::Hidden,
103 cl::desc("Use the DFA based hazard recognizer."));
104
105/// Constants for Hexagon instructions.
106const int Hexagon_MEMW_OFFSET_MAX = 4095;
107const int Hexagon_MEMW_OFFSET_MIN = -4096;
108const int Hexagon_MEMD_OFFSET_MAX = 8191;
109const int Hexagon_MEMD_OFFSET_MIN = -8192;
110const int Hexagon_MEMH_OFFSET_MAX = 2047;
111const int Hexagon_MEMH_OFFSET_MIN = -2048;
112const int Hexagon_MEMB_OFFSET_MAX = 1023;
113const int Hexagon_MEMB_OFFSET_MIN = -1024;
114const int Hexagon_ADDI_OFFSET_MAX = 32767;
115const int Hexagon_ADDI_OFFSET_MIN = -32768;
116
117// Pin the vtable to this file.
118void HexagonInstrInfo::anchor() {}
119
121 : HexagonGenInstrInfo(ST, Hexagon::ADJCALLSTACKDOWN,
122 Hexagon::ADJCALLSTACKUP),
123 Subtarget(ST) {}
124
125namespace llvm {
126namespace HexagonFUnits {
127 bool isSlot0Only(unsigned units);
128}
129}
130
132 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
133 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
134}
135
137 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&
138 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));
139}
140
141/// Calculate number of instructions excluding the debug instructions.
144 unsigned Count = 0;
145 for (; MIB != MIE; ++MIB) {
146 if (!MIB->isDebugInstr())
147 ++Count;
148 }
149 return Count;
150}
151
152// Check if the A2_tfrsi instruction is cheap or not. If the operand has
153// to be constant-extendend it is not cheap since it occupies two slots
154// in a packet.
156 // Enable the following steps only at Os/Oz
157 if (!(MI.getMF()->getFunction().hasOptSize()))
158 return MI.isAsCheapAsAMove();
159
160 if (MI.getOpcode() == Hexagon::A2_tfrsi) {
161 auto Op = MI.getOperand(1);
162 // If the instruction has a global address as operand, it is not cheap
163 // since the operand will be constant extended.
164 if (Op.isGlobal())
165 return false;
166 // If the instruction has an operand of size > 16bits, its will be
167 // const-extended and hence, it is not cheap.
168 if (Op.isImm()) {
169 int64_t Imm = Op.getImm();
170 if (!isInt<16>(Imm))
171 return false;
172 }
173 }
174 return MI.isAsCheapAsAMove();
175}
176
177// Do not sink floating point instructions that updates USR register.
178// Example:
179// feclearexcept
180// F2_conv_w2sf
181// fetestexcept
182// MachineSink sinks F2_conv_w2sf and we are not able to catch exceptions.
183// TODO: On some of these floating point instructions, USR is marked as Use.
184// In reality, these instructions also Def the USR. If USR is marked as Def,
185// some of the assumptions in assembler packetization are broken.
187 // Assumption: A floating point instruction that reads the USR will write
188 // the USR as well.
189 if (isFloat(MI) && MI.hasRegisterImplicitUseOperand(Hexagon::USR))
190 return false;
191 return true;
192}
193
194/// Find the hardware loop instruction used to set-up the specified loop.
195/// On Hexagon, we have two instructions used to set-up the hardware loop
196/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
197/// to indicate the end of a loop.
199 unsigned EndLoopOp, MachineBasicBlock *TargetBB,
201 unsigned LOOPi;
202 unsigned LOOPr;
203 if (EndLoopOp == Hexagon::ENDLOOP0) {
204 LOOPi = Hexagon::J2_loop0i;
205 LOOPr = Hexagon::J2_loop0r;
206 } else { // EndLoopOp == Hexagon::EndLOOP1
207 LOOPi = Hexagon::J2_loop1i;
208 LOOPr = Hexagon::J2_loop1r;
209 }
210
211 // The loop set-up instruction will be in a predecessor block
212 for (MachineBasicBlock *PB : BB->predecessors()) {
213 // If this has been visited, already skip it.
214 if (!Visited.insert(PB).second)
215 continue;
216 if (PB == BB)
217 continue;
218 for (MachineInstr &I : llvm::reverse(PB->instrs())) {
219 unsigned Opc = I.getOpcode();
220 if (Opc == LOOPi || Opc == LOOPr)
221 return &I;
222 // We've reached a different loop, which means the loop01 has been
223 // removed.
224 if (Opc == EndLoopOp && I.getOperand(0).getMBB() != TargetBB)
225 return nullptr;
226 }
227 // Check the predecessors for the LOOP instruction.
228 if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))
229 return Loop;
230 }
231 return nullptr;
232}
233
234/// Gather register def/uses from MI.
235/// This treats possible (predicated) defs as actually happening ones
236/// (conservatively).
237static inline void parseOperands(const MachineInstr &MI,
239 Defs.clear();
240 Uses.clear();
241
242 for (const MachineOperand &MO : MI.operands()) {
243 if (!MO.isReg())
244 continue;
245
246 Register Reg = MO.getReg();
247 if (!Reg)
248 continue;
249
250 if (MO.isUse())
251 Uses.push_back(MO.getReg());
252
253 if (MO.isDef())
254 Defs.push_back(MO.getReg());
255 }
256}
257
258// Position dependent, so check twice for swap.
259static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
260 switch (Ga) {
262 default:
263 return false;
265 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
267 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
268 Gb == HexagonII::HSIG_A);
270 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
273 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
274 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
275 Gb == HexagonII::HSIG_A);
277 return (Gb == HexagonII::HSIG_A);
279 return (Gb == HexagonII::HSIG_Compound);
280 }
281 return false;
282}
283
284/// isLoadFromStackSlot - If the specified machine instruction is a direct
285/// load from a stack slot, return the virtual or physical register number of
286/// the destination along with the FrameIndex of the loaded stack slot. If
287/// not, return 0. This predicate must return 0 if the instruction has
288/// any side effects other than loading from the stack slot.
290 int &FrameIndex) const {
291 switch (MI.getOpcode()) {
292 default:
293 break;
294 case Hexagon::L2_loadri_io:
295 case Hexagon::L2_loadrd_io:
296 case Hexagon::V6_vL32b_ai:
297 case Hexagon::V6_vL32b_nt_ai:
298 case Hexagon::V6_vL32Ub_ai:
299 case Hexagon::LDriw_pred:
300 case Hexagon::LDriw_ctr:
301 case Hexagon::PS_vloadrq_ai:
302 case Hexagon::PS_vloadrw_ai:
303 case Hexagon::PS_vloadrw_nt_ai: {
304 const MachineOperand OpFI = MI.getOperand(1);
305 if (!OpFI.isFI())
306 return 0;
307 const MachineOperand OpOff = MI.getOperand(2);
308 if (!OpOff.isImm() || OpOff.getImm() != 0)
309 return 0;
310 FrameIndex = OpFI.getIndex();
311 return MI.getOperand(0).getReg();
312 }
313
314 case Hexagon::L2_ploadrit_io:
315 case Hexagon::L2_ploadrif_io:
316 case Hexagon::L2_ploadrdt_io:
317 case Hexagon::L2_ploadrdf_io: {
318 const MachineOperand OpFI = MI.getOperand(2);
319 if (!OpFI.isFI())
320 return 0;
321 const MachineOperand OpOff = MI.getOperand(3);
322 if (!OpOff.isImm() || OpOff.getImm() != 0)
323 return 0;
324 FrameIndex = OpFI.getIndex();
325 return MI.getOperand(0).getReg();
326 }
327 }
328
329 return 0;
330}
331
332/// isStoreToStackSlot - If the specified machine instruction is a direct
333/// store to a stack slot, return the virtual or physical register number of
334/// the source reg along with the FrameIndex of the loaded stack slot. If
335/// not, return 0. This predicate must return 0 if the instruction has
336/// any side effects other than storing to the stack slot.
338 int &FrameIndex) const {
339 switch (MI.getOpcode()) {
340 default:
341 break;
342 case Hexagon::S2_storerb_io:
343 case Hexagon::S2_storerh_io:
344 case Hexagon::S2_storeri_io:
345 case Hexagon::S2_storerd_io:
346 case Hexagon::V6_vS32b_ai:
347 case Hexagon::V6_vS32Ub_ai:
348 case Hexagon::STriw_pred:
349 case Hexagon::STriw_ctr:
350 case Hexagon::PS_vstorerq_ai:
351 case Hexagon::PS_vstorerw_ai: {
352 const MachineOperand &OpFI = MI.getOperand(0);
353 if (!OpFI.isFI())
354 return 0;
355 const MachineOperand &OpOff = MI.getOperand(1);
356 if (!OpOff.isImm() || OpOff.getImm() != 0)
357 return 0;
358 FrameIndex = OpFI.getIndex();
359 return MI.getOperand(2).getReg();
360 }
361
362 case Hexagon::S2_pstorerbt_io:
363 case Hexagon::S2_pstorerbf_io:
364 case Hexagon::S2_pstorerht_io:
365 case Hexagon::S2_pstorerhf_io:
366 case Hexagon::S2_pstorerit_io:
367 case Hexagon::S2_pstorerif_io:
368 case Hexagon::S2_pstorerdt_io:
369 case Hexagon::S2_pstorerdf_io: {
370 const MachineOperand &OpFI = MI.getOperand(1);
371 if (!OpFI.isFI())
372 return 0;
373 const MachineOperand &OpOff = MI.getOperand(2);
374 if (!OpOff.isImm() || OpOff.getImm() != 0)
375 return 0;
376 FrameIndex = OpFI.getIndex();
377 return MI.getOperand(3).getReg();
378 }
379 }
380
381 return 0;
382}
383
384/// This function checks if the instruction or bundle of instructions
385/// has load from stack slot and returns frameindex and machine memory
386/// operand of that instruction if true.
388 const MachineInstr &MI,
390 if (MI.isBundle()) {
391 const MachineBasicBlock *MBB = MI.getParent();
393 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
395 return true;
396 return false;
397 }
398
400}
401
402/// This function checks if the instruction or bundle of instructions
403/// has store to stack slot and returns frameindex and machine memory
404/// operand of that instruction if true.
406 const MachineInstr &MI,
408 if (MI.isBundle()) {
409 const MachineBasicBlock *MBB = MI.getParent();
411 for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
413 return true;
414 return false;
415 }
416
418}
419
420/// This function can analyze one/two way branching only and should (mostly) be
421/// called by target independent side.
422/// First entry is always the opcode of the branching instruction, except when
423/// the Cond vector is supposed to be empty, e.g., when analyzeBranch fails, a
424/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
425/// e.g. Jump_c p will have
426/// Cond[0] = Jump_c
427/// Cond[1] = p
428/// HW-loop ENDLOOP:
429/// Cond[0] = ENDLOOP
430/// Cond[1] = MBB
431/// New value jump:
432/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
433/// Cond[1] = R
434/// Cond[2] = Imm
437 MachineBasicBlock *&FBB,
439 bool AllowModify) const {
440 TBB = nullptr;
441 FBB = nullptr;
442 Cond.clear();
443
444 // If the block has no terminators, it just falls into the block after it.
446 if (I == MBB.instr_begin())
447 return false;
448
449 // A basic block may looks like this:
450 //
451 // [ insn
452 // EH_LABEL
453 // insn
454 // insn
455 // insn
456 // EH_LABEL
457 // insn ]
458 //
459 // It has two succs but does not have a terminator
460 // Don't know how to handle it.
461 do {
462 --I;
463 if (I->isEHLabel())
464 // Don't analyze EH branches.
465 return true;
466 } while (I != MBB.instr_begin());
467
468 I = MBB.instr_end();
469 --I;
470
471 while (I->isDebugInstr()) {
472 if (I == MBB.instr_begin())
473 return false;
474 --I;
475 }
476
477 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
478 I->getOperand(0).isMBB();
479 // Delete the J2_jump if it's equivalent to a fall-through.
480 if (AllowModify && JumpToBlock &&
481 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
482 LLVM_DEBUG(dbgs() << "\nErasing the jump to successor block\n";);
483 I->eraseFromParent();
484 I = MBB.instr_end();
485 if (I == MBB.instr_begin())
486 return false;
487 --I;
488 }
489 if (!isUnpredicatedTerminator(*I))
490 return false;
491
492 // Get the last instruction in the block.
493 MachineInstr *LastInst = &*I;
494 MachineInstr *SecondLastInst = nullptr;
495 // Find one more terminator if present.
496 while (true) {
497 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
498 if (!SecondLastInst)
499 SecondLastInst = &*I;
500 else
501 // This is a third branch.
502 return true;
503 }
504 if (I == MBB.instr_begin())
505 break;
506 --I;
507 }
508
509 int LastOpcode = LastInst->getOpcode();
510 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
511 // If the branch target is not a basic block, it could be a tail call.
512 // (It is, if the target is a function.)
513 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
514 return true;
515 if (SecLastOpcode == Hexagon::J2_jump &&
516 !SecondLastInst->getOperand(0).isMBB())
517 return true;
518
519 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
520 bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);
521
522 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
523 return true;
524
525 // If there is only one terminator instruction, process it.
526 if (LastInst && !SecondLastInst) {
527 if (LastOpcode == Hexagon::J2_jump) {
528 TBB = LastInst->getOperand(0).getMBB();
529 return false;
530 }
531 if (isEndLoopN(LastOpcode)) {
532 TBB = LastInst->getOperand(0).getMBB();
533 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
534 Cond.push_back(LastInst->getOperand(0));
535 return false;
536 }
537 if (LastOpcodeHasJMP_c) {
538 TBB = LastInst->getOperand(1).getMBB();
539 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
540 Cond.push_back(LastInst->getOperand(0));
541 return false;
542 }
543 // Only supporting rr/ri versions of new-value jumps.
544 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
545 TBB = LastInst->getOperand(2).getMBB();
546 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
547 Cond.push_back(LastInst->getOperand(0));
548 Cond.push_back(LastInst->getOperand(1));
549 return false;
550 }
551 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
552 << " with one jump\n";);
553 // Otherwise, don't know what this is.
554 return true;
555 }
556
557 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
558 bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);
559 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
560 if (!SecondLastInst->getOperand(1).isMBB())
561 return true;
562 TBB = SecondLastInst->getOperand(1).getMBB();
563 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
564 Cond.push_back(SecondLastInst->getOperand(0));
565 FBB = LastInst->getOperand(0).getMBB();
566 return false;
567 }
568
569 // Only supporting rr/ri versions of new-value jumps.
570 if (SecLastOpcodeHasNVJump &&
571 (SecondLastInst->getNumExplicitOperands() == 3) &&
572 (LastOpcode == Hexagon::J2_jump)) {
573 TBB = SecondLastInst->getOperand(2).getMBB();
574 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
575 Cond.push_back(SecondLastInst->getOperand(0));
576 Cond.push_back(SecondLastInst->getOperand(1));
577 FBB = LastInst->getOperand(0).getMBB();
578 return false;
579 }
580
581 // If the block ends with two Hexagon:JMPs, handle it. The second one is not
582 // executed, so remove it.
583 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
584 TBB = SecondLastInst->getOperand(0).getMBB();
585 I = LastInst->getIterator();
586 if (AllowModify)
587 I->eraseFromParent();
588 return false;
589 }
590
591 // If the block ends with an ENDLOOP, and J2_jump, handle it.
592 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
593 TBB = SecondLastInst->getOperand(0).getMBB();
594 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
595 Cond.push_back(SecondLastInst->getOperand(0));
596 FBB = LastInst->getOperand(0).getMBB();
597 return false;
598 }
599 LLVM_DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
600 << " with two jumps";);
601 // Otherwise, can't handle this.
602 return true;
603}
604
606 int *BytesRemoved) const {
607 assert(!BytesRemoved && "code size not handled");
608
609 LLVM_DEBUG(dbgs() << "\nRemoving branches out of " << printMBBReference(MBB));
611 unsigned Count = 0;
612 while (I != MBB.begin()) {
613 --I;
614 if (I->isDebugInstr())
615 continue;
616 // Only removing branches from end of MBB.
617 if (!I->isBranch())
618 return Count;
619 if (Count && (I->getOpcode() == Hexagon::J2_jump))
620 llvm_unreachable("Malformed basic block: unconditional branch not last");
621 MBB.erase(&MBB.back());
622 I = MBB.end();
623 ++Count;
624 }
625 return Count;
626}
627
632 const DebugLoc &DL,
633 int *BytesAdded) const {
634 unsigned BOpc = Hexagon::J2_jump;
635 unsigned BccOpc = Hexagon::J2_jumpt;
636 assert(validateBranchCond(Cond) && "Invalid branching condition");
637 assert(TBB && "insertBranch must not be told to insert a fallthrough");
638 assert(!BytesAdded && "code size not handled");
639
640 // Check if reverseBranchCondition has asked to reverse this branch
641 // If we want to reverse the branch an odd number of times, we want
642 // J2_jumpf.
643 if (!Cond.empty() && Cond[0].isImm())
644 BccOpc = Cond[0].getImm();
645
646 if (!FBB) {
647 if (Cond.empty()) {
648 // Due to a bug in TailMerging/CFG Optimization, we need to add a
649 // special case handling of a predicated jump followed by an
650 // unconditional jump. If not, Tail Merging and CFG Optimization go
651 // into an infinite loop.
652 MachineBasicBlock *NewTBB, *NewFBB;
654 auto Term = MBB.getFirstTerminator();
655 if (Term != MBB.end() && isPredicated(*Term) &&
656 !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&
657 MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {
660 return insertBranch(MBB, TBB, nullptr, Cond, DL);
661 }
662 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
663 } else if (isEndLoopN(Cond[0].getImm())) {
664 int EndLoopOp = Cond[0].getImm();
665 assert(Cond[1].isMBB());
666 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
667 // Check for it, and change the BB target if needed.
669 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
670 VisitedBBs);
671 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
672 Loop->getOperand(0).setMBB(TBB);
673 // Add the ENDLOOP after the finding the LOOP0.
674 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
675 } else if (isNewValueJump(Cond[0].getImm())) {
676 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
677 // New value jump
678 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
679 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
680 unsigned Flags1 = getUndefRegState(Cond[1].isUndef());
681 LLVM_DEBUG(dbgs() << "\nInserting NVJump for "
683 if (Cond[2].isReg()) {
684 unsigned Flags2 = getUndefRegState(Cond[2].isUndef());
685 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
686 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
687 } else if(Cond[2].isImm()) {
688 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
689 addImm(Cond[2].getImm()).addMBB(TBB);
690 } else
691 llvm_unreachable("Invalid condition for branching");
692 } else {
693 assert((Cond.size() == 2) && "Malformed cond vector");
694 const MachineOperand &RO = Cond[1];
695 unsigned Flags = getUndefRegState(RO.isUndef());
696 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
697 }
698 return 1;
699 }
700 assert((!Cond.empty()) &&
701 "Cond. cannot be empty when multiple branchings are required");
702 assert((!isNewValueJump(Cond[0].getImm())) &&
703 "NV-jump cannot be inserted with another branch");
704 // Special case for hardware loops. The condition is a basic block.
705 if (isEndLoopN(Cond[0].getImm())) {
706 int EndLoopOp = Cond[0].getImm();
707 assert(Cond[1].isMBB());
708 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
709 // Check for it, and change the BB target if needed.
711 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
712 VisitedBBs);
713 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
714 Loop->getOperand(0).setMBB(TBB);
715 // Add the ENDLOOP after the finding the LOOP0.
716 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
717 } else {
718 const MachineOperand &RO = Cond[1];
719 unsigned Flags = getUndefRegState(RO.isUndef());
720 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
721 }
722 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
723
724 return 2;
725}
726
727namespace {
728class HexagonPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
729 MachineInstr *Loop, *EndLoop;
730 MachineFunction *MF;
731 const HexagonInstrInfo *TII;
732 int64_t TripCount;
733 Register LoopCount;
734 DebugLoc DL;
735
736public:
737 HexagonPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop)
738 : Loop(Loop), EndLoop(EndLoop), MF(Loop->getParent()->getParent()),
739 TII(MF->getSubtarget<HexagonSubtarget>().getInstrInfo()),
740 DL(Loop->getDebugLoc()) {
741 // Inspect the Loop instruction up-front, as it may be deleted when we call
742 // createTripCountGreaterCondition.
743 TripCount = Loop->getOpcode() == Hexagon::J2_loop0r
744 ? -1
745 : Loop->getOperand(1).getImm();
746 if (TripCount == -1)
747 LoopCount = Loop->getOperand(1).getReg();
748 }
749
750 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
751 // Only ignore the terminator.
752 return MI == EndLoop;
753 }
754
755 std::optional<bool> createTripCountGreaterCondition(
756 int TC, MachineBasicBlock &MBB,
757 SmallVectorImpl<MachineOperand> &Cond) override {
758 if (TripCount == -1) {
759 // Check if we're done with the loop.
760 Register Done = TII->createVR(MF, MVT::i1);
761 MachineInstr *NewCmp = BuildMI(&MBB, DL,
762 TII->get(Hexagon::C2_cmpgtui), Done)
763 .addReg(LoopCount)
764 .addImm(TC);
765 Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
766 Cond.push_back(NewCmp->getOperand(0));
767 return {};
768 }
769
770 return TripCount > TC;
771 }
772
773 void setPreheader(MachineBasicBlock *NewPreheader) override {
774 NewPreheader->splice(NewPreheader->getFirstTerminator(), Loop->getParent(),
775 Loop);
776 }
777
778 void adjustTripCount(int TripCountAdjust) override {
779 // If the loop trip count is a compile-time value, then just change the
780 // value.
781 if (Loop->getOpcode() == Hexagon::J2_loop0i ||
782 Loop->getOpcode() == Hexagon::J2_loop1i) {
783 int64_t TripCount = Loop->getOperand(1).getImm() + TripCountAdjust;
784 assert(TripCount > 0 && "Can't create an empty or negative loop!");
785 Loop->getOperand(1).setImm(TripCount);
786 return;
787 }
788
789 // The loop trip count is a run-time value. We generate code to subtract
790 // one from the trip count, and update the loop instruction.
791 Register LoopCount = Loop->getOperand(1).getReg();
792 Register NewLoopCount = TII->createVR(MF, MVT::i32);
793 BuildMI(*Loop->getParent(), Loop, Loop->getDebugLoc(),
794 TII->get(Hexagon::A2_addi), NewLoopCount)
795 .addReg(LoopCount)
796 .addImm(TripCountAdjust);
797 Loop->getOperand(1).setReg(NewLoopCount);
798 }
799
800 void disposed(LiveIntervals *LIS) override {
801 if (LIS)
802 LIS->RemoveMachineInstrFromMaps(*Loop);
803 Loop->eraseFromParent();
804 }
805};
806} // namespace
807
808std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
810 // We really "analyze" only hardware loops right now.
812
813 if (I != LoopBB->end() && isEndLoopN(I->getOpcode())) {
815 MachineInstr *LoopInst = findLoopInstr(
816 LoopBB, I->getOpcode(), I->getOperand(0).getMBB(), VisitedBBs);
817 if (LoopInst)
818 return std::make_unique<HexagonPipelinerLoopInfo>(LoopInst, &*I);
819 }
820 return nullptr;
821}
822
824 unsigned NumCycles, unsigned ExtraPredCycles,
825 BranchProbability Probability) const {
826 return nonDbgBBSize(&MBB) <= 3;
827}
828
830 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
831 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
832 const {
833 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
834}
835
837 unsigned NumInstrs, BranchProbability Probability) const {
838 return NumInstrs <= 4;
839}
840
841static void getLiveInRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
843 const MachineBasicBlock &B = *MI.getParent();
844 Regs.addLiveIns(B);
845 auto E = MachineBasicBlock::const_iterator(MI.getIterator());
846 for (auto I = B.begin(); I != E; ++I) {
847 Clobbers.clear();
848 Regs.stepForward(*I, Clobbers);
849 }
850}
851
852static void getLiveOutRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
853 const MachineBasicBlock &B = *MI.getParent();
854 Regs.addLiveOuts(B);
855 auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();
856 for (auto I = B.rbegin(); I != E; ++I)
857 Regs.stepBackward(*I);
858}
859
862 const DebugLoc &DL, Register DestReg,
863 Register SrcReg, bool KillSrc,
864 bool RenamableDest,
865 bool RenamableSrc) const {
866 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
867 unsigned KillFlag = getKillRegState(KillSrc);
868
869 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
870 BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)
871 .addReg(SrcReg, KillFlag);
872 return;
873 }
874 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
875 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)
876 .addReg(SrcReg, KillFlag);
877 return;
878 }
879 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
880 // Map Pd = Ps to Pd = or(Ps, Ps).
881 BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)
882 .addReg(SrcReg).addReg(SrcReg, KillFlag);
883 return;
884 }
885 if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
886 Hexagon::IntRegsRegClass.contains(SrcReg)) {
887 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
888 .addReg(SrcReg, KillFlag);
889 return;
890 }
891 if (Hexagon::IntRegsRegClass.contains(DestReg) &&
892 Hexagon::CtrRegsRegClass.contains(SrcReg)) {
893 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)
894 .addReg(SrcReg, KillFlag);
895 return;
896 }
897 if (Hexagon::ModRegsRegClass.contains(DestReg) &&
898 Hexagon::IntRegsRegClass.contains(SrcReg)) {
899 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
900 .addReg(SrcReg, KillFlag);
901 return;
902 }
903 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
904 Hexagon::IntRegsRegClass.contains(DestReg)) {
905 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
906 .addReg(SrcReg, KillFlag);
907 return;
908 }
909 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
910 Hexagon::PredRegsRegClass.contains(DestReg)) {
911 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)
912 .addReg(SrcReg, KillFlag);
913 return;
914 }
915 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
916 Hexagon::IntRegsRegClass.contains(DestReg)) {
917 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
918 .addReg(SrcReg, KillFlag);
919 return;
920 }
921 if (Hexagon::HvxVRRegClass.contains(SrcReg, DestReg)) {
922 BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).
923 addReg(SrcReg, KillFlag);
924 return;
925 }
926 if (Hexagon::HvxWRRegClass.contains(SrcReg, DestReg)) {
927 LivePhysRegs LiveAtMI(HRI);
928 getLiveInRegsAt(LiveAtMI, *I);
929 Register SrcLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
930 Register SrcHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
931 unsigned UndefLo = getUndefRegState(!LiveAtMI.contains(SrcLo));
932 unsigned UndefHi = getUndefRegState(!LiveAtMI.contains(SrcHi));
933 BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)
934 .addReg(SrcHi, KillFlag | UndefHi)
935 .addReg(SrcLo, KillFlag | UndefLo);
936 return;
937 }
938 if (Hexagon::HvxQRRegClass.contains(SrcReg, DestReg)) {
939 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)
940 .addReg(SrcReg)
941 .addReg(SrcReg, KillFlag);
942 return;
943 }
944 if (Hexagon::HvxQRRegClass.contains(SrcReg) &&
945 Hexagon::HvxVRRegClass.contains(DestReg)) {
946 llvm_unreachable("Unimplemented pred to vec");
947 return;
948 }
949 if (Hexagon::HvxQRRegClass.contains(DestReg) &&
950 Hexagon::HvxVRRegClass.contains(SrcReg)) {
951 llvm_unreachable("Unimplemented vec to pred");
952 return;
953 }
954
955#ifndef NDEBUG
956 // Show the invalid registers to ease debugging.
957 dbgs() << "Invalid registers for copy in " << printMBBReference(MBB) << ": "
958 << printReg(DestReg, &HRI) << " = " << printReg(SrcReg, &HRI) << '\n';
959#endif
960 llvm_unreachable("Unimplemented");
961}
962
965 Register SrcReg, bool isKill, int FI,
966 const TargetRegisterClass *RC,
967 const TargetRegisterInfo *TRI,
968 Register VReg,
969 MachineInstr::MIFlag Flags) const {
970 DebugLoc DL = MBB.findDebugLoc(I);
971 MachineFunction &MF = *MBB.getParent();
972 MachineFrameInfo &MFI = MF.getFrameInfo();
973 unsigned KillFlag = getKillRegState(isKill);
974
977 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
978
979 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
980 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
981 .addFrameIndex(FI).addImm(0)
982 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
983 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
984 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
985 .addFrameIndex(FI).addImm(0)
986 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
987 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
988 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
989 .addFrameIndex(FI).addImm(0)
990 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
991 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
992 BuildMI(MBB, I, DL, get(Hexagon::STriw_ctr))
993 .addFrameIndex(FI).addImm(0)
994 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
995 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
996 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))
997 .addFrameIndex(FI).addImm(0)
998 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
999 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
1000 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerv_ai))
1001 .addFrameIndex(FI).addImm(0)
1002 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1003 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
1004 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerw_ai))
1005 .addFrameIndex(FI).addImm(0)
1006 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
1007 } else {
1008 llvm_unreachable("Unimplemented");
1009 }
1010}
1011
1014 int FI, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
1015 Register VReg, 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();
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 unsigned UndefLo = getUndefRegState(!LiveIn.contains(SrcLo));
1149 unsigned UndefHi = getUndefRegState(!LiveIn.contains(SrcHi));
1150 unsigned 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 unsigned K1 = getKillRegState(Op1.isKill());
1355 unsigned K2 = getKillRegState(Op2.isKill());
1356 unsigned K3 = getKillRegState(Op3.isKill());
1357 if (Rd != Rs)
1358 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1359 .addReg(Pu, (Rd == Rt) ? K1 : 0)
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 unsigned PState = getRegState(Op1);
1378
1379 if (Op0.getReg() != Op2.getReg()) {
1380 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill
1381 : 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 unsigned PState = getRegState(Op1);
1411
1412 if (Op0.getReg() != Op2.getReg()) {
1413 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill
1414 : 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
1676// Returns true if an instruction is predicated irrespective of the predicate
1677// sense. For example, all of the following will return true.
1678// if (p0) R1 = add(R2, R3)
1679// if (!p0) R1 = add(R2, R3)
1680// if (p0.new) R1 = add(R2, R3)
1681// if (!p0.new) R1 = add(R2, R3)
1682// Note: New-value stores are not included here as in the current
1683// implementation, we don't need to check their predicate sense.
1685 const uint64_t F = MI.getDesc().TSFlags;
1687}
1688
1691 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1692 isEndLoopN(Cond[0].getImm())) {
1693 LLVM_DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
1694 return false;
1695 }
1696 int Opc = MI.getOpcode();
1697 assert (isPredicable(MI) && "Expected predicable instruction");
1698 bool invertJump = predOpcodeHasNot(Cond);
1699
1700 // We have to predicate MI "in place", i.e. after this function returns,
1701 // MI will need to be transformed into a predicated form. To avoid com-
1702 // plicated manipulations with the operands (handling tied operands,
1703 // etc.), build a new temporary instruction, then overwrite MI with it.
1704
1705 MachineBasicBlock &B = *MI.getParent();
1706 DebugLoc DL = MI.getDebugLoc();
1707 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1708 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
1709 unsigned NOp = 0, NumOps = MI.getNumOperands();
1710 while (NOp < NumOps) {
1711 MachineOperand &Op = MI.getOperand(NOp);
1712 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1713 break;
1714 T.add(Op);
1715 NOp++;
1716 }
1717
1718 Register PredReg;
1719 unsigned PredRegPos, PredRegFlags;
1720 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1721 (void)GotPredReg;
1722 assert(GotPredReg);
1723 T.addReg(PredReg, PredRegFlags);
1724 while (NOp < NumOps)
1725 T.add(MI.getOperand(NOp++));
1726
1727 MI.setDesc(get(PredOpc));
1728 while (unsigned n = MI.getNumOperands())
1729 MI.removeOperand(n-1);
1730 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
1731 MI.addOperand(T->getOperand(i));
1732
1733 MachineBasicBlock::instr_iterator TI = T->getIterator();
1734 B.erase(TI);
1735
1736 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1737 MRI.clearKillFlags(PredReg);
1738 return true;
1739}
1740
1742 ArrayRef<MachineOperand> Pred2) const {
1743 // TODO: Fix this
1744 return false;
1745}
1746
1748 std::vector<MachineOperand> &Pred,
1749 bool SkipDead) const {
1750 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
1751
1752 for (const MachineOperand &MO : MI.operands()) {
1753 if (MO.isReg()) {
1754 if (!MO.isDef())
1755 continue;
1756 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1757 if (RC == &Hexagon::PredRegsRegClass) {
1758 Pred.push_back(MO);
1759 return true;
1760 }
1761 continue;
1762 } else if (MO.isRegMask()) {
1763 for (Register PR : Hexagon::PredRegsRegClass) {
1764 if (!MI.modifiesRegister(PR, &HRI))
1765 continue;
1766 Pred.push_back(MO);
1767 return true;
1768 }
1769 }
1770 }
1771 return false;
1772}
1773
1775 if (!MI.getDesc().isPredicable())
1776 return false;
1777
1778 if (MI.isCall() || isTailCall(MI)) {
1779 if (!Subtarget.usePredicatedCalls())
1780 return false;
1781 }
1782
1783 // HVX loads are not predicable on v60, but are on v62.
1784 if (!Subtarget.hasV62Ops()) {
1785 switch (MI.getOpcode()) {
1786 case Hexagon::V6_vL32b_ai:
1787 case Hexagon::V6_vL32b_pi:
1788 case Hexagon::V6_vL32b_ppu:
1789 case Hexagon::V6_vL32b_cur_ai:
1790 case Hexagon::V6_vL32b_cur_pi:
1791 case Hexagon::V6_vL32b_cur_ppu:
1792 case Hexagon::V6_vL32b_nt_ai:
1793 case Hexagon::V6_vL32b_nt_pi:
1794 case Hexagon::V6_vL32b_nt_ppu:
1795 case Hexagon::V6_vL32b_tmp_ai:
1796 case Hexagon::V6_vL32b_tmp_pi:
1797 case Hexagon::V6_vL32b_tmp_ppu:
1798 case Hexagon::V6_vL32b_nt_cur_ai:
1799 case Hexagon::V6_vL32b_nt_cur_pi:
1800 case Hexagon::V6_vL32b_nt_cur_ppu:
1801 case Hexagon::V6_vL32b_nt_tmp_ai:
1802 case Hexagon::V6_vL32b_nt_tmp_pi:
1803 case Hexagon::V6_vL32b_nt_tmp_ppu:
1804 return false;
1805 }
1806 }
1807 return true;
1808}
1809
1811 const MachineBasicBlock *MBB,
1812 const MachineFunction &MF) const {
1813 // Debug info is never a scheduling boundary. It's necessary to be explicit
1814 // due to the special treatment of IT instructions below, otherwise a
1815 // dbg_value followed by an IT will result in the IT instruction being
1816 // considered a scheduling hazard, which is wrong. It should be the actual
1817 // instruction preceding the dbg_value instruction(s), just like it is
1818 // when debug info is not present.
1819 if (MI.isDebugInstr())
1820 return false;
1821
1822 // Throwing call is a boundary.
1823 if (MI.isCall()) {
1824 // Don't mess around with no return calls.
1825 if (doesNotReturn(MI))
1826 return true;
1827 // If any of the block's successors is a landing pad, this could be a
1828 // throwing call.
1829 for (auto *I : MBB->successors())
1830 if (I->isEHPad())
1831 return true;
1832 }
1833
1834 // Terminators and labels can't be scheduled around.
1835 if (MI.getDesc().isTerminator() || MI.isPosition())
1836 return true;
1837
1838 // INLINEASM_BR can jump to another block
1839 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
1840 return true;
1841
1842 if (MI.isInlineAsm() && !ScheduleInlineAsm)
1843 return true;
1844
1845 return false;
1846}
1847
1848/// Measure the specified inline asm to determine an approximation of its
1849/// length.
1850/// Comments (which run till the next SeparatorString or newline) do not
1851/// count as an instruction.
1852/// Any other non-whitespace text is considered an instruction, with
1853/// multiple instructions separated by SeparatorString or newlines.
1854/// Variable-length instructions are not handled here; this function
1855/// may be overloaded in the target code to do that.
1856/// Hexagon counts the number of ##'s and adjust for that many
1857/// constant exenders.
1859 const MCAsmInfo &MAI,
1860 const TargetSubtargetInfo *STI) const {
1861 StringRef AStr(Str);
1862 // Count the number of instructions in the asm.
1863 bool atInsnStart = true;
1864 unsigned Length = 0;
1865 const unsigned MaxInstLength = MAI.getMaxInstLength(STI);
1866 for (; *Str; ++Str) {
1867 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1868 strlen(MAI.getSeparatorString())) == 0)
1869 atInsnStart = true;
1870 if (atInsnStart && !isSpace(static_cast<unsigned char>(*Str))) {
1871 Length += MaxInstLength;
1872 atInsnStart = false;
1873 }
1874 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
1875 MAI.getCommentString().size()) == 0)
1876 atInsnStart = false;
1877 }
1878
1879 // Add to size number of constant extenders seen * 4.
1880 StringRef Occ("##");
1881 Length += AStr.count(Occ)*4;
1882 return Length;
1883}
1884
1892
1893/// For a comparison instruction, return the source registers in
1894/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1895/// compares against in CmpValue. Return true if the comparison instruction
1896/// can be analyzed.
1898 Register &SrcReg2, int64_t &Mask,
1899 int64_t &Value) const {
1900 unsigned Opc = MI.getOpcode();
1901
1902 // Set mask and the first source register.
1903 switch (Opc) {
1904 case Hexagon::C2_cmpeq:
1905 case Hexagon::C2_cmpeqp:
1906 case Hexagon::C2_cmpgt:
1907 case Hexagon::C2_cmpgtp:
1908 case Hexagon::C2_cmpgtu:
1909 case Hexagon::C2_cmpgtup:
1910 case Hexagon::C4_cmpneq:
1911 case Hexagon::C4_cmplte:
1912 case Hexagon::C4_cmplteu:
1913 case Hexagon::C2_cmpeqi:
1914 case Hexagon::C2_cmpgti:
1915 case Hexagon::C2_cmpgtui:
1916 case Hexagon::C4_cmpneqi:
1917 case Hexagon::C4_cmplteui:
1918 case Hexagon::C4_cmpltei:
1919 SrcReg = MI.getOperand(1).getReg();
1920 Mask = ~0;
1921 break;
1922 case Hexagon::A4_cmpbeq:
1923 case Hexagon::A4_cmpbgt:
1924 case Hexagon::A4_cmpbgtu:
1925 case Hexagon::A4_cmpbeqi:
1926 case Hexagon::A4_cmpbgti:
1927 case Hexagon::A4_cmpbgtui:
1928 SrcReg = MI.getOperand(1).getReg();
1929 Mask = 0xFF;
1930 break;
1931 case Hexagon::A4_cmpheq:
1932 case Hexagon::A4_cmphgt:
1933 case Hexagon::A4_cmphgtu:
1934 case Hexagon::A4_cmpheqi:
1935 case Hexagon::A4_cmphgti:
1936 case Hexagon::A4_cmphgtui:
1937 SrcReg = MI.getOperand(1).getReg();
1938 Mask = 0xFFFF;
1939 break;
1940 }
1941
1942 // Set the value/second source register.
1943 switch (Opc) {
1944 case Hexagon::C2_cmpeq:
1945 case Hexagon::C2_cmpeqp:
1946 case Hexagon::C2_cmpgt:
1947 case Hexagon::C2_cmpgtp:
1948 case Hexagon::C2_cmpgtu:
1949 case Hexagon::C2_cmpgtup:
1950 case Hexagon::A4_cmpbeq:
1951 case Hexagon::A4_cmpbgt:
1952 case Hexagon::A4_cmpbgtu:
1953 case Hexagon::A4_cmpheq:
1954 case Hexagon::A4_cmphgt:
1955 case Hexagon::A4_cmphgtu:
1956 case Hexagon::C4_cmpneq:
1957 case Hexagon::C4_cmplte:
1958 case Hexagon::C4_cmplteu:
1959 SrcReg2 = MI.getOperand(2).getReg();
1960 Value = 0;
1961 return true;
1962
1963 case Hexagon::C2_cmpeqi:
1964 case Hexagon::C2_cmpgtui:
1965 case Hexagon::C2_cmpgti:
1966 case Hexagon::C4_cmpneqi:
1967 case Hexagon::C4_cmplteui:
1968 case Hexagon::C4_cmpltei:
1969 case Hexagon::A4_cmpbeqi:
1970 case Hexagon::A4_cmpbgti:
1971 case Hexagon::A4_cmpbgtui:
1972 case Hexagon::A4_cmpheqi:
1973 case Hexagon::A4_cmphgti:
1974 case Hexagon::A4_cmphgtui: {
1975 SrcReg2 = 0;
1976 const MachineOperand &Op2 = MI.getOperand(2);
1977 if (!Op2.isImm())
1978 return false;
1979 Value = MI.getOperand(2).getImm();
1980 return true;
1981 }
1982 }
1983
1984 return false;
1985}
1986
1988 const MachineInstr &MI,
1989 unsigned *PredCost) const {
1990 return getInstrTimingClassLatency(ItinData, MI);
1991}
1992
1994 const TargetSubtargetInfo &STI) const {
1996 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
1997}
1998
1999// Inspired by this pair:
2000// %r13 = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]
2001// S2_storeri_io %r29, 132, killed %r1; flags: mem:ST4[FixedStack1]
2002// Currently AA considers the addresses in these instructions to be aliasing.
2004 const MachineInstr &MIa, const MachineInstr &MIb) const {
2007 return false;
2008
2009 // Instructions that are pure loads, not loads and stores like memops are not
2010 // dependent.
2011 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))
2012 return true;
2013
2014 // Get the base register in MIa.
2015 unsigned BasePosA, OffsetPosA;
2016 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))
2017 return false;
2018 const MachineOperand &BaseA = MIa.getOperand(BasePosA);
2019 Register BaseRegA = BaseA.getReg();
2020 unsigned BaseSubA = BaseA.getSubReg();
2021
2022 // Get the base register in MIb.
2023 unsigned BasePosB, OffsetPosB;
2024 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))
2025 return false;
2026 const MachineOperand &BaseB = MIb.getOperand(BasePosB);
2027 Register BaseRegB = BaseB.getReg();
2028 unsigned BaseSubB = BaseB.getSubReg();
2029
2030 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)
2031 return false;
2032
2033 // Get the access sizes.
2034 unsigned SizeA = getMemAccessSize(MIa);
2035 unsigned SizeB = getMemAccessSize(MIb);
2036
2037 // Get the offsets. Handle immediates only for now.
2038 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);
2039 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);
2040 if (!MIa.getOperand(OffsetPosA).isImm() ||
2041 !MIb.getOperand(OffsetPosB).isImm())
2042 return false;
2043 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();
2044 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();
2045
2046 // This is a mem access with the same base register and known offsets from it.
2047 // Reason about it.
2048 if (OffsetA > OffsetB) {
2049 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
2050 return SizeB <= OffDiff;
2051 }
2052 if (OffsetA < OffsetB) {
2053 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
2054 return SizeA <= OffDiff;
2055 }
2056
2057 return false;
2058}
2059
2060/// If the instruction is an increment of a constant value, return the amount.
2062 int &Value) const {
2063 if (isPostIncrement(MI)) {
2064 unsigned BasePos = 0, OffsetPos = 0;
2065 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
2066 return false;
2067 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
2068 if (OffsetOp.isImm()) {
2069 Value = OffsetOp.getImm();
2070 return true;
2071 }
2072 } else if (MI.getOpcode() == Hexagon::A2_addi) {
2073 const MachineOperand &AddOp = MI.getOperand(2);
2074 if (AddOp.isImm()) {
2075 Value = AddOp.getImm();
2076 return true;
2077 }
2078 }
2079
2080 return false;
2081}
2082
2083std::pair<unsigned, unsigned>
2085 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,
2087}
2088
2091 using namespace HexagonII;
2092
2093 static const std::pair<unsigned, const char*> Flags[] = {
2094 {MO_PCREL, "hexagon-pcrel"},
2095 {MO_GOT, "hexagon-got"},
2096 {MO_LO16, "hexagon-lo16"},
2097 {MO_HI16, "hexagon-hi16"},
2098 {MO_GPREL, "hexagon-gprel"},
2099 {MO_GDGOT, "hexagon-gdgot"},
2100 {MO_GDPLT, "hexagon-gdplt"},
2101 {MO_IE, "hexagon-ie"},
2102 {MO_IEGOT, "hexagon-iegot"},
2103 {MO_TPREL, "hexagon-tprel"}
2104 };
2105 return ArrayRef(Flags);
2106}
2107
2110 using namespace HexagonII;
2111
2112 static const std::pair<unsigned, const char*> Flags[] = {
2113 {HMOTF_ConstExtended, "hexagon-ext"}
2114 };
2115 return ArrayRef(Flags);
2116}
2117
2120 const TargetRegisterClass *TRC;
2121 if (VT == MVT::i1) {
2122 TRC = &Hexagon::PredRegsRegClass;
2123 } else if (VT == MVT::i32 || VT == MVT::f32) {
2124 TRC = &Hexagon::IntRegsRegClass;
2125 } else if (VT == MVT::i64 || VT == MVT::f64) {
2126 TRC = &Hexagon::DoubleRegsRegClass;
2127 } else {
2128 llvm_unreachable("Cannot handle this register class");
2129 }
2130
2131 Register NewReg = MRI.createVirtualRegister(TRC);
2132 return NewReg;
2133}
2134
2138
2140 const uint64_t F = MI.getDesc().TSFlags;
2142}
2143
2147
2149 return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&
2150 !MI.getDesc().mayStore() &&
2151 MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&
2152 MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&
2153 !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();
2154}
2155
2156// Return true if the instruction is a compound branch instruction.
2158 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
2159}
2160
2161// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
2162// isFPImm and later getFPImm as well.
2164 const uint64_t F = MI.getDesc().TSFlags;
2166 if (isExtended) // Instruction must be extended.
2167 return true;
2168
2169 unsigned isExtendable =
2171 if (!isExtendable)
2172 return false;
2173
2174 if (MI.isCall())
2175 return false;
2176
2177 short ExtOpNum = getCExtOpNum(MI);
2178 const MachineOperand &MO = MI.getOperand(ExtOpNum);
2179 // Use MO operand flags to determine if MO
2180 // has the HMOTF_ConstExtended flag set.
2182 return true;
2183 // If this is a Machine BB address we are talking about, and it is
2184 // not marked as extended, say so.
2185 if (MO.isMBB())
2186 return false;
2187
2188 // We could be using an instruction with an extendable immediate and shoehorn
2189 // a global address into it. If it is a global address it will be constant
2190 // extended. We do this for COMBINE.
2191 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
2192 MO.isJTI() || MO.isCPI() || MO.isFPImm())
2193 return true;
2194
2195 // If the extendable operand is not 'Immediate' type, the instruction should
2196 // have 'isExtended' flag set.
2197 assert(MO.isImm() && "Extendable operand must be Immediate type");
2198
2199 int64_t Value = MO.getImm();
2201 int32_t SValue = Value;
2202 int32_t MinValue = getMinValue(MI);
2203 int32_t MaxValue = getMaxValue(MI);
2204 return SValue < MinValue || SValue > MaxValue;
2205 }
2206 uint32_t UValue = Value;
2207 uint32_t MinValue = getMinValue(MI);
2208 uint32_t MaxValue = getMaxValue(MI);
2209 return UValue < MinValue || UValue > MaxValue;
2210}
2211
2213 switch (MI.getOpcode()) {
2214 case Hexagon::L4_return:
2215 case Hexagon::L4_return_t:
2216 case Hexagon::L4_return_f:
2217 case Hexagon::L4_return_tnew_pnt:
2218 case Hexagon::L4_return_fnew_pnt:
2219 case Hexagon::L4_return_tnew_pt:
2220 case Hexagon::L4_return_fnew_pt:
2221 return true;
2222 }
2223 return false;
2224}
2225
2226// Return true when ConsMI uses a register defined by ProdMI.
2228 const MachineInstr &ConsMI) const {
2229 if (!ProdMI.getDesc().getNumDefs())
2230 return false;
2231 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
2232
2237
2238 parseOperands(ProdMI, DefsA, UsesA);
2239 parseOperands(ConsMI, DefsB, UsesB);
2240
2241 for (auto &RegA : DefsA)
2242 for (auto &RegB : UsesB) {
2243 // True data dependency.
2244 if (RegA == RegB)
2245 return true;
2246
2247 if (RegA.isPhysical() && llvm::is_contained(HRI.subregs(RegA), RegB))
2248 return true;
2249
2250 if (RegB.isPhysical() && llvm::is_contained(HRI.subregs(RegB), RegA))
2251 return true;
2252 }
2253
2254 return false;
2255}
2256
2257// Returns true if the instruction is already a .cur.
2259 switch (MI.getOpcode()) {
2260 case Hexagon::V6_vL32b_cur_pi:
2261 case Hexagon::V6_vL32b_cur_ai:
2262 return true;
2263 }
2264 return false;
2265}
2266
2267// Returns true, if any one of the operands is a dot new
2268// insn, whether it is predicated dot new or register dot new.
2271 return true;
2272
2273 return false;
2274}
2275
2276/// Symmetrical. See if these two instructions are fit for duplex pair.
2278 const MachineInstr &MIb) const {
2281 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
2282}
2283
2284bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
2285 return (Opcode == Hexagon::ENDLOOP0 ||
2286 Opcode == Hexagon::ENDLOOP1);
2287}
2288
2289bool HexagonInstrInfo::isExpr(unsigned OpType) const {
2290 switch(OpType) {
2297 return true;
2298 default:
2299 return false;
2300 }
2301}
2302
2304 const MCInstrDesc &MID = MI.getDesc();
2305 const uint64_t F = MID.TSFlags;
2307 return true;
2308
2309 // TODO: This is largely obsolete now. Will need to be removed
2310 // in consecutive patches.
2311 switch (MI.getOpcode()) {
2312 // PS_fi and PS_fia remain special cases.
2313 case Hexagon::PS_fi:
2314 case Hexagon::PS_fia:
2315 return true;
2316 default:
2317 return false;
2318 }
2319 return false;
2320}
2321
2322// This returns true in two cases:
2323// - The OP code itself indicates that this is an extended instruction.
2324// - One of MOs has been marked with HMOTF_ConstExtended flag.
2326 // First check if this is permanently extended op code.
2327 const uint64_t F = MI.getDesc().TSFlags;
2329 return true;
2330 // Use MO operand flags to determine if one of MI's operands
2331 // has HMOTF_ConstExtended flag set.
2332 for (const MachineOperand &MO : MI.operands())
2333 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
2334 return true;
2335 return false;
2336}
2337
2339 unsigned Opcode = MI.getOpcode();
2340 const uint64_t F = get(Opcode).TSFlags;
2341 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
2342}
2343
2344// No V60 HVX VMEM with A_INDIRECT.
2346 const MachineInstr &J) const {
2347 if (!isHVXVec(I))
2348 return false;
2349 if (!I.mayLoad() && !I.mayStore())
2350 return false;
2351 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
2352}
2353
2355 switch (MI.getOpcode()) {
2356 case Hexagon::J2_callr:
2357 case Hexagon::J2_callrf:
2358 case Hexagon::J2_callrt:
2359 case Hexagon::PS_call_nr:
2360 return true;
2361 }
2362 return false;
2363}
2364
2366 switch (MI.getOpcode()) {
2367 case Hexagon::L4_return:
2368 case Hexagon::L4_return_t:
2369 case Hexagon::L4_return_f:
2370 case Hexagon::L4_return_fnew_pnt:
2371 case Hexagon::L4_return_fnew_pt:
2372 case Hexagon::L4_return_tnew_pnt:
2373 case Hexagon::L4_return_tnew_pt:
2374 return true;
2375 }
2376 return false;
2377}
2378
2380 switch (MI.getOpcode()) {
2381 case Hexagon::J2_jumpr:
2382 case Hexagon::J2_jumprt:
2383 case Hexagon::J2_jumprf:
2384 case Hexagon::J2_jumprtnewpt:
2385 case Hexagon::J2_jumprfnewpt:
2386 case Hexagon::J2_jumprtnew:
2387 case Hexagon::J2_jumprfnew:
2388 return true;
2389 }
2390 return false;
2391}
2392
2393// Return true if a given MI can accommodate given offset.
2394// Use abs estimate as oppose to the exact number.
2395// TODO: This will need to be changed to use MC level
2396// definition of instruction extendable field size.
2398 unsigned offset) const {
2399 // This selection of jump instructions matches to that what
2400 // analyzeBranch can parse, plus NVJ.
2401 if (isNewValueJump(MI)) // r9:2
2402 return isInt<11>(offset);
2403
2404 switch (MI.getOpcode()) {
2405 // Still missing Jump to address condition on register value.
2406 default:
2407 return false;
2408 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2409 case Hexagon::J2_call:
2410 case Hexagon::PS_call_nr:
2411 return isInt<24>(offset);
2412 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2413 case Hexagon::J2_jumpf:
2414 case Hexagon::J2_jumptnew:
2415 case Hexagon::J2_jumptnewpt:
2416 case Hexagon::J2_jumpfnew:
2417 case Hexagon::J2_jumpfnewpt:
2418 case Hexagon::J2_callt:
2419 case Hexagon::J2_callf:
2420 return isInt<17>(offset);
2421 case Hexagon::J2_loop0i:
2422 case Hexagon::J2_loop0iext:
2423 case Hexagon::J2_loop0r:
2424 case Hexagon::J2_loop0rext:
2425 case Hexagon::J2_loop1i:
2426 case Hexagon::J2_loop1iext:
2427 case Hexagon::J2_loop1r:
2428 case Hexagon::J2_loop1rext:
2429 return isInt<9>(offset);
2430 // TODO: Add all the compound branches here. Can we do this in Relation model?
2431 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2432 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2433 case Hexagon::J4_cmpeqn1_tp0_jump_nt:
2434 case Hexagon::J4_cmpeqn1_tp1_jump_nt:
2435 return isInt<11>(offset);
2436 }
2437}
2438
2440 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2441 // resource, but all operands can be received late like an ALU instruction.
2443}
2444
2446 unsigned Opcode = MI.getOpcode();
2447 return Opcode == Hexagon::J2_loop0i ||
2448 Opcode == Hexagon::J2_loop0r ||
2449 Opcode == Hexagon::J2_loop0iext ||
2450 Opcode == Hexagon::J2_loop0rext ||
2451 Opcode == Hexagon::J2_loop1i ||
2452 Opcode == Hexagon::J2_loop1r ||
2453 Opcode == Hexagon::J2_loop1iext ||
2454 Opcode == Hexagon::J2_loop1rext;
2455}
2456
2458 switch (MI.getOpcode()) {
2459 default: return false;
2460 case Hexagon::L4_iadd_memopw_io:
2461 case Hexagon::L4_isub_memopw_io:
2462 case Hexagon::L4_add_memopw_io:
2463 case Hexagon::L4_sub_memopw_io:
2464 case Hexagon::L4_and_memopw_io:
2465 case Hexagon::L4_or_memopw_io:
2466 case Hexagon::L4_iadd_memoph_io:
2467 case Hexagon::L4_isub_memoph_io:
2468 case Hexagon::L4_add_memoph_io:
2469 case Hexagon::L4_sub_memoph_io:
2470 case Hexagon::L4_and_memoph_io:
2471 case Hexagon::L4_or_memoph_io:
2472 case Hexagon::L4_iadd_memopb_io:
2473 case Hexagon::L4_isub_memopb_io:
2474 case Hexagon::L4_add_memopb_io:
2475 case Hexagon::L4_sub_memopb_io:
2476 case Hexagon::L4_and_memopb_io:
2477 case Hexagon::L4_or_memopb_io:
2478 case Hexagon::L4_ior_memopb_io:
2479 case Hexagon::L4_ior_memoph_io:
2480 case Hexagon::L4_ior_memopw_io:
2481 case Hexagon::L4_iand_memopb_io:
2482 case Hexagon::L4_iand_memoph_io:
2483 case Hexagon::L4_iand_memopw_io:
2484 return true;
2485 }
2486 return false;
2487}
2488
2490 const uint64_t F = MI.getDesc().TSFlags;
2492}
2493
2494bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2495 const uint64_t F = get(Opcode).TSFlags;
2497}
2498
2502
2504 return isNewValue(MI) && MI.isBranch();
2505}
2506
2507bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2508 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2509}
2510
2512 const uint64_t F = MI.getDesc().TSFlags;
2514}
2515
2516bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2517 const uint64_t F = get(Opcode).TSFlags;
2519}
2520
2521// Returns true if a particular operand is extendable for an instruction.
2523 unsigned OperandNum) const {
2524 const uint64_t F = MI.getDesc().TSFlags;
2526 == OperandNum;
2527}
2528
2530 const uint64_t F = MI.getDesc().TSFlags;
2533}
2534
2535bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2536 const uint64_t F = get(Opcode).TSFlags;
2537 assert(isPredicated(Opcode));
2539}
2540
2542 const uint64_t F = MI.getDesc().TSFlags;
2543 return !((F >> HexagonII::PredicatedFalsePos) &
2545}
2546
2547bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2548 const uint64_t F = get(Opcode).TSFlags;
2549 // Make sure that the instruction is predicated.
2551 return !((F >> HexagonII::PredicatedFalsePos) &
2553}
2554
2555bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2556 const uint64_t F = get(Opcode).TSFlags;
2558}
2559
2560bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2561 const uint64_t F = get(Opcode).TSFlags;
2563}
2564
2565bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2566 const uint64_t F = get(Opcode).TSFlags;
2567 assert(get(Opcode).isBranch() &&
2568 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2570}
2571
2573 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2574 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2575 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2576 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
2577}
2578
2580 switch (MI.getOpcode()) {
2581 // Byte
2582 case Hexagon::L2_loadrb_io:
2583 case Hexagon::L4_loadrb_ur:
2584 case Hexagon::L4_loadrb_ap:
2585 case Hexagon::L2_loadrb_pr:
2586 case Hexagon::L2_loadrb_pbr:
2587 case Hexagon::L2_loadrb_pi:
2588 case Hexagon::L2_loadrb_pci:
2589 case Hexagon::L2_loadrb_pcr:
2590 case Hexagon::L2_loadbsw2_io:
2591 case Hexagon::L4_loadbsw2_ur:
2592 case Hexagon::L4_loadbsw2_ap:
2593 case Hexagon::L2_loadbsw2_pr:
2594 case Hexagon::L2_loadbsw2_pbr:
2595 case Hexagon::L2_loadbsw2_pi:
2596 case Hexagon::L2_loadbsw2_pci:
2597 case Hexagon::L2_loadbsw2_pcr:
2598 case Hexagon::L2_loadbsw4_io:
2599 case Hexagon::L4_loadbsw4_ur:
2600 case Hexagon::L4_loadbsw4_ap:
2601 case Hexagon::L2_loadbsw4_pr:
2602 case Hexagon::L2_loadbsw4_pbr:
2603 case Hexagon::L2_loadbsw4_pi:
2604 case Hexagon::L2_loadbsw4_pci:
2605 case Hexagon::L2_loadbsw4_pcr:
2606 case Hexagon::L4_loadrb_rr:
2607 case Hexagon::L2_ploadrbt_io:
2608 case Hexagon::L2_ploadrbt_pi:
2609 case Hexagon::L2_ploadrbf_io:
2610 case Hexagon::L2_ploadrbf_pi:
2611 case Hexagon::L2_ploadrbtnew_io:
2612 case Hexagon::L2_ploadrbfnew_io:
2613 case Hexagon::L4_ploadrbt_rr:
2614 case Hexagon::L4_ploadrbf_rr:
2615 case Hexagon::L4_ploadrbtnew_rr:
2616 case Hexagon::L4_ploadrbfnew_rr:
2617 case Hexagon::L2_ploadrbtnew_pi:
2618 case Hexagon::L2_ploadrbfnew_pi:
2619 case Hexagon::L4_ploadrbt_abs:
2620 case Hexagon::L4_ploadrbf_abs:
2621 case Hexagon::L4_ploadrbtnew_abs:
2622 case Hexagon::L4_ploadrbfnew_abs:
2623 case Hexagon::L2_loadrbgp:
2624 // Half
2625 case Hexagon::L2_loadrh_io:
2626 case Hexagon::L4_loadrh_ur:
2627 case Hexagon::L4_loadrh_ap:
2628 case Hexagon::L2_loadrh_pr:
2629 case Hexagon::L2_loadrh_pbr:
2630 case Hexagon::L2_loadrh_pi:
2631 case Hexagon::L2_loadrh_pci:
2632 case Hexagon::L2_loadrh_pcr:
2633 case Hexagon::L4_loadrh_rr:
2634 case Hexagon::L2_ploadrht_io:
2635 case Hexagon::L2_ploadrht_pi:
2636 case Hexagon::L2_ploadrhf_io:
2637 case Hexagon::L2_ploadrhf_pi:
2638 case Hexagon::L2_ploadrhtnew_io:
2639 case Hexagon::L2_ploadrhfnew_io:
2640 case Hexagon::L4_ploadrht_rr:
2641 case Hexagon::L4_ploadrhf_rr:
2642 case Hexagon::L4_ploadrhtnew_rr:
2643 case Hexagon::L4_ploadrhfnew_rr:
2644 case Hexagon::L2_ploadrhtnew_pi:
2645 case Hexagon::L2_ploadrhfnew_pi:
2646 case Hexagon::L4_ploadrht_abs:
2647 case Hexagon::L4_ploadrhf_abs:
2648 case Hexagon::L4_ploadrhtnew_abs:
2649 case Hexagon::L4_ploadrhfnew_abs:
2650 case Hexagon::L2_loadrhgp:
2651 return true;
2652 default:
2653 return false;
2654 }
2655}
2656
2658 const uint64_t F = MI.getDesc().TSFlags;
2660}
2661
2663 switch (MI.getOpcode()) {
2664 case Hexagon::STriw_pred:
2665 case Hexagon::LDriw_pred:
2666 return true;
2667 default:
2668 return false;
2669 }
2670}
2671
2673 if (!MI.isBranch())
2674 return false;
2675
2676 for (auto &Op : MI.operands())
2677 if (Op.isGlobal() || Op.isSymbol())
2678 return true;
2679 return false;
2680}
2681
2682// Returns true when SU has a timing class TC1.
2684 unsigned SchedClass = MI.getDesc().getSchedClass();
2685 return is_TC1(SchedClass);
2686}
2687
2689 unsigned SchedClass = MI.getDesc().getSchedClass();
2690 return is_TC2(SchedClass);
2691}
2692
2694 unsigned SchedClass = MI.getDesc().getSchedClass();
2695 return is_TC2early(SchedClass);
2696}
2697
2699 unsigned SchedClass = MI.getDesc().getSchedClass();
2700 return is_TC4x(SchedClass);
2701}
2702
2703// Schedule this ASAP.
2705 const MachineInstr &MI2) const {
2706 if (mayBeCurLoad(MI1)) {
2707 // if (result of SU is used in Next) return true;
2708 Register DstReg = MI1.getOperand(0).getReg();
2709 int N = MI2.getNumOperands();
2710 for (int I = 0; I < N; I++)
2711 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())
2712 return true;
2713 }
2714 if (mayBeNewStore(MI2))
2715 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)
2716 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&
2717 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())
2718 return true;
2719 return false;
2720}
2721
2723 const uint64_t V = getType(MI);
2725}
2726
2727// Check if the Offset is a valid auto-inc imm by Load/Store Type.
2729 int Size = VT.getSizeInBits() / 8;
2730 if (Offset % Size != 0)
2731 return false;
2732 int Count = Offset / Size;
2733
2734 switch (VT.getSimpleVT().SimpleTy) {
2735 // For scalars the auto-inc is s4
2736 case MVT::i8:
2737 case MVT::i16:
2738 case MVT::i32:
2739 case MVT::i64:
2740 case MVT::f32:
2741 case MVT::f64:
2742 case MVT::v2i16:
2743 case MVT::v2i32:
2744 case MVT::v4i8:
2745 case MVT::v4i16:
2746 case MVT::v8i8:
2747 return isInt<4>(Count);
2748 // For HVX vectors the auto-inc is s3
2749 case MVT::v64i8:
2750 case MVT::v32i16:
2751 case MVT::v16i32:
2752 case MVT::v8i64:
2753 case MVT::v128i8:
2754 case MVT::v64i16:
2755 case MVT::v32i32:
2756 case MVT::v16i64:
2757 return isInt<3>(Count);
2758 default:
2759 break;
2760 }
2761
2762 llvm_unreachable("Not an valid type!");
2763}
2764
2765bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
2766 const TargetRegisterInfo *TRI, bool Extend) const {
2767 // This function is to check whether the "Offset" is in the correct range of
2768 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
2769 // inserted to calculate the final address. Due to this reason, the function
2770 // assumes that the "Offset" has correct alignment.
2771 // We used to assert if the offset was not properly aligned, however,
2772 // there are cases where a misaligned pointer recast can cause this
2773 // problem, and we need to allow for it. The front end warns of such
2774 // misaligns with respect to load size.
2775 switch (Opcode) {
2776 case Hexagon::PS_vstorerq_ai:
2777 case Hexagon::PS_vstorerv_ai:
2778 case Hexagon::PS_vstorerw_ai:
2779 case Hexagon::PS_vstorerw_nt_ai:
2780 case Hexagon::PS_vloadrq_ai:
2781 case Hexagon::PS_vloadrv_ai:
2782 case Hexagon::PS_vloadrw_ai:
2783 case Hexagon::PS_vloadrw_nt_ai:
2784 case Hexagon::V6_vL32b_ai:
2785 case Hexagon::V6_vS32b_ai:
2786 case Hexagon::V6_vS32b_pred_ai:
2787 case Hexagon::V6_vS32b_npred_ai:
2788 case Hexagon::V6_vS32b_qpred_ai:
2789 case Hexagon::V6_vS32b_nqpred_ai:
2790 case Hexagon::V6_vS32b_new_ai:
2791 case Hexagon::V6_vS32b_new_pred_ai:
2792 case Hexagon::V6_vS32b_new_npred_ai:
2793 case Hexagon::V6_vS32b_nt_pred_ai:
2794 case Hexagon::V6_vS32b_nt_npred_ai:
2795 case Hexagon::V6_vS32b_nt_new_ai:
2796 case Hexagon::V6_vS32b_nt_new_pred_ai:
2797 case Hexagon::V6_vS32b_nt_new_npred_ai:
2798 case Hexagon::V6_vS32b_nt_qpred_ai:
2799 case Hexagon::V6_vS32b_nt_nqpred_ai:
2800 case Hexagon::V6_vL32b_nt_ai:
2801 case Hexagon::V6_vS32b_nt_ai:
2802 case Hexagon::V6_vL32Ub_ai:
2803 case Hexagon::V6_vS32Ub_ai:
2804 case Hexagon::V6_vL32b_cur_ai:
2805 case Hexagon::V6_vL32b_tmp_ai:
2806 case Hexagon::V6_vL32b_pred_ai:
2807 case Hexagon::V6_vL32b_npred_ai:
2808 case Hexagon::V6_vL32b_cur_pred_ai:
2809 case Hexagon::V6_vL32b_cur_npred_ai:
2810 case Hexagon::V6_vL32b_tmp_pred_ai:
2811 case Hexagon::V6_vL32b_tmp_npred_ai:
2812 case Hexagon::V6_vL32b_nt_cur_ai:
2813 case Hexagon::V6_vL32b_nt_tmp_ai:
2814 case Hexagon::V6_vL32b_nt_pred_ai:
2815 case Hexagon::V6_vL32b_nt_npred_ai:
2816 case Hexagon::V6_vL32b_nt_cur_pred_ai:
2817 case Hexagon::V6_vL32b_nt_cur_npred_ai:
2818 case Hexagon::V6_vL32b_nt_tmp_pred_ai:
2819 case Hexagon::V6_vL32b_nt_tmp_npred_ai:
2820 case Hexagon::V6_vS32Ub_npred_ai:
2821 case Hexagon::V6_vgathermh_pseudo:
2822 case Hexagon::V6_vgather_vscatter_mh_pseudo:
2823 case Hexagon::V6_vgathermw_pseudo:
2824 case Hexagon::V6_vgathermhw_pseudo:
2825 case Hexagon::V6_vgathermhq_pseudo:
2826 case Hexagon::V6_vgathermwq_pseudo:
2827 case Hexagon::V6_vgathermhwq_pseudo: {
2828 unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);
2829 assert(isPowerOf2_32(VectorSize));
2830 if (Offset & (VectorSize-1))
2831 return false;
2832 return isInt<4>(Offset >> Log2_32(VectorSize));
2833 }
2834
2835 case Hexagon::J2_loop0i:
2836 case Hexagon::J2_loop1i:
2837 return isUInt<10>(Offset);
2838
2839 case Hexagon::S4_storeirb_io:
2840 case Hexagon::S4_storeirbt_io:
2841 case Hexagon::S4_storeirbf_io:
2842 return isUInt<6>(Offset);
2843
2844 case Hexagon::S4_storeirh_io:
2845 case Hexagon::S4_storeirht_io:
2846 case Hexagon::S4_storeirhf_io:
2847 return isShiftedUInt<6,1>(Offset);
2848
2849 case Hexagon::S4_storeiri_io:
2850 case Hexagon::S4_storeirit_io:
2851 case Hexagon::S4_storeirif_io:
2852 return isShiftedUInt<6,2>(Offset);
2853 // Handle these two compare instructions that are not extendable.
2854 case Hexagon::A4_cmpbeqi:
2855 return isUInt<8>(Offset);
2856 case Hexagon::A4_cmpbgti:
2857 return isInt<8>(Offset);
2858 }
2859
2860 if (Extend)
2861 return true;
2862
2863 switch (Opcode) {
2864 case Hexagon::L2_loadri_io:
2865 case Hexagon::S2_storeri_io:
2866 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2868
2869 case Hexagon::L2_loadrd_io:
2870 case Hexagon::S2_storerd_io:
2871 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2873
2874 case Hexagon::L2_loadrh_io:
2875 case Hexagon::L2_loadruh_io:
2876 case Hexagon::S2_storerh_io:
2877 case Hexagon::S2_storerf_io:
2878 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2880
2881 case Hexagon::L2_loadrb_io:
2882 case Hexagon::L2_loadrub_io:
2883 case Hexagon::S2_storerb_io:
2884 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2886
2887 case Hexagon::A2_addi:
2888 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2890
2891 case Hexagon::L4_iadd_memopw_io:
2892 case Hexagon::L4_isub_memopw_io:
2893 case Hexagon::L4_add_memopw_io:
2894 case Hexagon::L4_sub_memopw_io:
2895 case Hexagon::L4_iand_memopw_io:
2896 case Hexagon::L4_ior_memopw_io:
2897 case Hexagon::L4_and_memopw_io:
2898 case Hexagon::L4_or_memopw_io:
2899 return (0 <= Offset && Offset <= 255);
2900
2901 case Hexagon::L4_iadd_memoph_io:
2902 case Hexagon::L4_isub_memoph_io:
2903 case Hexagon::L4_add_memoph_io:
2904 case Hexagon::L4_sub_memoph_io:
2905 case Hexagon::L4_iand_memoph_io:
2906 case Hexagon::L4_ior_memoph_io:
2907 case Hexagon::L4_and_memoph_io:
2908 case Hexagon::L4_or_memoph_io:
2909 return (0 <= Offset && Offset <= 127);
2910
2911 case Hexagon::L4_iadd_memopb_io:
2912 case Hexagon::L4_isub_memopb_io:
2913 case Hexagon::L4_add_memopb_io:
2914 case Hexagon::L4_sub_memopb_io:
2915 case Hexagon::L4_iand_memopb_io:
2916 case Hexagon::L4_ior_memopb_io:
2917 case Hexagon::L4_and_memopb_io:
2918 case Hexagon::L4_or_memopb_io:
2919 return (0 <= Offset && Offset <= 63);
2920
2921 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
2922 // any size. Later pass knows how to handle it.
2923 case Hexagon::STriw_pred:
2924 case Hexagon::LDriw_pred:
2925 case Hexagon::STriw_ctr:
2926 case Hexagon::LDriw_ctr:
2927 return true;
2928
2929 case Hexagon::PS_fi:
2930 case Hexagon::PS_fia:
2931 case Hexagon::INLINEASM:
2932 return true;
2933
2934 case Hexagon::L2_ploadrbt_io:
2935 case Hexagon::L2_ploadrbf_io:
2936 case Hexagon::L2_ploadrubt_io:
2937 case Hexagon::L2_ploadrubf_io:
2938 case Hexagon::S2_pstorerbt_io:
2939 case Hexagon::S2_pstorerbf_io:
2940 return isUInt<6>(Offset);
2941
2942 case Hexagon::L2_ploadrht_io:
2943 case Hexagon::L2_ploadrhf_io:
2944 case Hexagon::L2_ploadruht_io:
2945 case Hexagon::L2_ploadruhf_io:
2946 case Hexagon::S2_pstorerht_io:
2947 case Hexagon::S2_pstorerhf_io:
2948 return isShiftedUInt<6,1>(Offset);
2949
2950 case Hexagon::L2_ploadrit_io:
2951 case Hexagon::L2_ploadrif_io:
2952 case Hexagon::S2_pstorerit_io:
2953 case Hexagon::S2_pstorerif_io:
2954 return isShiftedUInt<6,2>(Offset);
2955
2956 case Hexagon::L2_ploadrdt_io:
2957 case Hexagon::L2_ploadrdf_io:
2958 case Hexagon::S2_pstorerdt_io:
2959 case Hexagon::S2_pstorerdf_io:
2960 return isShiftedUInt<6,3>(Offset);
2961
2962 case Hexagon::L2_loadbsw2_io:
2963 case Hexagon::L2_loadbzw2_io:
2964 return isShiftedInt<11,1>(Offset);
2965
2966 case Hexagon::L2_loadbsw4_io:
2967 case Hexagon::L2_loadbzw4_io:
2968 return isShiftedInt<11,2>(Offset);
2969 } // switch
2970
2971 dbgs() << "Failed Opcode is : " << Opcode << " (" << getName(Opcode)
2972 << ")\n";
2973 llvm_unreachable("No offset range is defined for this opcode. "
2974 "Please define it in the above switch statement!");
2975}
2976
2978 return isHVXVec(MI) && isAccumulator(MI);
2979}
2980
2982 const uint64_t F = get(MI.getOpcode()).TSFlags;
2984 return
2985 V == HexagonII::TypeCVI_VA ||
2987}
2988
2990 const MachineInstr &ConsMI) const {
2991 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
2992 return true;
2993
2994 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
2995 return true;
2996
2997 if (mayBeNewStore(ConsMI))
2998 return true;
2999
3000 return false;
3001}
3002
3004 switch (MI.getOpcode()) {
3005 // Byte
3006 case Hexagon::L2_loadrub_io:
3007 case Hexagon::L4_loadrub_ur:
3008 case Hexagon::L4_loadrub_ap:
3009 case Hexagon::L2_loadrub_pr:
3010 case Hexagon::L2_loadrub_pbr:
3011 case Hexagon::L2_loadrub_pi:
3012 case Hexagon::L2_loadrub_pci:
3013 case Hexagon::L2_loadrub_pcr:
3014 case Hexagon::L2_loadbzw2_io:
3015 case Hexagon::L4_loadbzw2_ur:
3016 case Hexagon::L4_loadbzw2_ap:
3017 case Hexagon::L2_loadbzw2_pr:
3018 case Hexagon::L2_loadbzw2_pbr:
3019 case Hexagon::L2_loadbzw2_pi:
3020 case Hexagon::L2_loadbzw2_pci:
3021 case Hexagon::L2_loadbzw2_pcr:
3022 case Hexagon::L2_loadbzw4_io:
3023 case Hexagon::L4_loadbzw4_ur:
3024 case Hexagon::L4_loadbzw4_ap:
3025 case Hexagon::L2_loadbzw4_pr:
3026 case Hexagon::L2_loadbzw4_pbr:
3027 case Hexagon::L2_loadbzw4_pi:
3028 case Hexagon::L2_loadbzw4_pci:
3029 case Hexagon::L2_loadbzw4_pcr:
3030 case Hexagon::L4_loadrub_rr:
3031 case Hexagon::L2_ploadrubt_io:
3032 case Hexagon::L2_ploadrubt_pi:
3033 case Hexagon::L2_ploadrubf_io:
3034 case Hexagon::L2_ploadrubf_pi:
3035 case Hexagon::L2_ploadrubtnew_io:
3036 case Hexagon::L2_ploadrubfnew_io:
3037 case Hexagon::L4_ploadrubt_rr:
3038 case Hexagon::L4_ploadrubf_rr:
3039 case Hexagon::L4_ploadrubtnew_rr:
3040 case Hexagon::L4_ploadrubfnew_rr:
3041 case Hexagon::L2_ploadrubtnew_pi:
3042 case Hexagon::L2_ploadrubfnew_pi:
3043 case Hexagon::L4_ploadrubt_abs:
3044 case Hexagon::L4_ploadrubf_abs:
3045 case Hexagon::L4_ploadrubtnew_abs:
3046 case Hexagon::L4_ploadrubfnew_abs:
3047 case Hexagon::L2_loadrubgp:
3048 // Half
3049 case Hexagon::L2_loadruh_io:
3050 case Hexagon::L4_loadruh_ur:
3051 case Hexagon::L4_loadruh_ap:
3052 case Hexagon::L2_loadruh_pr:
3053 case Hexagon::L2_loadruh_pbr:
3054 case Hexagon::L2_loadruh_pi:
3055 case Hexagon::L2_loadruh_pci:
3056 case Hexagon::L2_loadruh_pcr:
3057 case Hexagon::L4_loadruh_rr:
3058 case Hexagon::L2_ploadruht_io:
3059 case Hexagon::L2_ploadruht_pi:
3060 case Hexagon::L2_ploadruhf_io:
3061 case Hexagon::L2_ploadruhf_pi:
3062 case Hexagon::L2_ploadruhtnew_io:
3063 case Hexagon::L2_ploadruhfnew_io:
3064 case Hexagon::L4_ploadruht_rr:
3065 case Hexagon::L4_ploadruhf_rr:
3066 case Hexagon::L4_ploadruhtnew_rr:
3067 case Hexagon::L4_ploadruhfnew_rr:
3068 case Hexagon::L2_ploadruhtnew_pi:
3069 case Hexagon::L2_ploadruhfnew_pi:
3070 case Hexagon::L4_ploadruht_abs:
3071 case Hexagon::L4_ploadruhf_abs:
3072 case Hexagon::L4_ploadruhtnew_abs:
3073 case Hexagon::L4_ploadruhfnew_abs:
3074 case Hexagon::L2_loadruhgp:
3075 return true;
3076 default:
3077 return false;
3078 }
3079}
3080
3081// Add latency to instruction.
3083 const MachineInstr &MI2) const {
3084 if (isHVXVec(MI1) && isHVXVec(MI2))
3085 if (!isVecUsableNextPacket(MI1, MI2))
3086 return true;
3087 return false;
3088}
3089
3090/// Get the base register and byte offset of a load/store instr.
3093 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
3094 const TargetRegisterInfo *TRI) const {
3095 OffsetIsScalable = false;
3096 const MachineOperand *BaseOp = getBaseAndOffset(LdSt, Offset, Width);
3097 if (!BaseOp || !BaseOp->isReg())
3098 return false;
3099 BaseOps.push_back(BaseOp);
3100 return true;
3101}
3102
3103/// Can these instructions execute at the same time in a bundle.
3105 const MachineInstr &Second) const {
3106 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {
3107 const MachineOperand &Op = Second.getOperand(0);
3108 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)
3109 return true;
3110 }
3112 return false;
3113 if (mayBeNewStore(Second)) {
3114 // Make sure the definition of the first instruction is the value being
3115 // stored.
3116 const MachineOperand &Stored =
3117 Second.getOperand(Second.getNumOperands() - 1);
3118 if (!Stored.isReg())
3119 return false;
3120 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {
3121 const MachineOperand &Op = First.getOperand(i);
3122 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
3123 return true;
3124 }
3125 }
3126 return false;
3127}
3128
3130 unsigned Opc = CallMI.getOpcode();
3131 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;
3132}
3133
3135 for (auto &I : *B)
3136 if (I.isEHLabel())
3137 return true;
3138 return false;
3139}
3140
3141// Returns true if an instruction can be converted into a non-extended
3142// equivalent instruction.
3144 short NonExtOpcode;
3145 // Check if the instruction has a register form that uses register in place
3146 // of the extended operand, if so return that as the non-extended form.
3147 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)
3148 return true;
3149
3150 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
3151 // Check addressing mode and retrieve non-ext equivalent instruction.
3152
3153 switch (getAddrMode(MI)) {
3155 // Load/store with absolute addressing mode can be converted into
3156 // base+offset mode.
3157 NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());
3158 break;
3160 // Load/store with base+offset addressing mode can be converted into
3161 // base+register offset addressing mode. However left shift operand should
3162 // be set to 0.
3163 NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());
3164 break;
3166 NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
3167 break;
3168 default:
3169 return false;
3170 }
3171 if (NonExtOpcode < 0)
3172 return false;
3173 return true;
3174 }
3175 return false;
3176}
3177
3179 return Hexagon::getRealHWInstr(MI.getOpcode(),
3180 Hexagon::InstrType_Pseudo) >= 0;
3181}
3182
3184 const {
3185 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
3186 while (I != E) {
3187 if (I->isBarrier())
3188 return true;
3189 ++I;
3190 }
3191 return false;
3192}
3193
3194// Returns true, if a LD insn can be promoted to a cur load.
3196 const uint64_t F = MI.getDesc().TSFlags;
3198 Subtarget.hasV60Ops();
3199}
3200
3201// Returns true, if a ST insn can be promoted to a new-value store.
3203 if (MI.mayStore() && !Subtarget.useNewValueStores())
3204 return false;
3205
3206 const uint64_t F = MI.getDesc().TSFlags;
3208}
3209
3211 const MachineInstr &ConsMI) const {
3212 // There is no stall when ProdMI is not a V60 vector.
3213 if (!isHVXVec(ProdMI))
3214 return false;
3215
3216 // There is no stall when ProdMI and ConsMI are not dependent.
3217 if (!isDependent(ProdMI, ConsMI))
3218 return false;
3219
3220 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
3221 // are scheduled in consecutive packets.
3222 if (isVecUsableNextPacket(ProdMI, ConsMI))
3223 return false;
3224
3225 return true;
3226}
3227
3230 // There is no stall when I is not a V60 vector.
3231 if (!isHVXVec(MI))
3232 return false;
3233
3235 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
3236
3237 if (!MII->isBundle())
3238 return producesStall(*MII, MI);
3239
3240 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
3241 const MachineInstr &J = *MII;
3242 if (producesStall(J, MI))
3243 return true;
3244 }
3245 return false;
3246}
3247
3249 Register PredReg) const {
3250 for (const MachineOperand &MO : MI.operands()) {
3251 // Predicate register must be explicitly defined.
3252 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))
3253 return false;
3254 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
3255 return false;
3256 }
3257
3258 // Instruction that produce late predicate cannot be used as sources of
3259 // dot-new.
3260 switch (MI.getOpcode()) {
3261 case Hexagon::A4_addp_c:
3262 case Hexagon::A4_subp_c:
3263 case Hexagon::A4_tlbmatch:
3264 case Hexagon::A5_ACS:
3265 case Hexagon::F2_sfinvsqrta:
3266 case Hexagon::F2_sfrecipa:
3267 case Hexagon::J2_endloop0:
3268 case Hexagon::J2_endloop01:
3269 case Hexagon::J2_ploop1si:
3270 case Hexagon::J2_ploop1sr:
3271 case Hexagon::J2_ploop2si:
3272 case Hexagon::J2_ploop2sr:
3273 case Hexagon::J2_ploop3si:
3274 case Hexagon::J2_ploop3sr:
3275 case Hexagon::S2_cabacdecbin:
3276 case Hexagon::S2_storew_locked:
3277 case Hexagon::S4_stored_locked:
3278 return false;
3279 }
3280 return true;
3281}
3282
3283bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
3284 return Opcode == Hexagon::J2_jumpt ||
3285 Opcode == Hexagon::J2_jumptpt ||
3286 Opcode == Hexagon::J2_jumpf ||
3287 Opcode == Hexagon::J2_jumpfpt ||
3288 Opcode == Hexagon::J2_jumptnew ||
3289 Opcode == Hexagon::J2_jumpfnew ||
3290 Opcode == Hexagon::J2_jumptnewpt ||
3291 Opcode == Hexagon::J2_jumpfnewpt;
3292}
3293
3295 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
3296 return false;
3297 return !isPredicatedTrue(Cond[0].getImm());
3298}
3299
3301 const uint64_t F = MI.getDesc().TSFlags;
3303}
3304
3305// Returns the base register in a memory access (load/store). The offset is
3306// returned in Offset and the access size is returned in AccessSize.
3307// If the base operand has a subregister or the offset field does not contain
3308// an immediate value, return nullptr.
3311 LocationSize &AccessSize) const {
3312 // Return if it is not a base+offset type instruction or a MemOp.
3316 return nullptr;
3317
3319
3320 unsigned BasePos = 0, OffsetPos = 0;
3321 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
3322 return nullptr;
3323
3324 // Post increment updates its EA after the mem access,
3325 // so we need to treat its offset as zero.
3326 if (isPostIncrement(MI)) {
3327 Offset = 0;
3328 } else {
3329 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
3330 if (!OffsetOp.isImm())
3331 return nullptr;
3332 Offset = OffsetOp.getImm();
3333 }
3334
3335 const MachineOperand &BaseOp = MI.getOperand(BasePos);
3336 if (BaseOp.getSubReg() != 0)
3337 return nullptr;
3338 return &const_cast<MachineOperand&>(BaseOp);
3339}
3340
3341/// Return the position of the base and offset operands for this instruction.
3343 unsigned &BasePos, unsigned &OffsetPos) const {
3345 return false;
3346
3347 // Deal with memops first.
3348 if (isMemOp(MI)) {
3349 BasePos = 0;
3350 OffsetPos = 1;
3351 } else if (MI.mayStore()) {
3352 BasePos = 0;
3353 OffsetPos = 1;
3354 } else if (MI.mayLoad()) {
3355 BasePos = 1;
3356 OffsetPos = 2;
3357 } else
3358 return false;
3359
3360 if (isPredicated(MI)) {
3361 BasePos++;
3362 OffsetPos++;
3363 }
3364 if (isPostIncrement(MI)) {
3365 BasePos++;
3366 OffsetPos++;
3367 }
3368
3369 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
3370 return false;
3371
3372 return true;
3373}
3374
3375// Inserts branching instructions in reverse order of their occurrence.
3376// e.g. jump_t t1 (i1)
3377// jump t2 (i2)
3378// Jumpers = {i2, i1}
3380 MachineBasicBlock& MBB) const {
3382 // If the block has no terminators, it just falls into the block after it.
3384 if (I == MBB.instr_begin())
3385 return Jumpers;
3386
3387 // A basic block may looks like this:
3388 //
3389 // [ insn
3390 // EH_LABEL
3391 // insn
3392 // insn
3393 // insn
3394 // EH_LABEL
3395 // insn ]
3396 //
3397 // It has two succs but does not have a terminator
3398 // Don't know how to handle it.
3399 do {
3400 --I;
3401 if (I->isEHLabel())
3402 return Jumpers;
3403 } while (I != MBB.instr_begin());
3404
3405 I = MBB.instr_end();
3406 --I;
3407
3408 while (I->isDebugInstr()) {
3409 if (I == MBB.instr_begin())
3410 return Jumpers;
3411 --I;
3412 }
3413 if (!isUnpredicatedTerminator(*I))
3414 return Jumpers;
3415
3416 // Get the last instruction in the block.
3417 MachineInstr *LastInst = &*I;
3418 Jumpers.push_back(LastInst);
3419 MachineInstr *SecondLastInst = nullptr;
3420 // Find one more terminator if present.
3421 do {
3422 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
3423 if (!SecondLastInst) {
3424 SecondLastInst = &*I;
3425 Jumpers.push_back(SecondLastInst);
3426 } else // This is a third branch.
3427 return Jumpers;
3428 }
3429 if (I == MBB.instr_begin())
3430 break;
3431 --I;
3432 } while (true);
3433 return Jumpers;
3434}
3435
3436// Returns Operand Index for the constant extended instruction.
3438 const uint64_t F = MI.getDesc().TSFlags;
3440}
3441
3442// See if instruction could potentially be a duplex candidate.
3443// If so, return its group. Zero otherwise.
3445 const MachineInstr &MI) const {
3446 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3447
3448 switch (MI.getOpcode()) {
3449 default:
3450 return HexagonII::HCG_None;
3451 //
3452 // Compound pairs.
3453 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3454 // "Rd16=#U6 ; jump #r9:2"
3455 // "Rd16=Rs16 ; jump #r9:2"
3456 //
3457 case Hexagon::C2_cmpeq:
3458 case Hexagon::C2_cmpgt:
3459 case Hexagon::C2_cmpgtu:
3460 DstReg = MI.getOperand(0).getReg();
3461 Src1Reg = MI.getOperand(1).getReg();
3462 Src2Reg = MI.getOperand(2).getReg();
3463 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3464 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3465 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3466 return HexagonII::HCG_A;
3467 break;
3468 case Hexagon::C2_cmpeqi:
3469 case Hexagon::C2_cmpgti:
3470 case Hexagon::C2_cmpgtui:
3471 // P0 = cmp.eq(Rs,#u2)
3472 DstReg = MI.getOperand(0).getReg();
3473 SrcReg = MI.getOperand(1).getReg();
3474 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3475 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3476 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3477 ((isUInt<5>(MI.getOperand(2).getImm())) ||
3478 (MI.getOperand(2).getImm() == -1)))
3479 return HexagonII::HCG_A;
3480 break;
3481 case Hexagon::A2_tfr:
3482 // Rd = Rs
3483 DstReg = MI.getOperand(0).getReg();
3484 SrcReg = MI.getOperand(1).getReg();
3485 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3486 return HexagonII::HCG_A;
3487 break;
3488 case Hexagon::A2_tfrsi:
3489 // Rd = #u6
3490 // Do not test for #u6 size since the const is getting extended
3491 // regardless and compound could be formed.
3492 DstReg = MI.getOperand(0).getReg();
3493 if (isIntRegForSubInst(DstReg))
3494 return HexagonII::HCG_A;
3495 break;
3496 case Hexagon::S2_tstbit_i:
3497 DstReg = MI.getOperand(0).getReg();
3498 Src1Reg = MI.getOperand(1).getReg();
3499 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3500 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3501 MI.getOperand(2).isImm() &&
3502 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))
3503 return HexagonII::HCG_A;
3504 break;
3505 // The fact that .new form is used pretty much guarantees
3506 // that predicate register will match. Nevertheless,
3507 // there could be some false positives without additional
3508 // checking.
3509 case Hexagon::J2_jumptnew:
3510 case Hexagon::J2_jumpfnew:
3511 case Hexagon::J2_jumptnewpt:
3512 case Hexagon::J2_jumpfnewpt:
3513 Src1Reg = MI.getOperand(0).getReg();
3514 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3515 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3516 return HexagonII::HCG_B;
3517 break;
3518 // Transfer and jump:
3519 // Rd=#U6 ; jump #r9:2
3520 // Rd=Rs ; jump #r9:2
3521 // Do not test for jump range here.
3522 case Hexagon::J2_jump:
3523 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3524 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
3525 return HexagonII::HCG_C;
3526 }
3527
3528 return HexagonII::HCG_None;
3529}
3530
3531// Returns -1 when there is no opcode found.
3533 const MachineInstr &GB) const {
3536 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
3537 (GB.getOpcode() != Hexagon::J2_jumptnew))
3538 return -1u;
3539 Register DestReg = GA.getOperand(0).getReg();
3540 if (!GB.readsRegister(DestReg, /*TRI=*/nullptr))
3541 return -1u;
3542 if (DestReg != Hexagon::P0 && DestReg != Hexagon::P1)
3543 return -1u;
3544 // The value compared against must be either u5 or -1.
3545 const MachineOperand &CmpOp = GA.getOperand(2);
3546 if (!CmpOp.isImm())
3547 return -1u;
3548 int V = CmpOp.getImm();
3549 if (V == -1)
3550 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqn1_tp0_jump_nt
3551 : Hexagon::J4_cmpeqn1_tp1_jump_nt;
3552 if (!isUInt<5>(V))
3553 return -1u;
3554 return DestReg == Hexagon::P0 ? Hexagon::J4_cmpeqi_tp0_jump_nt
3555 : Hexagon::J4_cmpeqi_tp1_jump_nt;
3556}
3557
3558// Returns -1 if there is no opcode found.
3560 bool ForBigCore) const {
3561 // Static table to switch the opcodes across Tiny Core and Big Core.
3562 // dup_ opcodes are Big core opcodes.
3563 // NOTE: There are special instructions that need to handled later.
3564 // L4_return* instructions, they will only occupy SLOT0 (on big core too).
3565 // PS_jmpret - This pseudo translates to J2_jumpr which occupies only SLOT2.
3566 // The compiler need to base the root instruction to L6_return_map_to_raw
3567 // which can go any slot.
3568 static const std::map<unsigned, unsigned> DupMap = {
3569 {Hexagon::A2_add, Hexagon::dup_A2_add},
3570 {Hexagon::A2_addi, Hexagon::dup_A2_addi},
3571 {Hexagon::A2_andir, Hexagon::dup_A2_andir},
3572 {Hexagon::A2_combineii, Hexagon::dup_A2_combineii},
3573 {Hexagon::A2_sxtb, Hexagon::dup_A2_sxtb},
3574 {Hexagon::A2_sxth, Hexagon::dup_A2_sxth},
3575 {Hexagon::A2_tfr, Hexagon::dup_A2_tfr},
3576 {Hexagon::A2_tfrsi, Hexagon::dup_A2_tfrsi},
3577 {Hexagon::A2_zxtb, Hexagon::dup_A2_zxtb},
3578 {Hexagon::A2_zxth, Hexagon::dup_A2_zxth},
3579 {Hexagon::A4_combineii, Hexagon::dup_A4_combineii},
3580 {Hexagon::A4_combineir, Hexagon::dup_A4_combineir},
3581 {Hexagon::A4_combineri, Hexagon::dup_A4_combineri},
3582 {Hexagon::C2_cmoveif, Hexagon::dup_C2_cmoveif},
3583 {Hexagon::C2_cmoveit, Hexagon::dup_C2_cmoveit},
3584 {Hexagon::C2_cmovenewif, Hexagon::dup_C2_cmovenewif},
3585 {Hexagon::C2_cmovenewit, Hexagon::dup_C2_cmovenewit},
3586 {Hexagon::C2_cmpeqi, Hexagon::dup_C2_cmpeqi},
3587 {Hexagon::L2_deallocframe, Hexagon::dup_L2_deallocframe},
3588 {Hexagon::L2_loadrb_io, Hexagon::dup_L2_loadrb_io},
3589 {Hexagon::L2_loadrd_io, Hexagon::dup_L2_loadrd_io},
3590 {Hexagon::L2_loadrh_io, Hexagon::dup_L2_loadrh_io},
3591 {Hexagon::L2_loadri_io, Hexagon::dup_L2_loadri_io},
3592 {Hexagon::L2_loadrub_io, Hexagon::dup_L2_loadrub_io},
3593 {Hexagon::L2_loadruh_io, Hexagon::dup_L2_loadruh_io},
3594 {Hexagon::S2_allocframe, Hexagon::dup_S2_allocframe},
3595 {Hexagon::S2_storerb_io, Hexagon::dup_S2_storerb_io},
3596 {Hexagon::S2_storerd_io, Hexagon::dup_S2_storerd_io},
3597 {Hexagon::S2_storerh_io, Hexagon::dup_S2_storerh_io},
3598 {Hexagon::S2_storeri_io, Hexagon::dup_S2_storeri_io},
3599 {Hexagon::S4_storeirb_io, Hexagon::dup_S4_storeirb_io},
3600 {Hexagon::S4_storeiri_io, Hexagon::dup_S4_storeiri_io},
3601 };
3602 unsigned OpNum = MI.getOpcode();
3603 // Conversion to Big core.
3604 if (ForBigCore) {
3605 auto Iter = DupMap.find(OpNum);
3606 if (Iter != DupMap.end())
3607 return Iter->second;
3608 } else { // Conversion to Tiny core.
3609 for (const auto &Iter : DupMap)
3610 if (Iter.second == OpNum)
3611 return Iter.first;
3612 }
3613 return -1;
3614}
3615
3616int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3617 enum Hexagon::PredSense inPredSense;
3618 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3619 Hexagon::PredSense_true;
3620 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3621 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3622 return CondOpcode;
3623
3624 llvm_unreachable("Unexpected predicable instruction");
3625}
3626
3627// Return the cur value instruction for a given store.
3629 switch (MI.getOpcode()) {
3630 default: llvm_unreachable("Unknown .cur type");
3631 case Hexagon::V6_vL32b_pi:
3632 return Hexagon::V6_vL32b_cur_pi;
3633 case Hexagon::V6_vL32b_ai:
3634 return Hexagon::V6_vL32b_cur_ai;
3635 case Hexagon::V6_vL32b_nt_pi:
3636 return Hexagon::V6_vL32b_nt_cur_pi;
3637 case Hexagon::V6_vL32b_nt_ai:
3638 return Hexagon::V6_vL32b_nt_cur_ai;
3639 case Hexagon::V6_vL32b_ppu:
3640 return Hexagon::V6_vL32b_cur_ppu;
3641 case Hexagon::V6_vL32b_nt_ppu:
3642 return Hexagon::V6_vL32b_nt_cur_ppu;
3643 }
3644 return 0;
3645}
3646
3647// Return the regular version of the .cur instruction.
3649 switch (MI.getOpcode()) {
3650 default: llvm_unreachable("Unknown .cur type");
3651 case Hexagon::V6_vL32b_cur_pi:
3652 return Hexagon::V6_vL32b_pi;
3653 case Hexagon::V6_vL32b_cur_ai:
3654 return Hexagon::V6_vL32b_ai;
3655 case Hexagon::V6_vL32b_nt_cur_pi:
3656 return Hexagon::V6_vL32b_nt_pi;
3657 case Hexagon::V6_vL32b_nt_cur_ai:
3658 return Hexagon::V6_vL32b_nt_ai;
3659 case Hexagon::V6_vL32b_cur_ppu:
3660 return Hexagon::V6_vL32b_ppu;
3661 case Hexagon::V6_vL32b_nt_cur_ppu:
3662 return Hexagon::V6_vL32b_nt_ppu;
3663 }
3664 return 0;
3665}
3666
3667// The diagram below shows the steps involved in the conversion of a predicated
3668// store instruction to its .new predicated new-value form.
3669//
3670// Note: It doesn't include conditional new-value stores as they can't be
3671// converted to .new predicate.
3672//
3673// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3674// ^ ^
3675// / \ (not OK. it will cause new-value store to be
3676// / X conditional on p0.new while R2 producer is
3677// / \ on p0)
3678// / \.
3679// p.new store p.old NV store
3680// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3681// ^ ^
3682// \ /
3683// \ /
3684// \ /
3685// p.old store
3686// [if (p0)memw(R0+#0)=R2]
3687//
3688// The following set of instructions further explains the scenario where
3689// conditional new-value store becomes invalid when promoted to .new predicate
3690// form.
3691//
3692// { 1) if (p0) r0 = add(r1, r2)
3693// 2) p0 = cmp.eq(r3, #0) }
3694//
3695// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3696// the first two instructions because in instr 1, r0 is conditional on old value
3697// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3698// is not valid for new-value stores.
3699// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3700// from the "Conditional Store" list. Because a predicated new value store
3701// would NOT be promoted to a double dot new store. See diagram below:
3702// This function returns yes for those stores that are predicated but not
3703// yet promoted to predicate dot new instructions.
3704//
3705// +---------------------+
3706// /-----| if (p0) memw(..)=r0 |---------\~
3707// || +---------------------+ ||
3708// promote || /\ /\ || promote
3709// || /||\ /||\ ||
3710// \||/ demote || \||/
3711// \/ || || \/
3712// +-------------------------+ || +-------------------------+
3713// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3714// +-------------------------+ || +-------------------------+
3715// || || ||
3716// || demote \||/
3717// promote || \/ NOT possible
3718// || || /\~
3719// \||/ || /||\~
3720// \/ || ||
3721// +-----------------------------+
3722// | if (p0.new) memw(..)=r0.new |
3723// +-----------------------------+
3724// Double Dot New Store
3725//
3726// Returns the most basic instruction for the .new predicated instructions and
3727// new-value stores.
3728// For example, all of the following instructions will be converted back to the
3729// same instruction:
3730// 1) if (p0.new) memw(R0+#0) = R1.new --->
3731// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3732// 3) if (p0.new) memw(R0+#0) = R1 --->
3733//
3734// To understand the translation of instruction 1 to its original form, consider
3735// a packet with 3 instructions.
3736// { p0 = cmp.eq(R0,R1)
3737// if (p0.new) R2 = add(R3, R4)
3738// R5 = add (R3, R1)
3739// }
3740// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3741//
3742// This instruction can be part of the previous packet only if both p0 and R2
3743// are promoted to .new values. This promotion happens in steps, first
3744// predicate register is promoted to .new and in the next iteration R2 is
3745// promoted. Therefore, in case of dependence check failure (due to R5) during
3746// next iteration, it should be converted back to its most basic form.
3747
3748// Return the new value instruction for a given store.
3750 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());
3751 if (NVOpcode >= 0) // Valid new-value store instruction.
3752 return NVOpcode;
3753
3754 switch (MI.getOpcode()) {
3755 default:
3756 report_fatal_error(Twine("Unknown .new type: ") +
3757 std::to_string(MI.getOpcode()));
3758 case Hexagon::S4_storerb_ur:
3759 return Hexagon::S4_storerbnew_ur;
3760
3761 case Hexagon::S2_storerb_pci:
3762 return Hexagon::S2_storerb_pci;
3763
3764 case Hexagon::S2_storeri_pci:
3765 return Hexagon::S2_storeri_pci;
3766
3767 case Hexagon::S2_storerh_pci:
3768 return Hexagon::S2_storerh_pci;
3769
3770 case Hexagon::S2_storerd_pci:
3771 return Hexagon::S2_storerd_pci;
3772
3773 case Hexagon::S2_storerf_pci:
3774 return Hexagon::S2_storerf_pci;
3775
3776 case Hexagon::V6_vS32b_ai:
3777 return Hexagon::V6_vS32b_new_ai;
3778
3779 case Hexagon::V6_vS32b_pi:
3780 return Hexagon::V6_vS32b_new_pi;
3781 }
3782 return 0;
3783}
3784
3785// Returns the opcode to use when converting MI, which is a conditional jump,
3786// into a conditional instruction which uses the .new value of the predicate.
3787// We also use branch probabilities to add a hint to the jump.
3788// If MBPI is null, all edges will be treated as equally likely for the
3789// purposes of establishing a predication hint.
3791 const MachineBranchProbabilityInfo *MBPI) const {
3792 // We assume that block can have at most two successors.
3793 const MachineBasicBlock *Src = MI.getParent();
3794 const MachineOperand &BrTarget = MI.getOperand(1);
3795 bool Taken = false;
3796 const BranchProbability OneHalf(1, 2);
3797
3798 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
3799 const MachineBasicBlock *Dst) {
3800 if (MBPI)
3801 return MBPI->getEdgeProbability(Src, Dst);
3802 return BranchProbability(1, Src->succ_size());
3803 };
3804
3805 if (BrTarget.isMBB()) {
3806 const MachineBasicBlock *Dst = BrTarget.getMBB();
3807 Taken = getEdgeProbability(Src, Dst) >= OneHalf;
3808 } else {
3809 // The branch target is not a basic block (most likely a function).
3810 // Since BPI only gives probabilities for targets that are basic blocks,
3811 // try to identify another target of this branch (potentially a fall-
3812 // -through) and check the probability of that target.
3813 //
3814 // The only handled branch combinations are:
3815 // - one conditional branch,
3816 // - one conditional branch followed by one unconditional branch.
3817 // Otherwise, assume not-taken.
3818 assert(MI.isConditionalBranch());
3819 const MachineBasicBlock &B = *MI.getParent();
3820 bool SawCond = false, Bad = false;
3821 for (const MachineInstr &I : B) {
3822 if (!I.isBranch())
3823 continue;
3824 if (I.isConditionalBranch()) {
3825 SawCond = true;
3826 if (&I != &MI) {
3827 Bad = true;
3828 break;
3829 }
3830 }
3831 if (I.isUnconditionalBranch() && !SawCond) {
3832 Bad = true;
3833 break;
3834 }
3835 }
3836 if (!Bad) {
3838 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
3839 if (NextIt == B.instr_end()) {
3840 // If this branch is the last, look for the fall-through block.
3841 for (const MachineBasicBlock *SB : B.successors()) {
3842 if (!B.isLayoutSuccessor(SB))
3843 continue;
3844 Taken = getEdgeProbability(Src, SB) < OneHalf;
3845 break;
3846 }
3847 } else {
3848 assert(NextIt->isUnconditionalBranch());
3849 // Find the first MBB operand and assume it's the target.
3850 const MachineBasicBlock *BT = nullptr;
3851 for (const MachineOperand &Op : NextIt->operands()) {
3852 if (!Op.isMBB())
3853 continue;
3854 BT = Op.getMBB();
3855 break;
3856 }
3857 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
3858 }
3859 } // if (!Bad)
3860 }
3861
3862 // The Taken flag should be set to something reasonable by this point.
3863
3864 switch (MI.getOpcode()) {
3865 case Hexagon::J2_jumpt:
3866 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
3867 case Hexagon::J2_jumpf:
3868 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
3869
3870 default:
3871 llvm_unreachable("Unexpected jump instruction.");
3872 }
3873}
3874
3875// Return .new predicate version for an instruction.
3877 const MachineBranchProbabilityInfo *MBPI) const {
3878 switch (MI.getOpcode()) {
3879 // Conditional Jumps
3880 case Hexagon::J2_jumpt:
3881 case Hexagon::J2_jumpf:
3882 return getDotNewPredJumpOp(MI, MBPI);
3883 }
3884
3885 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
3886 if (NewOpcode >= 0)
3887 return NewOpcode;
3888 return 0;
3889}
3890
3892 int NewOp = MI.getOpcode();
3893 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3894 NewOp = Hexagon::getPredOldOpcode(NewOp);
3895 // All Hexagon architectures have prediction bits on dot-new branches,
3896 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure
3897 // to pick the right opcode when converting back to dot-old.
3898 if (!Subtarget.hasFeature(Hexagon::ArchV60)) {
3899 switch (NewOp) {
3900 case Hexagon::J2_jumptpt:
3901 NewOp = Hexagon::J2_jumpt;
3902 break;
3903 case Hexagon::J2_jumpfpt:
3904 NewOp = Hexagon::J2_jumpf;
3905 break;
3906 case Hexagon::J2_jumprtpt:
3907 NewOp = Hexagon::J2_jumprt;
3908 break;
3909 case Hexagon::J2_jumprfpt:
3910 NewOp = Hexagon::J2_jumprf;
3911 break;
3912 }
3913 }
3914 assert(NewOp >= 0 &&
3915 "Couldn't change predicate new instruction to its old form.");
3916 }
3917
3918 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3919 NewOp = Hexagon::getNonNVStore(NewOp);
3920 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3921 }
3922
3923 if (Subtarget.hasV60Ops())
3924 return NewOp;
3925
3926 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.
3927 switch (NewOp) {
3928 case Hexagon::J2_jumpfpt:
3929 return Hexagon::J2_jumpf;
3930 case Hexagon::J2_jumptpt:
3931 return Hexagon::J2_jumpt;
3932 case Hexagon::J2_jumprfpt:
3933 return Hexagon::J2_jumprf;
3934 case Hexagon::J2_jumprtpt:
3935 return Hexagon::J2_jumprt;
3936 }
3937 return NewOp;
3938}
3939
3940// See if instruction could potentially be a duplex candidate.
3941// If so, return its group. Zero otherwise.
3943 const MachineInstr &MI) const {
3944 Register DstReg, SrcReg, Src1Reg, Src2Reg;
3945 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
3946
3947 switch (MI.getOpcode()) {
3948 default:
3949 return HexagonII::HSIG_None;
3950 //
3951 // Group L1:
3952 //
3953 // Rd = memw(Rs+#u4:2)
3954 // Rd = memub(Rs+#u4:0)
3955 case Hexagon::L2_loadri_io:
3956 case Hexagon::dup_L2_loadri_io:
3957 DstReg = MI.getOperand(0).getReg();
3958 SrcReg = MI.getOperand(1).getReg();
3959 // Special case this one from Group L2.
3960 // Rd = memw(r29+#u5:2)
3961 if (isIntRegForSubInst(DstReg)) {
3962 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3963 HRI.getStackRegister() == SrcReg &&
3964 MI.getOperand(2).isImm() &&
3965 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))
3966 return HexagonII::HSIG_L2;
3967 // Rd = memw(Rs+#u4:2)
3968 if (isIntRegForSubInst(SrcReg) &&
3969 (MI.getOperand(2).isImm() &&
3970 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))
3971 return HexagonII::HSIG_L1;
3972 }
3973 break;
3974 case Hexagon::L2_loadrub_io:
3975 case Hexagon::dup_L2_loadrub_io:
3976 // Rd = memub(Rs+#u4:0)
3977 DstReg = MI.getOperand(0).getReg();
3978 SrcReg = MI.getOperand(1).getReg();
3979 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3980 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))
3981 return HexagonII::HSIG_L1;
3982 break;
3983 //
3984 // Group L2:
3985 //
3986 // Rd = memh/memuh(Rs+#u3:1)
3987 // Rd = memb(Rs+#u3:0)
3988 // Rd = memw(r29+#u5:2) - Handled above.
3989 // Rdd = memd(r29+#u5:3)
3990 // deallocframe
3991 // [if ([!]p0[.new])] dealloc_return
3992 // [if ([!]p0[.new])] jumpr r31
3993 case Hexagon::L2_loadrh_io:
3994 case Hexagon::L2_loadruh_io:
3995 case Hexagon::dup_L2_loadrh_io:
3996 case Hexagon::dup_L2_loadruh_io:
3997 // Rd = memh/memuh(Rs+#u3:1)
3998 DstReg = MI.getOperand(0).getReg();
3999 SrcReg = MI.getOperand(1).getReg();
4000 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4001 MI.getOperand(2).isImm() &&
4002 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))
4003 return HexagonII::HSIG_L2;
4004 break;
4005 case Hexagon::L2_loadrb_io:
4006 case Hexagon::dup_L2_loadrb_io:
4007 // Rd = memb(Rs+#u3:0)
4008 DstReg = MI.getOperand(0).getReg();
4009 SrcReg = MI.getOperand(1).getReg();
4010 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4011 MI.getOperand(2).isImm() &&
4012 isUInt<3>(MI.getOperand(2).getImm()))
4013 return HexagonII::HSIG_L2;
4014 break;
4015 case Hexagon::L2_loadrd_io:
4016 case Hexagon::dup_L2_loadrd_io:
4017 // Rdd = memd(r29+#u5:3)
4018 DstReg = MI.getOperand(0).getReg();
4019 SrcReg = MI.getOperand(1).getReg();
4020 if (isDblRegForSubInst(DstReg, HRI) &&
4021 Hexagon::IntRegsRegClass.contains(SrcReg) &&
4022 HRI.getStackRegister() == SrcReg &&
4023 MI.getOperand(2).isImm() &&
4024 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4025 return HexagonII::HSIG_L2;
4026 break;
4027 // dealloc_return is not documented in Hexagon Manual, but marked
4028 // with A_SUBINSN attribute in iset_v4classic.py.
4029 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
4030 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
4031 case Hexagon::L4_return:
4032 case Hexagon::L2_deallocframe:
4033 case Hexagon::dup_L2_deallocframe:
4034 return HexagonII::HSIG_L2;
4035 case Hexagon::EH_RETURN_JMPR:
4036 case Hexagon::PS_jmpret:
4037 case Hexagon::SL2_jumpr31:
4038 // jumpr r31
4039 // Actual form JMPR implicit-def %pc, implicit %r31, implicit internal %r0
4040 DstReg = MI.getOperand(0).getReg();
4041 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
4042 return HexagonII::HSIG_L2;
4043 break;
4044 case Hexagon::PS_jmprett:
4045 case Hexagon::PS_jmpretf:
4046 case Hexagon::PS_jmprettnewpt:
4047 case Hexagon::PS_jmpretfnewpt:
4048 case Hexagon::PS_jmprettnew:
4049 case Hexagon::PS_jmpretfnew:
4050 case Hexagon::SL2_jumpr31_t:
4051 case Hexagon::SL2_jumpr31_f:
4052 case Hexagon::SL2_jumpr31_tnew:
4053 case Hexagon::SL2_jumpr31_fnew:
4054 DstReg = MI.getOperand(1).getReg();
4055 SrcReg = MI.getOperand(0).getReg();
4056 // [if ([!]p0[.new])] jumpr r31
4057 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
4058 (Hexagon::P0 == SrcReg)) &&
4059 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
4060 return HexagonII::HSIG_L2;
4061 break;
4062 case Hexagon::L4_return_t:
4063 case Hexagon::L4_return_f:
4064 case Hexagon::L4_return_tnew_pnt:
4065 case Hexagon::L4_return_fnew_pnt:
4066 case Hexagon::L4_return_tnew_pt:
4067 case Hexagon::L4_return_fnew_pt:
4068 // [if ([!]p0[.new])] dealloc_return
4069 SrcReg = MI.getOperand(0).getReg();
4070 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
4071 return HexagonII::HSIG_L2;
4072 break;
4073 //
4074 // Group S1:
4075 //
4076 // memw(Rs+#u4:2) = Rt
4077 // memb(Rs+#u4:0) = Rt
4078 case Hexagon::S2_storeri_io:
4079 case Hexagon::dup_S2_storeri_io:
4080 // Special case this one from Group S2.
4081 // memw(r29+#u5:2) = Rt
4082 Src1Reg = MI.getOperand(0).getReg();
4083 Src2Reg = MI.getOperand(2).getReg();
4084 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4085 isIntRegForSubInst(Src2Reg) &&
4086 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4087 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))
4088 return HexagonII::HSIG_S2;
4089 // memw(Rs+#u4:2) = Rt
4090 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4091 MI.getOperand(1).isImm() &&
4092 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))
4093 return HexagonII::HSIG_S1;
4094 break;
4095 case Hexagon::S2_storerb_io:
4096 case Hexagon::dup_S2_storerb_io:
4097 // memb(Rs+#u4:0) = Rt
4098 Src1Reg = MI.getOperand(0).getReg();
4099 Src2Reg = MI.getOperand(2).getReg();
4100 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4101 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))
4102 return HexagonII::HSIG_S1;
4103 break;
4104 //
4105 // Group S2:
4106 //
4107 // memh(Rs+#u3:1) = Rt
4108 // memw(r29+#u5:2) = Rt
4109 // memd(r29+#s6:3) = Rtt
4110 // memw(Rs+#u4:2) = #U1
4111 // memb(Rs+#u4) = #U1
4112 // allocframe(#u5:3)
4113 case Hexagon::S2_storerh_io:
4114 case Hexagon::dup_S2_storerh_io:
4115 // memh(Rs+#u3:1) = Rt
4116 Src1Reg = MI.getOperand(0).getReg();
4117 Src2Reg = MI.getOperand(2).getReg();
4118 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
4119 MI.getOperand(1).isImm() &&
4120 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))
4121 return HexagonII::HSIG_S1;
4122 break;
4123 case Hexagon::S2_storerd_io:
4124 case Hexagon::dup_S2_storerd_io:
4125 // memd(r29+#s6:3) = Rtt
4126 Src1Reg = MI.getOperand(0).getReg();
4127 Src2Reg = MI.getOperand(2).getReg();
4128 if (isDblRegForSubInst(Src2Reg, HRI) &&
4129 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
4130 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
4131 isShiftedInt<6,3>(MI.getOperand(1).getImm()))
4132 return HexagonII::HSIG_S2;
4133 break;
4134 case Hexagon::S4_storeiri_io:
4135 case Hexagon::dup_S4_storeiri_io:
4136 // memw(Rs+#u4:2) = #U1
4137 Src1Reg = MI.getOperand(0).getReg();
4138 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&
4139 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&
4140 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4141 return HexagonII::HSIG_S2;
4142 break;
4143 case Hexagon::S4_storeirb_io:
4144 case Hexagon::dup_S4_storeirb_io:
4145 // memb(Rs+#u4) = #U1
4146 Src1Reg = MI.getOperand(0).getReg();
4147 if (isIntRegForSubInst(Src1Reg) &&
4148 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&
4149 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
4150 return HexagonII::HSIG_S2;
4151 break;
4152 case Hexagon::S2_allocframe:
4153 case Hexagon::dup_S2_allocframe:
4154 if (MI.getOperand(2).isImm() &&
4155 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
4156 return HexagonII::HSIG_S1;
4157 break;
4158 //
4159 // Group A:
4160 //
4161 // Rx = add(Rx,#s7)
4162 // Rd = Rs
4163 // Rd = #u6
4164 // Rd = #-1
4165 // if ([!]P0[.new]) Rd = #0
4166 // Rd = add(r29,#u6:2)
4167 // Rx = add(Rx,Rs)
4168 // P0 = cmp.eq(Rs,#u2)
4169 // Rdd = combine(#0,Rs)
4170 // Rdd = combine(Rs,#0)
4171 // Rdd = combine(#u2,#U2)
4172 // Rd = add(Rs,#1)
4173 // Rd = add(Rs,#-1)
4174 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4175 // Rd = and(Rs,#1)
4176 case Hexagon::A2_addi:
4177 case Hexagon::dup_A2_addi:
4178 DstReg = MI.getOperand(0).getReg();
4179 SrcReg = MI.getOperand(1).getReg();
4180 if (isIntRegForSubInst(DstReg)) {
4181 // Rd = add(r29,#u6:2)
4182 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
4183 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&
4184 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))
4185 return HexagonII::HSIG_A;
4186 // Rx = add(Rx,#s7)
4187 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&
4188 isInt<7>(MI.getOperand(2).getImm()))
4189 return HexagonII::HSIG_A;
4190 // Rd = add(Rs,#1)
4191 // Rd = add(Rs,#-1)
4192 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
4193 ((MI.getOperand(2).getImm() == 1) ||
4194 (MI.getOperand(2).getImm() == -1)))
4195 return HexagonII::HSIG_A;
4196 }
4197 break;
4198 case Hexagon::A2_add:
4199 case Hexagon::dup_A2_add:
4200 // Rx = add(Rx,Rs)
4201 DstReg = MI.getOperand(0).getReg();
4202 Src1Reg = MI.getOperand(1).getReg();
4203 Src2Reg = MI.getOperand(2).getReg();
4204 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
4205 isIntRegForSubInst(Src2Reg))
4206 return HexagonII::HSIG_A;
4207 break;
4208 case Hexagon::A2_andir:
4209 case Hexagon::dup_A2_andir:
4210 // Same as zxtb.
4211 // Rd16=and(Rs16,#255)
4212 // Rd16=and(Rs16,#1)
4213 DstReg = MI.getOperand(0).getReg();
4214 SrcReg = MI.getOperand(1).getReg();
4215 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
4216 MI.getOperand(2).isImm() &&
4217 ((MI.getOperand(2).getImm() == 1) ||
4218 (MI.getOperand(2).getImm() == 255)))
4219 return HexagonII::HSIG_A;
4220 break;
4221 case Hexagon::A2_tfr:
4222 case Hexagon::dup_A2_tfr:
4223 // Rd = Rs
4224 DstReg = MI.getOperand(0).getReg();
4225 SrcReg = MI.getOperand(1).getReg();
4226 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4227 return HexagonII::HSIG_A;
4228 break;
4229 case Hexagon::A2_tfrsi:
4230 case Hexagon::dup_A2_tfrsi:
4231 // Rd = #u6
4232 // Do not test for #u6 size since the const is getting extended
4233 // regardless and compound could be formed.
4234 // Rd = #-1
4235 DstReg = MI.getOperand(0).getReg();
4236 if (isIntRegForSubInst(DstReg))
4237 return HexagonII::HSIG_A;
4238 break;
4239 case Hexagon::C2_cmoveit:
4240 case Hexagon::C2_cmovenewit:
4241 case Hexagon::C2_cmoveif:
4242 case Hexagon::C2_cmovenewif:
4243 case Hexagon::dup_C2_cmoveit:
4244 case Hexagon::dup_C2_cmovenewit:
4245 case Hexagon::dup_C2_cmoveif:
4246 case Hexagon::dup_C2_cmovenewif:
4247 // if ([!]P0[.new]) Rd = #0
4248 // Actual form:
4249 // %r16 = C2_cmovenewit internal %p0, 0, implicit undef %r16;
4250 DstReg = MI.getOperand(0).getReg();
4251 SrcReg = MI.getOperand(1).getReg();
4252 if (isIntRegForSubInst(DstReg) &&
4253 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
4254 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)
4255 return HexagonII::HSIG_A;
4256 break;
4257 case Hexagon::C2_cmpeqi:
4258 case Hexagon::dup_C2_cmpeqi:
4259 // P0 = cmp.eq(Rs,#u2)
4260 DstReg = MI.getOperand(0).getReg();
4261 SrcReg = MI.getOperand(1).getReg();
4262 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
4263 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
4264 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))
4265 return HexagonII::HSIG_A;
4266 break;
4267 case Hexagon::A2_combineii:
4268 case Hexagon::A4_combineii:
4269 case Hexagon::dup_A2_combineii:
4270 case Hexagon::dup_A4_combineii:
4271 // Rdd = combine(#u2,#U2)
4272 DstReg = MI.getOperand(0).getReg();
4273 if (isDblRegForSubInst(DstReg, HRI) &&
4274 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||
4275 (MI.getOperand(1).isGlobal() &&
4276 isUInt<2>(MI.getOperand(1).getOffset()))) &&
4277 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||
4278 (MI.getOperand(2).isGlobal() &&
4279 isUInt<2>(MI.getOperand(2).getOffset()))))
4280 return HexagonII::HSIG_A;
4281 break;
4282 case Hexagon::A4_combineri:
4283 case Hexagon::dup_A4_combineri:
4284 // Rdd = combine(Rs,#0)
4285 // Rdd = combine(Rs,#0)
4286 DstReg = MI.getOperand(0).getReg();
4287 SrcReg = MI.getOperand(1).getReg();
4288 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4289 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||
4290 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))
4291 return HexagonII::HSIG_A;
4292 break;
4293 case Hexagon::A4_combineir:
4294 case Hexagon::dup_A4_combineir:
4295 // Rdd = combine(#0,Rs)
4296 DstReg = MI.getOperand(0).getReg();
4297 SrcReg = MI.getOperand(2).getReg();
4298 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
4299 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||
4300 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))
4301 return HexagonII::HSIG_A;
4302 break;
4303 case Hexagon::A2_sxtb:
4304 case Hexagon::A2_sxth:
4305 case Hexagon::A2_zxtb:
4306 case Hexagon::A2_zxth:
4307 case Hexagon::dup_A2_sxtb:
4308 case Hexagon::dup_A2_sxth:
4309 case Hexagon::dup_A2_zxtb:
4310 case Hexagon::dup_A2_zxth:
4311 // Rd = sxth/sxtb/zxtb/zxth(Rs)
4312 DstReg = MI.getOperand(0).getReg();
4313 SrcReg = MI.getOperand(1).getReg();
4314 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
4315 return HexagonII::HSIG_A;
4316 break;
4317 }
4318
4319 return HexagonII::HSIG_None;
4320}
4321
4323 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real);
4324}
4325
4327 const InstrItineraryData *ItinData, const MachineInstr &MI) const {
4328 // Default to one cycle for no itinerary. However, an "empty" itinerary may
4329 // still have a MinLatency property, which getStageLatency checks.
4330 if (!ItinData)
4331 return getInstrLatency(ItinData, MI);
4332
4333 if (MI.isTransient())
4334 return 0;
4335 return ItinData->getStageLatency(MI.getDesc().getSchedClass());
4336}
4337
4338/// getOperandLatency - Compute and return the use operand latency of a given
4339/// pair of def and use.
4340/// In most cases, the static scheduling itinerary was enough to determine the
4341/// operand latency. But it may not be possible for instructions with variable
4342/// number of defs / uses.
4343///
4344/// This is a raw interface to the itinerary that may be directly overridden by
4345/// a target. Use computeOperandLatency to get the best estimate of latency.
4347 const InstrItineraryData *ItinData, const MachineInstr &DefMI,
4348 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
4349 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4350
4351 // Get DefIdx and UseIdx for super registers.
4352 const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
4353
4354 if (DefMO.isReg() && DefMO.getReg().isPhysical()) {
4355 if (DefMO.isImplicit()) {
4356 for (MCPhysReg SR : HRI.superregs(DefMO.getReg())) {
4357 int Idx = DefMI.findRegisterDefOperandIdx(SR, &HRI, false, false);
4358 if (Idx != -1) {
4359 DefIdx = Idx;
4360 break;
4361 }
4362 }
4363 }
4364
4365 const MachineOperand &UseMO = UseMI.getOperand(UseIdx);
4366 if (UseMO.isImplicit()) {
4367 for (MCPhysReg SR : HRI.superregs(UseMO.getReg())) {
4368 int Idx = UseMI.findRegisterUseOperandIdx(SR, &HRI, false);
4369 if (Idx != -1) {
4370 UseIdx = Idx;
4371 break;
4372 }
4373 }
4374 }
4375 }
4376
4377 std::optional<unsigned> Latency = TargetInstrInfo::getOperandLatency(
4378 ItinData, DefMI, DefIdx, UseMI, UseIdx);
4379 if (Latency == 0)
4380 // We should never have 0 cycle latency between two instructions unless
4381 // they can be packetized together. However, this decision can't be made
4382 // here.
4383 Latency = 1;
4384 return Latency;
4385}
4386
4387// inverts the predication logic.
4388// p -> NotP
4389// NotP -> P
4392 if (Cond.empty())
4393 return false;
4394 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
4395 Cond[0].setImm(Opc);
4396 return true;
4397}
4398
4400 int InvPredOpcode;
4401 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
4402 : Hexagon::getTruePredOpcode(Opc);
4403 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
4404 return InvPredOpcode;
4405
4406 llvm_unreachable("Unexpected predicated instruction");
4407}
4408
4409// Returns the max value that doesn't need to be extended.
4411 const uint64_t F = MI.getDesc().TSFlags;
4412 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4414 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4416
4417 if (isSigned) // if value is signed
4418 return ~(-1U << (bits - 1));
4419 else
4420 return ~(-1U << bits);
4421}
4422
4423
4425 switch (MI.getOpcode()) {
4426 case Hexagon::L2_loadrbgp:
4427 case Hexagon::L2_loadrdgp:
4428 case Hexagon::L2_loadrhgp:
4429 case Hexagon::L2_loadrigp:
4430 case Hexagon::L2_loadrubgp:
4431 case Hexagon::L2_loadruhgp:
4432 case Hexagon::S2_storerbgp:
4433 case Hexagon::S2_storerbnewgp:
4434 case Hexagon::S2_storerhgp:
4435 case Hexagon::S2_storerhnewgp:
4436 case Hexagon::S2_storerigp:
4437 case Hexagon::S2_storerinewgp:
4438 case Hexagon::S2_storerdgp:
4439 case Hexagon::S2_storerfgp:
4440 return true;
4441 }
4442 const uint64_t F = MI.getDesc().TSFlags;
4443 unsigned addrMode =
4445 // Disallow any base+offset instruction. The assembler does not yet reorder
4446 // based up any zero offset instruction.
4447 return (addrMode == HexagonII::BaseRegOffset ||
4448 addrMode == HexagonII::BaseImmOffset ||
4449 addrMode == HexagonII::BaseLongOffset);
4450}
4451
4453 // Workaround for the Global Scheduler. Sometimes, it creates
4454 // A4_ext as a Pseudo instruction and calls this function to see if
4455 // it can be added to an existing bundle. Since the instruction doesn't
4456 // belong to any BB yet, we can't use getUnits API.
4457 if (MI.getOpcode() == Hexagon::A4_ext)
4458 return false;
4459
4460 unsigned FuncUnits = getUnits(MI);
4461 return HexagonFUnits::isSlot0Only(FuncUnits);
4462}
4463
4465 const uint64_t F = MI.getDesc().TSFlags;
4468}
4469
4471 bool ToBigInstrs) const {
4472 int Opcode = -1;
4473 if (ToBigInstrs) { // To BigCore Instr.
4474 // Check if the instruction can form a Duplex.
4475 if (getDuplexCandidateGroup(*MII))
4476 // Get the opcode marked "dup_*" tag.
4477 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4478 } else // To TinyCore Instr.
4479 Opcode = getDuplexOpcode(*MII, ToBigInstrs);
4480
4481 // Change the opcode of the instruction.
4482 if (Opcode >= 0)
4483 MII->setDesc(get(Opcode));
4484}
4485
4486// This function is used to translate instructions to facilitate generating
4487// Duplexes on TinyCore.
4489 bool ToBigInstrs) const {
4490 for (auto &MB : MF)
4491 for (MachineBasicBlock::instr_iterator Instr = MB.instr_begin(),
4492 End = MB.instr_end();
4493 Instr != End; ++Instr)
4494 changeDuplexOpcode(Instr, ToBigInstrs);
4495}
4496
4497// This is a specialized form of above function.
4499 MachineBasicBlock::instr_iterator MII, bool ToBigInstrs) const {
4500 MachineBasicBlock *MBB = MII->getParent();
4501 while ((MII != MBB->instr_end()) && MII->isInsideBundle()) {
4502 changeDuplexOpcode(MII, ToBigInstrs);
4503 ++MII;
4504 }
4505}
4506
4508 using namespace HexagonII;
4509
4510 const uint64_t F = MI.getDesc().TSFlags;
4511 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
4512 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
4513 if (Size != 0)
4514 return Size;
4515 // Y2_dcfetchbo is special
4516 if (MI.getOpcode() == Hexagon::Y2_dcfetchbo)
4518
4519 // Handle vector access sizes.
4520 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
4521 switch (S) {
4523 return HRI.getSpillSize(Hexagon::HvxVRRegClass);
4524 default:
4525 llvm_unreachable("Unexpected instruction");
4526 }
4527}
4528
4529// Returns the min value that doesn't need to be extended.
4531 const uint64_t F = MI.getDesc().TSFlags;
4532 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4534 unsigned bits = (F >> HexagonII::ExtentBitsPos)
4536
4537 if (isSigned) // if value is signed
4538 return -1U << (bits - 1);
4539 else
4540 return 0;
4541}
4542
4543// Returns opcode of the non-extended equivalent instruction.
4545 // Check if the instruction has a register form that uses register in place
4546 // of the extended operand, if so return that as the non-extended form.
4547 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());
4548 if (NonExtOpcode >= 0)
4549 return NonExtOpcode;
4550
4551 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
4552 // Check addressing mode and retrieve non-ext equivalent instruction.
4553 switch (getAddrMode(MI)) {
4555 return Hexagon::changeAddrMode_abs_io(MI.getOpcode());
4557 return Hexagon::changeAddrMode_io_rr(MI.getOpcode());
4559 return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
4560
4561 default:
4562 return -1;
4563 }
4564 }
4565 return -1;
4566}
4567
4569 Register &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {
4570 if (Cond.empty())
4571 return false;
4572 assert(Cond.size() == 2);
4573 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
4574 LLVM_DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
4575 return false;
4576 }
4577 PredReg = Cond[1].getReg();
4578 PredRegPos = 1;
4579 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
4580 PredRegFlags = 0;
4581 if (Cond[1].isImplicit())
4582 PredRegFlags = RegState::Implicit;
4583 if (Cond[1].isUndef())
4584 PredRegFlags |= RegState::Undef;
4585 return true;
4586}
4587
4589 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo);
4590}
4591
4593 return Hexagon::getRegForm(MI.getOpcode());
4594}
4595
4596// Return the number of bytes required to encode the instruction.
4597// Hexagon instructions are fixed length, 4 bytes, unless they
4598// use a constant extender, which requires another 4 bytes.
4599// For debug instructions and prolog labels, return 0.
4601 if (MI.isDebugInstr() || MI.isPosition())
4602 return 0;
4603
4604 unsigned Size = MI.getDesc().getSize();
4605 if (!Size)
4606 // Assume the default insn size in case it cannot be determined
4607 // for whatever reason.
4609
4612
4613 // Try and compute number of instructions in asm.
4614 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {
4615 const MachineBasicBlock &MBB = *MI.getParent();
4616 const MachineFunction *MF = MBB.getParent();
4617 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
4618
4619 // Count the number of register definitions to find the asm string.
4620 unsigned NumDefs = 0;
4621 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();
4622 ++NumDefs)
4623 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");
4624
4625 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");
4626 // Disassemble the AsmStr and approximate number of instructions.
4627 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();
4628 Size = getInlineAsmLength(AsmStr, *MAI);
4629 }
4630
4631 return Size;
4632}
4633
4635 const uint64_t F = MI.getDesc().TSFlags;
4637}
4638
4640 const InstrItineraryData &II = *Subtarget.getInstrItineraryData();
4641 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());
4642
4643 return IS.getUnits();
4644}
4645
4646// Calculate size of the basic block without debug instructions.
4648 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4649}
4650
4652 MachineBasicBlock::const_iterator BundleHead) const {
4653 assert(BundleHead->isBundle() && "Not a bundle header");
4654 auto MII = BundleHead.getInstrIterator();
4655 // Skip the bundle header.
4656 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));
4657}
4658
4659/// immediateExtend - Changes the instruction in place to one using an immediate
4660/// extender.
4663 "Instruction must be extendable");
4664 // Find which operand is extendable.
4665 short ExtOpNum = getCExtOpNum(MI);
4666 MachineOperand &MO = MI.getOperand(ExtOpNum);
4667 // This needs to be something we understand.
4668 assert((MO.isMBB() || MO.isImm()) &&
4669 "Branch with unknown extendable field type");
4670 // Mark given operand as extended.
4672}
4673
4675 MachineInstr &MI, MachineBasicBlock *NewTarget) const {
4676 LLVM_DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "
4677 << printMBBReference(*NewTarget);
4678 MI.dump(););
4679 assert(MI.isBranch());
4680 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());
4681 int TargetPos = MI.getNumOperands() - 1;
4682 // In general branch target is the last operand,
4683 // but some implicit defs added at the end might change it.
4684 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())
4685 --TargetPos;
4686 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());
4687 MI.getOperand(TargetPos).setMBB(NewTarget);
4689 NewOpcode = reversePrediction(NewOpcode);
4690 }
4691 MI.setDesc(get(NewOpcode));
4692 return true;
4693}
4694
4696 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4698 MachineBasicBlock &B = *A;
4700 DebugLoc DL = I->getDebugLoc();
4701 MachineInstr *NewMI;
4702
4703 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4704 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
4705 NewMI = BuildMI(B, I, DL, get(insn));
4706 LLVM_DEBUG(dbgs() << "\n"
4707 << getName(NewMI->getOpcode())
4708 << " Class: " << NewMI->getDesc().getSchedClass());
4709 NewMI->eraseFromParent();
4710 }
4711 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4712}
4713
4714// inverts the predication logic.
4715// p -> NotP
4716// NotP -> P
4718 LLVM_DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());
4719 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));
4720 return true;
4721}
4722
4723// Reverse the branch prediction.
4724unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4725 int PredRevOpcode = -1;
4726 if (isPredictedTaken(Opcode))
4727 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4728 else
4729 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4730 assert(PredRevOpcode > 0);
4731 return PredRevOpcode;
4732}
4733
4734// TODO: Add more rigorous validation.
4736 const {
4737 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4738}
4739
4742 assert(MIB->isBundle());
4743 MachineOperand &Operand = MIB->getOperand(0);
4744 if (Operand.isImm())
4745 Operand.setImm(Operand.getImm() | memShufDisabledMask);
4746 else
4747 MIB->addOperand(MachineOperand::CreateImm(memShufDisabledMask));
4748}
4749
4751 assert(MIB.isBundle());
4752 const MachineOperand &Operand = MIB.getOperand(0);
4753 return (Operand.isImm() && (Operand.getImm() & memShufDisabledMask) != 0);
4754}
4755
4756// Addressing mode relations.
4758 return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
4759}
4760
4762 return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;
4763}
4764
4766 return Opc >= 0 ? Hexagon::changeAddrMode_io_pi(Opc) : Opc;
4767}
4768
4770 return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;
4771}
4772
4774 return Opc >= 0 ? Hexagon::changeAddrMode_pi_io(Opc) : Opc;
4775}
4776
4778 return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;
4779}
4780
4782 return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;
4783}
4784
4786 return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;
4787}
4788
4790 static const MCInst Nop = MCInstBuilder(Hexagon::A2_nop);
4791
4792 return MCInstBuilder(Hexagon::BUNDLE)
4793 .addImm(0)
4794 .addInst(&Nop);
4795}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool mayAlias(MachineInstr &MIa, SmallVectorImpl< MachineInstr * > &MemInsns, AliasAnalysis *AA)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 int Opcode)
const HexagonInstrInfo * TII
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 void parseOperands(const MachineInstr &MI, SmallVectorImpl< Register > &Defs, SmallVectorImpl< Register > &Uses)
Gather register def/uses from MI.
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:55
#define I(x, y, z)
Definition MD5.cpp:58
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, 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 unsigned 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:480
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
A debug info location.
Definition DebugLoc.h:124
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
bool isPredictedTaken(unsigned Opcode) const
bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) 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 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 getPredReg(ArrayRef< MachineOperand > Cond, Register &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const
bool isPredicatedNew(const MachineInstr &MI) const
bool isSignExtendingLoad(const MachineInstr &MI) const
bool isVecAcc(const MachineInstr &MI) const
bool reversePredSense(MachineInstr &MI) 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.
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 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.
InstrStage::FuncUnits getUnits(const MachineInstr &MI) const
unsigned getMemAccessSize(const MachineInstr &MI) const
bool predOpcodeHasNot(ArrayRef< MachineOperand > Cond) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, 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 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
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 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 isFloat(const MachineInstr &MI) const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
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 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...
void stepForward(const MachineInstr &MI, SmallVectorImpl< std::pair< MCPhysReg, const MachineOperand * > > &Clobbers)
Simulates liveness when stepping forward over an instruction(bundle).
void stepBackward(const MachineInstr &MI)
Simulates liveness when stepping backwards over an instruction(bundle).
void addLiveIns(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB.
bool available(const MachineRegisterInfo &MRI, MCRegister Reg) const
Returns true if register Reg and no aliasing register is in the set.
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:64
virtual unsigned getMaxInstLength(const MCSubtargetInfo *STI=nullptr) const
Returns the maximum possible encoded instruction size in bytes.
Definition MCAsmInfo.h:527
StringRef getCommentString() const
Definition MCAsmInfo.h:538
const char * getSeparatorString() const
Definition MCAsmInfo.h:533
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
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
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.
const MachineBasicBlock * getParent() const
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
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 DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
bool isIndirectBranch(QueryType Type=AnyInBundle) const
Return true if this is an indirect branch, such as a branch through a register.
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
void setImm(int64_t immVal)
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
unsigned getTargetFlags() const
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
void addTargetFlag(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
bool isFPImm() const
isFPImm - Tests if this is a MO_FPImmediate operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Special value supplied for machine level alias analysis.
Wrapper class representing virtual and physical registers.
Definition Register.h:19
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:78
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
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition StringRef.h:146
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:140
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition StringRef.h:453
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
unsigned const TypeCVI_FIRST
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ InternalRead
Register reads a value that is defined inside the same instruction or bundle.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
@ Length
Definition DWP.cpp:477
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:1725
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:165
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:331
auto reverse(ContainerTy &&C)
Definition STLExtras.h:406
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:279
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:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)
Returns an iterator pointing beyond the bundle containing I.
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:71
bool is_TC2(unsigned SchedClass)
unsigned getUndefRegState(bool B)
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
bool is_TC2early(unsigned SchedClass)
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
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:182
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:1897
bool isSpace(char C)
Checks whether character C is whitespace in the "C" locale.
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:198
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
bool is_TC4x(unsigned SchedClass)
#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:373
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:316
These values represent a non-pipelined step in the execution of an instruction.
uint64_t FuncUnits
Bitmask representing a set of functional units.
FuncUnits getUnits() const
Returns the choice of FUs.
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.