1 //===----- HexagonMCChecker.h - Instruction bundle checking ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This implements the checking of insns inside a bundle according to the 11 // packet constraint rules of the Hexagon ISA. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef HEXAGONMCCHECKER_H 16 #define HEXAGONMCCHECKER_H 17 18 #include <map> 19 #include <set> 20 #include <queue> 21 #include "MCTargetDesc/HexagonMCShuffler.h" 22 23 using namespace llvm; 24 25 namespace llvm { 26 class MCOperandInfo; 27 28 typedef struct { 29 unsigned Error, Warning, ShuffleError; 30 unsigned Register; 31 } ErrInfo_T; 32 33 class HexagonMCErrInfo { 34 public: 35 enum { 36 CHECK_SUCCESS = 0, 37 // Errors. 38 CHECK_ERROR_BRANCHES = 0x00001, 39 CHECK_ERROR_NEWP = 0x00002, 40 CHECK_ERROR_NEWV = 0x00004, 41 CHECK_ERROR_REGISTERS = 0x00008, 42 CHECK_ERROR_READONLY = 0x00010, 43 CHECK_ERROR_LOOP = 0x00020, 44 CHECK_ERROR_ENDLOOP = 0x00040, 45 CHECK_ERROR_SOLO = 0x00080, 46 CHECK_ERROR_SHUFFLE = 0x00100, 47 CHECK_ERROR_NOSLOTS = 0x00200, 48 CHECK_ERROR_UNKNOWN = 0x00400, 49 // Warnings. 50 CHECK_WARN_CURRENT = 0x10000, 51 CHECK_WARN_TEMPORARY = 0x20000 52 }; 53 ErrInfo_T s; 54 reset()55 void reset() { 56 s.Error = CHECK_SUCCESS; 57 s.Warning = CHECK_SUCCESS; 58 s.ShuffleError = HexagonShuffler::SHUFFLE_SUCCESS; 59 s.Register = Hexagon::NoRegister; 60 }; HexagonMCErrInfo()61 HexagonMCErrInfo() { 62 reset(); 63 }; 64 65 void setError(unsigned e, unsigned r = Hexagon::NoRegister) 66 { s.Error = e; s.Register = r; }; 67 void setWarning(unsigned w, unsigned r = Hexagon::NoRegister) 68 { s.Warning = w; s.Register = r; }; setShuffleError(unsigned e)69 void setShuffleError(unsigned e) { s.ShuffleError = e; }; 70 }; 71 72 /// Check for a valid bundle. 73 class HexagonMCChecker { 74 /// Insn bundle. 75 MCInst& MCB; 76 MCInst& MCBDX; 77 const MCRegisterInfo& RI; 78 MCInstrInfo const &MCII; 79 MCSubtargetInfo const &STI; 80 bool bLoadErrInfo; 81 82 /// Set of definitions: register #, if predicated, if predicated true. 83 typedef std::pair<unsigned, bool> PredSense; 84 static const PredSense Unconditional; 85 typedef std::multiset<PredSense> PredSet; 86 typedef std::multiset<PredSense>::iterator PredSetIterator; 87 88 typedef llvm::DenseMap<unsigned, PredSet>::iterator DefsIterator; 89 llvm::DenseMap<unsigned, PredSet> Defs; 90 91 /// Information about how a new-value register is defined or used: 92 /// PredReg = predicate register, 0 if use/def not predicated, 93 /// Cond = true/false for if(PredReg)/if(!PredReg) respectively, 94 /// IsFloat = true if definition produces a floating point value 95 /// (not valid for uses), 96 /// IsNVJ = true if the use is a new-value branch (not valid for 97 /// definitions). 98 struct NewSense { 99 unsigned PredReg; 100 bool IsFloat, IsNVJ, Cond; 101 // The special-case "constructors": JmpNewSense102 static NewSense Jmp(bool isNVJ) { 103 NewSense NS = { /*PredReg=*/ 0, /*IsFloat=*/ false, /*IsNVJ=*/ isNVJ, 104 /*Cond=*/ false }; 105 return NS; 106 } UseNewSense107 static NewSense Use(unsigned PR, bool True) { 108 NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ false, /*IsNVJ=*/ false, 109 /*Cond=*/ True }; 110 return NS; 111 } DefNewSense112 static NewSense Def(unsigned PR, bool True, bool Float) { 113 NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ Float, /*IsNVJ=*/ false, 114 /*Cond=*/ True }; 115 return NS; 116 } 117 }; 118 /// Set of definitions that produce new register: 119 typedef llvm::SmallVector<NewSense,2> NewSenseList; 120 typedef llvm::DenseMap<unsigned, NewSenseList>::iterator NewDefsIterator; 121 llvm::DenseMap<unsigned, NewSenseList> NewDefs; 122 123 /// Set of weak definitions whose clashes should be enforced selectively. 124 typedef std::set<unsigned>::iterator SoftDefsIterator; 125 std::set<unsigned> SoftDefs; 126 127 /// Set of current definitions committed to the register file. 128 typedef std::set<unsigned>::iterator CurDefsIterator; 129 std::set<unsigned> CurDefs; 130 131 /// Set of temporary definitions not committed to the register file. 132 typedef std::set<unsigned>::iterator TmpDefsIterator; 133 std::set<unsigned> TmpDefs; 134 135 /// Set of new predicates used. 136 typedef std::set<unsigned>::iterator NewPredsIterator; 137 std::set<unsigned> NewPreds; 138 139 /// Set of predicates defined late. 140 typedef std::multiset<unsigned>::iterator LatePredsIterator; 141 std::multiset<unsigned> LatePreds; 142 143 /// Set of uses. 144 typedef std::set<unsigned>::iterator UsesIterator; 145 std::set<unsigned> Uses; 146 147 /// Set of new values used: new register, if new-value jump. 148 typedef llvm::DenseMap<unsigned, NewSense>::iterator NewUsesIterator; 149 llvm::DenseMap<unsigned, NewSense> NewUses; 150 151 /// Pre-defined set of read-only registers. 152 typedef std::set<unsigned>::iterator ReadOnlyIterator; 153 std::set<unsigned> ReadOnly; 154 155 std::queue<ErrInfo_T> ErrInfoQ; 156 HexagonMCErrInfo CrntErrInfo; 157 getErrInfo()158 void getErrInfo() { 159 if (bLoadErrInfo == true) { 160 if (ErrInfoQ.empty()) { 161 CrntErrInfo.reset(); 162 } else { 163 CrntErrInfo.s = ErrInfoQ.front(); 164 ErrInfoQ.pop(); 165 } 166 } 167 bLoadErrInfo = false; 168 } 169 170 void init(); 171 void init(MCInst const&); 172 173 // Checks performed. 174 bool checkBranches(); 175 bool checkPredicates(); 176 bool checkNewValues(); 177 bool checkRegisters(); 178 bool checkSolo(); 179 bool checkShuffle(); 180 bool checkSlots(); 181 182 static void compoundRegisterMap(unsigned&); 183 isPredicateRegister(unsigned R)184 bool isPredicateRegister(unsigned R) const { 185 return (Hexagon::P0 == R || Hexagon::P1 == R || 186 Hexagon::P2 == R || Hexagon::P3 == R); 187 }; isLoopRegister(unsigned R)188 bool isLoopRegister(unsigned R) const { 189 return (Hexagon::SA0 == R || Hexagon::LC0 == R || 190 Hexagon::SA1 == R || Hexagon::LC1 == R); 191 }; 192 193 bool hasValidNewValueDef(const NewSense &Use, 194 const NewSenseList &Defs) const; 195 196 public: 197 explicit HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst& mcb, MCInst &mcbdx, 198 const MCRegisterInfo& ri); 199 200 bool check(); 201 202 /// add a new error/warning addErrInfo(HexagonMCErrInfo & err)203 void addErrInfo(HexagonMCErrInfo &err) { ErrInfoQ.push(err.s); }; 204 205 /// Return the error code for the last operation in the insn bundle. getError()206 unsigned getError() { getErrInfo(); return CrntErrInfo.s.Error; }; getWarning()207 unsigned getWarning() { getErrInfo(); return CrntErrInfo.s.Warning; }; getShuffleError()208 unsigned getShuffleError() { getErrInfo(); return CrntErrInfo.s.ShuffleError; }; getErrRegister()209 unsigned getErrRegister() { getErrInfo(); return CrntErrInfo.s.Register; }; getNextErrInfo()210 bool getNextErrInfo() { 211 bLoadErrInfo = true; 212 return (ErrInfoQ.empty()) ? false : (getErrInfo(), true); 213 } 214 }; 215 216 } 217 218 #endif // HEXAGONMCCHECKER_H 219