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