lvalue eval_lexpr(const Expr* e){ if(isa<DeclRefExpr>(e)){ const DeclRefExpr* expr = (const DeclRefExpr*)e; std::string name = expr->getDecl()->getNameAsString(); const auto ret = stack_var_map.find(name); if(ret == stack_var_map.end()){ return get_nonstack_var(name); } const auto list = &ret->second; const auto item = list->back(); lvalue ans = stack_vars[item.first][item.second].second; return ans; } else if(isa<ArraySubscriptExpr>(e)){ const ArraySubscriptExpr* expr = (const ArraySubscriptExpr*)e; const EmuVal* base = eval_rexpr(expr->getBase()); const EmuVal* idx = eval_rexpr(expr->getIdx()); const Type* basetype = base->obj_type.getCanonicalType().getTypePtr(); if(!basetype->isPointerType()){ llvm::errs() << "\n\n"; basetype->dump(); cant_handle(); } QualType t = idx->obj_type.getCanonicalType(); if(!t->isIntegerType()){ llvm::errs() << "\n\n"; t.dump(); cant_handle(); } const EmuPtr* emup = (const EmuPtr*)base; mem_ptr p = mem_ptr(emup->u.block, emup->offset); QualType subtype = ((const PointerType*)basetype)->getPointeeType(); const llvm::APInt idx_val = ((const EmuNumGeneric*)idx)->val; int64_t offset = ((int64_t)getSizeOf(subtype))*idx_val.getSExtValue() + p.offset; if(offset<0){ err_exit("Got pointer to invalid location"); } return lvalue(p.block, ((const PointerType*)basetype)->getPointeeType(), (size_t)offset); } else if(isa<StringLiteral>(e)){ const StringLiteral *obj = (const StringLiteral*)e; if(obj->getKind() != StringLiteral::StringKind::Ascii){ err_exit("Can't handle non-ascii strings"); } // allocate string at this point mem_block *stringstorage = new mem_block(MEM_TYPE_STATIC, obj->getByteLength()+1); for(unsigned int i = 0; i <= obj->getLength(); i++){ char c; if(i < obj->getLength()) c = (char)obj->getCodeUnit(i); else c = '\0'; ((char*)stringstorage->data)[i] = c; } return lvalue(stringstorage, e->getType(), 0); } else if(isa<ParenExpr>(e)){ return eval_lexpr(((const ParenExpr*)e)->getSubExpr()); } llvm::errs() << "DOUG DEBUG: eval_lexpr cant handle the following:\n"; e->dump(); cant_handle(); }
/// GetIntegerValue - Convert this numeric literal value to an APInt that /// matches Val's input width. If there is an overflow, set Val to the low bits /// of the result and return true. Otherwise, return false. bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { // Fast path: Compute a conservative bound on the maximum number of // bits per digit in this radix. If we can't possibly overflow a // uint64 based on that bound then do the simple conversion to // integer. This avoids the expensive overflow checking below, and // handles the common cases that matter (small decimal integers and // hex/octal values which don't overflow). const unsigned NumDigits = SuffixBegin - DigitsBegin; if (alwaysFitsInto64Bits(radix, NumDigits)) { uint64_t N = 0; for (const char *Ptr = DigitsBegin; Ptr != SuffixBegin; ++Ptr) if (!isDigitSeparator(*Ptr)) N = N * radix + llvm::hexDigitValue(*Ptr); // This will truncate the value to Val's input width. Simply check // for overflow by comparing. Val = N; return Val.getZExtValue() != N; } Val = 0; const char *Ptr = DigitsBegin; llvm::APInt RadixVal(Val.getBitWidth(), radix); llvm::APInt CharVal(Val.getBitWidth(), 0); llvm::APInt OldVal = Val; bool OverflowOccurred = false; while (Ptr < SuffixBegin) { if (isDigitSeparator(*Ptr)) { ++Ptr; continue; } unsigned C = llvm::hexDigitValue(*Ptr++); // If this letter is out of bound for this radix, reject it. assert(C < radix && "NumericLiteralParser ctor should have rejected this"); CharVal = C; // Add the digit to the value in the appropriate radix. If adding in digits // made the value smaller, then this overflowed. OldVal = Val; // Multiply by radix, did overflow occur on the multiply? Val *= RadixVal; OverflowOccurred |= Val.udiv(RadixVal) != OldVal; // Add value, did overflow occur on the value? // (a + b) ult b <=> overflow Val += CharVal; OverflowOccurred |= Val.ult(CharVal); } return OverflowOccurred; }
bool MagicNumbersCheck::isIgnoredValue(const IntegerLiteral *Literal) const { const llvm::APInt IntValue = Literal->getValue(); const int64_t Value = IntValue.getZExtValue(); if (Value == 0) return true; if (IgnorePowersOf2IntegerValues && IntValue.isPowerOf2()) return true; return std::binary_search(IgnoredIntegerValues.begin(), IgnoredIntegerValues.end(), Value); }
inline std::string get_padded_string(const llvm::APInt &x) { std::ostringstream os; // This creates enough zeroes if x itself is zero. for (unsigned i = 0, e = x.countLeadingZeros(); i != e; ++i) os << "0"; // Hence we check it here. if (x != 0) os << x.toString(2, false); return os.str(); }
void NumericOutput::OutputInteger(const llvm::APInt& intn) { // General size warnings if (m_warns_enabled && m_sign && !isOkSize(intn, m_size, m_rshift, 1)) m_warns |= INT_OVERFLOW; if (m_warns_enabled && !m_sign && !isOkSize(intn, m_size, m_rshift, 2)) m_warns |= INT_OVERFLOW; // Check low bits if right shifting if (m_warns_enabled && m_rshift > 0 && intn.countTrailingZeros() < m_rshift) m_warns |= TRUNCATED; // Make a working copy of the right-shifted value llvm::APInt work = intn.ashr(m_rshift); // Sign extend (or truncate) to correct size work.sextOrTrunc(m_size); // Shortcut easy case if (m_shift == 0 && m_bytes.size()*8 == m_size) { assert(m_bytes.isLittleEndian() && "big endian not yet supported"); const uint64_t* words = work.getRawData(); // whole words first unsigned int w = 0; int i = 0, o = 0; int n = static_cast<int>(m_size); for (; i<=n-64; i+=64, ++w) { uint64_t wrd = words[w]; for (int j=0; j<8; ++j) { m_bytes[o++] = static_cast<unsigned char>(wrd) & 0xFF; wrd >>= 8; } } // finish with bytes if (i < n) { uint64_t last = words[w]; for (; i<n; i+=8) { m_bytes[o++] = static_cast<unsigned char>(last) & 0xFF; last >>= 8; } }
//===----------------------------------------------------------------------===// // Primary Expressions. //===----------------------------------------------------------------------===// void APNumericStorage::setIntValue(ASTContext &C, const llvm::APInt &Val) { if (hasAllocation()) C.Deallocate(pVal); BitWidth = Val.getBitWidth(); unsigned NumWords = Val.getNumWords(); const uint64_t* Words = Val.getRawData(); if (NumWords > 1) { pVal = new (C) uint64_t[NumWords]; std::copy(Words, Words + NumWords, pVal); } else if (NumWords == 1) VAL = Words[0]; else VAL = 0; }
/// \brief Determine if two APInts have the same value, after zero-extending /// one of them (if needed!) to ensure that the bit-widths match. static bool IsSameValue(const llvm::APInt &I1, const llvm::APInt &I2) { if (I1.getBitWidth() == I2.getBitWidth()) return I1 == I2; if (I1.getBitWidth() > I2.getBitWidth()) return I1 == I2.zext(I1.getBitWidth()); return I1.zext(I2.getBitWidth()) == I2; }
bool CompareEquals(llvm::APInt a,llvm::APInt b) { if (a.getBitWidth()!=b.getBitWidth()) { if (a.getBitWidth()<b.getBitWidth()) a=a.zext(b.getBitWidth()); else b=b.zext(a.getBitWidth()); } return a==b; }
ClusteredBitVector ClusteredBitVector::fromAPInt(const llvm::APInt &bits) { // This is not a very efficient algorithm. ClusteredBitVector result; for (unsigned i = 0, e = bits.getBitWidth(); i != e; ++i) { if (bits[i]) { result.appendSetBits(1); } else { result.appendClearBits(1); } } return result; }
std::string Inst::getKnownBitsString(llvm::APInt Zero, llvm::APInt One) { std::string Str; for (int K=Zero.getBitWidth()-1; K>=0; --K) { if (Zero[K] && One[K]) llvm_unreachable("KnownZero and KnownOnes bit can't be set to 1 together"); if (Zero[K]) { Str.append("0"); } else { if (One[K]) Str.append("1"); else Str.append("x"); } } return Str; }