14#include <llvm/ADT/ArrayRef.h>
15#include <llvm/ADT/SmallString.h>
16#include <llvm/Support/raw_ostream.h>
23static DynamicAPInt po2(
const DynamicAPInt &e) {
26 assert(e <= std::numeric_limits<unsigned>::max() );
28 APSInt p = APSInt::get(1) << shiftAmt;
32static DynamicAPInt fromBigEndian(
const std::vector<bool> &bits) {
33 APSInt rawInt(bits.size(),
false);
34 for (
unsigned i = 0; i < bits.size(); ++i) {
35 rawInt.setBitVal(i, bits[i]);
41binaryBitOp(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs, function_ref<
bool(
bool,
bool)> fn) {
42 DynamicAPInt a = lhs, b = rhs;
43 std::vector<bool> bits;
44 while (a != 0 || b != 0) {
46 bool abit = a != 0 ? bool(int64_t(a % 2)) : lhs < 0;
47 bool bbit = b != 0 ? bool(int64_t(b % 2)) : rhs < 0;
48 bits.push_back(fn(abit, bbit));
54 bits.push_back(fn(lhs < 0, rhs < 0));
55 return fromBigEndian(bits);
60DynamicAPInt
operator&(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
61 auto fn = [](
bool a,
bool b) {
return a && b; };
62 return binaryBitOp(lhs, rhs, fn);
65DynamicAPInt
operator|(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
66 auto fn = [](
bool a,
bool b) {
return a || b; };
67 return binaryBitOp(lhs, rhs, fn);
70DynamicAPInt
operator^(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
71 auto fn = [](
bool a,
bool b) {
return a ^ b; };
72 return binaryBitOp(lhs, rhs, fn);
75DynamicAPInt
operator<<(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
return lhs * po2(rhs); }
77DynamicAPInt
operator>>(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
79 return lhs / po2(rhs);
82 DynamicAPInt divisor = po2(rhs);
83 if (lhs % divisor == 0) {
86 return (lhs - (divisor - 1)) / divisor;
92 APSInt parsedInt(str);
97 if (i.getBitWidth() <= 64) {
99 return DynamicAPInt(i.isNegative() ? i.getSExtValue() :
static_cast<int64_t
>(i.getZExtValue()));
102 DynamicAPInt res(0), po2(1);
106 APSInt raw = i < 0 ? -i : i;
107 for (
unsigned b = 0; b < raw.getActiveBits(); b++) {
108 DynamicAPInt bitSet(raw[b]);
109 res += (bitSet * po2);
112 if (i.isNegative() && res > 0) {
119 if (numeric_limits<int64_t>::min() <= i && i <= numeric_limits<int64_t>::max()) {
121 return APSInt::get(int64_t(i));
127 SmallString<64> repr;
128 raw_svector_ostream(repr) << i;
133 res = res.extend(res.getBitWidth() + 1);
134 res.setIsSigned(
true);
139APInt
toAPInt(
const DynamicAPInt &val,
unsigned bitWidth) {
141 raw_svector_ostream(str) << val;
142 return APInt(bitWidth + 1, str, 10);
145DynamicAPInt
modExp(
const DynamicAPInt &base,
const DynamicAPInt &exp,
const DynamicAPInt &
mod) {
146 DynamicAPInt result(1);
147 DynamicAPInt b = base;
148 DynamicAPInt e = exp;
153 result = (result * b) %
mod;
163 assert(f != 0 &&
"0 has no inverse");
165 DynamicAPInt exp = p - 2;
166 DynamicAPInt result =
modExp(f, exp, p);
167 assert((f * result) % p == 1 &&
"inverse is incorrect");
This file implements helper methods for constructing DynamicAPInts.
ExpressionValue mod(const llvm::SMTSolverRef &solver, const ExpressionValue &lhs, const ExpressionValue &rhs)
Interval operator|(const Interval &lhs, const Interval &rhs)
Interval operator^(const Interval &lhs, const Interval &rhs)
DynamicAPInt toDynamicAPInt(StringRef str)
Interval operator<<(const Interval &lhs, const Interval &rhs)
APInt toAPInt(const DynamicAPInt &val, unsigned bitWidth)
Interval operator>>(const Interval &lhs, const Interval &rhs)
Interval operator&(const Interval &lhs, const Interval &rhs)
DynamicAPInt modInversePrime(const DynamicAPInt &f, const DynamicAPInt &p)
APSInt toAPSInt(const DynamicAPInt &i)
DynamicAPInt modExp(const DynamicAPInt &base, const DynamicAPInt &exp, const DynamicAPInt &mod)