1996fe010SChris Lattner //===-- ExecutionEngine.cpp - Common Implementation shared by EE's --------===//
2996fe010SChris Lattner //
3996fe010SChris Lattner // This file defines the common interface used by the various execution engine
4996fe010SChris Lattner // subclasses.
5996fe010SChris Lattner //
6996fe010SChris Lattner //===----------------------------------------------------------------------===//
7996fe010SChris Lattner 
8996fe010SChris Lattner #include "ExecutionEngine.h"
9996fe010SChris Lattner #include "GenericValue.h"
10996fe010SChris Lattner #include "llvm/DerivedTypes.h"
11996fe010SChris Lattner #include "llvm/Constants.h"
12996fe010SChris Lattner #include "llvm/Module.h"
13996fe010SChris Lattner #include "llvm/Target/TargetData.h"
14996fe010SChris Lattner #include "Support/Statistic.h"
159de0d14dSChris Lattner #include <dlfcn.h>
16996fe010SChris Lattner 
17996fe010SChris Lattner Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized");
18996fe010SChris Lattner 
19996fe010SChris Lattner // getPointerToGlobal - This returns the address of the specified global
20996fe010SChris Lattner // value.  This may involve code generation if it's a function.
21996fe010SChris Lattner //
22996fe010SChris Lattner void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
23996fe010SChris Lattner   if (const Function *F = dyn_cast<Function>(GV))
24996fe010SChris Lattner     return getPointerToFunction(F);
25996fe010SChris Lattner 
26996fe010SChris Lattner   assert(GlobalAddress[GV] && "Global hasn't had an address allocated yet?");
27996fe010SChris Lattner   return GlobalAddress[GV];
28996fe010SChris Lattner }
29996fe010SChris Lattner 
30996fe010SChris Lattner 
31996fe010SChris Lattner GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
32996fe010SChris Lattner   GenericValue Result;
339de0d14dSChris Lattner 
349de0d14dSChris Lattner   if (ConstantExpr *CE = (ConstantExpr*)dyn_cast<ConstantExpr>(C))
359de0d14dSChris Lattner     switch (CE->getOpcode()) {
369de0d14dSChris Lattner     case Instruction::GetElementPtr: {
379de0d14dSChris Lattner       Result = getConstantValue(cast<Constant>(CE->getOperand(0)));
389de0d14dSChris Lattner       std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end());
399de0d14dSChris Lattner       uint64_t Offset =
409de0d14dSChris Lattner         TD->getIndexedOffset(CE->getOperand(0)->getType(), Indexes);
419de0d14dSChris Lattner 
429de0d14dSChris Lattner       Result.LongVal += Offset;
439de0d14dSChris Lattner       return Result;
449de0d14dSChris Lattner     }
459de0d14dSChris Lattner 
469de0d14dSChris Lattner     default:
479de0d14dSChris Lattner       std::cerr << "ConstantExpr not handled as global var init: " << *CE
489de0d14dSChris Lattner                 << "\n";
499de0d14dSChris Lattner       abort();
509de0d14dSChris Lattner     }
51996fe010SChris Lattner 
52996fe010SChris Lattner   switch (C->getType()->getPrimitiveID()) {
539de0d14dSChris Lattner #define GET_CONST_VAL(TY, CLASS) \
549de0d14dSChris Lattner   case Type::TY##TyID: Result.TY##Val = cast<CLASS>(C)->getValue(); break
55996fe010SChris Lattner     GET_CONST_VAL(Bool   , ConstantBool);
56996fe010SChris Lattner     GET_CONST_VAL(UByte  , ConstantUInt);
57996fe010SChris Lattner     GET_CONST_VAL(SByte  , ConstantSInt);
58996fe010SChris Lattner     GET_CONST_VAL(UShort , ConstantUInt);
59996fe010SChris Lattner     GET_CONST_VAL(Short  , ConstantSInt);
60996fe010SChris Lattner     GET_CONST_VAL(UInt   , ConstantUInt);
61996fe010SChris Lattner     GET_CONST_VAL(Int    , ConstantSInt);
62996fe010SChris Lattner     GET_CONST_VAL(ULong  , ConstantUInt);
63996fe010SChris Lattner     GET_CONST_VAL(Long   , ConstantSInt);
64996fe010SChris Lattner     GET_CONST_VAL(Float  , ConstantFP);
65996fe010SChris Lattner     GET_CONST_VAL(Double , ConstantFP);
66996fe010SChris Lattner #undef GET_CONST_VAL
67996fe010SChris Lattner   case Type::PointerTyID:
68996fe010SChris Lattner     if (isa<ConstantPointerNull>(C)) {
69996fe010SChris Lattner       Result.PointerVal = 0;
70996fe010SChris Lattner     } else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)){
71996fe010SChris Lattner       Result = PTOGV(getPointerToGlobal(CPR->getValue()));
72996fe010SChris Lattner 
73996fe010SChris Lattner     } else {
74996fe010SChris Lattner       assert(0 && "Unknown constant pointer type!");
75996fe010SChris Lattner     }
76996fe010SChris Lattner     break;
77996fe010SChris Lattner   default:
785aa56633SChris Lattner     std::cout << "ERROR: Constant unimp for type: " << C->getType() << "\n";
799de0d14dSChris Lattner     abort();
80996fe010SChris Lattner   }
81996fe010SChris Lattner   return Result;
82996fe010SChris Lattner }
83996fe010SChris Lattner 
84996fe010SChris Lattner void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
85996fe010SChris Lattner 				     const Type *Ty) {
86996fe010SChris Lattner   if (getTargetData().isLittleEndian()) {
87996fe010SChris Lattner     switch (Ty->getPrimitiveID()) {
88996fe010SChris Lattner     case Type::BoolTyID:
89996fe010SChris Lattner     case Type::UByteTyID:
90996fe010SChris Lattner     case Type::SByteTyID:   Ptr->Untyped[0] = Val.UByteVal; break;
91996fe010SChris Lattner     case Type::UShortTyID:
92996fe010SChris Lattner     case Type::ShortTyID:   Ptr->Untyped[0] = Val.UShortVal & 255;
93996fe010SChris Lattner                             Ptr->Untyped[1] = (Val.UShortVal >> 8) & 255;
94996fe010SChris Lattner                             break;
95*b348952dSChris Lattner     Store4BytesLittleEndian:
96996fe010SChris Lattner     case Type::FloatTyID:
97996fe010SChris Lattner     case Type::UIntTyID:
98996fe010SChris Lattner     case Type::IntTyID:     Ptr->Untyped[0] =  Val.UIntVal        & 255;
99996fe010SChris Lattner                             Ptr->Untyped[1] = (Val.UIntVal >>  8) & 255;
100996fe010SChris Lattner                             Ptr->Untyped[2] = (Val.UIntVal >> 16) & 255;
101996fe010SChris Lattner                             Ptr->Untyped[3] = (Val.UIntVal >> 24) & 255;
102996fe010SChris Lattner                             break;
103*b348952dSChris Lattner     case Type::PointerTyID: if (CurMod.has32BitPointers())
104*b348952dSChris Lattner                               goto Store4BytesLittleEndian;
105996fe010SChris Lattner     case Type::DoubleTyID:
106996fe010SChris Lattner     case Type::ULongTyID:
107*b348952dSChris Lattner     case Type::LongTyID:    Ptr->Untyped[0] =  Val.ULongVal        & 255;
108996fe010SChris Lattner                             Ptr->Untyped[1] = (Val.ULongVal >>  8) & 255;
109996fe010SChris Lattner                             Ptr->Untyped[2] = (Val.ULongVal >> 16) & 255;
110996fe010SChris Lattner                             Ptr->Untyped[3] = (Val.ULongVal >> 24) & 255;
111996fe010SChris Lattner                             Ptr->Untyped[4] = (Val.ULongVal >> 32) & 255;
112996fe010SChris Lattner                             Ptr->Untyped[5] = (Val.ULongVal >> 40) & 255;
113996fe010SChris Lattner                             Ptr->Untyped[6] = (Val.ULongVal >> 48) & 255;
114996fe010SChris Lattner                             Ptr->Untyped[7] = (Val.ULongVal >> 56) & 255;
115996fe010SChris Lattner                             break;
116996fe010SChris Lattner     default:
1175aa56633SChris Lattner       std::cout << "Cannot store value of type " << Ty << "!\n";
118996fe010SChris Lattner     }
119996fe010SChris Lattner   } else {
120996fe010SChris Lattner     switch (Ty->getPrimitiveID()) {
121996fe010SChris Lattner     case Type::BoolTyID:
122996fe010SChris Lattner     case Type::UByteTyID:
123996fe010SChris Lattner     case Type::SByteTyID:   Ptr->Untyped[0] = Val.UByteVal; break;
124996fe010SChris Lattner     case Type::UShortTyID:
125996fe010SChris Lattner     case Type::ShortTyID:   Ptr->Untyped[1] = Val.UShortVal & 255;
126996fe010SChris Lattner                             Ptr->Untyped[0] = (Val.UShortVal >> 8) & 255;
127996fe010SChris Lattner                             break;
128*b348952dSChris Lattner     Store4BytesBigEndian:
129996fe010SChris Lattner     case Type::FloatTyID:
130996fe010SChris Lattner     case Type::UIntTyID:
131996fe010SChris Lattner     case Type::IntTyID:     Ptr->Untyped[3] =  Val.UIntVal        & 255;
132996fe010SChris Lattner                             Ptr->Untyped[2] = (Val.UIntVal >>  8) & 255;
133996fe010SChris Lattner                             Ptr->Untyped[1] = (Val.UIntVal >> 16) & 255;
134996fe010SChris Lattner                             Ptr->Untyped[0] = (Val.UIntVal >> 24) & 255;
135996fe010SChris Lattner                             break;
136*b348952dSChris Lattner     case Type::PointerTyID: if (CurMod.has32BitPointers())
137*b348952dSChris Lattner                               goto Store4BytesBigEndian;
138996fe010SChris Lattner     case Type::DoubleTyID:
139996fe010SChris Lattner     case Type::ULongTyID:
140*b348952dSChris Lattner     case Type::LongTyID:    Ptr->Untyped[7] =  Val.ULongVal        & 255;
141996fe010SChris Lattner                             Ptr->Untyped[6] = (Val.ULongVal >>  8) & 255;
142996fe010SChris Lattner                             Ptr->Untyped[5] = (Val.ULongVal >> 16) & 255;
143996fe010SChris Lattner                             Ptr->Untyped[4] = (Val.ULongVal >> 24) & 255;
144996fe010SChris Lattner                             Ptr->Untyped[3] = (Val.ULongVal >> 32) & 255;
145996fe010SChris Lattner                             Ptr->Untyped[2] = (Val.ULongVal >> 40) & 255;
146996fe010SChris Lattner                             Ptr->Untyped[1] = (Val.ULongVal >> 48) & 255;
147996fe010SChris Lattner                             Ptr->Untyped[0] = (Val.ULongVal >> 56) & 255;
148996fe010SChris Lattner                             break;
149996fe010SChris Lattner     default:
1505aa56633SChris Lattner       std::cout << "Cannot store value of type " << Ty << "!\n";
151996fe010SChris Lattner     }
152996fe010SChris Lattner   }
153996fe010SChris Lattner }
154996fe010SChris Lattner 
155996fe010SChris Lattner // InitializeMemory - Recursive function to apply a Constant value into the
156996fe010SChris Lattner // specified memory location...
157996fe010SChris Lattner //
158996fe010SChris Lattner void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) {
159996fe010SChris Lattner   if (Init->getType()->isFirstClassType()) {
160996fe010SChris Lattner     GenericValue Val = getConstantValue(Init);
161996fe010SChris Lattner     StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType());
162996fe010SChris Lattner     return;
163996fe010SChris Lattner   }
164996fe010SChris Lattner 
165996fe010SChris Lattner   switch (Init->getType()->getPrimitiveID()) {
166996fe010SChris Lattner   case Type::ArrayTyID: {
167996fe010SChris Lattner     const ConstantArray *CPA = cast<ConstantArray>(Init);
1685aa56633SChris Lattner     const std::vector<Use> &Val = CPA->getValues();
169996fe010SChris Lattner     unsigned ElementSize =
170996fe010SChris Lattner       getTargetData().getTypeSize(cast<ArrayType>(CPA->getType())->getElementType());
171996fe010SChris Lattner     for (unsigned i = 0; i < Val.size(); ++i)
172996fe010SChris Lattner       InitializeMemory(cast<Constant>(Val[i].get()), (char*)Addr+i*ElementSize);
173996fe010SChris Lattner     return;
174996fe010SChris Lattner   }
175996fe010SChris Lattner 
176996fe010SChris Lattner   case Type::StructTyID: {
177996fe010SChris Lattner     const ConstantStruct *CPS = cast<ConstantStruct>(Init);
178996fe010SChris Lattner     const StructLayout *SL =
179996fe010SChris Lattner       getTargetData().getStructLayout(cast<StructType>(CPS->getType()));
1805aa56633SChris Lattner     const std::vector<Use> &Val = CPS->getValues();
181996fe010SChris Lattner     for (unsigned i = 0; i < Val.size(); ++i)
182996fe010SChris Lattner       InitializeMemory(cast<Constant>(Val[i].get()),
183996fe010SChris Lattner                        (char*)Addr+SL->MemberOffsets[i]);
184996fe010SChris Lattner     return;
185996fe010SChris Lattner   }
186996fe010SChris Lattner 
187996fe010SChris Lattner   default:
188996fe010SChris Lattner     std::cerr << "Bad Type: " << Init->getType() << "\n";
189996fe010SChris Lattner     assert(0 && "Unknown constant type to initialize memory with!");
190996fe010SChris Lattner   }
191996fe010SChris Lattner }
192996fe010SChris Lattner 
193996fe010SChris Lattner 
194996fe010SChris Lattner 
195996fe010SChris Lattner void *ExecutionEngine::CreateArgv(const std::vector<std::string> &InputArgv) {
196996fe010SChris Lattner   // Pointers are 64 bits...
197510e8ba6SChris Lattner   // FIXME: Assumes 64 bit target
198510e8ba6SChris Lattner   PointerTy *Result = new PointerTy[InputArgv.size()+1];
199996fe010SChris Lattner   DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n");
200996fe010SChris Lattner 
201996fe010SChris Lattner   for (unsigned i = 0; i < InputArgv.size(); ++i) {
202996fe010SChris Lattner     unsigned Size = InputArgv[i].size()+1;
203996fe010SChris Lattner     char *Dest = new char[Size];
204996fe010SChris Lattner     DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n");
205996fe010SChris Lattner 
206996fe010SChris Lattner     copy(InputArgv[i].begin(), InputArgv[i].end(), Dest);
207996fe010SChris Lattner     Dest[Size-1] = 0;
208996fe010SChris Lattner 
209996fe010SChris Lattner     // Endian safe: Result[i] = (PointerTy)Dest;
210996fe010SChris Lattner     StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i),
211996fe010SChris Lattner                        Type::LongTy);  // 64 bit assumption
212996fe010SChris Lattner   }
213996fe010SChris Lattner 
214996fe010SChris Lattner   Result[InputArgv.size()] = 0;
215996fe010SChris Lattner   return Result;
216996fe010SChris Lattner }
217996fe010SChris Lattner 
218996fe010SChris Lattner /// EmitGlobals - Emit all of the global variables to memory, storing their
219996fe010SChris Lattner /// addresses into GlobalAddress.  This must make sure to copy the contents of
220996fe010SChris Lattner /// their initializers into the memory.
221996fe010SChris Lattner ///
222996fe010SChris Lattner void ExecutionEngine::emitGlobals() {
223996fe010SChris Lattner   const TargetData &TD = getTargetData();
224996fe010SChris Lattner 
225996fe010SChris Lattner   // Loop over all of the global variables in the program, allocating the memory
226996fe010SChris Lattner   // to hold them.
227996fe010SChris Lattner   for (Module::giterator I = getModule().gbegin(), E = getModule().gend();
228996fe010SChris Lattner        I != E; ++I)
229996fe010SChris Lattner     if (!I->isExternal()) {
230996fe010SChris Lattner       // Get the type of the global...
231996fe010SChris Lattner       const Type *Ty = I->getType()->getElementType();
232996fe010SChris Lattner 
233996fe010SChris Lattner       // Allocate some memory for it!
234996fe010SChris Lattner       unsigned Size = TD.getTypeSize(Ty);
235996fe010SChris Lattner       GlobalAddress[I] = new char[Size];
236996fe010SChris Lattner       NumInitBytes += Size;
237996fe010SChris Lattner 
238996fe010SChris Lattner       DEBUG(std::cerr << "Global '" << I->getName() << "' -> "
239996fe010SChris Lattner 	              << (void*)GlobalAddress[I] << "\n");
240996fe010SChris Lattner     } else {
2419de0d14dSChris Lattner       // External variable reference, try to use dlsym to get a pointer to it in
2429de0d14dSChris Lattner       // the LLI image.
2439de0d14dSChris Lattner       if (void *SymAddr = dlsym(0, I->getName().c_str()))
2449de0d14dSChris Lattner         GlobalAddress[I] = SymAddr;
2459de0d14dSChris Lattner       else {
2469de0d14dSChris Lattner         std::cerr << "Could not resolve external global address: "
2479de0d14dSChris Lattner                   << I->getName() << "\n";
2489de0d14dSChris Lattner         abort();
2499de0d14dSChris Lattner       }
250996fe010SChris Lattner     }
251996fe010SChris Lattner 
252996fe010SChris Lattner   // Now that all of the globals are set up in memory, loop through them all and
253996fe010SChris Lattner   // initialize their contents.
254996fe010SChris Lattner   for (Module::giterator I = getModule().gbegin(), E = getModule().gend();
255996fe010SChris Lattner        I != E; ++I)
256996fe010SChris Lattner     if (!I->isExternal())
257996fe010SChris Lattner       InitializeMemory(I->getInitializer(), GlobalAddress[I]);
258996fe010SChris Lattner }
259996fe010SChris Lattner 
260