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
25namespace llvm {
26
27class MCContext;
28class MCInst;
29class MCInstrInfo;
30class MCRegisterInfo;
31class MCSubtargetInfo;
32
33/// Check for a valid bundle.
34class 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
110public:
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