P4C
The P4 Compiler
Loading...
Searching...
No Matches
parde_utils.h
1
19#ifndef BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_UTILS_H_
20#define BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_UTILS_H_
21
22#include "bf-p4c/device.h"
23
24static const IR::BFN::PacketRVal *get_packet_range(const IR::BFN::ParserPrimitive *p) {
25 if (auto e = p->to<IR::BFN::Extract>()) {
26 if (auto range = e->source->to<IR::BFN::PacketRVal>()) {
27 return range;
28 } else {
29 return nullptr;
30 }
31 } else if (auto c = p->to<IR::BFN::ChecksumResidualDeposit>()) {
32 return c->header_end_byte;
33 } else if (auto c = p->to<IR::BFN::ChecksumSubtract>()) {
34 return c->source;
35 } else if (auto c = p->to<IR::BFN::ChecksumAdd>()) {
36 return c->source;
37 }
38 return nullptr;
39}
40
42 explicit SortExtracts(IR::BFN::ParserState *state) {
43 std::stable_sort(state->statements.begin(), state->statements.end(),
44 [&](const IR::BFN::ParserPrimitive *a, const IR::BFN::ParserPrimitive *b) {
45 auto va = get_packet_range(a);
46 auto vb = get_packet_range(b);
47 return (va && vb) ? (va->range < vb->range) : !!va;
48 });
49
50 if (LOGGING(5)) {
51 std::clog << "sorted primitives in " << state->name << std::endl;
52 for (auto p : state->statements) std::clog << p << std::endl;
53 }
54 }
55};
56
58 int rv = -1;
59
60 bool preorder(const IR::BFN::InputBufferRVal *rval) override {
61 rv = std::max(rval->range.hi, rv);
62 return false;
63 }
64};
65
67 int rv = Device::pardeSpec().byteInputBufferSize() * 8;
68
69 bool preorder(const IR::BFN::InputBufferRVal *rval) override {
70 if (rval->range.hi < 0) return false;
71 if (rval->range.lo < 0) BUG("rval straddles input buffer?");
72 rv = std::min(rval->range.lo, rv);
73 return false;
74 }
75};
76
77struct Shift : Transform {
78 int shift_amt = 0; // in bits
79 explicit Shift(int shft) : shift_amt(shft) {
80 BUG_CHECK(shift_amt % 8 == 0, "shift amount not byte-aligned?");
81 }
82};
83
85 bool negative_ok = false;
86 explicit ShiftPacketRVal(int shft, bool neg_ok = false) : Shift(shft), negative_ok(neg_ok) {}
87
88 IR::Node *preorder(IR::BFN::PacketRVal *rval) override {
89 auto new_range = rval->range.shiftedByBits(-shift_amt);
90 if (!negative_ok) BUG_CHECK(new_range.lo >= 0, "packet rval shifted to be negative?");
91 rval->range = new_range;
92 return rval;
93 }
94
95 IR::Node *postorder(IR::BFN::ChecksumSubtract *csum) {
96 auto *orig = getOriginal<IR::BFN::ChecksumSubtract>();
97 if (csum->source->range.loByte() % 2 != orig->source->range.loByte() % 2) {
98 return new IR::BFN::ChecksumSubtract(csum->declName, csum->source, !csum->swap,
99 csum->isPayloadChecksum);
100 }
101 return csum;
102 }
103
104 IR::Node *postorder(IR::BFN::ChecksumAdd *csum) {
105 auto *orig = getOriginal<IR::BFN::ChecksumAdd>();
106 if (csum->source->range.loByte() % 2 != orig->source->range.loByte() % 2) {
107 return new IR::BFN::ChecksumAdd(csum->declName, csum->source, !csum->swap,
108 csum->isHeaderChecksum);
109 }
110 return csum;
111 }
112};
113
114inline unsigned get_state_shift(const IR::BFN::ParserState *state) {
115 unsigned state_shift = 0;
116
117 for (unsigned i = 0; i < state->transitions.size(); i++) {
118 auto t = state->transitions[i];
119
120 if (i == 0)
121 state_shift = t->shift;
122 else
123 BUG_CHECK(state_shift == t->shift, "Inconsistent shifts in %1%", state->name);
124 }
125
126 return state_shift;
127}
128
129#endif /* BACKENDS_TOFINO_BF_P4C_PARDE_PARDE_UTILS_H_ */
Definition node.h:95
Definition visitor.h:400
Definition visitor.h:424
int byteInputBufferSize() const
The size of input buffer, in bytes.
Definition parde_spec.h:410
Definition parde_utils.h:57
Definition parde_utils.h:66
Definition parde_utils.h:77
Definition parde_utils.h:84
Definition parde_utils.h:41