P4C
The P4 Compiler
Loading...
Searching...
No Matches
big_int_util.h
1/*
2Copyright 2013-present Barefoot Networks, Inc.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17#ifndef LIB_BIG_INT_UTIL_H_
18#define LIB_BIG_INT_UTIL_H_
19
20#include <boost/version.hpp>
21
22#if BOOST_VERSION < 106700
23#include <boost/functional/hash.hpp>
24#endif
25
26#include "big_int.h"
27#include "hash.h"
28
29namespace P4::Util {
30
31// Useful functions for manipulating GMP values
32// (arbitrary-precision values)
33
34big_int ripBits(big_int &value, int bits);
35
36struct BitRange {
37 unsigned lowIndex;
38 unsigned highIndex;
39 big_int value;
40};
41
42// Find a consecutive scan of 1 bits at the "bottom"
43BitRange findOnes(const big_int &value);
44
45big_int cvtInt(const char *s, unsigned base);
46big_int shift_left(const big_int &v, unsigned bits);
47big_int shift_right(const big_int &v, unsigned bits);
48// Convert a slice [m:l] into a mask
49big_int maskFromSlice(unsigned m, unsigned l);
50big_int mask(unsigned bits);
51
52inline unsigned scan0_positive(const boost::multiprecision::cpp_int &val, unsigned pos) {
53 while (boost::multiprecision::bit_test(val, pos)) ++pos;
54 return pos;
55}
56inline unsigned scan1_positive(const boost::multiprecision::cpp_int &val, unsigned pos) {
57 if (val == 0 || pos > boost::multiprecision::msb(val)) return ~0U;
58 unsigned lsb = boost::multiprecision::lsb(val);
59 if (lsb >= pos) return lsb;
60 while (!boost::multiprecision::bit_test(val, pos)) ++pos;
61 return pos;
62}
63inline unsigned scan0(const boost::multiprecision::cpp_int &val, unsigned pos) {
64 if (val < 0) return scan1_positive(-val - 1, pos);
65 return scan0_positive(val, pos);
66}
67inline unsigned scan1(const boost::multiprecision::cpp_int &val, unsigned pos) {
68 if (val < 0) return scan0_positive(-val - 1, pos);
69 return scan1_positive(val, pos);
70}
71
72} // namespace P4::Util
73
74namespace P4 {
75
76static inline unsigned bitcount(big_int v) {
77 if (v < 0) return ~0U;
78 unsigned rv = 0;
79 while (v != 0) {
80 v &= v - 1;
81 ++rv;
82 }
83 return rv;
84}
85
86static inline int ffs(big_int v) {
87 if (v <= 0) return -1;
88 return boost::multiprecision::lsb(v);
89}
90
91static inline int floor_log2(big_int v) {
92 int rv = -1;
93 while (v > 0) {
94 rv++;
95 v /= 2;
96 }
97 return rv;
98}
99
100static inline int ceil_log2(big_int v) { return v ? floor_log2(v - 1) + 1 : -1; }
101
102template <>
103struct Util::Hasher<big_int> : Detail::StdHasher {};
104
105} // namespace P4
106
107#endif /* LIB_BIG_INT_UTIL_H_ */
Definition hash.h:90
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
Definition big_int_util.h:36
Definition hash.h:123