P4C
The P4 Compiler
Loading...
Searching...
No Matches
tcExterns.h
1/*
2Copyright (C) 2024 Intel Corporation
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6http://www.apache.org/licenses/LICENSE-2.0
7Unless required by applicable law or agreed to in writing,
8software distributed under the License is distributed on an "AS IS" BASIS,
9WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10See the License for the specific language governing permissions
11and limitations under the License.
12*/
13
14#ifndef BACKENDS_TC_TCEXTERNS_H_
15#define BACKENDS_TC_TCEXTERNS_H_
16
17#include "backend.h"
18#include "ebpfCodeGen.h"
19
20namespace P4::TC {
21
22using namespace P4::literals;
23
26
27class EBPFCounterPNA : public EBPF::EBPFCounterPSA {
28 const IR::Declaration_Instance *di;
29 cstring tblname;
30
31 public:
32 EBPFCounterPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *di,
33 cstring name, EBPF::CodeGenInspector *codeGen, cstring tblname)
34 : EBPF::EBPFCounterPSA(program, di, name, codeGen) {
35 this->tblname = tblname;
36 this->di = di;
37 }
38 EBPFCounterPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *di,
39 cstring name, EBPF::CodeGenInspector *codeGen)
40 : EBPF::EBPFCounterPSA(program, di, name, codeGen) {
41 this->di = di;
42 }
43
44 void emitDirectMethodInvocation(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
45 const ConvertToBackendIR *tcIR);
46 void emitMethodInvocation(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
47 ControlBodyTranslatorPNA *translator);
48 virtual void emitCounterUpdate(EBPF::CodeBuilder *builder, const ConvertToBackendIR *tcIR);
49 virtual void emitCount(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
50 ControlBodyTranslatorPNA *translator);
51};
52
53class EBPFRegisterPNA : public EBPF::EBPFTableBase {
54 protected:
55 cstring instanceName;
56 const IR::Type *keyArg;
57 const IR::Type *valueArg;
58 EBPF::EBPFType *keyType;
59 EBPF::EBPFType *valueType;
60
61 public:
62 EBPFRegisterPNA(const EBPF::EBPFProgram *program, cstring instanceName,
63 const IR::Declaration_Instance *di, EBPF::CodeGenInspector *codeGen)
64 : EBPF::EBPFTableBase(program, instanceName, codeGen) {
65 CHECK_NULL(di);
66 this->instanceName = di->toString();
67 if (!di->type->is<IR::Type_Specialized>()) {
68 ::P4::error(ErrorType::ERR_MODEL, "Missing specialization: %1%", di);
69 return;
70 }
71 auto ts = di->type->to<IR::Type_Specialized>();
72
73 if (ts->arguments->size() != PARAM_INDEX_2) {
74 ::P4::error(ErrorType::ERR_MODEL, "Expected a type specialized with two arguments: %1%",
75 ts);
76 return;
77 }
78
79 this->valueArg = ts->arguments->at(0);
80 this->keyArg = ts->arguments->at(1);
81
82 this->keyType = EBPF::EBPFTypeFactory::instance->create(keyArg);
83 this->valueType = EBPF::EBPFTypeFactory::instance->create(valueArg);
84 }
85 void emitRegisterRead(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
86 ControlBodyTranslatorPNA *translator,
87 const IR::Expression *leftExpression);
88 void emitRegisterWrite(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
89 ControlBodyTranslatorPNA *translator);
90 void emitInitializer(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
91 ControlBodyTranslatorPNA *translator);
92};
93
94class EBPFTablePNADirectCounterPropertyVisitor : public EBPF::EBPFTablePsaPropertyVisitor {
95 public:
96 explicit EBPFTablePNADirectCounterPropertyVisitor(EBPF::EBPFTablePSA *table)
98
99 bool preorder(const IR::PathExpression *pe) override {
100 auto decl = table->program->refMap->getDeclaration(pe->path, true);
101 auto di = decl->to<IR::Declaration_Instance>();
102 CHECK_NULL(di);
103 if (EBPF::EBPFObject::getSpecializedTypeName(di) != "DirectCounter") {
104 ::P4::error(ErrorType::ERR_UNEXPECTED,
105 "%1%: not a DirectCounter, see declaration of %2%", pe, decl);
106 return false;
107 }
108 auto counterName = EBPF::EBPFObject::externalName(di);
109 auto tblname = table->table->container->name.originalName;
110 auto ctr = new EBPFCounterPNA(table->program, di, counterName, table->codeGen, tblname);
111 table->counters.emplace_back(std::make_pair(counterName, ctr));
112 return false;
113 }
114
115 void visitTableProperty() {
116 EBPF::EBPFTablePsaPropertyVisitor::visitTableProperty("pna_direct_counter"_cs);
117 }
118};
119
120class InternetChecksumAlgorithmPNA : public EBPF::EBPFHashAlgorithmPSA {
121 protected:
122 cstring stateVar;
123 cstring csumVar;
124
125 void updateChecksum(EBPF::CodeBuilder *builder, const ArgumentsList &arguments, bool addData);
126
127 public:
128 InternetChecksumAlgorithmPNA(const EBPF::EBPFProgram *program, cstring name)
129 : EBPF::EBPFHashAlgorithmPSA(program, name) {}
130
131 void emitVariables(EBPF::CodeBuilder *builder, const IR::Declaration_Instance *decl) override;
132
133 void emitClear(EBPF::CodeBuilder *builder) override;
134 void emitAddData(EBPF::CodeBuilder *builder, const ArgumentsList &arguments) override;
135 void emitGet(EBPF::CodeBuilder *builder) override;
136
137 void emitSubtractData(EBPF::CodeBuilder *builder, const ArgumentsList &arguments) override;
138
139 void emitGetInternalState(EBPF::CodeBuilder *builder) override;
140 void emitSetInternalState(EBPF::CodeBuilder *builder,
141 const IR::MethodCallExpression *expr) override;
142 cstring getConvertByteOrderFunction(unsigned widthToEmit, cstring byte_order);
143};
144
145class EBPFChecksumPNA : public EBPF::EBPFChecksumPSA {
146 protected:
147 cstring csumVar;
148 void init(const EBPF::EBPFProgram *program, cstring name, int type);
149
150 public:
151 EBPFChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block,
152 cstring name)
153 : EBPF::EBPFChecksumPSA(program, block, name) {
154 auto di = block->to<IR::Declaration_Instance>();
155 if (di->arguments->size() != 1) {
156 ::P4::error(ErrorType::ERR_UNEXPECTED, "Expected exactly 1 argument %1%", block);
157 return;
158 }
159 int type = di->arguments->at(0)->expression->checkedTo<IR::Constant>()->asInt();
160 init(program, name, type);
161 }
162
163 EBPFChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block,
164 cstring name, int type)
165 : EBPF::EBPFChecksumPSA(program, block, name, type) {
166 init(program, name, type);
167 }
168};
169
170class EBPFInternetChecksumPNA : public EBPFChecksumPNA {
171 public:
172 EBPFInternetChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block,
173 cstring name)
174 : EBPFChecksumPNA(program, block, name,
175 EBPF::EBPFHashAlgorithmPSA::HashAlgorithm::ONES_COMPLEMENT16) {}
176
177 void processMethod(EBPF::CodeBuilder *builder, cstring method,
178 const IR::MethodCallExpression *expr, Visitor *visitor) override;
179};
180
181class EBPFHashPNA : public EBPF::EBPFChecksumPSA {
182 protected:
183 void init(const EBPF::EBPFProgram *program, cstring name, int type);
184
185 public:
186 EBPFHashPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block,
187 cstring name)
188 : EBPF::EBPFChecksumPSA(program, block, name) {
189 auto di = block->to<IR::Declaration_Instance>();
190 if (di->arguments->size() != 1) {
191 ::P4::error(ErrorType::ERR_UNEXPECTED, "Expected exactly 1 argument %1%", block);
192 return;
193 }
194 int type = di->arguments->at(0)->expression->checkedTo<IR::Constant>()->asInt();
195 init(program, name, type);
196 }
197 void processMethod(EBPF::CodeBuilder *builder, cstring method,
198 const IR::MethodCallExpression *expr, Visitor *visitor) override;
199 void calculateHash(EBPF::CodeBuilder *builder, const IR::MethodCallExpression *expr,
200 Visitor *visitor);
201 void emitVariables(EBPF::CodeBuilder *builder);
202};
203
204class EBPFCRCChecksumPNA : public EBPFChecksumPNA {
205 public:
206 EBPFCRCChecksumPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *block,
207 cstring name)
208 : EBPFChecksumPNA(program, block, name) {}
209
210 void processMethod(EBPF::CodeBuilder *builder, cstring method,
211 const IR::MethodCallExpression *expr, Visitor *visitor) override;
212 void emitVariables(EBPF::CodeBuilder *builder);
213};
214
215class CRCChecksumAlgorithmPNA : public EBPF::CRCChecksumAlgorithm {
216 protected:
217 cstring csumVar;
218
219 public:
220 CRCChecksumAlgorithmPNA(const EBPF::EBPFProgram *program, cstring name, int width)
221 : EBPF::CRCChecksumAlgorithm(program, name, width) {
222 BUG_CHECK(width == 16 || width == 32, "Must be 16 bits width or 32 bits width.");
223 initialValue = "0"_cs;
224 }
225 void emitGet(EBPF::CodeBuilder *builder) override;
226 void emitAddData(EBPF::CodeBuilder *builder, const ArgumentsList &arguments,
227 const IR::MethodCallExpression *expr);
228 void emitAddData(EBPF::CodeBuilder *builder, int dataPos,
229 const IR::MethodCallExpression *expr) override;
230 void emitVariables(EBPF::CodeBuilder *builder, const IR::Declaration_Instance *decl) override;
231 void emitClear(EBPF::CodeBuilder *builder) override;
232};
233
234class HashAlgorithmPNA : public EBPF::CRCChecksumAlgorithm {
235 public:
236 HashAlgorithmPNA(const EBPF::EBPFProgram *program, cstring name, int width)
237 : EBPF::CRCChecksumAlgorithm(program, name, width) {
238 BUG_CHECK(width == 16 || width == 32, "Must be 16 bits width or 32 bits width.");
239 initialValue = "0"_cs;
240 }
241 void emitGet(EBPF::CodeBuilder *builder) override;
242 void emitAddData(EBPF::CodeBuilder *builder, const ArgumentsList &arguments,
243 const IR::MethodCallExpression *expr);
244 void emitAddData(EBPF::CodeBuilder *builder, int dataPos,
245 const IR::MethodCallExpression *expr) override;
246 void emitVariables(EBPF::CodeBuilder *builder);
247};
248
249class EBPFDigestPNA : public EBPF::EBPFDigestPSA {
250 const ConvertToBackendIR *tcIR;
251 cstring externName;
252 cstring instanceName;
253
254 public:
255 EBPFDigestPNA(const EBPF::EBPFProgram *program, const IR::Declaration_Instance *di,
256 cstring externName, const ConvertToBackendIR *tcIR)
257 : EBPF::EBPFDigestPSA(program, di) {
258 this->tcIR = tcIR;
259 this->externName = externName;
260 this->instanceName = di->toString();
261 }
262 void emitInitializer(EBPF::CodeBuilder *builder) const;
263 void emitPushElement(EBPF::CodeBuilder *builder, const IR::Expression *elem,
264 Inspector *codegen) const;
265 void emitPushElement(EBPF::CodeBuilder *builder, cstring elem) const;
266};
267
268class EBPFMeterPNA : public EBPF::EBPFMeterPSA {
269 cstring tblname;
270 cstring instanceName;
271
272 public:
273 EBPFMeterPNA(const EBPF::EBPFProgram *program, cstring instanceName,
274 const IR::Declaration_Instance *di, EBPF::CodeGenInspector *codeGen)
275 : EBPF::EBPFMeterPSA(program, instanceName, di, codeGen) {
276 this->instanceName = di->toString();
277 }
278 EBPFMeterPNA(const EBPF::EBPFProgram *program, cstring instanceName, cstring tblname,
279 const IR::Declaration_Instance *di, EBPF::CodeGenInspector *codeGen)
280 : EBPF::EBPFMeterPSA(program, instanceName, di, codeGen) {
281 this->tblname = tblname;
282 this->instanceName = di->toString();
283 }
284 void emitExecute(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
285 ControlBodyTranslatorPNA *translator,
286 const IR::Expression *leftExpression) const;
287 void emitDirectMeterExecute(EBPF::CodeBuilder *builder, const P4::ExternMethod *method,
288 ControlBodyTranslatorPNA *translator,
289 const IR::Expression *leftExpression) const;
290 void emitInitializer(EBPF::CodeBuilder *builder, const ConvertToBackendIR *tcIR,
291 cstring externName) const;
292};
293
294class EBPFTablePNADirectMeterPropertyVisitor : public EBPF::EBPFTablePsaPropertyVisitor {
295 public:
296 explicit EBPFTablePNADirectMeterPropertyVisitor(EBPF::EBPFTablePSA *table)
298
299 bool preorder(const IR::PathExpression *pe) override {
300 auto decl = table->program->refMap->getDeclaration(pe->path, true);
301 auto di = decl->to<IR::Declaration_Instance>();
302 CHECK_NULL(di);
303 if (EBPF::EBPFObject::getTypeName(di) != "DirectMeter") {
304 ::P4::error(ErrorType::ERR_UNEXPECTED, "%1%: not a DirectMeter, see declaration of %2%",
305 pe, decl);
306 return false;
307 }
308
309 auto meterName = EBPF::EBPFObject::externalName(di);
310 auto tblname = table->table->container->name.originalName;
311 auto met = new EBPFMeterPNA(table->program, meterName, tblname, di, table->codeGen);
312 table->meters.emplace_back(std::make_pair(meterName, met));
313 return false;
314 }
315
316 void visitTableProperty() {
317 EBPF::EBPFTablePsaPropertyVisitor::visitTableProperty("pna_direct_meter"_cs);
318 }
319};
320
321class EBPFRandomPNA : public EBPF::EBPFRandomPSA {
322 public:
323 explicit EBPFRandomPNA(const IR::Declaration_Instance *di) : EBPF::EBPFRandomPSA(di) {}
324
325 void emitExecute(EBPF::CodeBuilder *builder, ControlBodyTranslatorPNA *translator,
326 const IR::Type *ltype, const IR::Expression *lexpr,
327 const IR::Expression *rexpr) const;
328};
329} // namespace P4::TC
330
331#endif /* BACKENDS_TC_TCEXTERNS_H_ */
Definition ebpfPsaHashAlgorithm.h:74
Definition ebpf/codeGen.h:33
Definition ebpf/codeGen.h:41
Definition ebpfPsaChecksum.h:25
Definition ebpfPsaCounter.h:26
Definition ebpfPsaDigest.h:27
Definition ebpfPsaHashAlgorithm.h:26
Definition ebpfPsaMeter.h:23
Definition ebpfProgram.h:39
Definition ebpfPsaRandom.h:22
Also used to represent counters.
Definition ebpfTable.h:49
Definition ebpfPsaTable.h:29
Definition ebpfPsaTable.h:123
Base class for EBPF types.
Definition ebpfType.h:29
Definition methodInstance.h:168
Definition visitor.h:413
void emitVariables(EBPF::CodeBuilder *builder, const IR::Declaration_Instance *decl) override
decl might be a null pointer
Definition tcExterns.cpp:534
Definition ebpfCodeGen.h:403
Definition tc/backend.h:327
Definition tcExterns.h:27
Definition tcExterns.h:268
void emitVariables(EBPF::CodeBuilder *builder, const IR::Declaration_Instance *decl) override
decl might be a null pointer
Definition tcExterns.cpp:215
Definition visitor.h:75
Definition cstring.h:85
This file defines functions for the pass to generate the introspection file.
Definition tc/backend.cpp:27
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:58
T * to() noexcept
Definition rtti.h:226