P4C
The P4 Compiler
Loading...
Searching...
No Matches
common/asm_output.h
1
19#ifndef BF_P4C_COMMON_ASM_OUTPUT_H_
20#define BF_P4C_COMMON_ASM_OUTPUT_H_
21
22#include <map>
23
24#include "backends/tofino/bf-p4c/bf-p4c-options.h"
25#include "backends/tofino/bf-p4c/ir/bitrange.h"
26#include "backends/tofino/bf-p4c/phv/phv_fields.h"
27#include "lib/ordered_map.h"
28#include "lib/safe_vector.h"
29#include "lib/stringref.h"
30
31using namespace P4;
32
33StringRef trim_asm_name(StringRef name);
34
36 StringRef name;
37 friend std::ostream &operator<<(std::ostream &, canon_name);
38
39 public:
40 explicit canon_name(StringRef n) : name(n) {}
41 explicit canon_name(cstring n) : name(n) {}
42 explicit canon_name(IR::ID n) : name(n.name) {}
43
44 operator cstring() const { return cstring::to_cstring(*this); }
45};
46
47class Slice {
48 const PHV::Field *field;
50 int lo, hi;
51 friend std::ostream &operator<<(std::ostream &, const Slice &);
52 Slice &invalidate() {
53 field = 0;
54 reg = PHV::Container();
55 lo = -1;
56 hi = -2;
57 return *this;
58 }
59
60 public:
61 Slice() : field(0), lo(-1), hi(-2) {} // hi = -2 to make width() = 0
62 explicit Slice(const PHV::Field *f) : field(f), lo(0), hi(f->size - 1) {}
63 Slice(const PHV::Field *f, int bit) : field(f), lo(bit), hi(bit) {}
64 Slice(const PHV::Field *f, int l, int h) : field(f), lo(l), hi(h) {}
65 Slice(const PHV::Field *f, le_bitrange r) : field(f), lo(r.lo), hi(r.hi) {}
66 explicit Slice(const PHV::AbstractField *f)
67 : field(f->field()), lo(f->range().lo), hi(f->range().hi) {}
68 Slice(const PHV::AbstractField *f, int l, int h)
69 : field(f->field()), lo(f->range().lo + l), hi(f->range().lo + h) {
70 if (hi > f->range().hi) hi = f->range().hi;
71 if (!field || lo > hi) invalidate();
72 }
73 Slice(const PHV::AbstractField *f, le_bitrange r) : Slice(f, r.lo, r.hi) {}
74 Slice(const PHV::AbstractField *f, int bit) : Slice(f, bit, bit) {}
75 Slice(const PhvInfo &phv, const IR::Expression *e) {
76 le_bitrange bits;
77 if (!(field = phv.field(e, &bits))) {
78 invalidate();
79 } else {
80 lo = bits.lo;
81 hi = bits.hi;
82 }
83 }
84 Slice(const PhvInfo &phv, const IR::Expression *e, int l, int h) {
85 le_bitrange bits;
86 if (!(field = phv.field(e, &bits))) {
87 invalidate();
88 } else {
89 lo = bits.lo + l;
90 hi = bits.lo + h;
91 if (hi > bits.hi) hi = bits.hi;
92 if (lo > hi) invalidate();
93 }
94 }
95 Slice(const PhvInfo &phv, const IR::Expression *e, le_bitrange r) : Slice(phv, e, r.lo, r.hi) {}
96 Slice(const PhvInfo &phv, const IR::Expression *e, int bit) : Slice(phv, e, bit, bit) {}
97 Slice(const PhvInfo &phv, cstring n) : field(phv.field(n)), lo(0), hi(field->size - 1) {}
98 Slice(const PhvInfo &phv, cstring n, int bit) : field(phv.field(n)), lo(bit), hi(bit) {
99 BUG_CHECK((bit >= 0 && bit < field->size),
100 "Slice out of range for field = '%s', bit=%d, size=%d", field->name, bit,
101 field->size);
102 }
103 Slice(const PhvInfo &phv, cstring n, int l, int h) : field(phv.field(n)), lo(l), hi(h) {
104 BUG_CHECK((lo < field->size), "Slice out of range for field = '%s', lo=%d, size=%d",
105 field->name, lo, field->size);
106 if (lo < 0) lo = 0;
107 if (hi >= field->size) hi = field->size - 1;
108 }
109 explicit Slice(PHV::Container r) : field(0), reg(r), lo(0), hi(r.size() - 1) {}
110 Slice(PHV::Container r, int bit) : field(0), reg(r), lo(bit), hi(bit) {}
111 Slice(PHV::Container r, int lo, int hi) : field(0), reg(r), lo(lo), hi(hi) {}
112 Slice(const Slice &s, int bit) : field(s.field), reg(s.reg), lo(s.lo + bit), hi(lo) {}
113 Slice(const Slice &s, int l, int h) : field(s.field), reg(s.reg), lo(s.lo + l), hi(s.lo + h) {
114 if (hi > s.hi) hi = s.hi;
115 if (!field || lo > hi) invalidate();
116 }
117 explicit operator bool() const { return field != nullptr || reg; }
118 Slice operator()(int bit) const { return Slice(*this, bit); }
119 Slice operator()(int l, int h) const { return Slice(*this, l, h); }
120 Slice join(Slice &a) const;
121 Slice &operator-=(const Slice &a) {
122 if (field != a.field || reg != a.reg || hi < a.lo || lo > a.hi) return *this;
123 if (a.lo <= lo) lo = a.hi + 1;
124 if (a.hi >= hi) hi = a.lo - 1;
125 if (lo > hi) invalidate();
126 return *this;
127 }
128 Slice &operator-=(const std::vector<Slice> &a) {
129 for (auto &v : a) *this -= v;
130 return *this;
131 }
132 Slice operator-(const Slice &a) const {
133 auto tmp = *this;
134 tmp -= a;
135 return tmp;
136 }
137 Slice operator-(const std::vector<Slice> &a) const {
138 auto tmp = *this;
139 tmp -= a;
140 return tmp;
141 }
142 Slice &operator&=(const Slice &a) {
143 if (field != a.field || reg != a.reg) return invalidate();
144 if (a.lo > lo) lo = a.lo;
145 if (a.hi < hi) hi = a.hi;
146 if (lo > hi) invalidate();
147 return *this;
148 }
149 Slice operator&(const Slice &a) const {
150 auto tmp = *this;
151 tmp &= a;
152 return tmp;
153 }
154 safe_vector<Slice> split(const Slice &a, bool &split);
155 safe_vector<Slice> split(const safe_vector<Slice> &vec, safe_vector<Slice> &splitters);
156 int width() const { return hi - lo + 1; }
157 int align(int size) const;
158 int bytealign() const { return align(8); }
159 Slice fullbyte() const;
160 const PHV::Field *get_field() const { return field; }
161 const PHV::Container get_container() const { return reg; }
162 int get_lo() const { return lo; }
163 int get_hi() const { return hi; }
164 void shrink_lo(int shrink) {
165 if (shrink + lo >= hi)
166 lo = hi;
167 else
168 lo += shrink;
169 }
170 le_bitrange range() const { return {lo, hi}; }
171 void shrink_hi(int shrink) {
172 if (hi - shrink <= lo)
173 hi = lo;
174 else
175 hi -= shrink;
176 }
177};
178
179/* The rest of this is pretty generic formatting stuff -- should be in lib somewhere? */
180
181template <class K, class V>
182std::ostream &operator<<(std::ostream &out, const std::map<K, V> &m) {
183 const char *sep = " ";
184 out << "{";
185 for (const auto &kv : m) {
186 out << sep << kv.first << ": " << kv.second;
187 sep = ", ";
188 }
189 out << (sep + 1) << "}";
190 return out;
191}
192
193template <class K, class V>
194std::ostream &operator<<(std::ostream &out, const std::multimap<K, V> &m) {
195 const char *sep = " ";
196 out << "{";
197 for (const auto &kv : m) {
198 out << sep << kv.first << ": " << kv.second;
199 sep = ", ";
200 }
201 out << (sep + 1) << "}";
202 return out;
203}
204
205template <class K, class V>
206std::ostream &operator<<(std::ostream &out, const ordered_map<K, V> &m) {
207 const char *sep = " ";
208 out << "{";
209 for (const auto &kv : m) {
210 out << sep << kv.first << ": " << kv.second;
211 sep = ", ";
212 }
213 out << "}";
214 return out;
215}
216
217template <class VEC>
219 const VEC &vec;
220 const char *sep;
221};
222
223template <class VEC>
224std::ostream &operator<<(std::ostream &out, const emit_vector_formatter<VEC> &v) {
225 const char *sep = "";
226 for (const auto &el : v.vec) {
227 out << sep << el;
228 sep = v.sep;
229 }
230 return out;
231}
232
233template <class VEC>
234emit_vector_formatter<VEC> emit_vector(const VEC &v, const char *sep = ", ") {
235 return emit_vector_formatter<VEC>{v, sep};
236}
237
238bool has_user_annotation(const IR::IAnnotated *node);
239
241void emit_user_annotation_context_json(std::ostream &out, indent_t indent,
242 const IR::IAnnotated *node, bool emit_dash = false);
243
244void emit_user_annotation_context_json(indent_t indent, const IR::IAnnotated *node,
245 std::stringstream &context_json_entries);
246
247template <class T>
248inline auto operator<<(std::ostream &out, const T &obj) -> decltype((void)obj.print(out), out) {
249 obj.print(out);
250 return out;
251}
252
253template <class T>
254inline auto operator<<(std::ostream &out, const T *obj) -> decltype((void)obj->print(out), out) {
255 if (obj)
256 obj->print(out);
257 else
258 out << "<null>";
259 return out;
260}
261
262#endif /* BF_P4C_COMMON_ASM_OUTPUT_H_ */
Definition cstring.h:85
Definition indent.h:26
Definition ordered_map.h:32
Definition safe_vector.h:27
Definition phv_fields.h:855
Definition phv.h:176
Definition phv_fields.h:154
int size
Total size of Field in bits.
Definition phv_fields.h:194
cstring name
Definition phv_fields.h:161
Definition phv_fields.h:1095
Definition common/asm_output.h:47
Definition common/asm_output.h:35
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
int lo
Definition lib/bitrange.h:694
ssize_t size() const
Definition lib/bitrange.h:539
int hi
Definition lib/bitrange.h:700
Definition id.h:28
Definition stringref.h:43
Definition common/asm_output.h:218