1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-09 09:34:49 +09:00

[LoongArch64] JIT/EE interface for getting ABI-info (#62893)

* [LoongArch64] add ToolBox directory about jitinterace for getting ABI-info. (#59561)

Co-authored-by: Loongson's .NET-teams

* [LoongArch64] add new interace for getting ABI-info. (#59561)

* [LoongArch64] add the linking page for LoongArch64 ABI-info. (#59561)

* [LoongArch64] moved ThunkInput.txt to #62885.

* [LoongArch64] moved vm/jitinterface.cpp to #62885.

* remove the JIT/EE interface back from #62885..

* [LoongArch64] Fix the compiling error after merge.

* [LoongArch64] add comments for the returned value of `getFieldTypeByHnd`.

* [LoongArch64] rename getFieldTypeByHnd to getFieldSizeClassificationByHnd.
Also add macro define for returned value of `getFieldSizeClassificationByHnd`.

* [LoongArch64] Delete the interface `getArgType2`.
And refactor the returned values of `getFieldSizeClassificationByHnd`.

* [LoongArch64] delete `GetArgType` within `ToolBox/superpmi`.

* [LoongArch64] rename `getFieldSizeClassificationByHnd` to
`getLoongArch64PassStructInRegisterFlags`.

* [LoongArch64] amend the floating-ABI for native-struct.

* [LoongArch64] update all related `GetFieldSizeClassificationByHnd`
by `GetLoongArch64PassStructInRegisterFlags` and amend some comments.

* [LoongArch64] replace `LookupApproxFieldTypeHandle()`
by `GetFieldTypeHandleThrowing()`.

* [LoongArch64] implements the crossgen2 for LoongArch64.

* Revert "[LoongArch64] implements the crossgen2 for LoongArch64."

This reverts commit b05a2b90e8d8a2f6d1cf7f101ddfc9d4ed8d984e.

The crossgen2 for LoongArch64 will be submitted by a new PR.

* [LoongArch64] update the `GUID JITEEVersionIdentifier`.
Also delete some unused comments.

Co-authored-by: qiaopengcheng <qiaopengcheng-hf@loongson.cn>
This commit is contained in:
Qiao Pengcheng 2022-02-18 16:07:48 +08:00 committed by GitHub
parent d59bfff93e
commit 90b7be39c4
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 658 additions and 61 deletions

View file

@ -26,6 +26,8 @@ Arm corporation ABI documentation (for ARM32 and ARM64) is [here](https://develo
The Linux System V x86_64 ABI is documented in [System V Application Binary Interface / AMD64 Architecture Processor Supplement](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf), with document source material [here](https://gitlab.com/x86-psABIs/x86-64-ABI). The Linux System V x86_64 ABI is documented in [System V Application Binary Interface / AMD64 Architecture Processor Supplement](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf), with document source material [here](https://gitlab.com/x86-psABIs/x86-64-ABI).
The LoongArch64 ABI documentation is [here](https://github.com/loongson/LoongArch-Documentation/blob/main/docs/LoongArch-ELF-ABI-EN.adoc)
# General Unwind/Frame Layout # General Unwind/Frame Layout
For all non-x86 platforms, all methods must have unwind information so the garbage collector (GC) can unwind them (unlike native code in which a leaf method may be omitted). For all non-x86 platforms, all methods must have unwind information so the garbage collector (GC) can unwind them (unlike native code in which a leaf method may be omitted).

View file

@ -316,6 +316,45 @@ private:
} }
}; };
// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` API
// to convey struct argument passing information.
//
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
//
// Otherwise, and only for structs with no more than two fields and a total struct size no larger
// than two pointers:
//
// The lowest four bits denote the floating-point info:
// bit 0: `1` means there is only one float or double field within the struct.
// bit 1: `1` means only the first field is floating-point type.
// bit 2: `1` means only the second field is floating-point type.
// bit 3: `1` means the two fields are both floating-point type.
// The bits[5:4] denoting whether the field size is 8-bytes:
// bit 4: `1` means the first field's size is 8.
// bit 5: `1` means the second field's size is 8.
//
// Note that bit 0 and 3 cannot both be set.
enum StructFloatFieldInfoFlags
{
STRUCT_NO_FLOAT_FIELD = 0x0,
STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1,
STRUCT_FLOAT_FIELD_ONLY_TWO = 0x8,
STRUCT_FLOAT_FIELD_FIRST = 0x2,
STRUCT_FLOAT_FIELD_SECOND = 0x4,
STRUCT_FIRST_FIELD_SIZE_IS8 = 0x10,
STRUCT_SECOND_FIELD_SIZE_IS8 = 0x20,
STRUCT_FIRST_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FIRST_FIELD_SIZE_IS8),
STRUCT_SECOND_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_SECOND | STRUCT_SECOND_FIELD_SIZE_IS8),
STRUCT_FIELD_TWO_DOUBLES = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8 | STRUCT_FLOAT_FIELD_ONLY_TWO),
STRUCT_MERGE_FIRST_SECOND = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO),
STRUCT_MERGE_FIRST_SECOND_8 = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_SECOND_FIELD_SIZE_IS8),
STRUCT_HAS_FLOAT_FIELDS_MASK = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_SECOND | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_FLOAT_FIELD_ONLY_ONE),
STRUCT_HAS_8BYTES_FIELDS_MASK = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8),
};
#include "corinfoinstructionset.h" #include "corinfoinstructionset.h"
// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn()) // CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
@ -2843,6 +2882,7 @@ public:
/* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr
) = 0; ) = 0;
virtual uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
}; };
/***************************************************************************** /*****************************************************************************

View file

@ -480,6 +480,9 @@ bool getSystemVAmd64PassStructInRegisterDescriptor(
CORINFO_CLASS_HANDLE structHnd, CORINFO_CLASS_HANDLE structHnd,
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr) override; SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr) override;
uint32_t getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd) override;
uint32_t getThreadTLSIndex( uint32_t getThreadTLSIndex(
void** ppIndirection) override; void** ppIndirection) override;

View file

@ -43,12 +43,12 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED #define GUID_DEFINED
#endif // !GUID_DEFINED #endif // !GUID_DEFINED
constexpr GUID JITEEVersionIdentifier = { /* e6a73797-0cbe-4cf8-b4ad-724a25466211 */ constexpr GUID JITEEVersionIdentifier = { /* 80a6aaf7-7fb3-44b2-8fe5-95fd47308798 */
0xe6a73797, 0x80a6aaf7,
0x0cbe, 0x7fb3,
0x4cf8, 0x44b2,
{0xb4, 0xad, 0x72, 0x4a, 0x25, 0x46, 0x62, 0x11} {0x8f, 0xe5, 0x95, 0xfd, 0x47, 0x30, 0x87, 0x98}
}; };
////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////
// //

View file

@ -122,6 +122,7 @@ DEF_CLR_API(getMethodNameFromMetadata)
DEF_CLR_API(getMethodHash) DEF_CLR_API(getMethodHash)
DEF_CLR_API(findNameOfToken) DEF_CLR_API(findNameOfToken)
DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor) DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor)
DEF_CLR_API(getLoongArch64PassStructInRegisterFlags)
DEF_CLR_API(getThreadTLSIndex) DEF_CLR_API(getThreadTLSIndex)
DEF_CLR_API(getInlinedCallFrameVptr) DEF_CLR_API(getInlinedCallFrameVptr)
DEF_CLR_API(getAddrOfCaptureThreadGlobal) DEF_CLR_API(getAddrOfCaptureThreadGlobal)

View file

@ -1154,6 +1154,15 @@ bool WrapICorJitInfo::getSystemVAmd64PassStructInRegisterDescriptor(
return temp; return temp;
} }
uint32_t WrapICorJitInfo::getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
{
API_ENTER(getLoongArch64PassStructInRegisterFlags);
uint32_t temp = wrapHnd->getLoongArch64PassStructInRegisterFlags(structHnd);
API_LEAVE(getLoongArch64PassStructInRegisterFlags);
return temp;
}
uint32_t WrapICorJitInfo::getThreadTLSIndex( uint32_t WrapICorJitInfo::getThreadTLSIndex(
void** ppIndirection) void** ppIndirection)
{ {

View file

@ -1757,6 +1757,21 @@ namespace Internal.JitInterface
} }
} }
[UnmanagedCallersOnly]
static uint _getLoongArch64PassStructInRegisterFlags(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* structHnd)
{
var _this = GetThis(thisHandle);
try
{
return _this.getLoongArch64PassStructInRegisterFlags(structHnd);
}
catch (Exception ex)
{
*ppException = _this.AllocException(ex);
return default;
}
}
[UnmanagedCallersOnly] [UnmanagedCallersOnly]
static uint _getThreadTLSIndex(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection) static uint _getThreadTLSIndex(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection)
{ {
@ -2552,7 +2567,7 @@ namespace Internal.JitInterface
static IntPtr GetUnmanagedCallbacks() static IntPtr GetUnmanagedCallbacks()
{ {
void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172); void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 173);
callbacks[0] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte>)&_isIntrinsic; callbacks[0] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte>)&_isIntrinsic;
callbacks[1] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodAttribs; callbacks[1] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodAttribs;
@ -2672,60 +2687,61 @@ namespace Internal.JitInterface
callbacks[115] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodHash; callbacks[115] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, uint>)&_getMethodHash;
callbacks[116] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, byte*, UIntPtr, UIntPtr>)&_findNameOfToken; callbacks[116] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, byte*, UIntPtr, UIntPtr>)&_findNameOfToken;
callbacks[117] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte>)&_getSystemVAmd64PassStructInRegisterDescriptor; callbacks[117] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR*, byte>)&_getSystemVAmd64PassStructInRegisterDescriptor;
callbacks[118] = (delegate* unmanaged<IntPtr, IntPtr*, void**, uint>)&_getThreadTLSIndex; callbacks[118] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, uint>)&_getLoongArch64PassStructInRegisterFlags;
callbacks[119] = (delegate* unmanaged<IntPtr, IntPtr*, void**, void*>)&_getInlinedCallFrameVptr; callbacks[119] = (delegate* unmanaged<IntPtr, IntPtr*, void**, uint>)&_getThreadTLSIndex;
callbacks[120] = (delegate* unmanaged<IntPtr, IntPtr*, void**, int*>)&_getAddrOfCaptureThreadGlobal; callbacks[120] = (delegate* unmanaged<IntPtr, IntPtr*, void**, void*>)&_getInlinedCallFrameVptr;
callbacks[121] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, void**, void*>)&_getHelperFtn; callbacks[121] = (delegate* unmanaged<IntPtr, IntPtr*, void**, int*>)&_getAddrOfCaptureThreadGlobal;
callbacks[122] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, CORINFO_ACCESS_FLAGS, void>)&_getFunctionEntryPoint; callbacks[122] = (delegate* unmanaged<IntPtr, IntPtr*, CorInfoHelpFunc, void**, void*>)&_getHelperFtn;
callbacks[123] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte, CORINFO_CONST_LOOKUP*, void>)&_getFunctionFixedEntryPoint; callbacks[123] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, CORINFO_ACCESS_FLAGS, void>)&_getFunctionEntryPoint;
callbacks[124] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, void*>)&_getMethodSync; callbacks[124] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, byte, CORINFO_CONST_LOOKUP*, void>)&_getFunctionFixedEntryPoint;
callbacks[125] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CorInfoHelpFunc>)&_getLazyStringLiteralHelper; callbacks[125] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, void*>)&_getMethodSync;
callbacks[126] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, void**, CORINFO_MODULE_STRUCT_*>)&_embedModuleHandle; callbacks[126] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CorInfoHelpFunc>)&_getLazyStringLiteralHelper;
callbacks[127] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, CORINFO_CLASS_STRUCT_*>)&_embedClassHandle; callbacks[127] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, void**, CORINFO_MODULE_STRUCT_*>)&_embedModuleHandle;
callbacks[128] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, CORINFO_METHOD_STRUCT_*>)&_embedMethodHandle; callbacks[128] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, CORINFO_CLASS_STRUCT_*>)&_embedClassHandle;
callbacks[129] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, CORINFO_FIELD_STRUCT_*>)&_embedFieldHandle; callbacks[129] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void**, CORINFO_METHOD_STRUCT_*>)&_embedMethodHandle;
callbacks[130] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CORINFO_GENERICHANDLE_RESULT*, void>)&_embedGenericHandle; callbacks[130] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, CORINFO_FIELD_STRUCT_*>)&_embedFieldHandle;
callbacks[131] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_LOOKUP_KIND*, void>)&_getLocationOfThisType; callbacks[131] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, CORINFO_GENERICHANDLE_RESULT*, void>)&_embedGenericHandle;
callbacks[132] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getAddressOfPInvokeTarget; callbacks[132] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_LOOKUP_KIND*, void>)&_getLocationOfThisType;
callbacks[133] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, void*>)&_GetCookieForPInvokeCalliSig; callbacks[133] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CONST_LOOKUP*, void>)&_getAddressOfPInvokeTarget;
callbacks[134] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetCookieForPInvokeCalliSig; callbacks[134] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, void*>)&_GetCookieForPInvokeCalliSig;
callbacks[135] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_JUST_MY_CODE_HANDLE_**, CORINFO_JUST_MY_CODE_HANDLE_*>)&_getJustMyCodeHandle; callbacks[135] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetCookieForPInvokeCalliSig;
callbacks[136] = (delegate* unmanaged<IntPtr, IntPtr*, bool*, void**, bool*, void>)&_GetProfilingHandle; callbacks[136] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_JUST_MY_CODE_HANDLE_**, CORINFO_JUST_MY_CODE_HANDLE_*>)&_getJustMyCodeHandle;
callbacks[137] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_CALLINFO_FLAGS, CORINFO_CALL_INFO*, void>)&_getCallInfo; callbacks[137] = (delegate* unmanaged<IntPtr, IntPtr*, bool*, void**, bool*, void>)&_GetProfilingHandle;
callbacks[138] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canAccessFamily; callbacks[138] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_RESOLVED_TOKEN*, CORINFO_METHOD_STRUCT_*, CORINFO_CALLINFO_FLAGS, CORINFO_CALL_INFO*, void>)&_getCallInfo;
callbacks[139] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isRIDClassDomainID; callbacks[139] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_canAccessFamily;
callbacks[140] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, uint>)&_getClassDomainID; callbacks[140] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, byte>)&_isRIDClassDomainID;
callbacks[141] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, void*>)&_getFieldAddress; callbacks[141] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CLASS_STRUCT_*, void**, uint>)&_getClassDomainID;
callbacks[142] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, CORINFO_CLASS_STRUCT_*>)&_getStaticFieldCurrentClass; callbacks[142] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, void*>)&_getFieldAddress;
callbacks[143] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, IntPtr>)&_getVarArgsHandle; callbacks[143] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, byte*, CORINFO_CLASS_STRUCT_*>)&_getStaticFieldCurrentClass;
callbacks[144] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetVarArgsHandle; callbacks[144] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, void**, IntPtr>)&_getVarArgsHandle;
callbacks[145] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, void**, InfoAccessType>)&_constructStringLiteral; callbacks[145] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_SIG_INFO*, byte>)&_canGetVarArgsHandle;
callbacks[146] = (delegate* unmanaged<IntPtr, IntPtr*, void**, InfoAccessType>)&_emptyStringLiteral; callbacks[146] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, mdToken, void**, InfoAccessType>)&_constructStringLiteral;
callbacks[147] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, uint>)&_getFieldThreadLocalStoreID; callbacks[147] = (delegate* unmanaged<IntPtr, IntPtr*, void**, InfoAccessType>)&_emptyStringLiteral;
callbacks[148] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CORINFO_MODULE_STRUCT_*, void>)&_addActiveDependency; callbacks[148] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, void**, uint>)&_getFieldThreadLocalStoreID;
callbacks[149] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, DelegateCtorArgs*, CORINFO_METHOD_STRUCT_*>)&_GetDelegateCtor; callbacks[149] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_MODULE_STRUCT_*, CORINFO_MODULE_STRUCT_*, void>)&_addActiveDependency;
callbacks[150] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_MethodCompileComplete; callbacks[150] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, CORINFO_CLASS_STRUCT_*, CORINFO_METHOD_STRUCT_*, DelegateCtorArgs*, CORINFO_METHOD_STRUCT_*>)&_GetDelegateCtor;
callbacks[151] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_SIG_INFO*, CORINFO_GET_TAILCALL_HELPERS_FLAGS, CORINFO_TAILCALL_HELPERS*, byte>)&_getTailCallHelpers; callbacks[151] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, void>)&_MethodCompileComplete;
callbacks[152] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, byte>)&_convertPInvokeCalliToCall; callbacks[152] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, CORINFO_SIG_INFO*, CORINFO_GET_TAILCALL_HELPERS_FLAGS, CORINFO_TAILCALL_HELPERS*, byte>)&_getTailCallHelpers;
callbacks[153] = (delegate* unmanaged<IntPtr, IntPtr*, InstructionSet, byte, byte>)&_notifyInstructionSetUsage; callbacks[153] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_RESOLVED_TOKEN*, byte, byte>)&_convertPInvokeCalliToCall;
callbacks[154] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CONST_LOOKUP*, void>)&_updateEntryPointForTailCall; callbacks[154] = (delegate* unmanaged<IntPtr, IntPtr*, InstructionSet, byte, byte>)&_notifyInstructionSetUsage;
callbacks[155] = (delegate* unmanaged<IntPtr, IntPtr*, AllocMemArgs*, void>)&_allocMem; callbacks[155] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_CONST_LOOKUP*, void>)&_updateEntryPointForTailCall;
callbacks[156] = (delegate* unmanaged<IntPtr, IntPtr*, byte, byte, uint, void>)&_reserveUnwindInfo; callbacks[156] = (delegate* unmanaged<IntPtr, IntPtr*, AllocMemArgs*, void>)&_allocMem;
callbacks[157] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, byte*, uint, uint, uint, byte*, CorJitFuncKind, void>)&_allocUnwindInfo; callbacks[157] = (delegate* unmanaged<IntPtr, IntPtr*, byte, byte, uint, void>)&_reserveUnwindInfo;
callbacks[158] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocGCInfo; callbacks[158] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, byte*, uint, uint, uint, byte*, CorJitFuncKind, void>)&_allocUnwindInfo;
callbacks[159] = (delegate* unmanaged<IntPtr, IntPtr*, uint, void>)&_setEHcount; callbacks[159] = (delegate* unmanaged<IntPtr, IntPtr*, UIntPtr, void*>)&_allocGCInfo;
callbacks[160] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_EH_CLAUSE*, void>)&_setEHinfo; callbacks[160] = (delegate* unmanaged<IntPtr, IntPtr*, uint, void>)&_setEHcount;
callbacks[161] = (delegate* unmanaged<IntPtr, IntPtr*, uint, byte*, IntPtr, byte>)&_logMsg; callbacks[161] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_EH_CLAUSE*, void>)&_setEHinfo;
callbacks[162] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, int, byte*, int>)&_doAssert; callbacks[162] = (delegate* unmanaged<IntPtr, IntPtr*, uint, byte*, IntPtr, byte>)&_logMsg;
callbacks[163] = (delegate* unmanaged<IntPtr, IntPtr*, CorJitResult, void>)&_reportFatalError; callbacks[163] = (delegate* unmanaged<IntPtr, IntPtr*, byte*, int, byte*, int>)&_doAssert;
callbacks[164] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema**, uint*, byte**, PgoSource*, HRESULT>)&_getPgoInstrumentationResults; callbacks[164] = (delegate* unmanaged<IntPtr, IntPtr*, CorJitResult, void>)&_reportFatalError;
callbacks[165] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema*, uint, byte**, HRESULT>)&_allocPgoInstrumentationBySchema; callbacks[165] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema**, uint*, byte**, PgoSource*, HRESULT>)&_getPgoInstrumentationResults;
callbacks[166] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_SIG_INFO*, CORINFO_METHOD_STRUCT_*, void>)&_recordCallSite; callbacks[166] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_METHOD_STRUCT_*, PgoInstrumentationSchema*, uint, byte**, HRESULT>)&_allocPgoInstrumentationBySchema;
callbacks[167] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, void*, ushort, ushort, int, void>)&_recordRelocation; callbacks[167] = (delegate* unmanaged<IntPtr, IntPtr*, uint, CORINFO_SIG_INFO*, CORINFO_METHOD_STRUCT_*, void>)&_recordCallSite;
callbacks[168] = (delegate* unmanaged<IntPtr, IntPtr*, void*, ushort>)&_getRelocTypeHint; callbacks[168] = (delegate* unmanaged<IntPtr, IntPtr*, void*, void*, void*, ushort, ushort, int, void>)&_recordRelocation;
callbacks[169] = (delegate* unmanaged<IntPtr, IntPtr*, uint>)&_getExpectedTargetArchitecture; callbacks[169] = (delegate* unmanaged<IntPtr, IntPtr*, void*, ushort>)&_getRelocTypeHint;
callbacks[170] = (delegate* unmanaged<IntPtr, IntPtr*, CORJIT_FLAGS*, uint, uint>)&_getJitFlags; callbacks[170] = (delegate* unmanaged<IntPtr, IntPtr*, uint>)&_getExpectedTargetArchitecture;
callbacks[171] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_doesFieldBelongToClass; callbacks[171] = (delegate* unmanaged<IntPtr, IntPtr*, CORJIT_FLAGS*, uint, uint>)&_getJitFlags;
callbacks[172] = (delegate* unmanaged<IntPtr, IntPtr*, CORINFO_FIELD_STRUCT_*, CORINFO_CLASS_STRUCT_*, byte>)&_doesFieldBelongToClass;
return (IntPtr)callbacks; return (IntPtr)callbacks;
} }

View file

@ -2936,6 +2936,11 @@ namespace Internal.JitInterface
} }
} }
private uint getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_STRUCT_* cls)
{
throw new NotImplementedException("For LoongArch64, would be implemented later");
}
private CORINFO_CLASS_STRUCT_* getArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args) private CORINFO_CLASS_STRUCT_* getArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args)
{ {
int index = (int)args; int index = (int)args;

View file

@ -271,6 +271,7 @@ FUNCTIONS
unsigned getMethodHash(CORINFO_METHOD_HANDLE ftn); unsigned getMethodHash(CORINFO_METHOD_HANDLE ftn);
size_t findNameOfToken(CORINFO_MODULE_HANDLE moduleHandle,mdToken token, char * szFQName,size_t FQNameCapacity); size_t findNameOfToken(CORINFO_MODULE_HANDLE moduleHandle,mdToken token, char * szFQName,size_t FQNameCapacity);
bool getSystemVAmd64PassStructInRegisterDescriptor(CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); bool getSystemVAmd64PassStructInRegisterDescriptor(CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd);
uint32_t getThreadTLSIndex(void **ppIndirection); uint32_t getThreadTLSIndex(void **ppIndirection);
const void * getInlinedCallFrameVptr(void **ppIndirection); const void * getInlinedCallFrameVptr(void **ppIndirection);
int32_t * getAddrOfCaptureThreadGlobal(void **ppIndirection); int32_t * getAddrOfCaptureThreadGlobal(void **ppIndirection);

View file

@ -129,6 +129,7 @@ struct JitInterfaceCallbacks
unsigned (* getMethodHash)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn); unsigned (* getMethodHash)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn);
size_t (* findNameOfToken)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE moduleHandle, unsigned int token, char* szFQName, size_t FQNameCapacity); size_t (* findNameOfToken)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE moduleHandle, unsigned int token, char* szFQName, size_t FQNameCapacity);
bool (* getSystemVAmd64PassStructInRegisterDescriptor)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); bool (* getSystemVAmd64PassStructInRegisterDescriptor)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
uint32_t (* getLoongArch64PassStructInRegisterFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE structHnd);
uint32_t (* getThreadTLSIndex)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); uint32_t (* getThreadTLSIndex)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
const void* (* getInlinedCallFrameVptr)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); const void* (* getInlinedCallFrameVptr)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
int32_t* (* getAddrOfCaptureThreadGlobal)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); int32_t* (* getAddrOfCaptureThreadGlobal)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection);
@ -1322,6 +1323,15 @@ public:
return temp; return temp;
} }
virtual uint32_t getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
{
CorInfoExceptionClass* pException = nullptr;
uint32_t temp = _callbacks->getLoongArch64PassStructInRegisterFlags(_thisHandle, &pException, structHnd);
if (pException != nullptr) throw pException;
return temp;
}
virtual uint32_t getThreadTLSIndex( virtual uint32_t getThreadTLSIndex(
void** ppIndirection) void** ppIndirection)
{ {

View file

@ -127,6 +127,7 @@ LWM(GetExpectedTargetArchitecture, DWORD, DWORD)
LWM(GetSharedCCtorHelper, DWORDLONG, DWORD) LWM(GetSharedCCtorHelper, DWORDLONG, DWORD)
LWM(GetStringConfigValue, DWORD, DWORD) LWM(GetStringConfigValue, DWORD, DWORD)
LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor) LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor)
LWM(GetLoongArch64PassStructInRegisterFlags, DWORDLONG, DWORD)
LWM(GetTailCallHelpers, Agnostic_GetTailCallHelpers, Agnostic_CORINFO_TAILCALL_HELPERS) LWM(GetTailCallHelpers, Agnostic_GetTailCallHelpers, Agnostic_CORINFO_TAILCALL_HELPERS)
LWM(UpdateEntryPointForTailCall, Agnostic_CORINFO_CONST_LOOKUP, Agnostic_CORINFO_CONST_LOOKUP) LWM(UpdateEntryPointForTailCall, Agnostic_CORINFO_CONST_LOOKUP, Agnostic_CORINFO_CONST_LOOKUP)
LWM(GetThreadTLSIndex, DWORD, DLD) LWM(GetThreadTLSIndex, DWORD, DLD)

View file

@ -2661,6 +2661,7 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig,
GetArgType->Add(key, value); GetArgType->Add(key, value);
DEBUG_REC(dmpGetArgType(key, value)); DEBUG_REC(dmpGetArgType(key, value));
} }
void MethodContext::dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value) void MethodContext::dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value)
{ {
printf("GetArgType key flg-%08X na-%u %s %s msig-%016llX scp-%016llX arg-%016llX", printf("GetArgType key flg-%08X na-%u %s %s msig-%016llX scp-%016llX arg-%016llX",
@ -2670,6 +2671,7 @@ void MethodContext::dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agno
key.methodSignature, key.scope, key.args); key.methodSignature, key.scope, key.args);
printf(", value result(cit)-%u(%s) vcType-%016llX excp-%08X", value.result, toString((CorInfoTypeWithMod)value.result), value.vcTypeRet, value.exceptionCode); printf(", value result(cit)-%u(%s) vcType-%016llX excp-%08X", value.result, toString((CorInfoTypeWithMod)value.result), value.vcTypeRet, value.exceptionCode);
} }
CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig,
CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE args,
CORINFO_CLASS_HANDLE* vcTypeRet, CORINFO_CLASS_HANDLE* vcTypeRet,
@ -6120,6 +6122,31 @@ bool MethodContext::repGetSystemVAmd64PassStructInRegisterDescriptor(
return value.result ? true : false; return value.result ? true : false;
} }
void MethodContext::recGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd, DWORD value)
{
if (GetLoongArch64PassStructInRegisterFlags == nullptr)
GetLoongArch64PassStructInRegisterFlags = new LightWeightMap<DWORDLONG, DWORD>();
DWORDLONG key = CastHandle(structHnd);
GetLoongArch64PassStructInRegisterFlags->Add(key, value);
DEBUG_REC(dmpGetLoongArch64PassStructInRegisterFlags(key, value));
}
void MethodContext::dmpGetLoongArch64PassStructInRegisterFlags(DWORDLONG key, DWORD value)
{
printf("GetLoongArch64PassStructInRegisterFlags key %016llX value-%08X", key, value);
}
DWORD MethodContext::repGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd)
{
DWORDLONG key = CastHandle(structHnd);
DWORD value = GetLoongArch64PassStructInRegisterFlags->Get(key);
DEBUG_REP(dmpGetLoongArch64PassStructInRegisterFlags(key, value));
return value;
}
void MethodContext::recGetRelocTypeHint(void* target, WORD result) void MethodContext::recGetRelocTypeHint(void* target, WORD result)
{ {
if (GetRelocTypeHint == nullptr) if (GetRelocTypeHint == nullptr)

View file

@ -751,6 +751,10 @@ public:
bool repGetSystemVAmd64PassStructInRegisterDescriptor( bool repGetSystemVAmd64PassStructInRegisterDescriptor(
CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
void recGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd, DWORD value);
void dmpGetLoongArch64PassStructInRegisterFlags(DWORDLONG key, DWORD value);
DWORD repGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd);
void recGetRelocTypeHint(void* target, WORD result); void recGetRelocTypeHint(void* target, WORD result);
void dmpGetRelocTypeHint(DWORDLONG key, DWORD value); void dmpGetRelocTypeHint(DWORDLONG key, DWORD value);
WORD repGetRelocTypeHint(void* target); WORD repGetRelocTypeHint(void* target);
@ -1095,6 +1099,7 @@ enum mcPackets
Packet_GetAssemblyName = 191, Packet_GetAssemblyName = 191,
Packet_IsIntrinsic = 192, Packet_IsIntrinsic = 192,
Packet_UpdateEntryPointForTailCall = 193, Packet_UpdateEntryPointForTailCall = 193,
Packet_GetLoongArch64PassStructInRegisterFlags = 194,
}; };
void SetDebugDumpVariables(); void SetDebugDumpVariables();

View file

@ -1385,6 +1385,14 @@ bool interceptor_ICJI::getSystemVAmd64PassStructInRegisterDescriptor(
return result; return result;
} }
uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd)
{
mc->cr->AddCall("getLoongArch64PassStructInRegisterFlags");
uint32_t temp = original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(structHnd);
mc->recGetLoongArch64PassStructInRegisterFlags(structHnd, temp);
return temp;
}
// Stuff on ICorDynamicInfo // Stuff on ICorDynamicInfo
uint32_t interceptor_ICJI::getThreadTLSIndex(void** ppIndirection) uint32_t interceptor_ICJI::getThreadTLSIndex(void** ppIndirection)
{ {

View file

@ -943,6 +943,13 @@ bool interceptor_ICJI::getSystemVAmd64PassStructInRegisterDescriptor(
return original_ICorJitInfo->getSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr); return original_ICorJitInfo->getSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr);
} }
uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
{
mcs->AddCall("getLoongArch64PassStructInRegisterFlags");
return original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(structHnd);
}
uint32_t interceptor_ICJI::getThreadTLSIndex( uint32_t interceptor_ICJI::getThreadTLSIndex(
void** ppIndirection) void** ppIndirection)
{ {

View file

@ -825,6 +825,12 @@ bool interceptor_ICJI::getSystemVAmd64PassStructInRegisterDescriptor(
return original_ICorJitInfo->getSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr); return original_ICorJitInfo->getSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr);
} }
uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags(
CORINFO_CLASS_HANDLE structHnd)
{
return original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(structHnd);
}
uint32_t interceptor_ICJI::getThreadTLSIndex( uint32_t interceptor_ICJI::getThreadTLSIndex(
void** ppIndirection) void** ppIndirection)
{ {

View file

@ -1227,6 +1227,12 @@ bool MyICJI::getSystemVAmd64PassStructInRegisterDescriptor(
return jitInstance->mc->repGetSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr); return jitInstance->mc->repGetSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr);
} }
uint32_t MyICJI::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd)
{
jitInstance->mc->cr->AddCall("getLoongArch64PassStructInRegisterFlags");
return jitInstance->mc->repGetLoongArch64PassStructInRegisterFlags(structHnd);
}
// Stuff on ICorDynamicInfo // Stuff on ICorDynamicInfo
uint32_t MyICJI::getThreadTLSIndex(void** ppIndirection) uint32_t MyICJI::getThreadTLSIndex(void** ppIndirection)
{ {

View file

@ -9279,6 +9279,456 @@ CorInfoTypeWithMod CEEInfo::getArgType (
return result; return result;
} }
// Now the implementation is only focused on the float fields info,
// while a struct-arg has no more than two fields and total size is no larger than two-pointer-size.
// These depends on the platform's ABI rules.
//
// The returned value's encoding details how a struct argument uses float registers:
// see the enum `StructFloatFieldInfoFlags`.
uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls)
{
CONTRACTL {
NOTHROW;
GC_NOTRIGGER;
MODE_PREEMPTIVE;
} CONTRACTL_END;
JIT_TO_EE_TRANSITION_LEAF();
TypeHandle th(cls);
bool useNativeLayout = false;
uint32_t size = STRUCT_NO_FLOAT_FIELD;
MethodTable* pMethodTable = nullptr;
if (!th.IsTypeDesc())
{
pMethodTable = th.AsMethodTable();
if (pMethodTable->HasLayout())
useNativeLayout = true;
else if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/)
{
DWORD numIntroducedFields = pMethodTable->GetNumIntroducedInstanceFields();
if (numIntroducedFields == 1)
{
FieldDesc *pFieldStart = pMethodTable->GetApproxFieldDescListRaw();
CorElementType fieldType = pFieldStart[0].GetFieldType();
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8))
size = STRUCT_FLOAT_FIELD_ONLY_ONE;
}
else if (fieldType == ELEMENT_TYPE_VALUETYPE)
{
pMethodTable = pFieldStart->GetFieldTypeHandleThrowing().GetMethodTable();
if (pMethodTable->GetNumIntroducedInstanceFields() == 1)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable);
}
else if (pMethodTable->GetNumIntroducedInstanceFields() == 2)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable);
}
}
}
else if (numIntroducedFields == 2)
{
FieldDesc *pFieldStart = pMethodTable->GetApproxFieldDescListRaw();
CorElementType fieldType = pFieldStart[0].GetFieldType();
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if (fieldType == ELEMENT_TYPE_R4)
size = STRUCT_FLOAT_FIELD_FIRST;
else if (fieldType == ELEMENT_TYPE_R8)
size = STRUCT_FIRST_FIELD_DOUBLE;
else if (pFieldStart[0].GetSize() == 8)
size = STRUCT_FIRST_FIELD_SIZE_IS8;
}
else if (fieldType == ELEMENT_TYPE_VALUETYPE)
{
pMethodTable = pFieldStart->GetFieldTypeHandleThrowing().GetMethodTable();
if (pMethodTable->GetNumIntroducedInstanceFields() == 1)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable);
if (size == STRUCT_FLOAT_FIELD_ONLY_ONE)
{
size = pFieldStart[0].GetSize() == 8 ? STRUCT_FIRST_FIELD_DOUBLE : STRUCT_FLOAT_FIELD_FIRST;
}
else if (size == STRUCT_NO_FLOAT_FIELD)
{
size = pFieldStart[0].GetSize() == 8 ? STRUCT_FIRST_FIELD_SIZE_IS8: 0;
}
else
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
}
else
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
}
else if (pFieldStart[0].GetSize() == 8)
size = STRUCT_FIRST_FIELD_SIZE_IS8;
fieldType = pFieldStart[1].GetFieldType();
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if (fieldType == ELEMENT_TYPE_R4)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
else if (fieldType == ELEMENT_TYPE_R8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
else if (pFieldStart[1].GetSize() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
}
else if (fieldType == ELEMENT_TYPE_VALUETYPE)
{
pMethodTable = pFieldStart[1].GetFieldTypeHandleThrowing().GetMethodTable();
if (pMethodTable->GetNumIntroducedInstanceFields() == 1)
{
DWORD size2 = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable);
if (size2 == STRUCT_FLOAT_FIELD_ONLY_ONE)
{
if (pFieldStart[1].GetSize() == 8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
else
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
}
else if (size2 == 0)
{
size |= pFieldStart[1].GetSize() == 8 ? STRUCT_SECOND_FIELD_SIZE_IS8 : 0;
}
else
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
}
else
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
}
else if (pFieldStart[1].GetSize() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
}
goto _End_arg;
}
}
else
{
_ASSERTE(th.IsNativeValueType());
useNativeLayout = true;
pMethodTable = th.AsNativeValueType();
}
_ASSERTE(pMethodTable != nullptr);
if (useNativeLayout)
{
if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/)
{
DWORD numIntroducedFields = pMethodTable->GetNumIntroducedInstanceFields();
FieldDesc *pFieldStart = nullptr;
if (numIntroducedFields == 1)
{
pFieldStart = pMethodTable->GetApproxFieldDescListRaw();
CorElementType fieldType = pFieldStart->GetFieldType();
bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)
|| fieldType == ELEMENT_TYPE_VALUETYPE)
&& (pFieldStart->GetOffset() == 0)
&& pMethodTable->HasLayout()
&& (pMethodTable->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0);
if (isFixedBuffer)
{
numIntroducedFields = pMethodTable->GetNumInstanceFieldBytes() / pFieldStart->GetSize();
if (numIntroducedFields > 2)
goto _End_arg;
if (fieldType == ELEMENT_TYPE_R4)
{
if (numIntroducedFields == 1)
size = STRUCT_FLOAT_FIELD_ONLY_ONE;
else if (numIntroducedFields == 2)
size = STRUCT_FLOAT_FIELD_ONLY_TWO;
goto _End_arg;
}
else if (fieldType == ELEMENT_TYPE_R8)
{
if (numIntroducedFields == 1)
size = STRUCT_FLOAT_FIELD_ONLY_ONE;
else if (numIntroducedFields == 2)
size = STRUCT_FIELD_TWO_DOUBLES;
goto _End_arg;
}
}
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8))
size = STRUCT_FLOAT_FIELD_ONLY_ONE;
}
else if (fieldType == ELEMENT_TYPE_VALUETYPE)
{
const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors();
if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable());
return size;
}
else if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::FLOAT)
{
if (pNativeFieldDescs->NativeSize() == 4)
{
size = STRUCT_FLOAT_FIELD_ONLY_ONE;
}
else if (pNativeFieldDescs->NativeSize() == 8)
{
size = STRUCT_FLOAT_FIELD_ONLY_ONE;
}
else
{
UNREACHABLE_MSG("Invalid NativeFieldCategory.----LoongArch64----");
}
}
else
{
pMethodTable = pNativeFieldDescs->GetNestedNativeMethodTable();
if (pNativeFieldDescs->GetNumElements() == 1)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable);
}
else if (pNativeFieldDescs->GetNumElements() == 2)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable);
}
}
}
}
else if (numIntroducedFields == 2)
{
pFieldStart = pMethodTable->GetApproxFieldDescListRaw();
if (pFieldStart->GetOffset() || !pFieldStart[1].GetOffset() || (pFieldStart[0].GetSize() > pFieldStart[1].GetOffset()))
{
goto _End_arg;
}
CorElementType fieldType = pFieldStart[0].GetFieldType();
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if (fieldType == ELEMENT_TYPE_R4)
size = STRUCT_FLOAT_FIELD_FIRST;
else if (fieldType == ELEMENT_TYPE_R8)
size = STRUCT_FIRST_FIELD_DOUBLE;
else if (pFieldStart[0].GetSize() == 8)
size = STRUCT_FIRST_FIELD_SIZE_IS8;
fieldType = pFieldStart[1].GetFieldType();
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if (fieldType == ELEMENT_TYPE_R4)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
else if (fieldType == ELEMENT_TYPE_R8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
else if (pFieldStart[1].GetSize() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
goto _End_arg;
}
}
else if (fieldType == ELEMENT_TYPE_VALUETYPE)
{
const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors();
if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED)
{
MethodTable* pMethodTable2 = pNativeFieldDescs->GetNestedNativeMethodTable();
if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1))
goto _End_arg;
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2);
if (size == STRUCT_FLOAT_FIELD_ONLY_ONE)
{
if (pFieldStart[0].GetSize() == 8)
size = STRUCT_FIRST_FIELD_DOUBLE;
else
size = STRUCT_FLOAT_FIELD_FIRST;
}
else if (pFieldStart[0].GetSize() == 8)
{
size = STRUCT_FIRST_FIELD_SIZE_IS8;
}
else
size = STRUCT_NO_FLOAT_FIELD;
}
else if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::FLOAT)
{
if (pNativeFieldDescs->NativeSize() == 4)
{
size = STRUCT_FLOAT_FIELD_FIRST;
}
else if (pNativeFieldDescs->NativeSize() == 8)
{
size = STRUCT_FIRST_FIELD_DOUBLE;
}
else
{
UNREACHABLE_MSG("Invalid NativeFieldCategory.----LoongArch64----2");
}
}
else
{
MethodTable* pMethodTable2 = pFieldStart[0].GetFieldTypeHandleThrowing().AsMethodTable();
if (pMethodTable2->GetNumIntroducedInstanceFields() == 1)
{
size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2);
if (size == STRUCT_FLOAT_FIELD_ONLY_ONE)
{
if (pFieldStart[0].GetSize() == 8)
size = STRUCT_FIRST_FIELD_DOUBLE;
else
size = STRUCT_FLOAT_FIELD_FIRST;
}
else if (pFieldStart[0].GetSize() == 8)
{
size = STRUCT_FIRST_FIELD_SIZE_IS8;
}
else
size = STRUCT_NO_FLOAT_FIELD;
}
else
goto _End_arg;
}
}
else if (pFieldStart[0].GetSize() == 8)
size = STRUCT_FIRST_FIELD_SIZE_IS8;
fieldType = pFieldStart[1].GetFieldType();
if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType))
{
if (fieldType == ELEMENT_TYPE_R4)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
else if (fieldType == ELEMENT_TYPE_R8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
else if (pFieldStart[1].GetSize() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
}
else if (fieldType == ELEMENT_TYPE_VALUETYPE)
{
MethodTable* pMethodTable2 = pFieldStart[1].GetFieldTypeHandleThrowing().AsMethodTable();
if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1))
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
if (pMethodTable2->HasLayout())
{
const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable2->GetNativeLayoutInfo()->GetNativeFieldDescriptors();
if (pNativeFieldDescs->NativeSize() > 8)
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED)
{
pMethodTable = pNativeFieldDescs->GetNestedNativeMethodTable();
if (pMethodTable->GetNumIntroducedInstanceFields() > 1)
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
if (getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable) == STRUCT_FLOAT_FIELD_ONLY_ONE)
{
if (pMethodTable->GetNumInstanceFieldBytes() == 4)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
else if (pMethodTable->GetNumInstanceFieldBytes() == 8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
}
else if (pMethodTable->GetNumInstanceFieldBytes() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
else
{
size = STRUCT_NO_FLOAT_FIELD;
}
}
else if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::FLOAT)
{
if (pNativeFieldDescs->NativeSize() == 4)
{
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
}
else if (pNativeFieldDescs->NativeSize() == 8)
{
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
}
else
{
UNREACHABLE_MSG("Invalid NativeFieldCategory.----LoongArch64----3");
}
}
else
{
if (pNativeFieldDescs->GetNumElements() == 1)
{
fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType();
if (fieldType == ELEMENT_TYPE_R4)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
else if (fieldType == ELEMENT_TYPE_R8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
else if ((size & STRUCT_FLOAT_FIELD_FIRST) == 0)
{
size = STRUCT_NO_FLOAT_FIELD;
goto _End_arg;
}
else if (pNativeFieldDescs->NativeSize() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
}
else
{
size = STRUCT_NO_FLOAT_FIELD;
}
}
}
else
{
if (getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2) == 1)
{
if (pMethodTable2->GetNumInstanceFieldBytes() == 4)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND);
else if (pMethodTable2->GetNumInstanceFieldBytes() == 8)
size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE);
}
else if (pMethodTable2->GetNumInstanceFieldBytes() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
}
}
else if (pFieldStart[1].GetSize() == 8)
size |= STRUCT_SECOND_FIELD_SIZE_IS8;
}
}
}
_End_arg:
EE_TO_JIT_TRANSITION_LEAF();
return size;
}
/*********************************************************************/ /*********************************************************************/
CORINFO_CLASS_HANDLE CEEInfo::getArgClass ( CORINFO_CLASS_HANDLE CEEInfo::getArgClass (