P4C
The P4 Compiler
Loading...
Searching...
No Matches
push_pop.h
1
19#ifndef BF_P4C_MAU_PUSH_POP_H_
20#define BF_P4C_MAU_PUSH_POP_H_
21
22#include "bf-p4c/common/header_stack.h"
23#include "bf-p4c/common/slice.h"
24#include "mau_visitor.h"
25
26using namespace P4;
27
116 const BFN::HeaderStackInfo *stacks = nullptr;
117
118 IR::BFN::Pipe *preorder(IR::BFN::Pipe *pipe) override {
119 BUG_CHECK(pipe->headerStackInfo != nullptr,
120 "Running HeaderPushPop without running "
121 "CollectHeaderStackInfo first?");
122 stacks = pipe->headerStackInfo;
123 return pipe;
124 }
125
126 void copy_hdr(IR::Vector<IR::MAU::Primitive> *rv, const IR::Type_StructLike *hdr,
127 const IR::HeaderRef *to, const IR::HeaderRef *from) {
128 for (auto field : hdr->fields) {
129 auto dst = new IR::Member(field->type, to, field->name);
130 auto src = new IR::Member(field->type, from, field->name);
131 rv->push_back(new IR::MAU::Primitive("modify_field"_cs, dst, src));
132 }
133 }
134 IR::Node *do_push(const IR::HeaderRef *stack, int count) {
135 auto &info = stacks->at(stack->toString());
136 auto *rv = new IR::Vector<IR::MAU::Primitive>;
137 for (int i = info.size - 1; i >= count; --i)
138 copy_hdr(rv, stack->baseRef()->type,
139 new IR::HeaderStackItemRef(stack, new IR::Constant(i)),
140 new IR::HeaderStackItemRef(stack, new IR::Constant(i - count)));
141 auto *valid = new IR::Member(IR::Type::Bits::get(info.size + info.maxpop + info.maxpush),
142 stack, "$stkvalid");
143 rv->push_back(new IR::MAU::Primitive(
144 "modify_field"_cs, MakeSlice(valid, info.maxpop, info.maxpop + info.size - 1),
145 MakeSlice(valid, info.maxpop + count, info.maxpop + info.size + count - 1)));
146 return rv;
147 }
148 IR::Node *do_pop(const IR::HeaderRef *stack, int count) {
149 auto &info = stacks->at(stack->toString());
150 auto *rv = new IR::Vector<IR::MAU::Primitive>;
151 for (int i = count; i < info.size; ++i)
152 copy_hdr(rv, stack->baseRef()->type,
153 new IR::HeaderStackItemRef(stack, new IR::Constant(i - count)),
154 new IR::HeaderStackItemRef(stack, new IR::Constant(i)));
155 auto *valid = new IR::Member(IR::Type::Bits::get(info.size + info.maxpop + info.maxpush),
156 stack, "$stkvalid");
157 rv->push_back(new IR::MAU::Primitive(
158 "modify_field"_cs, MakeSlice(valid, info.maxpop, info.maxpop + info.size - 1),
159 MakeSlice(valid, info.maxpop - count, info.maxpop + info.size - count - 1)));
160 return rv;
161 }
162
163 IR::Node *preorder(IR::MAU::Primitive *prim) override {
164 BUG_CHECK(stacks != nullptr,
165 "No HeaderStackInfo; was HeaderPushPop "
166 "applied to a non-Pipe node?");
167 if (prim->name == "push_front")
168 return do_push(prim->operands[0]->to<IR::HeaderRef>(),
169 prim->operands[1]->to<IR::Constant>()->asInt());
170 else if (prim->name == "pop_front")
171 return do_pop(prim->operands[0]->to<IR::HeaderRef>(),
172 prim->operands[1]->to<IR::Constant>()->asInt());
173 return prim;
174 }
175};
176
177#endif /* BF_P4C_MAU_PUSH_POP_H_ */
Definition push_pop.h:115
Definition mau_visitor.h:55
Definition node.h:95
Definition vector.h:59
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void info(const int kind, const char *format, const T *node, Args &&...args)
Report info messages of type kind. Requires that the node argument have source info.
Definition lib/error.h:148
Metadata about how header stacks are used in the program.
Definition header_stack.h:94