1 //===- HexagonMCChecker.h - Instruction bundle checking ---------*- C++ -*-===// 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 implements the checking of insns inside a bundle according to the 10 // packet constraint rules of the Hexagon ISA. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H 15 #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H 16 17 #include "MCTargetDesc/HexagonMCInstrInfo.h" 18 #include "MCTargetDesc/HexagonMCTargetDesc.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/Support/SMLoc.h" 22 #include <set> 23 #include <utility> 24 25 namespace llvm { 26 27 class MCContext; 28 class MCInst; 29 class MCInstrInfo; 30 class MCRegisterInfo; 31 class MCSubtargetInfo; 32 33 /// Check for a valid bundle. 34 class HexagonMCChecker { 35 MCContext &Context; 36 MCInst &MCB; 37 const MCRegisterInfo &RI; 38 MCInstrInfo const &MCII; 39 MCSubtargetInfo const &STI; 40 bool ReportErrors; 41 42 /// Set of definitions: register #, if predicated, if predicated true. 43 using PredSense = std::pair<unsigned, bool>; 44 static const PredSense Unconditional; 45 using PredSet = std::multiset<PredSense>; 46 using PredSetIterator = std::multiset<PredSense>::iterator; 47 48 using DefsIterator = DenseMap<unsigned, PredSet>::iterator; 49 DenseMap<unsigned, PredSet> Defs; 50 51 /// Set of weak definitions whose clashes should be enforced selectively. 52 using SoftDefsIterator = std::set<unsigned>::iterator; 53 std::set<unsigned> SoftDefs; 54 55 /// Set of temporary definitions not committed to the register file. 56 using TmpDefsIterator = std::set<unsigned>::iterator; 57 std::set<unsigned> TmpDefs; 58 59 /// Set of new predicates used. 60 using NewPredsIterator = std::set<unsigned>::iterator; 61 std::set<unsigned> NewPreds; 62 63 /// Set of predicates defined late. 64 using LatePredsIterator = std::multiset<unsigned>::iterator; 65 std::multiset<unsigned> LatePreds; 66 67 /// Set of uses. 68 using UsesIterator = std::set<unsigned>::iterator; 69 std::set<unsigned> Uses; 70 71 /// Pre-defined set of read-only registers. 72 using ReadOnlyIterator = std::set<unsigned>::iterator; 73 std::set<unsigned> ReadOnly; 74 75 void init(); 76 void init(MCInst const &); 77 void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue); 78 79 bool registerUsed(unsigned Register); 80 std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo> 81 registerProducer(unsigned Register, 82 HexagonMCInstrInfo::PredicateInfo Predicated); 83 84 // Checks performed. 85 bool checkBranches(); 86 bool checkPredicates(); 87 bool checkNewValues(); 88 bool checkRegisters(); 89 bool checkRegistersReadOnly(); 90 void checkRegisterCurDefs(); 91 bool checkSolo(); 92 bool checkShuffle(); 93 bool checkSlots(); 94 bool checkAXOK(); 95 bool checkHWLoop(); 96 bool checkCOFMax1(); 97 98 static void compoundRegisterMap(unsigned &); 99 100 bool isPredicateRegister(unsigned R) const { 101 return (Hexagon::P0 == R || Hexagon::P1 == R || Hexagon::P2 == R || 102 Hexagon::P3 == R); 103 } 104 105 bool isLoopRegister(unsigned R) const { 106 return (Hexagon::SA0 == R || Hexagon::LC0 == R || Hexagon::SA1 == R || 107 Hexagon::LC1 == R); 108 } 109 110 public: 111 explicit HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII, 112 MCSubtargetInfo const &STI, MCInst &mcb, 113 const MCRegisterInfo &ri, bool ReportErrors = true); 114 explicit HexagonMCChecker(HexagonMCChecker const &Check, 115 MCSubtargetInfo const &STI, bool CopyReportErrors); 116 117 bool check(bool FullCheck = true); 118 void reportErrorRegisters(unsigned Register); 119 void reportErrorNewValue(unsigned Register); 120 void reportError(SMLoc Loc, Twine const &Msg); 121 void reportNote(SMLoc Loc, Twine const &Msg); 122 void reportError(Twine const &Msg); 123 void reportWarning(Twine const &Msg); 124 void reportBranchErrors(); 125 }; 126 127 } // end namespace llvm 128 129 #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H 130