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/multiprecision/cpp_int.hpp>
21
22#include "config.h"
23typedef boost::multiprecision::cpp_int big_int;
24
25namespace Util {
26
27// Useful functions for manipulating GMP values
28// (arbitrary-precision values)
29
30big_int ripBits(big_int &value, int bits);
31
32struct BitRange {
33 unsigned lowIndex;
34 unsigned highIndex;
35 big_int value;
36};
37
38// Find a consecutive scan of 1 bits at the "bottom"
39BitRange findOnes(const big_int &value);
40
41big_int cvtInt(const char *s, unsigned base);
42big_int shift_left(const big_int &v, unsigned bits);
43big_int shift_right(const big_int &v, unsigned bits);
44// Convert a slice [m:l] into a mask
45big_int maskFromSlice(unsigned m, unsigned l);
46big_int mask(unsigned bits);
47
48inline unsigned scan0_positive(const boost::multiprecision::cpp_int &val, unsigned pos) {
49 while (boost::multiprecision::bit_test(val, pos)) ++pos;
50 return pos;
51}
52inline unsigned scan1_positive(const boost::multiprecision::cpp_int &val, unsigned pos) {
53 if (val == 0 || pos > boost::multiprecision::msb(val)) return ~0U;
54 unsigned lsb = boost::multiprecision::lsb(val);
55 if (lsb >= pos) return lsb;
56 while (!boost::multiprecision::bit_test(val, pos)) ++pos;
57 return pos;
58}
59inline unsigned scan0(const boost::multiprecision::cpp_int &val, unsigned pos) {
60 if (val < 0) return scan1_positive(-val - 1, pos);
61 return scan0_positive(val, pos);
62}
63inline unsigned scan1(const boost::multiprecision::cpp_int &val, unsigned pos) {
64 if (val < 0) return scan0_positive(-val - 1, pos);
65 return scan1_positive(val, pos);
66}
67
68} // namespace Util
69
70static inline unsigned bitcount(big_int v) {
71 if (v < 0) return ~0U;
72 unsigned rv = 0;
73 while (v != 0) {
74 v &= v - 1;
75 ++rv;
76 }
77 return rv;
78}
79
80static inline int ffs(big_int v) {
81 if (v <= 0) return -1;
82 return boost::multiprecision::lsb(v);
83}
84
85static inline int floor_log2(big_int v) {
86 int rv = -1;
87 while (v > 0) {
88 rv++;
89 v /= 2;
90 }
91 return rv;
92}
93
94static inline int ceil_log2(big_int v) { return v ? floor_log2(v - 1) + 1 : -1; }
95
96#endif /* LIB_BIG_INT_UTIL_H_ */
Definition big_int_util.h:32