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