51 friend std::ostream &operator<<(std::ostream &,
const Slice &);
61 Slice() : field(0), lo(-1), hi(-2) {}
62 explicit Slice(
const PHV::Field *f) : field(f), lo(0), hi(f->
size - 1) {}
63 Slice(
const PHV::Field *f,
int bit) : field(f), lo(bit), hi(bit) {}
64 Slice(
const PHV::Field *f,
int l,
int h) : field(f), lo(l), hi(h) {}
65 Slice(
const PHV::Field *f, le_bitrange r) : field(f), lo(r.
lo), hi(r.
hi) {}
67 : field(f->field()), lo(f->range().lo), hi(f->range().hi) {}
69 : field(f->field()), lo(f->range().lo + l), hi(f->range().lo + h) {
70 if (hi > f->range().hi) hi = f->range().hi;
71 if (!field || lo > hi) invalidate();
75 Slice(
const PhvInfo &phv,
const IR::Expression *e) {
77 if (!(field = phv.field(e, &bits))) {
84 Slice(
const PhvInfo &phv,
const IR::Expression *e,
int l,
int h) {
86 if (!(field = phv.field(e, &bits))) {
91 if (hi > bits.
hi) hi = bits.
hi;
92 if (lo > hi) invalidate();
95 Slice(
const PhvInfo &phv,
const IR::Expression *e, le_bitrange r) : Slice(phv, e, r.
lo, r.
hi) {}
96 Slice(
const PhvInfo &phv,
const IR::Expression *e,
int bit) : Slice(phv, e, bit, bit) {}
97 Slice(
const PhvInfo &phv,
cstring n) : field(phv.field(n)), lo(0), hi(field->size - 1) {}
98 Slice(
const PhvInfo &phv,
cstring n,
int bit) : field(phv.field(n)), lo(bit), hi(bit) {
99 BUG_CHECK((bit >= 0 && bit < field->size),
100 "Slice out of range for field = '%s', bit=%d, size=%d", field->name, bit,
103 Slice(
const PhvInfo &phv,
cstring n,
int l,
int h) : field(phv.field(n)), lo(l), hi(h) {
104 BUG_CHECK((lo < field->size),
"Slice out of range for field = '%s', lo=%d, size=%d",
105 field->name, lo, field->size);
107 if (hi >= field->size) hi = field->size - 1;
110 Slice(
PHV::Container r,
int bit) : field(0), reg(r), lo(bit), hi(bit) {}
111 Slice(
PHV::Container r,
int lo,
int hi) : field(0), reg(r), lo(lo), hi(hi) {}
112 Slice(
const Slice &s,
int bit) : field(s.field), reg(s.reg), lo(s.lo + bit), hi(lo) {}
113 Slice(
const Slice &s,
int l,
int h) : field(s.field), reg(s.reg), lo(s.lo + l), hi(s.lo + h) {
114 if (hi > s.hi) hi = s.hi;
115 if (!field || lo > hi) invalidate();
117 explicit operator bool()
const {
return field !=
nullptr || reg; }
118 Slice operator()(
int bit)
const {
return Slice(*
this, bit); }
119 Slice operator()(
int l,
int h)
const {
return Slice(*
this, l, h); }
120 Slice join(Slice &a)
const;
121 Slice &operator-=(
const Slice &a) {
122 if (field != a.field || reg != a.reg || hi < a.lo || lo > a.hi)
return *
this;
123 if (a.lo <= lo) lo = a.hi + 1;
124 if (a.hi >= hi) hi = a.lo - 1;
125 if (lo > hi) invalidate();
128 Slice &operator-=(
const std::vector<Slice> &a) {
129 for (
auto &v : a) *
this -= v;
132 Slice operator-(
const Slice &a)
const {
137 Slice operator-(
const std::vector<Slice> &a)
const {
142 Slice &operator&=(
const Slice &a) {
143 if (field != a.field || reg != a.reg)
return invalidate();
144 if (a.lo > lo) lo = a.lo;
145 if (a.hi < hi) hi = a.hi;
146 if (lo > hi) invalidate();
149 Slice operator&(
const Slice &a)
const {
156 int width()
const {
return hi - lo + 1; }
157 int align(
int size)
const;
158 int bytealign()
const {
return align(8); }
159 Slice fullbyte()
const;
160 const PHV::Field *get_field()
const {
return field; }
162 int get_lo()
const {
return lo; }
163 int get_hi()
const {
return hi; }
164 void shrink_lo(
int shrink) {
165 if (shrink + lo >= hi)
170 le_bitrange range()
const {
return {lo, hi}; }
171 void shrink_hi(
int shrink) {
172 if (hi - shrink <= lo)