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