18#ifndef BACKENDS_TOFINO_BF_ASM_ASM_TYPES_H_
19#define BACKENDS_TOFINO_BF_ASM_ASM_TYPES_H_
33#include "backends/tofino/bf-asm/json.h"
34#include "backends/tofino/bf-asm/map.h"
36#include "lib/bitops.h"
37#include "lib/bitvec.h"
38#include "mask_counter.h"
41enum gress_t { INGRESS, EGRESS, GHOST, NUM_GRESS_T };
45inline gress_t timing_thread(gress_t gress) {
return gress == GHOST ? INGRESS : gress; }
47inline gress_t imem_thread(gress_t gress) {
return gress == GHOST ? INGRESS : gress; }
50 uint64_t word0, word1;
52 operator bool()
const {
return (word0 | word1) != 0; }
53 bool operator==(
const match_t &a)
const {
return word0 == a.word0 && word1 == a.word1; }
54 bool matches(uint64_t v)
const {
55 return (v | word1) == word1 && ((~v & word1) | word0) == word0;
57 bool matches(
const match_t &v)
const {
61 unsigned dirtcam(
unsigned width,
unsigned bit);
77 for (
int i = 0; i < v.size; ++i) {
78 word0.putrange(i * 64, 64, v.data[i].word0);
79 word1.putrange(i * 64, 64, v.data[i].word1);
82 operator bool()
const {
return word0 || word1; }
83 bool operator==(
const wmatch_t &a)
const {
return word0 == a.word0 && word1 == a.word1; }
84 bool matches(
bitvec v)
const {
return (v | word1) == word1 && ((word1 - v) | word0) == word0; }
85 bool matches(
const wmatch_t &v)
const {
89 unsigned dirtcam(
unsigned width,
unsigned bit);
93enum value_type { tINT, tBIGINT, tRANGE, tSTR, tMATCH, tBIGMATCH, tVEC, tMAP, tCMD };
94extern const char *value_type_desc[];
103 VECTOR(
value_t) & add(
const char *);)
106 pair_t & operator[](
int)
const;
pair_t * operator[](
const char *)
const;
pair_t & back()
const;
107 pair_t * begin()
const {
return data; }
pair_t * end()
const;
pair_t & front()
const;)
112DECLARE_VECTOR(uintptr_t);
115 enum value_type type;
119 VECTOR(uintptr_t) bigi;
131 value_t &operator[](
int i)
const {
132 assert(type == tVEC || type == tCMD);
135 bool startsWith(
const char *pfx)
const {
136 if (type == tSTR)
return strncmp(s, pfx, strlen(pfx)) == 0;
137 if (type == tCMD && vec.size > 0 && vec[0].type == tSTR)
138 return strncmp(vec[0].s, pfx, strlen(pfx)) == 0;
141 bool checkSize()
const {
142 if (type == tVEC)
return (vec.size > 0);
143 if (type == tMAP)
return (map.size > 0);
144 if (type == tCMD)
return (vec.size > 0);
159const char *value_desc(
const value_t *v);
160static inline void free_pair(
pair_t *p) {
162 free_value(&p->value);
164bool get_bool(
const value_t &v);
168bitvec get_bitvec(
const value_t &v,
unsigned max_bits = 0,
const char *error_message =
nullptr);
169uint64_t get_int64(
const value_t &v,
unsigned max_bits = 0,
const char *error_message =
nullptr);
173inline bool operator==(
const struct value_t &a,
const char *b) {
174 if (a.type == tCMD && a.vec.size > 0 && a[0].type == tSTR)
return !strcmp(a[0].s, b);
175 return a.type == tSTR && !strcmp(a.s, b);
177inline bool operator==(
const char *a,
const struct value_t &b) {
178 if (b.type == tCMD && b.vec.size > 0 && b[0].type == tSTR)
return !strcmp(a, b[0].s);
179 return b.type == tSTR && !strcmp(a, b.s);
181inline bool operator==(
const struct value_t &a,
int b) {
return a.type == tINT && a.i == b; }
182inline bool operator==(
int a,
const struct value_t &b) {
return b.type == tINT && a == b.i; }
184inline const char *value_desc(
const value_t &v) {
return value_desc(&v); }
187 assert(i >= 0 && i < size);
191 assert(i >= 0 && i < size);
194inline pair_t *VECTOR(
pair_t)::operator[](const char *k) const {
195 for (int i = 0; i < size; i++)
196 if (data[i].key == k)
return &data[i];
199inline value_t *VECTOR(
value_t)::end() const { return data + size; }
206 return data[size - 1];
208inline pair_t *VECTOR(
pair_t)::end() const { return data + size; }
215 return data[size - 1];
220extern void push_back(VECTOR(
pair_t) & m,
const char *s,
223inline void fini(
value_t &v) { free_value(&v); }
224inline void fini(
pair_t &p) { free_pair(&p); }
225inline void fini(VECTOR(
value_t) & v) {
226 VECTOR_foreach(v, free_value);
229inline void fini(VECTOR(
pair_t) & v) {
230 VECTOR_foreach(v, free_pair);
233void collapse_list_of_maps(
value_t &,
bool singleton_only =
false);
235std::unique_ptr<json::obj> toJson(
value_t &);
236std::unique_ptr<json::vector> toJson(VECTOR(
value_t) &);
237std::unique_ptr<json::map> toJson(
pair_t &);
238std::unique_ptr<json::map> toJson(VECTOR(
pair_t) &);
242#define CHECKTYPE(V, T) \
243 ((V).type == (T) || (error((V).lineno, "Syntax error, expecting %s", value_type_desc[T]), 0))
244#define CHECKTYPESIZE(V, T) \
245 (CHECKTYPE(V, T) && \
246 ((V).checkSize() || (error((V).lineno, "Syntax error, empty %s", value_type_desc[T]), 0)))
247#define PCHECKTYPE(P, V, T) \
248 (((P) && (V).type == (T)) || \
249 (error((V).lineno, "Syntax error, expecting %s", value_type_desc[T]), 0))
250#define CHECKTYPEM(V, T, M) \
251 ((V).type == (T) || (error((V).lineno, "Syntax error, expecting %s", M), 0))
252#define CHECKTYPEPM(V, T, P, M) \
253 (((V).type == (T) && (P)) || (error((V).lineno, "Syntax error, expecting %s", M), 0))
254#define PCHECKTYPEM(P, V, T, M) \
255 (((P) && (V).type == (T)) || (error((V).lineno, "Syntax error, expecting %s", M), 0))
256#define CHECKTYPE2(V, T1, T2) \
257 ((V).type == (T1) || (V).type == (T2) || \
258 (error((V).lineno, "Syntax error, expecting %s or %s but got %s", value_type_desc[T1], \
259 value_type_desc[T2], value_desc(V)), \
261#define CHECKTYPE3(V, T1, T2, T3) \
262 ((V).type == (T1) || (V).type == (T2) || (V).type == (T3) || \
263 (error((V).lineno, "Syntax error, expecting %s or %s or %s", value_type_desc[T1], \
264 value_type_desc[T2], value_type_desc[T3]), \
266#define PCHECKTYPE2(P, V, T1, T2) \
267 (((P) && ((V).type == (T1) || (V).type == (T2))) || \
268 (error((V).lineno, "Syntax error, expecting %s or %s", value_type_desc[T1], \
269 value_type_desc[T2]), \
271#define CHECKTYPE2M(V, T1, T2, M) \
272 ((V).type == (T1) || (V).type == (T2) || \
273 (error((V).lineno, "Syntax error, expecting %s but got %s", M, value_desc(V)), 0))
274#define PCHECKTYPE2M(P, V, T1, T2, M) \
275 (((P) && ((V).type == (T1) || (V).type == (T2))) || \
276 (error((V).lineno, "Syntax error, expecting %s", M), 0))
277#define VALIDATE_RANGE(V) \
278 ((V).type != tRANGE || (V).range.lo <= (V).range.hi || \
279 (error((V).lineno, "Invalid range %d..%d", (V).range.lo, (V).range.hi), 0))
283 if (kv.key == key)
return &kv.value;
286inline const value_t *get(
const VECTOR(
pair_t) & map,
const char *key) {
288 if (kv.key == key)
return &kv.value;
295inline void parse_vector(std::vector<T> &vec,
const VECTOR(
value_t) & data) {
296 for (
auto &v : data) vec.emplace_back(v);
299inline void parse_vector(std::vector<int> &vec,
const VECTOR(
value_t) & data) {
301 if (CHECKTYPE(v, tINT)) vec.push_back(v.i);
304inline void parse_vector(std::vector<int64_t> &vec,
const VECTOR(
value_t) & data) {
306 if (CHECKTYPE(v, tINT)) vec.push_back(v.i);
309inline void parse_vector(std::vector<std::string> &vec,
const VECTOR(
value_t) & data) {
311 if (CHECKTYPE(v, tSTR)) vec.emplace_back(v.s);
314inline void parse_vector(std::vector<T> &vec,
const value_t &data) {
315 if (data.type == tVEC)
316 parse_vector(vec, data.vec);
318 vec.emplace_back(data);
321inline void parse_vector(std::vector<int> &vec,
const value_t &data) {
322 if (CHECKTYPE2(data, tINT, tVEC)) {
323 if (data.type == tVEC)
324 parse_vector(vec, data.vec);
326 vec.push_back(data.i);
330inline void parse_vector(std::vector<int64_t> &vec,
const value_t &data) {
331 if (CHECKTYPE2(data, tINT, tVEC)) {
332 if (data.type == tVEC)
333 parse_vector(vec, data.vec);
335 vec.push_back(data.i);
339inline void parse_vector(std::vector<std::string> &vec,
const value_t &data) {
340 if (CHECKTYPE2(data, tSTR, tVEC)) {
341 if (data.type == tVEC)
342 parse_vector(vec, data.vec);
344 vec.push_back(data.s);
348std::ostream &operator<<(std::ostream &out,
match_t m);
349void print_match(FILE *fp,
match_t m);
351inline std::ostream &operator<<(std::ostream &out, gress_t gress) {
363 out <<
"(invalid gress " <<
static_cast<int>(gress) <<
")";
369inline std::string to_string(T val) {
370 std::stringstream tmp;
375class MapIterChecked {
378 const VECTOR(pair_t) & map;
380 std::set<std::string> duplicates_allowed;
381 std::map<std::string, int> keys_seen;
383 MapIterChecked *self;
386 while (p != self->map.end()) {
387 if (self->allow && p->key.type != tSTR)
break;
388 if (!CHECKTYPE(p->key, tSTR)) {
392 if (self->duplicates_allowed.count(p->key.s))
break;
393 if (self->keys_seen.count(p->key.s)) {
394 error(p->key.lineno,
"Duplicate element %s", p->key.s);
395 warning(self->keys_seen[p->key.s],
"previous element %s", p->key.s);
399 self->keys_seen[p->key.s] = p->key.lineno;
405 iter(MapIterChecked *s, pair_t *p_) : self(s), p(p_) { check(); }
406 pair_t &operator*()
const {
return *p; }
407 pair_t *operator->()
const {
return p; }
408 bool operator==(
const iter &a)
const {
return p == a.p; }
417 explicit MapIterChecked(
const VECTOR(pair_t) & map_,
bool o =
false,
418 const std::set<std::string> &dup = {})
419 : map(map_), allow(o), duplicates_allowed(dup) {}
420 MapIterChecked(
const VECTOR(pair_t) & map_,
const std::set<std::string> &dup)
421 : map(map_), allow(false), duplicates_allowed(dup) {}
422 iter begin() {
return iter(
this, map.begin()); }
423 iter end() {
return iter(
this, map.end()); }
429 class iter :
public MaskCounter {
433 explicit iter(MatchIter *s) : MaskCounter(s->m.word0 & s->m.word1), self(s) {
434 if (!(self->m.word1 | self->m.word0)) overflow();
436 unsigned operator*()
const {
437 return this->
operator unsigned() | (self->m.word1 & ~self->m.word0);
446 explicit MatchIter(match_t m_) : m(m_) {}
447 iter begin() {
return iter(
this); }
448 iter end() {
return iter(
this).end(); }
453 friend std::ostream &operator<<(std::ostream &,
const SrcInfo &);
456 explicit SrcInfo(
int l) : lineno(l) {}
459struct RegisterSetBase {
460 virtual ~RegisterSetBase() =
default;
463struct ParserRegisterSet :
public RegisterSetBase {};
469 virtual void input(VECTOR(value_t) args, value_t data) = 0;
470 virtual ~Parsable() =
default;
476 virtual void write_config(RegisterSetBase ®s, json::map &json,
bool legacy =
true) = 0;
477 virtual ~Configurable() =
default;
483 virtual void output(json::map &ctxtJson) = 0;
484 virtual ~Contextable() =
default;
void warning(const char *format, Args &&...args)
Report a warning with the given message.
Definition lib/error.h:128
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
Definition asm-types.h:150
Definition asm-types.h:114
Definition asm-types.h:67