aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
blob: dbd3d8ae45e6a860ad63c4b64fdea29893f0f8ef (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//===- HexagonMCChecker.h - Instruction bundle checking ---------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This implements the checking of insns inside a bundle according to the
// packet constraint rules of the Hexagon ISA.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H

#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/SMLoc.h"
#include <set>
#include <utility>

namespace llvm {

class MCContext;
class MCInst;
class MCInstrInfo;
class MCRegisterInfo;
class MCSubtargetInfo;

/// Check for a valid bundle.
class HexagonMCChecker {
  MCContext &Context;
  MCInst &MCB;
  const MCRegisterInfo &RI;
  MCInstrInfo const &MCII;
  MCSubtargetInfo const &STI;
  bool ReportErrors;

  /// Set of definitions: register #, if predicated, if predicated true.
  using PredSense = std::pair<unsigned, bool>;
  static const PredSense Unconditional;
  using PredSet = std::multiset<PredSense>;
  using PredSetIterator = std::multiset<PredSense>::iterator;

  using DefsIterator = DenseMap<unsigned, PredSet>::iterator;
  DenseMap<unsigned, PredSet> Defs;

  /// Set of weak definitions whose clashes should be enforced selectively.
  using SoftDefsIterator = std::set<unsigned>::iterator;
  std::set<unsigned> SoftDefs;

  /// Set of temporary definitions not committed to the register file.
  using TmpDefsIterator = std::set<unsigned>::iterator;
  std::set<unsigned> TmpDefs;

  /// Set of new predicates used.
  using NewPredsIterator = std::set<unsigned>::iterator;
  std::set<unsigned> NewPreds;

  /// Set of predicates defined late.
  using LatePredsIterator = std::multiset<unsigned>::iterator;
  std::multiset<unsigned> LatePreds;

  /// Set of uses.
  using UsesIterator = std::set<unsigned>::iterator;
  std::set<unsigned> Uses;

  /// Pre-defined set of read-only registers.
  using ReadOnlyIterator = std::set<unsigned>::iterator;
  std::set<unsigned> ReadOnly;

  // Contains the vector-pair-registers with the even number
  // first ("v0:1", e.g.) used/def'd in this packet.
  std::set<unsigned> ReversePairs;

  void init();
  void init(MCInst const &);
  void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue);

  bool registerUsed(unsigned Register);
  std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo>
  registerProducer(unsigned Register,
                   HexagonMCInstrInfo::PredicateInfo Predicated);

  // Checks performed.
  bool checkBranches();
  bool checkPredicates();
  bool checkNewValues();
  bool checkRegisters();
  bool checkRegistersReadOnly();
  void checkRegisterCurDefs();
  bool checkSolo();
  bool checkShuffle();
  bool checkSlots();
  bool checkAXOK();
  bool checkHWLoop();
  bool checkCOFMax1();
  bool checkLegalVecRegPair();
  bool checkValidTmpDst();

  static void compoundRegisterMap(unsigned &);

  bool isPredicateRegister(unsigned R) const {
    return (Hexagon::P0 == R || Hexagon::P1 == R || Hexagon::P2 == R ||
            Hexagon::P3 == R);
  }

  bool isLoopRegister(unsigned R) const {
    return (Hexagon::SA0 == R || Hexagon::LC0 == R || Hexagon::SA1 == R ||
            Hexagon::LC1 == R);
  }

public:
  explicit HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII,
                            MCSubtargetInfo const &STI, MCInst &mcb,
                            const MCRegisterInfo &ri, bool ReportErrors = true);
  explicit HexagonMCChecker(HexagonMCChecker const &Check,
                            MCSubtargetInfo const &STI, bool CopyReportErrors);

  bool check(bool FullCheck = true);
  void reportErrorRegisters(unsigned Register);
  void reportErrorNewValue(unsigned Register);
  void reportError(SMLoc Loc, Twine const &Msg);
  void reportNote(SMLoc Loc, Twine const &Msg);
  void reportError(Twine const &Msg);
  void reportWarning(Twine const &Msg);
  void reportBranchErrors();
};

} // end namespace llvm

#endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H