ExecutionEngine.cpp revision 3db4b62c2fa43b23fa02d32a7d3253885acafb9f
144d362409d5469aed47d19e7908d19bd194493aThomas Graf//===-- ExecutionEngine.cpp - Common Implementation shared by EEs ---------===// 244d362409d5469aed47d19e7908d19bd194493aThomas Graf// 344d362409d5469aed47d19e7908d19bd194493aThomas Graf// The LLVM Compiler Infrastructure 444d362409d5469aed47d19e7908d19bd194493aThomas Graf// 544d362409d5469aed47d19e7908d19bd194493aThomas Graf// This file was developed by the LLVM research group and is distributed under 644d362409d5469aed47d19e7908d19bd194493aThomas Graf// the University of Illinois Open Source License. See LICENSE.TXT for details. 744d362409d5469aed47d19e7908d19bd194493aThomas Graf// 844d362409d5469aed47d19e7908d19bd194493aThomas Graf//===----------------------------------------------------------------------===// 944d362409d5469aed47d19e7908d19bd194493aThomas Graf// 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf// This file defines the common interface used by the various execution engine 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf// subclasses. 1244d362409d5469aed47d19e7908d19bd194493aThomas Graf// 1344d362409d5469aed47d19e7908d19bd194493aThomas Graf//===----------------------------------------------------------------------===// 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf 1544d362409d5469aed47d19e7908d19bd194493aThomas Graf#define DEBUG_TYPE "jit" 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "Interpreter/Interpreter.h" 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "JIT/JIT.h" 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/Constants.h" 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/DerivedTypes.h" 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/Module.h" 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/ModuleProvider.h" 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/ADT/Statistic.h" 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/CodeGen/IntrinsicLowering.h" 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/ExecutionEngine/ExecutionEngine.h" 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/ExecutionEngine/GenericValue.h" 2644d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/Support/Debug.h" 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/System/DynamicLibrary.h" 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf#include "llvm/Target/TargetData.h" 2944d362409d5469aed47d19e7908d19bd194493aThomas Grafusing namespace llvm; 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf 3144d362409d5469aed47d19e7908d19bd194493aThomas Grafnamespace { 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized"); 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf Statistic<> NumGlobals ("lli", "Number of global vars initialized"); 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 3544d362409d5469aed47d19e7908d19bd194493aThomas Graf 3644d362409d5469aed47d19e7908d19bd194493aThomas GrafExecutionEngine::ExecutionEngine(ModuleProvider *P) : 3744d362409d5469aed47d19e7908d19bd194493aThomas Graf CurMod(*P->getModule()), MP(P) { 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(P && "ModuleProvider is null?"); 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf} 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf 4144d362409d5469aed47d19e7908d19bd194493aThomas GrafExecutionEngine::ExecutionEngine(Module *M) : CurMod(*M), MP(0) { 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(M && "Module is null?"); 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf 4544d362409d5469aed47d19e7908d19bd194493aThomas GrafExecutionEngine::~ExecutionEngine() { 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf delete MP; 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf} 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf/// getGlobalValueAtAddress - Return the LLVM global value object that starts 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf/// at the specified address. 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 5244d362409d5469aed47d19e7908d19bd194493aThomas Grafconst GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) { 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf MutexGuard locked(lock); 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf // If we haven't computed the reverse mapping yet, do so first. 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (state.getGlobalAddressReverseMap(locked).empty()) { 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf for (std::map<const GlobalValue*, void *>::iterator I = 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf state.getGlobalAddressMap(locked).begin(), E = state.getGlobalAddressMap(locked).end(); I != E; ++I) 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second, I->first)); 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf std::map<void *, const GlobalValue*>::iterator I = 6344d362409d5469aed47d19e7908d19bd194493aThomas Graf state.getGlobalAddressReverseMap(locked).find(Addr); 6444d362409d5469aed47d19e7908d19bd194493aThomas Graf return I != state.getGlobalAddressReverseMap(locked).end() ? I->second : 0; 6544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf// CreateArgv - Turn a vector of strings into a nice argv style array of 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf// pointers to null terminated strings. 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf// 7044d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void *CreateArgv(ExecutionEngine *EE, 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf const std::vector<std::string> &InputArgv) { 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned PtrSize = EE->getTargetData().getPointerSize(); 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf char *Result = new char[(InputArgv.size()+1)*PtrSize]; 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf const Type *SBytePtr = PointerType::get(Type::SByteTy); 7744d362409d5469aed47d19e7908d19bd194493aThomas Graf 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf for (unsigned i = 0; i != InputArgv.size(); ++i) { 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned Size = InputArgv[i].size()+1; 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf char *Dest = new char[Size]; 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf 8344d362409d5469aed47d19e7908d19bd194493aThomas Graf std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); 8444d362409d5469aed47d19e7908d19bd194493aThomas Graf Dest[Size-1] = 0; 8544d362409d5469aed47d19e7908d19bd194493aThomas Graf 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf // Endian safe: Result[i] = (PointerTy)Dest; 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf SBytePtr); 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf // Null terminate it 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf EE->StoreValueToMemory(PTOGV(0), 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf (GenericValue*)(Result+InputArgv.size()*PtrSize), 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf SBytePtr); 9544d362409d5469aed47d19e7908d19bd194493aThomas Graf return Result; 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf/// runFunctionAsMain - This is a helper function which wraps runFunction to 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf/// handle the common task of starting up main with the specified argc, argv, 100eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf/// and envp parameters. 10144d362409d5469aed47d19e7908d19bd194493aThomas Grafint ExecutionEngine::runFunctionAsMain(Function *Fn, 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf const std::vector<std::string> &argv, 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf const char * const * envp) { 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf std::vector<GenericValue> GVArgs; 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf GenericValue GVArgc; 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf GVArgc.IntVal = argv.size(); 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned NumArgs = Fn->getFunctionType()->getNumParams(); 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (NumArgs) { 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf GVArgs.push_back(GVArgc); // Arg #0 = argc. 11044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (NumArgs > 1) { 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf GVArgs.push_back(PTOGV(CreateArgv(this, argv))); // Arg #1 = argv. 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(((char **)GVTOP(GVArgs[1]))[0] && 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf "argv[0] was null after CreateArgv"); 11444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (NumArgs > 2) { 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf std::vector<std::string> EnvVars; 11644d362409d5469aed47d19e7908d19bd194493aThomas Graf for (unsigned i = 0; envp[i]; ++i) 11744d362409d5469aed47d19e7908d19bd194493aThomas Graf EnvVars.push_back(envp[i]); 11844d362409d5469aed47d19e7908d19bd194493aThomas Graf GVArgs.push_back(PTOGV(CreateArgv(this, EnvVars))); // Arg #2 = envp. 11944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 12044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 12144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 122eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf return runFunction(Fn, GVArgs).IntVal; 12344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 12444d362409d5469aed47d19e7908d19bd194493aThomas Graf 12544d362409d5469aed47d19e7908d19bd194493aThomas Graf 12644d362409d5469aed47d19e7908d19bd194493aThomas Graf 12744d362409d5469aed47d19e7908d19bd194493aThomas Graf/// If possible, create a JIT, unless the caller specifically requests an 12844d362409d5469aed47d19e7908d19bd194493aThomas Graf/// Interpreter or there's an error. If even an Interpreter cannot be created, 129eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf/// NULL is returned. 13044d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 13144d362409d5469aed47d19e7908d19bd194493aThomas GrafExecutionEngine *ExecutionEngine::create(ModuleProvider *MP, 13244d362409d5469aed47d19e7908d19bd194493aThomas Graf bool ForceInterpreter, 13344d362409d5469aed47d19e7908d19bd194493aThomas Graf IntrinsicLowering *IL) { 13444d362409d5469aed47d19e7908d19bd194493aThomas Graf ExecutionEngine *EE = 0; 13544d362409d5469aed47d19e7908d19bd194493aThomas Graf 13644d362409d5469aed47d19e7908d19bd194493aThomas Graf // Unless the interpreter was explicitly selected, try making a JIT. 13744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!ForceInterpreter) 13844d362409d5469aed47d19e7908d19bd194493aThomas Graf EE = JIT::create(MP, IL); 13944d362409d5469aed47d19e7908d19bd194493aThomas Graf 1408a3efffa5b3fde252675239914118664d36a2c24Thomas Graf // If we can't make a JIT, make an interpreter instead. 14144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (EE == 0) { 14244d362409d5469aed47d19e7908d19bd194493aThomas Graf try { 14344d362409d5469aed47d19e7908d19bd194493aThomas Graf Module *M = MP->materializeModule(); 14444d362409d5469aed47d19e7908d19bd194493aThomas Graf try { 14544d362409d5469aed47d19e7908d19bd194493aThomas Graf EE = Interpreter::create(M, IL); 14644d362409d5469aed47d19e7908d19bd194493aThomas Graf } catch (...) { 14744d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cerr << "Error creating the interpreter!\n"; 1488a3efffa5b3fde252675239914118664d36a2c24Thomas Graf } 14944d362409d5469aed47d19e7908d19bd194493aThomas Graf } catch (std::string& errmsg) { 15044d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cerr << "Error reading the bytecode file: " << errmsg << "\n"; 15144d362409d5469aed47d19e7908d19bd194493aThomas Graf } catch (...) { 152eed2afaab7aa72fae393a395a8879b91a922ff5eThomas Graf std::cerr << "Error reading the bytecode file!\n"; 15344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 15544d362409d5469aed47d19e7908d19bd194493aThomas Graf 15644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (EE == 0) 15744d362409d5469aed47d19e7908d19bd194493aThomas Graf delete IL; 15844d362409d5469aed47d19e7908d19bd194493aThomas Graf else 15944d362409d5469aed47d19e7908d19bd194493aThomas Graf // Make sure we can resolve symbols in the program as well. The zero arg 16044d362409d5469aed47d19e7908d19bd194493aThomas Graf // to the function tells DynamicLibrary to load the program, not a library. 16144d362409d5469aed47d19e7908d19bd194493aThomas Graf sys::DynamicLibrary::LoadLibraryPermanently(0); 16244d362409d5469aed47d19e7908d19bd194493aThomas Graf 16344d362409d5469aed47d19e7908d19bd194493aThomas Graf return EE; 16444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 16544d362409d5469aed47d19e7908d19bd194493aThomas Graf 1668a3efffa5b3fde252675239914118664d36a2c24Thomas Graf/// getPointerToGlobal - This returns the address of the specified global 16744d362409d5469aed47d19e7908d19bd194493aThomas Graf/// value. This may involve code generation if it's a function. 16844d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 16944d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { 17044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (Function *F = const_cast<Function*>(dyn_cast<Function>(GV))) 17144d362409d5469aed47d19e7908d19bd194493aThomas Graf return getPointerToFunction(F); 17244d362409d5469aed47d19e7908d19bd194493aThomas Graf 17344d362409d5469aed47d19e7908d19bd194493aThomas Graf MutexGuard locked(lock); 17444d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(state.getGlobalAddressMap(locked)[GV] && "Global hasn't had an address allocated yet?"); 17544d362409d5469aed47d19e7908d19bd194493aThomas Graf return state.getGlobalAddressMap(locked)[GV]; 17644d362409d5469aed47d19e7908d19bd194493aThomas Graf} 17744d362409d5469aed47d19e7908d19bd194493aThomas Graf 17844d362409d5469aed47d19e7908d19bd194493aThomas Graf/// FIXME: document 17944d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 18044d362409d5469aed47d19e7908d19bd194493aThomas GrafGenericValue ExecutionEngine::getConstantValue(const Constant *C) { 18144d362409d5469aed47d19e7908d19bd194493aThomas Graf GenericValue Result; 18244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (isa<UndefValue>(C)) return Result; 18344d362409d5469aed47d19e7908d19bd194493aThomas Graf 18444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (ConstantExpr *CE = const_cast<ConstantExpr*>(dyn_cast<ConstantExpr>(C))) { 18544d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (CE->getOpcode()) { 18644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Instruction::GetElementPtr: { 18744d362409d5469aed47d19e7908d19bd194493aThomas Graf Result = getConstantValue(CE->getOperand(0)); 18844d362409d5469aed47d19e7908d19bd194493aThomas Graf std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end()); 18944d362409d5469aed47d19e7908d19bd194493aThomas Graf uint64_t Offset = 19044d362409d5469aed47d19e7908d19bd194493aThomas Graf TD->getIndexedOffset(CE->getOperand(0)->getType(), Indexes); 19144d362409d5469aed47d19e7908d19bd194493aThomas Graf 19244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (getTargetData().getPointerSize() == 4) 19344d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.IntVal += Offset; 19444d362409d5469aed47d19e7908d19bd194493aThomas Graf else 1958a3efffa5b3fde252675239914118664d36a2c24Thomas Graf Result.LongVal += Offset; 19644d362409d5469aed47d19e7908d19bd194493aThomas Graf return Result; 19744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 19844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Instruction::Cast: { 1998a3efffa5b3fde252675239914118664d36a2c24Thomas Graf // We only need to handle a few cases here. Almost all casts will 20044d362409d5469aed47d19e7908d19bd194493aThomas Graf // automatically fold, just the ones involving pointers won't. 20144d362409d5469aed47d19e7908d19bd194493aThomas Graf // 20244d362409d5469aed47d19e7908d19bd194493aThomas Graf Constant *Op = CE->getOperand(0); 2038a3efffa5b3fde252675239914118664d36a2c24Thomas Graf GenericValue GV = getConstantValue(Op); 20444d362409d5469aed47d19e7908d19bd194493aThomas Graf 20544d362409d5469aed47d19e7908d19bd194493aThomas Graf // Handle cast of pointer to pointer... 20644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (Op->getType()->getTypeID() == C->getType()->getTypeID()) 2078a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return GV; 20844d362409d5469aed47d19e7908d19bd194493aThomas Graf 20944d362409d5469aed47d19e7908d19bd194493aThomas Graf // Handle a cast of pointer to any integral type... 21044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (isa<PointerType>(Op->getType()) && C->getType()->isIntegral()) 2118a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return GV; 21244d362409d5469aed47d19e7908d19bd194493aThomas Graf 21344d362409d5469aed47d19e7908d19bd194493aThomas Graf // Handle cast of integer to a pointer... 21444d362409d5469aed47d19e7908d19bd194493aThomas Graf if (isa<PointerType>(C->getType()) && Op->getType()->isIntegral()) 21544d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (Op->getType()->getTypeID()) { 21644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::BoolTyID: return PTOGV((void*)(uintptr_t)GV.BoolVal); 21744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::SByteTyID: return PTOGV((void*)( intptr_t)GV.SByteVal); 21844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UByteTyID: return PTOGV((void*)(uintptr_t)GV.UByteVal); 21944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ShortTyID: return PTOGV((void*)( intptr_t)GV.ShortVal); 22044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UShortTyID: return PTOGV((void*)(uintptr_t)GV.UShortVal); 22144d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::IntTyID: return PTOGV((void*)( intptr_t)GV.IntVal); 22244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UIntTyID: return PTOGV((void*)(uintptr_t)GV.UIntVal); 22344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::LongTyID: return PTOGV((void*)( intptr_t)GV.LongVal); 22444d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ULongTyID: return PTOGV((void*)(uintptr_t)GV.ULongVal); 22544d362409d5469aed47d19e7908d19bd194493aThomas Graf default: assert(0 && "Unknown integral type!"); 22644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 22744d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 22844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 22944d362409d5469aed47d19e7908d19bd194493aThomas Graf 23044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Instruction::Add: 23144d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (CE->getOperand(0)->getType()->getTypeID()) { 23244d362409d5469aed47d19e7908d19bd194493aThomas Graf default: assert(0 && "Bad add type!"); abort(); 23344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::LongTyID: 23444d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ULongTyID: 23544d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.LongVal = getConstantValue(CE->getOperand(0)).LongVal + 23644d362409d5469aed47d19e7908d19bd194493aThomas Graf getConstantValue(CE->getOperand(1)).LongVal; 23744d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 23844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::IntTyID: 23944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UIntTyID: 24044d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.IntVal = getConstantValue(CE->getOperand(0)).IntVal + 24144d362409d5469aed47d19e7908d19bd194493aThomas Graf getConstantValue(CE->getOperand(1)).IntVal; 24244d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 24344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ShortTyID: 24444d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UShortTyID: 24544d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.ShortVal = getConstantValue(CE->getOperand(0)).ShortVal + 24644d362409d5469aed47d19e7908d19bd194493aThomas Graf getConstantValue(CE->getOperand(1)).ShortVal; 24744d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 24844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::SByteTyID: 24944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UByteTyID: 25044d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.SByteVal = getConstantValue(CE->getOperand(0)).SByteVal + 25144d362409d5469aed47d19e7908d19bd194493aThomas Graf getConstantValue(CE->getOperand(1)).SByteVal; 25244d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 25344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::FloatTyID: 25444d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.FloatVal = getConstantValue(CE->getOperand(0)).FloatVal + 25544d362409d5469aed47d19e7908d19bd194493aThomas Graf getConstantValue(CE->getOperand(1)).FloatVal; 25644d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 25744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::DoubleTyID: 25844d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.DoubleVal = getConstantValue(CE->getOperand(0)).DoubleVal + 25944d362409d5469aed47d19e7908d19bd194493aThomas Graf getConstantValue(CE->getOperand(1)).DoubleVal; 26044d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 26144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26244d362409d5469aed47d19e7908d19bd194493aThomas Graf return Result; 26344d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 26444d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 26544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26644d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cerr << "ConstantExpr not handled as global var init: " << *CE << "\n"; 26744d362409d5469aed47d19e7908d19bd194493aThomas Graf abort(); 26844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 26944d362409d5469aed47d19e7908d19bd194493aThomas Graf 27044d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (C->getType()->getTypeID()) { 27144d362409d5469aed47d19e7908d19bd194493aThomas Graf#define GET_CONST_VAL(TY, CTY, CLASS) \ 27244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::TY##TyID: Result.TY##Val = (CTY)cast<CLASS>(C)->getValue(); break 27344d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(Bool , bool , ConstantBool); 27444d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(UByte , unsigned char , ConstantUInt); 27544d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(SByte , signed char , ConstantSInt); 27644d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(UShort , unsigned short, ConstantUInt); 27744d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(Short , signed short , ConstantSInt); 27844d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(UInt , unsigned int , ConstantUInt); 27944d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(Int , signed int , ConstantSInt); 28044d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(ULong , uint64_t , ConstantUInt); 28144d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(Long , int64_t , ConstantSInt); 28244d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(Float , float , ConstantFP); 28344d362409d5469aed47d19e7908d19bd194493aThomas Graf GET_CONST_VAL(Double , double , ConstantFP); 28444d362409d5469aed47d19e7908d19bd194493aThomas Graf#undef GET_CONST_VAL 28544d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::PointerTyID: 28644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (isa<ConstantPointerNull>(C)) 28744d362409d5469aed47d19e7908d19bd194493aThomas Graf Result.PointerVal = 0; 28844d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (const Function *F = dyn_cast<Function>(C)) 28944d362409d5469aed47d19e7908d19bd194493aThomas Graf Result = PTOGV(getPointerToFunctionOrStub(const_cast<Function*>(F))); 29044d362409d5469aed47d19e7908d19bd194493aThomas Graf else if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C)) 29144d362409d5469aed47d19e7908d19bd194493aThomas Graf Result = PTOGV(getOrEmitGlobalVariable(const_cast<GlobalVariable*>(GV))); 29244d362409d5469aed47d19e7908d19bd194493aThomas Graf else 29344d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0 && "Unknown constant pointer type!"); 29444d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 29544d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 29644d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cout << "ERROR: Constant unimp for type: " << *C->getType() << "\n"; 29744d362409d5469aed47d19e7908d19bd194493aThomas Graf abort(); 29844d362409d5469aed47d19e7908d19bd194493aThomas Graf } 29944d362409d5469aed47d19e7908d19bd194493aThomas Graf return Result; 30044d362409d5469aed47d19e7908d19bd194493aThomas Graf} 30144d362409d5469aed47d19e7908d19bd194493aThomas Graf 30244d362409d5469aed47d19e7908d19bd194493aThomas Graf/// FIXME: document 30344d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 30444d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr, 30544d362409d5469aed47d19e7908d19bd194493aThomas Graf const Type *Ty) { 30644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (getTargetData().isLittleEndian()) { 30744d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (Ty->getTypeID()) { 30844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::BoolTyID: 30944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UByteTyID: 31044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break; 31144d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UShortTyID: 31244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ShortTyID: Ptr->Untyped[0] = Val.UShortVal & 255; 31344d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[1] = (Val.UShortVal >> 8) & 255; 31444d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 31544d362409d5469aed47d19e7908d19bd194493aThomas Graf Store4BytesLittleEndian: 31644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::FloatTyID: 31744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UIntTyID: 31844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::IntTyID: Ptr->Untyped[0] = Val.UIntVal & 255; 31944d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[1] = (Val.UIntVal >> 8) & 255; 32044d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[2] = (Val.UIntVal >> 16) & 255; 32144d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[3] = (Val.UIntVal >> 24) & 255; 32244d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 32344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 32444d362409d5469aed47d19e7908d19bd194493aThomas Graf goto Store4BytesLittleEndian; 32544d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::DoubleTyID: 32644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ULongTyID: 32744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::LongTyID: 32844d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[0] = (unsigned char)(Val.ULongVal ); 32944d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[1] = (unsigned char)(Val.ULongVal >> 8); 33044d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[2] = (unsigned char)(Val.ULongVal >> 16); 33144d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[3] = (unsigned char)(Val.ULongVal >> 24); 33244d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[4] = (unsigned char)(Val.ULongVal >> 32); 33344d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[5] = (unsigned char)(Val.ULongVal >> 40); 33444d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[6] = (unsigned char)(Val.ULongVal >> 48); 33544d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[7] = (unsigned char)(Val.ULongVal >> 56); 33644d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 33744d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 33844d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cout << "Cannot store value of type " << *Ty << "!\n"; 33944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 34044d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 34144d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (Ty->getTypeID()) { 34244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::BoolTyID: 34344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UByteTyID: 34444d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break; 34544d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UShortTyID: 34644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ShortTyID: Ptr->Untyped[1] = Val.UShortVal & 255; 34744d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[0] = (Val.UShortVal >> 8) & 255; 34844d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 34944d362409d5469aed47d19e7908d19bd194493aThomas Graf Store4BytesBigEndian: 35044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::FloatTyID: 35144d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UIntTyID: 35244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::IntTyID: Ptr->Untyped[3] = Val.UIntVal & 255; 35344d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[2] = (Val.UIntVal >> 8) & 255; 35444d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[1] = (Val.UIntVal >> 16) & 255; 35544d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[0] = (Val.UIntVal >> 24) & 255; 35644d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 35744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 35844d362409d5469aed47d19e7908d19bd194493aThomas Graf goto Store4BytesBigEndian; 35944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::DoubleTyID: 36044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ULongTyID: 36144d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::LongTyID: 36244d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[7] = (unsigned char)(Val.ULongVal ); 36344d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[6] = (unsigned char)(Val.ULongVal >> 8); 36444d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[5] = (unsigned char)(Val.ULongVal >> 16); 36544d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[4] = (unsigned char)(Val.ULongVal >> 24); 36644d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[3] = (unsigned char)(Val.ULongVal >> 32); 36744d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[2] = (unsigned char)(Val.ULongVal >> 40); 36844d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[1] = (unsigned char)(Val.ULongVal >> 48); 36944d362409d5469aed47d19e7908d19bd194493aThomas Graf Ptr->Untyped[0] = (unsigned char)(Val.ULongVal >> 56); 37044d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 37144d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 37244d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cout << "Cannot store value of type " << *Ty << "!\n"; 37344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 37444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 37544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 37644d362409d5469aed47d19e7908d19bd194493aThomas Graf 37744d362409d5469aed47d19e7908d19bd194493aThomas Graf/// FIXME: document 37844d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 37944d362409d5469aed47d19e7908d19bd194493aThomas GrafGenericValue ExecutionEngine::LoadValueFromMemory(GenericValue *Ptr, 38044d362409d5469aed47d19e7908d19bd194493aThomas Graf const Type *Ty) { 38144d362409d5469aed47d19e7908d19bd194493aThomas Graf GenericValue Result; 38244d362409d5469aed47d19e7908d19bd194493aThomas Graf if (getTargetData().isLittleEndian()) { 38344d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (Ty->getTypeID()) { 38444d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::BoolTyID: 38544d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UByteTyID: 38644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; 38744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UShortTyID: 38844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[0] | 38944d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[1] << 8); 39044d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 39144d362409d5469aed47d19e7908d19bd194493aThomas Graf Load4BytesLittleEndian: 39244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::FloatTyID: 39344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UIntTyID: 39444d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[0] | 39544d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[1] << 8) | 39644d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[2] << 16) | 39744d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[3] << 24); 39844d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 39944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 40044d362409d5469aed47d19e7908d19bd194493aThomas Graf goto Load4BytesLittleEndian; 40144d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::DoubleTyID: 40244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ULongTyID: 40344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[0] | 40444d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[1] << 8) | 40544d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[2] << 16) | 40644d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[3] << 24) | 40744d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[4] << 32) | 40844d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[5] << 40) | 40944d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[6] << 48) | 41044d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[7] << 56); 41144d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 41244d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 41344d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cout << "Cannot load value of type " << *Ty << "!\n"; 41444d362409d5469aed47d19e7908d19bd194493aThomas Graf abort(); 41544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 41644d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 41744d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (Ty->getTypeID()) { 41844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::BoolTyID: 4198a3efffa5b3fde252675239914118664d36a2c24Thomas Graf case Type::UByteTyID: 42044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; 42144d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UShortTyID: 42244d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[1] | 42344d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[0] << 8); 42444d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 42544d362409d5469aed47d19e7908d19bd194493aThomas Graf Load4BytesBigEndian: 42644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::FloatTyID: 42744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::UIntTyID: 42844d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[3] | 42944d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[2] << 8) | 43044d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[1] << 16) | 43144d362409d5469aed47d19e7908d19bd194493aThomas Graf ((unsigned)Ptr->Untyped[0] << 24); 43244d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 43344d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 43444d362409d5469aed47d19e7908d19bd194493aThomas Graf goto Load4BytesBigEndian; 43544d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::DoubleTyID: 43644d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ULongTyID: 43744d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[7] | 43844d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[6] << 8) | 43944d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[5] << 16) | 44044d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[4] << 24) | 4418a3efffa5b3fde252675239914118664d36a2c24Thomas Graf ((uint64_t)Ptr->Untyped[3] << 32) | 44244d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[2] << 40) | 44344d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[1] << 48) | 44444d362409d5469aed47d19e7908d19bd194493aThomas Graf ((uint64_t)Ptr->Untyped[0] << 56); 4458a3efffa5b3fde252675239914118664d36a2c24Thomas Graf break; 44644d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 44744d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cout << "Cannot load value of type " << *Ty << "!\n"; 44844d362409d5469aed47d19e7908d19bd194493aThomas Graf abort(); 44944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 45044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 45144d362409d5469aed47d19e7908d19bd194493aThomas Graf return Result; 45244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 45344d362409d5469aed47d19e7908d19bd194493aThomas Graf 45444d362409d5469aed47d19e7908d19bd194493aThomas Graf// InitializeMemory - Recursive function to apply a Constant value into the 45544d362409d5469aed47d19e7908d19bd194493aThomas Graf// specified memory location... 45644d362409d5469aed47d19e7908d19bd194493aThomas Graf// 45744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) { 45844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (isa<UndefValue>(Init)) { 45944d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 46044d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (Init->getType()->isFirstClassType()) { 46144d362409d5469aed47d19e7908d19bd194493aThomas Graf GenericValue Val = getConstantValue(Init); 46244d362409d5469aed47d19e7908d19bd194493aThomas Graf StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType()); 46344d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 46444d362409d5469aed47d19e7908d19bd194493aThomas Graf } else if (isa<ConstantAggregateZero>(Init)) { 46544d362409d5469aed47d19e7908d19bd194493aThomas Graf memset(Addr, 0, (size_t)getTargetData().getTypeSize(Init->getType())); 46644d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 46744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 46844d362409d5469aed47d19e7908d19bd194493aThomas Graf 46944d362409d5469aed47d19e7908d19bd194493aThomas Graf switch (Init->getType()->getTypeID()) { 47044d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::ArrayTyID: { 47144d362409d5469aed47d19e7908d19bd194493aThomas Graf const ConstantArray *CPA = cast<ConstantArray>(Init); 47244d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned ElementSize = 47344d362409d5469aed47d19e7908d19bd194493aThomas Graf getTargetData().getTypeSize(CPA->getType()->getElementType()); 47444d362409d5469aed47d19e7908d19bd194493aThomas Graf for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) 47544d362409d5469aed47d19e7908d19bd194493aThomas Graf InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); 4768a3efffa5b3fde252675239914118664d36a2c24Thomas Graf return; 47744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 47844d362409d5469aed47d19e7908d19bd194493aThomas Graf 47944d362409d5469aed47d19e7908d19bd194493aThomas Graf case Type::StructTyID: { 4808a3efffa5b3fde252675239914118664d36a2c24Thomas Graf const ConstantStruct *CPS = cast<ConstantStruct>(Init); 48144d362409d5469aed47d19e7908d19bd194493aThomas Graf const StructLayout *SL = 48244d362409d5469aed47d19e7908d19bd194493aThomas Graf getTargetData().getStructLayout(cast<StructType>(CPS->getType())); 48344d362409d5469aed47d19e7908d19bd194493aThomas Graf for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) 48444d362409d5469aed47d19e7908d19bd194493aThomas Graf InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->MemberOffsets[i]); 48544d362409d5469aed47d19e7908d19bd194493aThomas Graf return; 48644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 48744d362409d5469aed47d19e7908d19bd194493aThomas Graf 48844d362409d5469aed47d19e7908d19bd194493aThomas Graf default: 48944d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cerr << "Bad Type: " << *Init->getType() << "\n"; 49044d362409d5469aed47d19e7908d19bd194493aThomas Graf assert(0 && "Unknown constant type to initialize memory with!"); 49144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 49244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 49344d362409d5469aed47d19e7908d19bd194493aThomas Graf 49444d362409d5469aed47d19e7908d19bd194493aThomas Graf/// EmitGlobals - Emit all of the global variables to memory, storing their 49544d362409d5469aed47d19e7908d19bd194493aThomas Graf/// addresses into GlobalAddress. This must make sure to copy the contents of 49644d362409d5469aed47d19e7908d19bd194493aThomas Graf/// their initializers into the memory. 49744d362409d5469aed47d19e7908d19bd194493aThomas Graf/// 49844d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid ExecutionEngine::emitGlobals() { 49944d362409d5469aed47d19e7908d19bd194493aThomas Graf const TargetData &TD = getTargetData(); 50044d362409d5469aed47d19e7908d19bd194493aThomas Graf 50144d362409d5469aed47d19e7908d19bd194493aThomas Graf // Loop over all of the global variables in the program, allocating the memory 50244d362409d5469aed47d19e7908d19bd194493aThomas Graf // to hold them. 50344d362409d5469aed47d19e7908d19bd194493aThomas Graf Module &M = getModule(); 50444d362409d5469aed47d19e7908d19bd194493aThomas Graf for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 50544d362409d5469aed47d19e7908d19bd194493aThomas Graf I != E; ++I) 50644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!I->isExternal()) { 50744d362409d5469aed47d19e7908d19bd194493aThomas Graf // Get the type of the global... 50844d362409d5469aed47d19e7908d19bd194493aThomas Graf const Type *Ty = I->getType()->getElementType(); 50944d362409d5469aed47d19e7908d19bd194493aThomas Graf 51044d362409d5469aed47d19e7908d19bd194493aThomas Graf // Allocate some memory for it! 51144d362409d5469aed47d19e7908d19bd194493aThomas Graf unsigned Size = TD.getTypeSize(Ty); 51244d362409d5469aed47d19e7908d19bd194493aThomas Graf addGlobalMapping(I, new char[Size]); 51344d362409d5469aed47d19e7908d19bd194493aThomas Graf } else { 51444d362409d5469aed47d19e7908d19bd194493aThomas Graf // External variable reference. Try to use the dynamic loader to 51544d362409d5469aed47d19e7908d19bd194493aThomas Graf // get a pointer to it. 51644d362409d5469aed47d19e7908d19bd194493aThomas Graf if (void *SymAddr = sys::DynamicLibrary::SearchForAddressOfSymbol( 51744d362409d5469aed47d19e7908d19bd194493aThomas Graf I->getName().c_str())) 51844d362409d5469aed47d19e7908d19bd194493aThomas Graf addGlobalMapping(I, SymAddr); 51944d362409d5469aed47d19e7908d19bd194493aThomas Graf else { 52044d362409d5469aed47d19e7908d19bd194493aThomas Graf std::cerr << "Could not resolve external global address: " 52144d362409d5469aed47d19e7908d19bd194493aThomas Graf << I->getName() << "\n"; 52244d362409d5469aed47d19e7908d19bd194493aThomas Graf abort(); 5238a3efffa5b3fde252675239914118664d36a2c24Thomas Graf } 52444d362409d5469aed47d19e7908d19bd194493aThomas Graf } 52544d362409d5469aed47d19e7908d19bd194493aThomas Graf 52644d362409d5469aed47d19e7908d19bd194493aThomas Graf // Now that all of the globals are set up in memory, loop through them all and 52744d362409d5469aed47d19e7908d19bd194493aThomas Graf // initialize their contents. 52844d362409d5469aed47d19e7908d19bd194493aThomas Graf for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 52944d362409d5469aed47d19e7908d19bd194493aThomas Graf I != E; ++I) 53044d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!I->isExternal()) 53144d362409d5469aed47d19e7908d19bd194493aThomas Graf EmitGlobalVariable(I); 53244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 53344d362409d5469aed47d19e7908d19bd194493aThomas Graf 53444d362409d5469aed47d19e7908d19bd194493aThomas Graf// EmitGlobalVariable - This method emits the specified global variable to the 53544d362409d5469aed47d19e7908d19bd194493aThomas Graf// address specified in GlobalAddresses, or allocates new memory if it's not 53644d362409d5469aed47d19e7908d19bd194493aThomas Graf// already in the map. 53744d362409d5469aed47d19e7908d19bd194493aThomas Grafvoid ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) { 53844d362409d5469aed47d19e7908d19bd194493aThomas Graf void *GA = getPointerToGlobalIfAvailable(GV); 53944d362409d5469aed47d19e7908d19bd194493aThomas Graf DEBUG(std::cerr << "Global '" << GV->getName() << "' -> " << GA << "\n"); 54044d362409d5469aed47d19e7908d19bd194493aThomas Graf 54144d362409d5469aed47d19e7908d19bd194493aThomas Graf const Type *ElTy = GV->getType()->getElementType(); 54244d362409d5469aed47d19e7908d19bd194493aThomas Graf size_t GVSize = (size_t)getTargetData().getTypeSize(ElTy); 54344d362409d5469aed47d19e7908d19bd194493aThomas Graf if (GA == 0) { 54444d362409d5469aed47d19e7908d19bd194493aThomas Graf // If it's not already specified, allocate memory for the global. 54544d362409d5469aed47d19e7908d19bd194493aThomas Graf GA = new char[GVSize]; 54644d362409d5469aed47d19e7908d19bd194493aThomas Graf addGlobalMapping(GV, GA); 54744d362409d5469aed47d19e7908d19bd194493aThomas Graf } 54844d362409d5469aed47d19e7908d19bd194493aThomas Graf 54944d362409d5469aed47d19e7908d19bd194493aThomas Graf InitializeMemory(GV->getInitializer(), GA); 55044d362409d5469aed47d19e7908d19bd194493aThomas Graf NumInitBytes += (unsigned)GVSize; 55144d362409d5469aed47d19e7908d19bd194493aThomas Graf ++NumGlobals; 55244d362409d5469aed47d19e7908d19bd194493aThomas Graf} 55344d362409d5469aed47d19e7908d19bd194493aThomas Graf