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