P4C
The P4 Compiler
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
misc.h
1
17
18#ifndef BACKENDS_TOFINO_BF_ASM_MISC_H_
19#define BACKENDS_TOFINO_BF_ASM_MISC_H_
20
21#include <iomanip>
22#include <limits>
23#include <memory>
24#include <sstream>
25#include <string>
26#include <type_traits>
27#include <vector>
28
29#include <boost/numeric/conversion/converter.hpp>
30
31#include "asm-types.h"
32#include "backends/tofino/bf-asm/json.h"
33
34template <class T>
35auto setup_muxctl(T &reg, int val) -> decltype((void)reg.enabled_2bit_muxctl_enable) {
36 reg.enabled_2bit_muxctl_select = val;
37 reg.enabled_2bit_muxctl_enable = 1;
38}
39template <class T>
40auto setup_muxctl(T &reg, int val) -> decltype((void)reg.enabled_3bit_muxctl_enable) {
41 reg.enabled_3bit_muxctl_select = val;
42 reg.enabled_3bit_muxctl_enable = 1;
43}
44template <class T>
45auto setup_muxctl(T &reg, int val) -> decltype((void)reg.enabled_4bit_muxctl_enable) {
46 reg.enabled_4bit_muxctl_select = val;
47 reg.enabled_4bit_muxctl_enable = 1;
48}
49template <class T>
50auto setup_muxctl(T &reg, int val) -> decltype((void)reg.enabled_5bit_muxctl_enable) {
51 reg.enabled_5bit_muxctl_select = val;
52 reg.enabled_5bit_muxctl_enable = 1;
53}
54template <class T>
55auto setup_muxctl(T &reg, int val) -> decltype((void)reg.exactmatch_row_vh_xbar_enable) {
56 reg.exactmatch_row_vh_xbar_select = val;
57 reg.exactmatch_row_vh_xbar_enable = 1;
58}
59
60template <class T, class Alloc>
61void append(std::vector<T, Alloc> &a, const std::vector<T, Alloc> &b) {
62 for (auto &e : b) a.push_back(e);
63}
64
65template <class T, class U>
66T join(const std::vector<T> &vec, U sep) {
67 T rv;
68 bool first = true;
69 for (auto &el : vec) {
70 if (first)
71 first = false;
72 else
73 rv += sep;
74 rv += el;
75 }
76 return rv;
77}
78
79extern int remove_name_tail_range(std::string &, int *size = nullptr);
80
81// Convert an integer to hex string of specified width (in bytes)
82std::string int_to_hex_string(unsigned val, unsigned width);
83
84// Add a reg to CJSON Configuration Cache
85void add_cfg_reg(json::vector &cfg_cache, std::string full_name, std::string name, std::string val);
86
87bool check_zero_string(const std::string &s);
88
89// Get filename
90std::string get_filename(const char *s);
91std::string get_directory(const char *s);
92
97void gen_instfield_name(const std::string &fullname, std::string &instname, std::string &fieldname);
98
101template <class T>
102struct ptrless {
103 bool operator()(const T *a, const T *b) const { return b ? a ? *a < *b : true : false; }
104 bool operator()(const std::unique_ptr<T> &a, const std::unique_ptr<T> &b) const {
105 return b ? a ? *a < *b : true : false;
106 }
107};
108
109/* word with size (lowest) bits set */
110uint64_t bitMask(unsigned size);
111/* word with range of bits from lo to hi (inclusive) set */
112uint64_t bitRange(unsigned lo, unsigned hi);
113
114int parity(uint32_t v);
115int parity_2b(uint32_t v); // two-bit parity (parity of pairs in the word)
116
117inline bool check_value(const value_t value, const decltype(value_t::i) expected) {
118 if (!CHECKTYPE(value, tINT)) return false;
119 if (value.i != expected) {
120 error(value.lineno, "unexpected value %ld; expected %ld", value.i, expected);
121 return false;
122 }
123 return true;
124}
125
140template <typename IntType,
141 typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
142bool check_range_strict(value_t value, IntType lo, IntType hi) {
143 auto format_error_message([](value_t value, IntType lo, IntType hi) {
144 /* -- As we don't know actual type of the IntType, we cannot use the printf-like
145 * formatting. */
146 std::ostringstream oss;
147 oss << "value " << value.i << " is out of allowed range <" << +lo << "; " << +hi << ">";
148 error(value.lineno, "%s", oss.str().c_str());
149 });
150
151 if (!CHECKTYPE(value, tINT)) return false;
152
153 /* -- Handle different ranges (signed, unsigned, different size) of the value_t::i
154 * and IntType. */
155 typedef boost::numeric::converter<IntType, decltype(value_t::i)> Converter;
156 if (Converter::out_of_range(value.i)) {
157 format_error_message(value, lo, hi);
158 return false;
159 }
160
161 /* -- Now check requested limits */
162 IntType converted(static_cast<IntType>(value.i));
163 if (converted < lo || converted > hi) {
164 format_error_message(value, lo, hi);
165 return false;
166 }
167 return true;
168}
169
170inline bool check_range(const value_t value, const decltype(value_t::i) lo,
171 const decltype(value_t::i) hi) {
172 return check_range_strict<decltype(value_t::i)>(value, lo, hi);
173}
174
175inline bool check_range_match(const value_t &match, const decltype(match_t::word0) mask,
176 int width) {
177 if (!CHECKTYPE(match, tMATCH)) return false;
178 if ((match.m.word0 | match.m.word1) != mask) {
179 error(match.lineno, "invalid match width; expected %i bits", width);
180 return false;
181 }
182 return true;
183}
184
185template <typename IntType>
186void convert_i2m(IntType i, match_t &m) {
187 static_assert(sizeof(IntType) == sizeof(match_t::word0));
188 static_assert(std::is_integral<IntType>::value);
189
190 m.word0 = ~static_cast<decltype(match_t::word0)>(i);
191 m.word1 = static_cast<decltype(match_t::word0)>(i);
192}
193
194bool check_bigint_unsigned(value_t value, uint32_t byte_width);
195
198inline void fix_match_star(match_t &match, const decltype(match_t::word0) mask) {
199 if (match.word0 == 0 && match.word1 == 0) match.word0 = match.word1 = mask;
200}
201
209bool input_int_match(const value_t value, match_t &match, int width);
210
216bool require_keys(const value_t &data, std::set<const char *> keys);
217
218#endif /* BACKENDS_TOFINO_BF_ASM_MISC_H_ */
Definition backends/tofino/bf-asm/json.h:222
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
Definition match.h:36
Definition misc.h:102
Definition asm-types.h:114