GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
GenericValue Result;
- if (ConstantExpr *CE = (ConstantExpr*)dyn_cast<ConstantExpr>(C))
+ if (ConstantExpr *CE = const_cast<ConstantExpr*>(dyn_cast<ConstantExpr>(C))) {
switch (CE->getOpcode()) {
case Instruction::GetElementPtr: {
- Result = getConstantValue(cast<Constant>(CE->getOperand(0)));
+ Result = getConstantValue(CE->getOperand(0));
std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end());
uint64_t Offset =
TD->getIndexedOffset(CE->getOperand(0)->getType(), Indexes);
Result.LongVal += Offset;
return Result;
}
+ case Instruction::Cast: {
+ // We only need to handle a few cases here. Almost all casts will
+ // automatically fold, just the ones involving pointers won't.
+ //
+ Constant *Op = CE->getOperand(0);
- default:
- std::cerr << "ConstantExpr not handled as global var init: " << *CE
- << "\n";
- abort();
+ // Handle cast of pointer to pointer...
+ if (Op->getType()->getPrimitiveID() == C->getType()->getPrimitiveID())
+ return getConstantValue(Op);
+
+ // Handle cast of long to pointer or pointer to long...
+ if ((isa<PointerType>(Op->getType()) && (C->getType() == Type::LongTy ||
+ C->getType() == Type::ULongTy))||
+ (isa<PointerType>(C->getType()) && (Op->getType() == Type::LongTy ||
+ Op->getType() == Type::ULongTy))){
+ return getConstantValue(Op);
+ }
+ break;
}
+ case Instruction::Add:
+ if (CE->getOperand(0)->getType() == Type::LongTy ||
+ CE->getOperand(0)->getType() == Type::ULongTy)
+ Result.LongVal = getConstantValue(CE->getOperand(0)).LongVal +
+ getConstantValue(CE->getOperand(1)).LongVal;
+ else
+ break;
+ return Result;
+
+ default:
+ break;
+ }
+ std::cerr << "ConstantExpr not handled as global var init: " << *CE << "\n";
+ abort();
+ }
+
switch (C->getType()->getPrimitiveID()) {
#define GET_CONST_VAL(TY, CLASS) \
case Type::TY##TyID: Result.TY##Val = cast<CLASS>(C)->getValue(); break
}
}
+GenericValue ExecutionEngine::LoadValueFromMemory(GenericValue *Ptr,
+ const Type *Ty) {
+ GenericValue Result;
+ if (getTargetData().isLittleEndian()) {
+ switch (Ty->getPrimitiveID()) {
+ case Type::BoolTyID:
+ case Type::UByteTyID:
+ case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break;
+ case Type::UShortTyID:
+ case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[0] |
+ ((unsigned)Ptr->Untyped[1] << 8);
+ break;
+ Load4BytesLittleEndian:
+ case Type::FloatTyID:
+ case Type::UIntTyID:
+ case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[0] |
+ ((unsigned)Ptr->Untyped[1] << 8) |
+ ((unsigned)Ptr->Untyped[2] << 16) |
+ ((unsigned)Ptr->Untyped[3] << 24);
+ break;
+ case Type::PointerTyID: if (getModule().has32BitPointers())
+ goto Load4BytesLittleEndian;
+ case Type::DoubleTyID:
+ case Type::ULongTyID:
+ case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[0] |
+ ((uint64_t)Ptr->Untyped[1] << 8) |
+ ((uint64_t)Ptr->Untyped[2] << 16) |
+ ((uint64_t)Ptr->Untyped[3] << 24) |
+ ((uint64_t)Ptr->Untyped[4] << 32) |
+ ((uint64_t)Ptr->Untyped[5] << 40) |
+ ((uint64_t)Ptr->Untyped[6] << 48) |
+ ((uint64_t)Ptr->Untyped[7] << 56);
+ break;
+ default:
+ std::cout << "Cannot load value of type " << *Ty << "!\n";
+ abort();
+ }
+ } else {
+ switch (Ty->getPrimitiveID()) {
+ case Type::BoolTyID:
+ case Type::UByteTyID:
+ case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break;
+ case Type::UShortTyID:
+ case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[1] |
+ ((unsigned)Ptr->Untyped[0] << 8);
+ break;
+ Load4BytesBigEndian:
+ case Type::FloatTyID:
+ case Type::UIntTyID:
+ case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[3] |
+ ((unsigned)Ptr->Untyped[2] << 8) |
+ ((unsigned)Ptr->Untyped[1] << 16) |
+ ((unsigned)Ptr->Untyped[0] << 24);
+ break;
+ case Type::PointerTyID: if (getModule().has32BitPointers())
+ goto Load4BytesBigEndian;
+ case Type::DoubleTyID:
+ case Type::ULongTyID:
+ case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[7] |
+ ((uint64_t)Ptr->Untyped[6] << 8) |
+ ((uint64_t)Ptr->Untyped[5] << 16) |
+ ((uint64_t)Ptr->Untyped[4] << 24) |
+ ((uint64_t)Ptr->Untyped[3] << 32) |
+ ((uint64_t)Ptr->Untyped[2] << 40) |
+ ((uint64_t)Ptr->Untyped[1] << 48) |
+ ((uint64_t)Ptr->Untyped[0] << 56);
+ break;
+ default:
+ std::cout << "Cannot load value of type " << *Ty << "!\n";
+ abort();
+ }
+ }
+ return Result;
+}
+
+
// InitializeMemory - Recursive function to apply a Constant value into the
// specified memory location...
//