8b6c72ee25e647bfad8a06f45790ea934fa0eaab
[oota-llvm.git] / lib / Target / Hexagon / MCTargetDesc / HexagonShuffler.h
1 //===----- HexagonShuffler.h - Instruction bundle shuffling ---------------===//
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 shuffling of insns inside a bundle according to the
11 // packet formation rules of the Hexagon ISA.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef HEXAGONSHUFFLER_H
16 #define HEXAGONSHUFFLER_H
17
18 #include "Hexagon.h"
19 #include "MCTargetDesc/HexagonMCInstrInfo.h"
20
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/MC/MCInstrInfo.h"
23
24 using namespace llvm;
25
26 namespace llvm {
27 // Insn resources.
28 class HexagonResource {
29   // Mask of the slots or units that may execute the insn and
30   // the weight or priority that the insn requires to be assigned a slot.
31   unsigned Slots, Weight;
32
33 public:
34   HexagonResource(unsigned s) { setUnits(s); };
35
36   void setUnits(unsigned s) {
37     Slots = s & ~(~0U << HEXAGON_PACKET_SIZE);
38   };
39   unsigned setWeight(unsigned s);
40
41   unsigned getUnits() const { return (Slots); };
42   unsigned getWeight() const { return (Weight); };
43
44   // Check if the resources are in ascending slot order.
45   static bool lessUnits(const HexagonResource &A, const HexagonResource &B) {
46     return (countPopulation(A.getUnits()) < countPopulation(B.getUnits()));
47   };
48   // Check if the resources are in ascending weight order.
49   static bool lessWeight(const HexagonResource &A, const HexagonResource &B) {
50     return (A.getWeight() < B.getWeight());
51   };
52 };
53
54 // Handle to an insn used by the shuffling algorithm.
55 class HexagonInstr {
56   friend class HexagonShuffler;
57
58   MCInst const *ID;
59   MCInst const *Extender;
60   HexagonResource Core;
61   bool SoloException;
62
63 public:
64   HexagonInstr(MCInst const *id, MCInst const *Extender, unsigned s,
65                bool x = false)
66       : ID(id), Extender(Extender), Core(s), SoloException(x){};
67
68   MCInst const *getDesc() const { return (ID); };
69
70   MCInst const *getExtender() const { return Extender; }
71
72   unsigned isSoloException() const { return (SoloException); };
73
74   // Check if the handles are in ascending order for shuffling purposes.
75   bool operator<(const HexagonInstr &B) const {
76     return (HexagonResource::lessWeight(B.Core, Core));
77   };
78   // Check if the handles are in ascending order by core slots.
79   static bool lessCore(const HexagonInstr &A, const HexagonInstr &B) {
80     return (HexagonResource::lessUnits(A.Core, B.Core));
81   };
82 };
83
84 // Bundle shuffler.
85 class HexagonShuffler {
86   typedef SmallVector<HexagonInstr, HEXAGON_PRESHUFFLE_PACKET_SIZE>
87       HexagonPacket;
88
89   // Insn handles in a bundle.
90   HexagonPacket Packet;
91
92   // Shuffling error code.
93   unsigned Error;
94
95 protected:
96   int64_t BundleFlags;
97   MCInstrInfo const &MCII;
98   MCSubtargetInfo const &STI;
99
100 public:
101   typedef HexagonPacket::iterator iterator;
102
103   enum {
104     SHUFFLE_SUCCESS = 0,    ///< Successful operation.
105     SHUFFLE_ERROR_INVALID,  ///< Invalid bundle.
106     SHUFFLE_ERROR_STORES,   ///< No free slots for store insns.
107     SHUFFLE_ERROR_LOADS,    ///< No free slots for load insns.
108     SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
109     SHUFFLE_ERROR_NOSLOTS,  ///< No free slots for other insns.
110     SHUFFLE_ERROR_SLOTS,    ///< Over-subscribed slots.
111     SHUFFLE_ERROR_UNKNOWN   ///< Unknown error.
112   };
113
114   explicit HexagonShuffler(MCInstrInfo const &MCII, MCSubtargetInfo const &STI);
115
116   // Reset to initial state.
117   void reset();
118   // Check if the bundle may be validly shuffled.
119   bool check();
120   // Reorder the insn handles in the bundle.
121   bool shuffle();
122
123   unsigned size() const { return (Packet.size()); };
124
125   iterator begin() { return (Packet.begin()); };
126   iterator end() { return (Packet.end()); };
127
128   // Add insn handle to the bundle .
129   void append(MCInst const *ID, MCInst const *Extender, unsigned S,
130               bool X = false);
131
132   // Return the error code for the last check or shuffling of the bundle.
133   void setError(unsigned Err) { Error = Err; };
134   unsigned getError() const { return (Error); };
135 };
136 }
137
138 #endif // HEXAGONSHUFFLER_H