ExecutionEngine.cpp revision 68835dd5119150383938c701fc223077d2bc1e25
18dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===-- ExecutionEngine.cpp - Common Implementation shared by EEs ---------===// 28dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 38dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// The LLVM Compiler Infrastructure 48dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 58dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// This file was developed by the LLVM research group and is distributed under 68dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// the University of Illinois Open Source License. See LICENSE.TXT for details. 78dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 88dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===----------------------------------------------------------------------===// 98dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 108dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// This file defines the common interface used by the various execution engine 118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// subclasses. 128dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 13aba43bb13b3aa3e81990989375fba3a902bfe1c2Douglas Gregor//===----------------------------------------------------------------------===// 148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 158dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#define DEBUG_TYPE "jit" 168dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "Interpreter/Interpreter.h" 178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "JIT/JIT.h" 188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/Constants.h" 198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/DerivedTypes.h" 208dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/Module.h" 218dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/ModuleProvider.h" 228dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/ADT/Statistic.h" 238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/CodeGen/IntrinsicLowering.h" 24b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner#include "llvm/ExecutionEngine/ExecutionEngine.h" 258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/ExecutionEngine/GenericValue.h" 268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/Support/Debug.h" 277e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor#include "llvm/System/DynamicLibrary.h" 288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/Target/TargetData.h" 298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregorusing namespace llvm; 308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregornamespace { 328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized"); 337e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor Statistic<> NumGlobals ("lli", "Number of global vars initialized"); 347e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor} 358dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 36390b4cc8b45a05612349269ef08faab3e4688f06Mike StumpExecutionEngine::ExecutionEngine(ModuleProvider *P) : 37390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump CurMod(*P->getModule()), MP(P) { 38390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump assert(P && "ModuleProvider is null?"); 394f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor} 404f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor 418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorExecutionEngine::ExecutionEngine(Module *M) : CurMod(*M), MP(0) { 423d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor assert(M && "Module is null?"); 438dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor} 448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorExecutionEngine::~ExecutionEngine() { 466477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor delete MP; 47e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor} 48d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor 492dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor/// getGlobalValueAtAddress - Return the LLVM global value object that starts 50615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor/// at the specified address. 5103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor/// 52bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregorconst GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) { 536477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor MutexGuard locked(lock); 542dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor 555545e166a956a20d7a6b58408e251a1119025485Douglas Gregor // If we haven't computed the reverse mapping yet, do so first. 568dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (state.getGlobalAddressReverseMap(locked).empty()) { 578dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor for (std::map<const GlobalValue*, void *>::iterator I = 583d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor state.getGlobalAddressMap(locked).begin(), E = state.getGlobalAddressMap(locked).end(); I != E; ++I) 598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor state.getGlobalAddressReverseMap(locked).insert(std::make_pair(I->second, I->first)); 608dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 615545e166a956a20d7a6b58408e251a1119025485Douglas Gregor 625545e166a956a20d7a6b58408e251a1119025485Douglas Gregor std::map<void *, const GlobalValue*>::iterator I = 635545e166a956a20d7a6b58408e251a1119025485Douglas Gregor state.getGlobalAddressReverseMap(locked).find(Addr); 645545e166a956a20d7a6b58408e251a1119025485Douglas Gregor return I != state.getGlobalAddressReverseMap(locked).end() ? I->second : 0; 65e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor} 665545e166a956a20d7a6b58408e251a1119025485Douglas Gregor 678dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// CreateArgv - Turn a vector of strings into a nice argv style array of 688dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// pointers to null terminated strings. 698dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// 704f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregorstatic void *CreateArgv(ExecutionEngine *EE, 714f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor const std::vector<std::string> &InputArgv) { 724f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor unsigned PtrSize = EE->getTargetData().getPointerSize(); 734f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor char *Result = new char[(InputArgv.size()+1)*PtrSize]; 744f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor 754f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n"); 764f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor const Type *SBytePtr = PointerType::get(Type::SByteTy); 774f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor 784f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor for (unsigned i = 0; i != InputArgv.size(); ++i) { 794f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor unsigned Size = InputArgv[i].size()+1; 804f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor char *Dest = new char[Size]; 814f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n"); 828dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 838dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor std::copy(InputArgv[i].begin(), InputArgv[i].end(), Dest); 848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Dest[Size-1] = 0; 858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 861eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor // Endian safe: Result[i] = (PointerTy)Dest; 871eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor EE->StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i*PtrSize), 888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor SBytePtr); 898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 918dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Null terminate it 928dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor EE->StoreValueToMemory(PTOGV(0), 938dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor (GenericValue*)(Result+InputArgv.size()*PtrSize), 948dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor SBytePtr); 958dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return Result; 968dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor} 978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 988dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// runFunctionAsMain - This is a helper function which wraps runFunction to 998dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// handle the common task of starting up main with the specified argc, argv, 1008dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// and envp parameters. 1016ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregorint ExecutionEngine::runFunctionAsMain(Function *Fn, 102bc221637f5ed3538b8495dd13b831c11e821c712Douglas Gregor const std::vector<std::string> &argv, 1038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor const char * const * envp) { 1048dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor std::vector<GenericValue> GVArgs; 1058dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor GenericValue GVArgc; 1063d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor GVArgc.IntVal = argv.size(); 1073d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor unsigned NumArgs = Fn->getFunctionType()->getNumParams(); 1083d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor if (NumArgs) { 1093d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor GVArgs.push_back(GVArgc); // Arg #0 = argc. 1103d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor if (NumArgs > 1) { 1113d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor GVArgs.push_back(PTOGV(CreateArgv(this, argv))); // Arg #1 = argv. 1123d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor assert(((char **)GVTOP(GVArgs[1]))[0] && 1133d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor "argv[0] was null after CreateArgv"); 114b9f1b8d877541e76390cd3807c2dcff2f950360aDouglas Gregor if (NumArgs > 2) { 1153d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor std::vector<std::string> EnvVars; 1163d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor for (unsigned i = 0; envp[i]; ++i) 1173d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor EnvVars.push_back(envp[i]); 1183d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor GVArgs.push_back(PTOGV(CreateArgv(this, EnvVars))); // Arg #2 = envp. 1193d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor } 1203d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor } 1213d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor } 1223d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor return runFunction(Fn, GVArgs).IntVal; 123390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump} 124390b4cc8b45a05612349269ef08faab3e4688f06Mike Stump 1253d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor 126eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner 1276ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor/// If possible, create a JIT, unless the caller specifically requests an 1283d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor/// Interpreter or there's an error. If even an Interpreter cannot be created, 1293d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor/// NULL is returned. 1303d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor/// 1317e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas GregorExecutionEngine *ExecutionEngine::create(ModuleProvider *MP, 1323d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor bool ForceInterpreter, 1333d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor IntrinsicLowering *IL) { 1343d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor ExecutionEngine *EE = 0; 135b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner 1363d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor // Unless the interpreter was explicitly selected, try making a JIT. 137d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor if (!ForceInterpreter) 138d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor EE = JIT::create(MP, IL); 1393d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor 1403d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor // If we can't make a JIT, make an interpreter instead. 1413d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor if (EE == 0) { 1423d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor try { 1433d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor Module *M = MP->materializeModule(); 1448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor try { 1458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor EE = Interpreter::create(M, IL); 1468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } catch (...) { 1478dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor std::cerr << "Error creating the interpreter!\n"; 1481eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor } 1491eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor } catch (std::string& errmsg) { 1508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor std::cerr << "Error reading the bytecode file: " << errmsg << "\n"; 1518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } catch (...) { 1528dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor std::cerr << "Error reading the bytecode file!\n"; 1538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 1548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 1558dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 1568dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (EE == 0) 1578dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor delete IL; 1588dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor else 1598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Make sure we can resolve symbols in the program as well. The zero arg 1608dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // to the function tells DynamicLibrary to load the program, not a library. 1618dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor sys::DynamicLibrary::LoadLibraryPermanently(0); 1628dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 1638dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return EE; 1648dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor} 1658dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 1668dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// getPointerToGlobal - This returns the address of the specified global 1678dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// value. This may involve code generation if it's a function. 168ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor/// 169ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregorvoid *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) { 170ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor if (Function *F = const_cast<Function*>(dyn_cast<Function>(GV))) 1718dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return getPointerToFunction(F); 1727e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor 1738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor MutexGuard locked(lock); 1748dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor void *p = state.getGlobalAddressMap(locked)[GV]; 1758dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (p) 1768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return p; 177e9146f2e9f1c4e281544e8c080934c72d41012caAnders Carlsson 1788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Global variable might have been added since interpreter started. 1798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (GlobalVariable *GVar = 1808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor const_cast<GlobalVariable *>(dyn_cast<GlobalVariable>(GV))) 1818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor EmitGlobalVariable(GVar); 1828dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor else 1838dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor assert("Global hasn't had an address allocated yet!"); 1848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return state.getGlobalAddressMap(locked)[GV]; 1858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor} 1868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 1878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// FIXME: document 1888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor/// 1898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorGenericValue ExecutionEngine::getConstantValue(const Constant *C) { 1908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor GenericValue Result; 1916ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor if (isa<UndefValue>(C)) return Result; 1928dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 1938dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (ConstantExpr *CE = const_cast<ConstantExpr*>(dyn_cast<ConstantExpr>(C))) { 1948dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor switch (CE->getOpcode()) { 1958dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Instruction::GetElementPtr: { 1968dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Result = getConstantValue(CE->getOperand(0)); 1978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end()); 1988dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor uint64_t Offset = 1998dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor TD->getIndexedOffset(CE->getOperand(0)->getType(), Indexes); 200ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor 201ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor if (getTargetData().getPointerSize() == 4) 202ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor Result.IntVal += Offset; 2038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor else 2047e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor Result.LongVal += Offset; 2058dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return Result; 2068dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 2078dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Instruction::Cast: { 2088dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // We only need to handle a few cases here. Almost all casts will 2098dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // automatically fold, just the ones involving pointers won't. 210b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner // 211b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner Constant *Op = CE->getOperand(0); 212b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner GenericValue GV = getConstantValue(Op); 2138dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 2148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Handle cast of pointer to pointer... 2158dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (Op->getType()->getTypeID() == C->getType()->getTypeID()) 2168dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return GV; 2178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 2188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Handle a cast of pointer to any integral type... 2198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (isa<PointerType>(Op->getType()) && C->getType()->isIntegral()) 2208dbc3c64965f99e48830885835b7d2fc26ec3cf5Douglas Gregor return GV; 22106c0fecd197fef21e265a41bca8dc5022de1f864Douglas Gregor 2226ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor // Handle cast of integer to a pointer... 2238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor if (isa<PointerType>(C->getType()) && Op->getType()->isIntegral()) 2248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor switch (Op->getType()->getTypeID()) { 2250ca20ac8cea99c43d89510f29cf3dc876f9c9111Douglas Gregor case Type::BoolTyID: return PTOGV((void*)(uintptr_t)GV.BoolVal); 2268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::SByteTyID: return PTOGV((void*)( intptr_t)GV.SByteVal); 2278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::UByteTyID: return PTOGV((void*)(uintptr_t)GV.UByteVal); 2286ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor case Type::ShortTyID: return PTOGV((void*)( intptr_t)GV.ShortVal); 2296ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor case Type::UShortTyID: return PTOGV((void*)(uintptr_t)GV.UShortVal); 2308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::IntTyID: return PTOGV((void*)( intptr_t)GV.IntVal); 2318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::UIntTyID: return PTOGV((void*)(uintptr_t)GV.UIntVal); 2328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::LongTyID: return PTOGV((void*)( intptr_t)GV.LongVal); 233ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor case Type::ULongTyID: return PTOGV((void*)(uintptr_t)GV.ULongVal); 234ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor default: assert(0 && "Unknown integral type!"); 235ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor } 236ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor break; 237ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor } 2387e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor 239ac7610dad6653bad02dd42de198ca358b6fb1f1dDouglas Gregor case Instruction::Add: 2408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor switch (CE->getOperand(0)->getType()->getTypeID()) { 2418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor default: assert(0 && "Bad add type!"); abort(); 2428dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::LongTyID: 2438dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::ULongTyID: 2448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Result.LongVal = getConstantValue(CE->getOperand(0)).LongVal + 2458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor getConstantValue(CE->getOperand(1)).LongVal; 2468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor break; 2478dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::IntTyID: 2488dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::UIntTyID: 2498dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Result.IntVal = getConstantValue(CE->getOperand(0)).IntVal + 2508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor getConstantValue(CE->getOperand(1)).IntVal; 2518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor break; 2528dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::ShortTyID: 2538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::UShortTyID: 2548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Result.ShortVal = getConstantValue(CE->getOperand(0)).ShortVal + 2558dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor getConstantValue(CE->getOperand(1)).ShortVal; 2568dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor break; 2578dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::SByteTyID: 2588dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::UByteTyID: 2598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Result.SByteVal = getConstantValue(CE->getOperand(0)).SByteVal + 2606ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor getConstantValue(CE->getOperand(1)).SByteVal; 261b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner break; 2628dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor case Type::FloatTyID: 2638dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor Result.FloatVal = getConstantValue(CE->getOperand(0)).FloatVal + 2648dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor getConstantValue(CE->getOperand(1)).FloatVal; 2658dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor break; 266c6e35aae23bc3cea7daf5ee075fa695c01c0f66fMike Stump case Type::DoubleTyID: 267c6e35aae23bc3cea7daf5ee075fa695c01c0f66fMike Stump Result.DoubleVal = getConstantValue(CE->getOperand(0)).DoubleVal + 268c6e35aae23bc3cea7daf5ee075fa695c01c0f66fMike Stump getConstantValue(CE->getOperand(1)).DoubleVal; 2698dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor break; 2708dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor } 2718dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor return Result; 2728dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor default: 2738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor break; 2746477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor } 2756477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor std::cerr << "ConstantExpr not handled as global var init: " << *CE << "\n"; 2766477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor abort(); 2776477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor } 2786477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor 279d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor switch (C->getType()->getTypeID()) { 280d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor#define GET_CONST_VAL(TY, CTY, CLASS) \ 281d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor case Type::TY##TyID: Result.TY##Val = (CTY)cast<CLASS>(C)->getValue(); break 282d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(Bool , bool , ConstantBool); 283d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(UByte , unsigned char , ConstantUInt); 284d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(SByte , signed char , ConstantSInt); 285d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(UShort , unsigned short, ConstantUInt); 286d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(Short , signed short , ConstantSInt); 287d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(UInt , unsigned int , ConstantUInt); 288d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(Int , signed int , ConstantSInt); 289d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(ULong , uint64_t , ConstantUInt); 290d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(Long , int64_t , ConstantSInt); 291d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor GET_CONST_VAL(Float , float , ConstantFP); 2926ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor GET_CONST_VAL(Double , double , ConstantFP); 293d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor#undef GET_CONST_VAL 294d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor case Type::PointerTyID: 295d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor if (isa<ConstantPointerNull>(C)) 296e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Result.PointerVal = 0; 297e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor else if (const Function *F = dyn_cast<Function>(C)) 298e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Result = PTOGV(getPointerToFunctionOrStub(const_cast<Function*>(F))); 299e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor else if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C)) 300e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Result = PTOGV(getOrEmitGlobalVariable(const_cast<GlobalVariable*>(GV))); 301e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor else 302e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor assert(0 && "Unknown constant pointer type!"); 303e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor break; 3042dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor default: 305e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor std::cout << "ERROR: Constant unimp for type: " << *C->getType() << "\n"; 306e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor abort(); 307e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor } 308e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor return Result; 309e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor} 310e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor 311e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// FIXME: document 312e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor/// 313e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregorvoid ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr, 314e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor const Type *Ty) { 315e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor if (getTargetData().isLittleEndian()) { 316e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor switch (Ty->getTypeID()) { 317e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::BoolTyID: 318e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::UByteTyID: 319e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break; 320e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::UShortTyID: 321e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::ShortTyID: Ptr->Untyped[0] = Val.UShortVal & 255; 322e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Ptr->Untyped[1] = (Val.UShortVal >> 8) & 255; 323e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor break; 324e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Store4BytesLittleEndian: 325e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::FloatTyID: 326e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::UIntTyID: 327e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::IntTyID: Ptr->Untyped[0] = Val.UIntVal & 255; 328e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Ptr->Untyped[1] = (Val.UIntVal >> 8) & 255; 329e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Ptr->Untyped[2] = (Val.UIntVal >> 16) & 255; 330e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor Ptr->Untyped[3] = (Val.UIntVal >> 24) & 255; 331e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor break; 332e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 333e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor goto Store4BytesLittleEndian; 3342dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::DoubleTyID: 335e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::ULongTyID: 336e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::LongTyID: 33748dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor Ptr->Untyped[0] = (unsigned char)(Val.ULongVal ); 33848dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor Ptr->Untyped[1] = (unsigned char)(Val.ULongVal >> 8); 3390ca20ac8cea99c43d89510f29cf3dc876f9c9111Douglas Gregor Ptr->Untyped[2] = (unsigned char)(Val.ULongVal >> 16); 3405545e166a956a20d7a6b58408e251a1119025485Douglas Gregor Ptr->Untyped[3] = (unsigned char)(Val.ULongVal >> 24); 3412dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[4] = (unsigned char)(Val.ULongVal >> 32); 3422dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[5] = (unsigned char)(Val.ULongVal >> 40); 3432dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[6] = (unsigned char)(Val.ULongVal >> 48); 3442dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[7] = (unsigned char)(Val.ULongVal >> 56); 3452dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor break; 3462dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor default: 3472dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor std::cout << "Cannot store value of type " << *Ty << "!\n"; 3482dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor } 3492dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor } else { 3501eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor switch (Ty->getTypeID()) { 3512dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::BoolTyID: 3525545e166a956a20d7a6b58408e251a1119025485Douglas Gregor case Type::UByteTyID: 3535545e166a956a20d7a6b58408e251a1119025485Douglas Gregor case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break; 3545545e166a956a20d7a6b58408e251a1119025485Douglas Gregor case Type::UShortTyID: 355beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad case Type::ShortTyID: Ptr->Untyped[1] = Val.UShortVal & 255; 3565545e166a956a20d7a6b58408e251a1119025485Douglas Gregor Ptr->Untyped[0] = (Val.UShortVal >> 8) & 255; 3575545e166a956a20d7a6b58408e251a1119025485Douglas Gregor break; 3585545e166a956a20d7a6b58408e251a1119025485Douglas Gregor Store4BytesBigEndian: 3592dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::FloatTyID: 3602dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::UIntTyID: 3612dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::IntTyID: Ptr->Untyped[3] = Val.UIntVal & 255; 3622dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[2] = (Val.UIntVal >> 8) & 255; 3632dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[1] = (Val.UIntVal >> 16) & 255; 3642dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[0] = (Val.UIntVal >> 24) & 255; 3652dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor break; 3662dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 3672dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor goto Store4BytesBigEndian; 3682dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::DoubleTyID: 3692dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::ULongTyID: 3702dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor case Type::LongTyID: 371eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner Ptr->Untyped[7] = (unsigned char)(Val.ULongVal ); 372eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner Ptr->Untyped[6] = (unsigned char)(Val.ULongVal >> 8); 3732dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[5] = (unsigned char)(Val.ULongVal >> 16); 3742dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[4] = (unsigned char)(Val.ULongVal >> 24); 3756ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor Ptr->Untyped[3] = (unsigned char)(Val.ULongVal >> 32); 3762dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[2] = (unsigned char)(Val.ULongVal >> 40); 3772dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[1] = (unsigned char)(Val.ULongVal >> 48); 3782dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Ptr->Untyped[0] = (unsigned char)(Val.ULongVal >> 56); 379615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor break; 380e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor default: 38148dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor std::cout << "Cannot store value of type " << *Ty << "!\n"; 38248dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor } 3830ca20ac8cea99c43d89510f29cf3dc876f9c9111Douglas Gregor } 384615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor} 385615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor 386615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor/// FIXME: document 387615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor/// 388615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas GregorGenericValue ExecutionEngine::LoadValueFromMemory(GenericValue *Ptr, 389615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor const Type *Ty) { 390615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor GenericValue Result; 391615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor if (getTargetData().isLittleEndian()) { 39249f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor switch (Ty->getTypeID()) { 39349f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor case Type::BoolTyID: 394615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::UByteTyID: 395615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; 396615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::UShortTyID: 397615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[0] | 3981eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor ((unsigned)Ptr->Untyped[1] << 8); 399615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor break; 400615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor Load4BytesLittleEndian: 401615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::FloatTyID: 402615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::UIntTyID: 403beaaccd8e2a8748f77b66e2b330fb9136937e14cJay Foad case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[0] | 404615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((unsigned)Ptr->Untyped[1] << 8) | 405615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((unsigned)Ptr->Untyped[2] << 16) | 406615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((unsigned)Ptr->Untyped[3] << 24); 407615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor break; 408615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 409615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor goto Load4BytesLittleEndian; 410615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::DoubleTyID: 411615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::ULongTyID: 412615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[0] | 413615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((uint64_t)Ptr->Untyped[1] << 8) | 414615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((uint64_t)Ptr->Untyped[2] << 16) | 415615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((uint64_t)Ptr->Untyped[3] << 24) | 416615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((uint64_t)Ptr->Untyped[4] << 32) | 417615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((uint64_t)Ptr->Untyped[5] << 40) | 418615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor ((uint64_t)Ptr->Untyped[6] << 48) | 419eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner ((uint64_t)Ptr->Untyped[7] << 56); 420eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner break; 421615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor default: 42249f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor std::cout << "Cannot load value of type " << *Ty << "!\n"; 423eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner abort(); 424615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor } 425615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor } else { 426615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor switch (Ty->getTypeID()) { 42703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor case Type::BoolTyID: 428e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor case Type::UByteTyID: 42948dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor case Type::SByteTyID: Result.UByteVal = Ptr->Untyped[0]; break; 43048dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor case Type::UShortTyID: 4310ca20ac8cea99c43d89510f29cf3dc876f9c9111Douglas Gregor case Type::ShortTyID: Result.UShortVal = (unsigned)Ptr->Untyped[1] | 4325545e166a956a20d7a6b58408e251a1119025485Douglas Gregor ((unsigned)Ptr->Untyped[0] << 8); 43303b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor break; 43403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor Load4BytesBigEndian: 4355545e166a956a20d7a6b58408e251a1119025485Douglas Gregor case Type::FloatTyID: 4365545e166a956a20d7a6b58408e251a1119025485Douglas Gregor case Type::UIntTyID: 43703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor case Type::IntTyID: Result.UIntVal = (unsigned)Ptr->Untyped[3] | 43803b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor ((unsigned)Ptr->Untyped[2] << 8) | 43949f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor ((unsigned)Ptr->Untyped[1] << 16) | 44049f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor ((unsigned)Ptr->Untyped[0] << 24); 44103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor break; 44203b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor case Type::PointerTyID: if (getTargetData().getPointerSize() == 4) 44303b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor goto Load4BytesBigEndian; 44403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor case Type::DoubleTyID: 44503b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor case Type::ULongTyID: 4461eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor case Type::LongTyID: Result.ULongVal = (uint64_t)Ptr->Untyped[7] | 4475545e166a956a20d7a6b58408e251a1119025485Douglas Gregor ((uint64_t)Ptr->Untyped[6] << 8) | 4485545e166a956a20d7a6b58408e251a1119025485Douglas Gregor ((uint64_t)Ptr->Untyped[5] << 16) | 44903b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor ((uint64_t)Ptr->Untyped[4] << 24) | 45003b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor ((uint64_t)Ptr->Untyped[3] << 32) | 45103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor ((uint64_t)Ptr->Untyped[2] << 40) | 45203b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor ((uint64_t)Ptr->Untyped[1] << 48) | 453eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner ((uint64_t)Ptr->Untyped[0] << 56); 454eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner break; 4556ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor default: 45603b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor std::cout << "Cannot load value of type " << *Ty << "!\n"; 45703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor abort(); 45803b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor } 459bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor } 460e53060fa78ad7e98352049f72787bdb7543e2a48Douglas Gregor return Result; 46148dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor} 46248dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor 4630ca20ac8cea99c43d89510f29cf3dc876f9c9111Douglas Gregor// InitializeMemory - Recursive function to apply a Constant value into the 464bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor// specified memory location... 465bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor// 466bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregorvoid ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) { 467bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor if (isa<UndefValue>(Init)) { 468bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor return; 469bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(Init)) { 470bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor unsigned ElementSize = 471bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor getTargetData().getTypeSize(CP->getType()->getElementType()); 472bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) 473bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor InitializeMemory(CP->getOperand(i), (char*)Addr+i*ElementSize); 474bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor return; 475bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor } else if (Init->getType()->isFirstClassType()) { 476bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor GenericValue Val = getConstantValue(Init); 477bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType()); 478bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor return; 4791eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor } else if (isa<ConstantAggregateZero>(Init)) { 480bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor memset(Addr, 0, (size_t)getTargetData().getTypeSize(Init->getType())); 481bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor return; 482bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor } 483bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor 484bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor switch (Init->getType()->getTypeID()) { 485bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor case Type::ArrayTyID: { 486eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner const ConstantArray *CPA = cast<ConstantArray>(Init); 487eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner unsigned ElementSize = 4886ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor getTargetData().getTypeSize(CPA->getType()->getElementType()); 489bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i) 490bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor InitializeMemory(CPA->getOperand(i), (char*)Addr+i*ElementSize); 491bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor return; 4926477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor } 4932dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor 4947e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor case Type::StructTyID: { 4952dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor const ConstantStruct *CPS = cast<ConstantStruct>(Init); 4962dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor const StructLayout *SL = 4972dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor getTargetData().getStructLayout(cast<StructType>(CPS->getType())); 4982dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) 4992dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor InitializeMemory(CPS->getOperand(i), (char*)Addr+SL->MemberOffsets[i]); 5002dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor return; 5012dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor } 5022dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor 5032dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor default: 5042dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor std::cerr << "Bad Type: " << *Init->getType() << "\n"; 5052dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor assert(0 && "Unknown constant type to initialize memory with!"); 5062dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor } 5072dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor} 5082dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor 5092dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor/// EmitGlobals - Emit all of the global variables to memory, storing their 5102dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor/// addresses into GlobalAddress. This must make sure to copy the contents of 5112dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor/// their initializers into the memory. 5122dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor/// 5132dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregorvoid ExecutionEngine::emitGlobals() { 5142dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor const TargetData &TD = getTargetData(); 5152dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor 5162dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // Loop over all of the global variables in the program, allocating the memory 5172dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // to hold them. 5182dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor Module &M = getModule(); 5192dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 5202dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor I != E; ++I) 5212dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor if (!I->isExternal()) { 5222dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // Get the type of the global... 5232dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor const Type *Ty = I->getType()->getElementType(); 52448dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor 5252dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // Allocate some memory for it! 5262dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor unsigned Size = TD.getTypeSize(Ty); 5272dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor addGlobalMapping(I, new char[Size]); 5282dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor } else { 5292dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // External variable reference. Try to use the dynamic loader to 5302dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor // get a pointer to it. 5312dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor if (void *SymAddr = sys::DynamicLibrary::SearchForAddressOfSymbol( 5322dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor I->getName().c_str())) 5332dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor addGlobalMapping(I, SymAddr); 5342dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor else { 5352dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor std::cerr << "Could not resolve external global address: " 5362dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor << I->getName() << "\n"; 5378dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor abort(); 5387e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor } 5397e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor } 5408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor 5418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // Now that all of the globals are set up in memory, loop through them all and 5428dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor // initialize their contents. 5435545e166a956a20d7a6b58408e251a1119025485Douglas Gregor for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); 5445545e166a956a20d7a6b58408e251a1119025485Douglas Gregor I != E; ++I) 5455545e166a956a20d7a6b58408e251a1119025485Douglas Gregor if (!I->isExternal()) 5465545e166a956a20d7a6b58408e251a1119025485Douglas Gregor EmitGlobalVariable(I); 5475545e166a956a20d7a6b58408e251a1119025485Douglas Gregor} 5485545e166a956a20d7a6b58408e251a1119025485Douglas Gregor 5495545e166a956a20d7a6b58408e251a1119025485Douglas Gregor// EmitGlobalVariable - This method emits the specified global variable to the 5505545e166a956a20d7a6b58408e251a1119025485Douglas Gregor// address specified in GlobalAddresses, or allocates new memory if it's not 5515545e166a956a20d7a6b58408e251a1119025485Douglas Gregor// already in the map. 5525545e166a956a20d7a6b58408e251a1119025485Douglas Gregorvoid ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) { 5535545e166a956a20d7a6b58408e251a1119025485Douglas Gregor void *GA = getPointerToGlobalIfAvailable(GV); 5545545e166a956a20d7a6b58408e251a1119025485Douglas Gregor DEBUG(std::cerr << "Global '" << GV->getName() << "' -> " << GA << "\n"); 5555545e166a956a20d7a6b58408e251a1119025485Douglas Gregor 5565545e166a956a20d7a6b58408e251a1119025485Douglas Gregor const Type *ElTy = GV->getType()->getElementType(); 5575545e166a956a20d7a6b58408e251a1119025485Douglas Gregor size_t GVSize = (size_t)getTargetData().getTypeSize(ElTy); 5587e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor if (GA == 0) { 5590ca20ac8cea99c43d89510f29cf3dc876f9c9111Douglas Gregor // If it's not already specified, allocate memory for the global. 5605545e166a956a20d7a6b58408e251a1119025485Douglas Gregor GA = new char[GVSize]; 5615545e166a956a20d7a6b58408e251a1119025485Douglas Gregor addGlobalMapping(GV, GA); 5625545e166a956a20d7a6b58408e251a1119025485Douglas Gregor } 5636477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor 5645545e166a956a20d7a6b58408e251a1119025485Douglas Gregor InitializeMemory(GV->getInitializer(), GA); 5655545e166a956a20d7a6b58408e251a1119025485Douglas Gregor NumInitBytes += (unsigned)GVSize; 5665545e166a956a20d7a6b58408e251a1119025485Douglas Gregor ++NumGlobals; 5675545e166a956a20d7a6b58408e251a1119025485Douglas Gregor} 5685545e166a956a20d7a6b58408e251a1119025485Douglas Gregor