Ejemplo n.º 1
0
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();
}
Ejemplo n.º 2
0
/// 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);
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
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;
            }
        }
Ejemplo n.º 6
0
//===----------------------------------------------------------------------===//
// 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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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;
}