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