[Orc] Add TransformUtils to Orc's dependency list.
[oota-llvm.git] / lib / ExecutionEngine / Orc / OrcMCJITReplacement.cpp
1 //===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "OrcMCJITReplacement.h"
11 #include "llvm/ExecutionEngine/GenericValue.h"
12
13 namespace {
14
15 static struct RegisterJIT {
16   RegisterJIT() { llvm::OrcMCJITReplacement::Register(); }
17 } JITRegistrator;
18
19 }
20
21 extern "C" void LLVMLinkInOrcMCJITReplacement() {}
22
23 namespace llvm {
24
25 GenericValue
26 OrcMCJITReplacement::runFunction(Function *F,
27                                  const std::vector<GenericValue> &ArgValues) {
28   assert(F && "Function *F was null at entry to run()");
29
30   void *FPtr = getPointerToFunction(F);
31   assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
32   FunctionType *FTy = F->getFunctionType();
33   Type *RetTy = FTy->getReturnType();
34
35   assert((FTy->getNumParams() == ArgValues.size() ||
36           (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
37          "Wrong number of arguments passed into function!");
38   assert(FTy->getNumParams() == ArgValues.size() &&
39          "This doesn't support passing arguments through varargs (yet)!");
40
41   // Handle some common cases first.  These cases correspond to common `main'
42   // prototypes.
43   if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
44     switch (ArgValues.size()) {
45     case 3:
46       if (FTy->getParamType(0)->isIntegerTy(32) &&
47           FTy->getParamType(1)->isPointerTy() &&
48           FTy->getParamType(2)->isPointerTy()) {
49         int (*PF)(int, char **, const char **) =
50             (int (*)(int, char **, const char **))(intptr_t)FPtr;
51
52         // Call the function.
53         GenericValue rv;
54         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
55                                  (char **)GVTOP(ArgValues[1]),
56                                  (const char **)GVTOP(ArgValues[2])));
57         return rv;
58       }
59       break;
60     case 2:
61       if (FTy->getParamType(0)->isIntegerTy(32) &&
62           FTy->getParamType(1)->isPointerTy()) {
63         int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
64
65         // Call the function.
66         GenericValue rv;
67         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
68                                  (char **)GVTOP(ArgValues[1])));
69         return rv;
70       }
71       break;
72     case 1:
73       if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
74         GenericValue rv;
75         int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
76         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
77         return rv;
78       }
79       break;
80     }
81   }
82
83   // Handle cases where no arguments are passed first.
84   if (ArgValues.empty()) {
85     GenericValue rv;
86     switch (RetTy->getTypeID()) {
87     default:
88       llvm_unreachable("Unknown return type for function call!");
89     case Type::IntegerTyID: {
90       unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
91       if (BitWidth == 1)
92         rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
93       else if (BitWidth <= 8)
94         rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
95       else if (BitWidth <= 16)
96         rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
97       else if (BitWidth <= 32)
98         rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
99       else if (BitWidth <= 64)
100         rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
101       else
102         llvm_unreachable("Integer types > 64 bits not supported");
103       return rv;
104     }
105     case Type::VoidTyID:
106       rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
107       return rv;
108     case Type::FloatTyID:
109       rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
110       return rv;
111     case Type::DoubleTyID:
112       rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
113       return rv;
114     case Type::X86_FP80TyID:
115     case Type::FP128TyID:
116     case Type::PPC_FP128TyID:
117       llvm_unreachable("long double not supported yet");
118     case Type::PointerTyID:
119       return PTOGV(((void *(*)())(intptr_t)FPtr)());
120     }
121   }
122
123   llvm_unreachable("Full-featured argument passing not supported yet!");
124 }
125 }