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