P4C
The P4 Compiler
Loading...
Searching...
No Matches
bf-asm/alloc.h
1/*
2 * SPDX-FileCopyrightText: 2025 The P4 Language Consortium
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#ifndef BACKENDS_TOFINO_BF_ASM_ALLOC_H_
8#define BACKENDS_TOFINO_BF_ASM_ALLOC_H_
9
10#include <stdlib.h>
11
12#include <stdexcept>
13#include <tuple>
14#include <utility>
15
16namespace BFN {
17
18template <class T>
19class Alloc1Dbase {
20 int size_;
21 T *data;
22 Alloc1Dbase() = delete;
23 Alloc1Dbase(const Alloc1Dbase &) = delete;
24 Alloc1Dbase &operator=(const Alloc1Dbase &) = delete;
25 Alloc1Dbase &operator=(Alloc1Dbase &&) = delete;
26
27 public:
28 explicit Alloc1Dbase(int sz) : size_(sz) { data = sz ? new T[sz]{} : nullptr; }
29 Alloc1Dbase(Alloc1Dbase &&a) noexcept : size_(a.size_), data(a.data) { a.data = 0; }
30 virtual ~Alloc1Dbase() { delete[] data; }
31
32 typedef T *iterator;
33 typedef T *const_iterator;
34 T &operator[](int i) {
35 if (i < 0 || i >= size_) throw std::out_of_range("Alloc1D");
36 return data[i];
37 }
38 const T &operator[](int i) const {
39 if (i < 0 || i >= size_) throw std::out_of_range("Alloc1D");
40 return data[i];
41 }
42 bool operator==(const Alloc1Dbase<T> &t) const {
43 return std::equal(data, data + size_, t.data, t.data + t.size_);
44 }
45 bool operator!=(const Alloc1Dbase<T> &t) const { return !(*this == t); }
46
47 int size() const { return size_; }
48 void clear() { std::fill(data, data + size_, T()); }
49 T *begin() { return data; }
50 T *end() { return data + size_; }
51};
52
53template <class T, int S>
54class Alloc1D : public Alloc1Dbase<T> {
55 public:
56 Alloc1D() : Alloc1Dbase<T>(S) {}
57 Alloc1Dbase<T> &base() { return *this; }
58 bool operator!=(const Alloc1D<T, S> &t) const { return Alloc1Dbase<T>::operator!=(t); }
59};
60
61template <class T>
62class Alloc3Dbase;
63
64template <class T>
65class Alloc2Dbase {
66 int nrows, ncols;
67 T *data;
68 template <class U>
69 class rowref {
70 U *row;
71 int ncols;
72 friend class Alloc2Dbase;
73 friend class Alloc3Dbase<U>;
74 rowref(U *r, int c) : row(r), ncols(c) {}
75
76 public:
77 typedef U *iterator;
78 typedef const U *const_iterator;
79 U &operator[](int i) const {
80 if (i < 0 || i >= ncols) throw std::out_of_range("Alloc2D");
81 return row[i];
82 }
83 U *begin() const { return row; }
84 U *end() const { return row + ncols; }
85 };
86 Alloc2Dbase() = delete;
87 Alloc2Dbase(const Alloc2Dbase &) = delete;
88 Alloc2Dbase &operator=(const Alloc2Dbase &) = delete;
89 Alloc2Dbase &operator=(Alloc2Dbase &&) = delete;
90 friend class Alloc3Dbase<T>;
91
92 public:
93 Alloc2Dbase(int r, int c) : nrows(r), ncols(c) {
94 size_t sz = r * c;
95 data = sz ? new T[sz]{} : nullptr;
96 }
97 Alloc2Dbase(Alloc2Dbase &&a) noexcept : nrows(a.nrows), ncols(a.ncols), data(a.data) {
98 a.data = 0;
99 }
100 virtual ~Alloc2Dbase() { delete[] data; }
101
102 rowref<T> operator[](int i) {
103 if (i < 0 || i >= nrows) throw std::out_of_range("Alloc2D");
104 return {data + i * ncols, ncols};
105 }
106 rowref<const T> operator[](int i) const {
107 if (i < 0 || i >= nrows) throw std::out_of_range("Alloc2D");
108 return {data + i * ncols, ncols};
109 }
110 T &at(int i, int j) {
111 if (i < 0 || i >= nrows || j < 0 || j >= ncols) throw std::out_of_range("Alloc2D");
112 return data[i * ncols + j];
113 }
114 const T &at(int i, int j) const {
115 if (i < 0 || i >= nrows || j < 0 || j >= ncols) throw std::out_of_range("Alloc2D");
116 return data[i * ncols + j];
117 }
118 T &operator[](std::pair<int, int> i) {
119 if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols)
120 throw std::out_of_range("Alloc2D");
121 return data[i.first * ncols + i.second];
122 }
123 const T &operator[](std::pair<int, int> i) const {
124 if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols)
125 throw std::out_of_range("Alloc2D");
126 return data[i.first * ncols + i.second];
127 }
128 bool operator==(const Alloc2Dbase<T> &t) const {
129 int sz = nrows * ncols;
130 if (nrows != t.nrows || ncols != t.ncols) return false;
131 return std::equal(data, data + sz, t.data);
132 }
133 bool operator!=(const Alloc2Dbase<T> &t) const { return !(*this == t); }
134
135 int rows() const { return nrows; }
136 int cols() const { return ncols; }
137 void clear() { std::fill(data, data + nrows * ncols, T()); }
138};
139
140template <class T, int R, int C>
141class Alloc2D : public Alloc2Dbase<T> {
142 public:
143 Alloc2D() : Alloc2Dbase<T>(R, C) {}
144 Alloc2Dbase<T> &base() { return *this; }
145};
146
147template <class T>
148class Alloc3Dbase {
149 int nmats, nrows, ncols;
150 T *data;
151 template <class U>
152 class matref {
153 U *matrix;
154 int nrows, ncols;
155 friend class Alloc3Dbase;
156
157 public:
158 typename Alloc2Dbase<T>::template rowref<U> operator[](int i) const {
159 if (i < 0 || i >= nrows) throw std::out_of_range("Alloc3D");
160 return {matrix + i * ncols, ncols};
161 }
162 U &operator[](std::pair<int, int> i) const {
163 if (i.first < 0 || i.first >= nrows || i.second < 0 || i.second >= ncols)
164 throw std::out_of_range("Alloc3D");
165 return matrix[i.first * ncols + i.second];
166 }
167 };
168 Alloc3Dbase() = delete;
169 Alloc3Dbase(const Alloc3Dbase &) = delete;
170 Alloc3Dbase &operator=(const Alloc3Dbase &) = delete;
171 Alloc3Dbase &operator=(Alloc3Dbase &&) = delete;
172
173 public:
174 Alloc3Dbase(int m, int r, int c) : nmats(m), nrows(r), ncols(c) {
175 size_t sz = m * r * c;
176 data = sz ? new T[sz]{} : nullptr;
177 }
178 Alloc3Dbase(Alloc3Dbase &&a) noexcept
179 : nmats(a.nmats), nrows(a.nrows), ncols(a.ncols), data(a.data) {
180 a.data = 0;
181 }
182 virtual ~Alloc3Dbase() { delete[] data; }
183
184 matref<T> operator[](int i) {
185 if (i < 0 || i >= nmats) throw std::out_of_range("Alloc3D");
186 return {data + i * nrows * ncols, nrows, ncols};
187 }
188 matref<const T> operator[](int i) const {
189 if (i < 0 || i >= nmats) throw std::out_of_range("Alloc3D");
190 return {data + i * nrows * ncols, nrows, ncols};
191 }
192 T &at(int i, int j, int k) {
193 if (i < 0 || i >= nmats || j < 0 || j >= nrows || k < 0 || k >= ncols)
194 throw std::out_of_range("Alloc3D");
195 return data[i * nrows * ncols + j * ncols + k];
196 }
197 const T &at(int i, int j, int k) const {
198 if (i < 0 || i >= nmats || j < 0 || j >= nrows || k < 0 || k >= ncols)
199 throw std::out_of_range("Alloc3D");
200 return data[i * nrows * ncols + j * ncols + k];
201 }
202 T &operator[](std::tuple<int, int, int> i) {
203 if (std::get<0>(i) < 0 || std::get<0>(i) >= nmats || std::get<1>(i) < 0 ||
204 std::get<1>(i) >= nrows || std::get<2>(i) < 0 || std::get<2>(i) >= ncols)
205 throw std::out_of_range("Alloc3D");
206 return data[std::get<0>(i) * nrows * ncols + std::get<1>(i) * ncols + std::get<2>(i)];
207 }
208 const T &operator[](std::tuple<int, int, int> i) const {
209 if (std::get<0>(i) < 0 || std::get<0>(i) >= nmats || std::get<1>(i) < 0 ||
210 std::get<1>(i) >= nrows || std::get<2>(i) < 0 || std::get<2>(i) >= ncols)
211 throw std::out_of_range("Alloc3D");
212 return data[std::get<0>(i) * nrows * ncols + std::get<1>(i) * ncols + std::get<2>(i)];
213 }
214 bool operator==(const Alloc3Dbase<T> &t) const {
215 int sz = nmats * nrows * ncols;
216 if (nmats != t.nmats || nrows != t.nrows || ncols != t.ncols) return false;
217 return std::equal(data, data + sz, t.data);
218 }
219 bool operator!=(const Alloc3Dbase<T> &t) const { return !(*this == t); }
220
221 int matrixes() const { return nmats; }
222 int rows() const { return nrows; }
223 int cols() const { return ncols; }
224 void clear() { std::fill(data, data + nmats * nrows * ncols, T()); }
225};
226
227template <class T, int B, int R, int C>
228class Alloc3D : public Alloc3Dbase<T> {
229 public:
230 Alloc3D() : Alloc3Dbase<T>(B, R, C) {}
231 Alloc3Dbase<T> &base() { return *this; }
232};
233
234} // namespace BFN
235
236#endif /* BACKENDS_TOFINO_BF_ASM_ALLOC_H_ */
Definition bf-asm/alloc.h:65
Definition bf-p4c/common/alloc.h:160
The namespace encapsulating Barefoot/Intel-specific stuff.
Definition bf-asm/alloc.h:16