//===-- offload/plugins-nextgen/common/include/Emissary.h ------ C++ ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Defines emissary helper functions. This include is only used for host // compilation. // //===----------------------------------------------------------------------===// #ifndef OFFLOAD_EMISSARY_H #define OFFLOAD_EMISSARY_H #include "../../../../openmp/device/include/EmissaryIds.h" extern "C" { /// Called by rpc after receiving emissary argument buffer emis_return_t Emissary(char *data); /// Called by Emissary for all Fortrt emissary functions emis_return_t EmissaryFortrt(char *data, emisArgBuf_t *ab); /// Called by Emissary for all misc print functions emis_return_t EmissaryPrint(char *data, emisArgBuf_t *ab); /// Called by Emissary for all MPI emissary API functions __attribute((weak)) emis_return_t EmissaryMPI(char *data, emisArgBuf_t *ab, emis_argptr_t *arg[MAXVARGS]); /// Called by Emissary for all HDF5 Emissary API functions __attribute((weak)) emis_return_t EmissaryHDF5(char *data, emisArgBuf_t *ab, emis_argptr_t *arg[MAXVARGS]); /// Support externally supplied emissary API __attribute((weak)) emis_return_t EmissaryReserve(char *data, emisArgBuf_t *ab, emis_argptr_t *arg[MAXVARGS]); /// Called by Emissary to build the emisArgBuf_t structure from the emissary /// data buffer sent to the CPU by rpc. This buffer is created by clang CodeGen /// when variadic function _emissary_exec(...) is encountered when compiling // /the device stub for each emissary function. void emisExtractArgBuf(char *buf, emisArgBuf_t *ab); /// Get uint32 value extended to uint64_t value from a char ptr uint64_t getuint32(char *val); /// Get uint64_t value from a char ptr uint64_t getuint64(char *val); /// Get a function pointer from a char ptr void *getfnptr(char *val); /// Builds the array of pointers passed to V_ functions uint32_t EmissaryBuildVargs(int NumArgs, char *keyptr, char *dataptr, char *strptr, unsigned long long *data_not_used, emis_argptr_t *a[MAXVARGS]); } // end extern "C" /// Call the associated V_ function template extern T EmissaryCallFnptr(uint32_t NumArgs, void *fnptr, emis_argptr_t *a[MAXVARGS]); // Error return codes (deprecated) typedef enum service_rc { _RC_SUCCESS = 0, _RC_STATUS_UNKNOWN = 1, _RC_STATUS_ERROR = 2, _RC_STATUS_TERMINATE = 3, _RC_DATA_USED_ERROR = 4, _RC_ADDINT_ERROR = 5, _RC_ADDFLOAT_ERROR = 6, _RC_ADDSTRING_ERROR = 7, _RC_UNSUPPORTED_ID_ERROR = 8, _RC_INVALID_ID_ERROR = 9, _RC_ERROR_INVALID_REQUEST = 10, _RC_EXCEED_MAXVARGS_ERROR = 11, _RC_INVALIDSERVICE_ERROR = 12, _RC_ERROR_MEMFREE = 13, _RC_ERROR_CONSUMER_ACTIVE = 14, _RC_ERROR_CONSUMER_INACTIVE = 15, _RC_ERROR_CONSUMER_LAUNCH_FAILED = 16, _RC_ERROR_SERVICE_UNKNOWN = 17, _RC_ERROR_INCORRECT_ALIGNMENT = 18, _RC_ERROR_NULLPTR = 19, _RC_ERROR_WRONGVERSION = 20, _RC_ERROR_OLDHOSTVERSIONMOD = 21, _RC_ERROR_HSAFAIL = 22, _RC_ERROR_ZEROPACKETS = 23, _RC_ERROR_ALIGNMENT = 24, } service_rc; // We would like to get llvm typeID enum from Type.h. e.g. // #include ".../llvm/include/llvm/IR/Type.h" // But we cannot include LLVM headers in a runtime function. // So we a have a manual copy of llvm TypeID enum from Type.h // The codegen for _emissary_exec puts this ID in the key for // each arg and the host runtime needs to decode this key. // // NOTE: This enum MUST stay in lockstep with llvm::Type::TypeID in // llvm/include/llvm/IR/Type.h. The device encoder // (clang/lib/CodeGen/CGEmitEmissaryExec.cpp) stores getTypeID() from the live // LLVM enum into the per-arg key, so any drift between the two enums silently // mis-routes args. enum TypeID { // PrimitiveTypes HalfTyID = 0, ///< 16-bit floating point type BFloatTyID, ///< 16-bit floating point type (7-bit significand) FloatTyID, ///< 32-bit floating point type DoubleTyID, ///< 64-bit floating point type X86_FP80TyID, ///< 80-bit floating point type (X87) FP128TyID, ///< 128-bit floating point type (112-bit significand) PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC) VoidTyID, ///< type with no size LabelTyID, ///< Labels MetadataTyID, ///< Metadata X86_AMXTyID, ///< AMX vectors (8192 bits, X86 specific) TokenTyID, ///< Tokens // Derived types... see DerivedTypes.h file. IntegerTyID, ///< Arbitrary bit width integers ByteTyID, ///< Arbitrary bit width bytes FunctionTyID, ///< Functions PointerTyID, ///< Pointers StructTyID, ///< Structures ArrayTyID, ///< Arrays FixedVectorTyID, ///< Fixed width SIMD vector type ScalableVectorTyID, ///< Scalable SIMD vector type TypedPointerTyID, ///< Typed pointer used by some GPU targets TargetExtTyID, ///< Target extension type }; template extern T EmissaryCallFnptr(uint32_t NumArgs, void *fnptr, emis_argptr_t *a[MAXVARGS]) { T rv; FT *vfnptr = (FT *)fnptr; switch (NumArgs) { case 1: rv = (T)vfnptr(fnptr, a[0]); break; case 2: rv = (T)vfnptr(fnptr, a[0], a[1]); break; case 3: rv = (T)vfnptr(fnptr, a[0], a[1], a[2]); break; case 4: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3]); break; case 5: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4]); break; case 6: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5]); break; case 7: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6]); break; case 8: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break; case 9: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); break; case 10: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); break; case 11: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]); break; case 12: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]); break; case 13: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12]); break; case 14: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13]); break; case 15: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]); break; case 16: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); break; case 17: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16]); break; case 18: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17]); break; case 19: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18]); break; case 20: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19]); break; case 21: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20]); break; case 22: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21]); break; case 23: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22]); break; case 24: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23]); break; case 25: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24]); break; case 26: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25]); break; case 27: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26]); break; case 28: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26], a[27]); break; case 29: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26], a[27], a[28]); break; case 30: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26], a[27], a[28], a[29]); break; case 31: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26], a[27], a[28], a[29], a[30]); break; case 32: rv = (T)vfnptr(fnptr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26], a[27], a[28], a[29], a[30], a[31]); break; default: rv = 0; } return rv; } #endif // OFFLOAD_EMISSARY_H