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