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) {
27 assert(e < std::numeric_limits<unsigned>::max());
29 APSInt p(shiftAmt + 1,
true);
34static DynamicAPInt fromBigEndian(
const std::vector<bool> &bits) {
35 APSInt rawInt(bits.size(),
false);
36 for (
unsigned i = 0; i < bits.size(); ++i) {
37 rawInt.setBitVal(i, bits[i]);
43binaryBitOp(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs, function_ref<
bool(
bool,
bool)> fn) {
44 DynamicAPInt a = lhs, b = rhs;
45 std::vector<bool> bits;
46 while (a != 0 || b != 0) {
48 bool abit = a != 0 ? bool(int64_t(a % 2)) : lhs < 0;
49 bool bbit = b != 0 ? bool(int64_t(b % 2)) : rhs < 0;
50 bits.push_back(fn(abit, bbit));
56 bits.push_back(fn(lhs < 0, rhs < 0));
57 return fromBigEndian(bits);
62DynamicAPInt
operator&(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
63 auto fn = [](
bool a,
bool b) {
return a && b; };
64 return binaryBitOp(lhs, rhs, fn);
67DynamicAPInt
operator|(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
68 auto fn = [](
bool a,
bool b) {
return a || b; };
69 return binaryBitOp(lhs, rhs, fn);
72DynamicAPInt
operator^(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
73 auto fn = [](
bool a,
bool b) {
return a ^ b; };
74 return binaryBitOp(lhs, rhs, fn);
77DynamicAPInt
operator<<(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
return lhs * po2(rhs); }
79DynamicAPInt
operator>>(
const DynamicAPInt &lhs,
const DynamicAPInt &rhs) {
81 return lhs / po2(rhs);
84 DynamicAPInt divisor = po2(rhs);
85 if (lhs % divisor == 0) {
88 return (lhs - (divisor - 1)) / divisor;
94 APSInt parsedInt(str);
102 if (i.getBitWidth() <= 64 && (i.isSigned() || i.isSignBitClear())) {
103 return DynamicAPInt(i.isNegative() ? i.getSExtValue() :
static_cast<int64_t
>(i.getZExtValue()));
106 DynamicAPInt res(0), po2(1);
110 APSInt raw = i < 0 ? -i : i;
111 for (
unsigned b = 0; b < raw.getActiveBits(); b++) {
112 DynamicAPInt bitSet(raw[b]);
113 res += (bitSet * po2);
116 if (i.isNegative() && res > 0) {
123 if (numeric_limits<int64_t>::min() <= i && i <= numeric_limits<int64_t>::max()) {
125 return APSInt::get(int64_t(i));
131 SmallString<64> repr;
132 raw_svector_ostream(repr) << i;
137 res = res.extend(res.getBitWidth() + 1);
138 res.setIsSigned(
true);
143APInt
toAPInt(
const DynamicAPInt &val,
unsigned bitWidth) {
145 raw_svector_ostream(str) << val;
146 return APInt(bitWidth + 1, str, 10);
151 raw_svector_ostream(str) << val;
152 return APInt(bitWidth, str, 10);
155DynamicAPInt
modExp(
const DynamicAPInt &base,
const DynamicAPInt &exp,
const DynamicAPInt &
mod) {
156 DynamicAPInt result(1);
157 DynamicAPInt b = base;
158 DynamicAPInt e = exp;
163 result = (result * b) %
mod;
173 assert(f != 0 &&
"0 has no inverse");
175 DynamicAPInt exp = p - 2;
176 DynamicAPInt result =
modExp(f, exp, p);
177 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)
APInt toExactWidthAPInt(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)