From 485a681fcab6be67b30e0d811dc3e81a7dbef34c Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Thu, 16 Dec 2021 15:29:29 +0800 Subject: [PATCH 01/18] [LoongArch64] add ToolBox directory about jitinterace for getting ABI-info. (#59561) Co-authored-by: Loongson's .NET-teams --- .../ToolBox/superpmi/mcs/verbildump.cpp | 5 + .../superpmi/superpmi-shared/agnostic.h | 3 + .../superpmi/superpmi-shared/callutils.cpp | 10 + .../superpmi/superpmi-shared/lwmlist.h | 1 + .../superpmi-shared/methodcontext.cpp | 34 ++ .../superpmi/superpmi-shared/methodcontext.h | 11 + .../superpmi-shim-collector/icorjitinfo.cpp | 30 ++ .../superpmi-shim-counter/icorjitinfo.cpp | 16 +- .../superpmi-shim-simple/icorjitinfo.cpp | 16 +- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 13 + src/coreclr/inc/icorjitinfoimpl_generated.h | 8 +- src/coreclr/vm/jitinterface.cpp | 438 ++++++++++++++++++ 12 files changed, 582 insertions(+), 3 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp index 506d14e587f992..b49d615df9fee7 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp @@ -90,7 +90,12 @@ void DumpSigToConsoleBare(MethodContext* mc, CORINFO_SIG_INFO* pSig) for (int i = 0; i < (int)pSig->numArgs; i++) { DWORDLONG dl; +#if defined(TARGET_LOONGARCH64) + int flags; + CorInfoTypeWithMod type = mc->repGetArgType(pSig, currentItem, (CORINFO_CLASS_HANDLE*)&dl, &flags, &exceptionCode); +#else CorInfoTypeWithMod type = mc->repGetArgType(pSig, currentItem, (CORINFO_CLASS_HANDLE*)&dl, &exceptionCode); +#endif CorInfoType cit = strip(type); if (cit == CORINFO_TYPE_CLASS) dl = CastHandle(mc->repGetArgClass(pSig, currentItem, &exceptionCode)); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h index fd2a35093c7dec..148ca45fb90bc0 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h @@ -528,6 +528,9 @@ struct Agnostic_GetArgType_Value { DWORDLONG vcTypeRet; DWORD result; +#if defined(TARGET_LOONGARCH64) + int flags; +#endif DWORD exceptionCode; }; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp index 75bbf2a55c76ec..403fd88b003215 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp @@ -282,7 +282,12 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL // Tweaked to use EE types instead of JIT-specific types CORINFO_CLASS_HANDLE typeHandle; DWORD exception; +#if defined(TARGET_LOONGARCH64) + int flags; + CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &flags, &exception)); +#else CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &exception)); +#endif length += strlen(TypeUtils::GetCorInfoTypeName(type)); argList = mc->repGetArgNext(argList); @@ -339,7 +344,12 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL // Tweaked to use EE types instead of JIT-specific types CORINFO_CLASS_HANDLE typeHandle; DWORD exception; +#if defined(TARGET_LOONGARCH64) + int flags; + CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &flags, &exception)); +#else CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &exception)); +#endif strcat_s(retName, length, TypeUtils::GetCorInfoTypeName(type)); argList = mc->repGetArgNext(argList); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index aae223f728562c..46f17128435177 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -51,6 +51,7 @@ LWM(GetAddrOfCaptureThreadGlobal, DWORD, DLDL) LWM(GetArgClass, Agnostic_GetArgClass_Key, Agnostic_GetArgClass_Value) LWM(GetArgNext, DWORDLONG, DWORDLONG) LWM(GetArgType, Agnostic_GetArgType_Key, Agnostic_GetArgType_Value) +LWM(GetFieldTypeByHnd, DWORDLONG, DWORD) LWM(GetArrayInitializationData, DLD, DWORDLONG) LWM(GetArrayRank, DWORDLONG, DWORD) LWM(GetArrayIntrinsicID, DWORDLONG, DWORD) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index ab8717dae42e80..823e4141c55e56 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -2638,6 +2638,9 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, CorInfoTypeWithMod result, +#if defined(TARGET_LOONGARCH64) + int flags, +#endif DWORD exceptionCode) { if (GetArgType == nullptr) @@ -2664,6 +2667,9 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, Agnostic_GetArgType_Value value; value.vcTypeRet = CastHandle(*vcTypeRet); value.result = (DWORD)result; +#if defined(TARGET_LOONGARCH64) + value.flags = flags; +#endif value.exceptionCode = (DWORD)exceptionCode; GetArgType->Add(key, value); @@ -2681,6 +2687,9 @@ void MethodContext::dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agno CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, +#if defined(TARGET_LOONGARCH64) + int *flags, +#endif DWORD* exceptionCode) { AssertMapExists(GetArgType, ": key %016llX %016llX", CastHandle(sig->scope), CastHandle(args)); @@ -2701,6 +2710,10 @@ CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, AssertKeyExists(GetArgType, key, ": key %016llX %016llX", key.scope, key.args); Agnostic_GetArgType_Value value = GetArgType->Get(key); +#if defined(TARGET_LOONGARCH64) + if (flags) + *flags = value.flags; +#endif DEBUG_REP(dmpGetArgType(key, value)); *vcTypeRet = (CORINFO_CLASS_HANDLE)value.vcTypeRet; @@ -2709,6 +2722,27 @@ CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, return temp; } +void MethodContext::recGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls, DWORD value) +{ + if (GetFieldTypeByHnd == nullptr) + GetFieldTypeByHnd = new LightWeightMap(); + + DWORDLONG key = (DWORDLONG)cls; + + GetFieldTypeByHnd->Add((DWORDLONG)cls, value); + //DEBUG_REC(dmpGetArgType(key, value)); +} + +void MethodContext::dmpGetFieldTypeByHnd(DWORDLONG key, DWORD value) +{ + printf("GetFieldTypeByHnd key %08X value-%X", key, value); +} + +DWORD MethodContext::repGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + return GetFieldTypeByHnd->Get((DWORDLONG)cls); +} + void MethodContext::recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result) { if (GetArgNext == nullptr) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index d18c531dd86483..0bb6981426f8f2 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -362,13 +362,23 @@ class MethodContext CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, CorInfoTypeWithMod result, +#if defined(TARGET_LOONGARCH64) + int flags, +#endif DWORD exception); void dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value); CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, +#if defined(TARGET_LOONGARCH64) + int *flags, +#endif DWORD* exception); + void recGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls, DWORD value); + void dmpGetFieldTypeByHnd(DWORDLONG key, DWORD value); + DWORD repGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls); + void recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result); void dmpGetArgNext(DWORDLONG key, DWORDLONG value); CORINFO_ARG_LIST_HANDLE repGetArgNext(CORINFO_ARG_LIST_HANDLE args); @@ -1097,6 +1107,7 @@ enum mcPackets Packet_GetAssemblyName = 191, Packet_IsIntrinsic = 192, Packet_UpdateEntryPointForTailCall = 193, + Packet_GetFieldTypeByHnd = 194, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index ad4830fa73b1ab..720fa225cdf876 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1186,6 +1186,9 @@ CORINFO_ARG_LIST_HANDLE interceptor_ICJI::getArgNext(CORINFO_ARG_LIST_HANDLE arg CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE* vcTypeRet /* OUT */ +#if defined(TARGET_LOONGARCH64) + ,int *flags +#endif ) { CorInfoTypeWithMod temp = (CorInfoTypeWithMod)CORINFO_TYPE_UNDEF; @@ -1195,7 +1198,11 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, { mc->cr->AddCall("getArgType"); temp = +#if defined(TARGET_LOONGARCH64) + original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); +#else original_ICorJitInfo->getArgType(sig, args, vcTypeRet); +#endif #ifdef fatMC CORINFO_CLASS_HANDLE temp3 = getArgClass(sig, args); @@ -1203,7 +1210,30 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, }, [&](DWORD exceptionCode) { + +#if defined(TARGET_LOONGARCH64) + this->mc->recGetArgType(sig, args, vcTypeRet, temp, flags ? *flags : 0, exceptionCode); +#else this->mc->recGetArgType(sig, args, vcTypeRet, temp, exceptionCode); +#endif + }); + + return temp; +} + +uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + + uint32_t temp = 0; + RunWithErrorExceptionCodeCaptureAndContinue( + [&]() + { + mc->cr->AddCall("getFieldTypeByHnd"); + temp = original_ICorJitInfo->getFieldTypeByHnd(cls); + }, + [&](DWORD exceptionCode) + { + this->mc->recGetFieldTypeByHnd(cls, temp); }); return temp; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 88e0e03e42d989..1fe4ea0296e81d 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -808,10 +808,24 @@ CORINFO_ARG_LIST_HANDLE interceptor_ICJI::getArgNext( CorInfoTypeWithMod interceptor_ICJI::getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet) + CORINFO_CLASS_HANDLE* vcTypeRet +#if defined(TARGET_LOONGARCH64) + ,int *flags +#endif + ) { mcs->AddCall("getArgType"); +#if defined(TARGET_LOONGARCH64) + return original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); +#else return original_ICorJitInfo->getArgType(sig, args, vcTypeRet); +#endif +} + +uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + mcs->AddCall("getFieldTypeByHnd"); + return original_ICorJitInfo->getFieldTypeByHnd(cls); } CORINFO_CLASS_HANDLE interceptor_ICJI::getArgClass( diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 16926858871788..c0864eac617441 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -708,9 +708,23 @@ CORINFO_ARG_LIST_HANDLE interceptor_ICJI::getArgNext( CorInfoTypeWithMod interceptor_ICJI::getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet) + CORINFO_CLASS_HANDLE* vcTypeRet +#if defined(TARGET_LOONGARCH64) + ,int *flags +#endif + ) { + +#if defined(TARGET_LOONGARCH64) + return original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); +#else return original_ICorJitInfo->getArgType(sig, args, vcTypeRet); +#endif +} + +uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + return original_ICorJitInfo->getFieldTypeByHnd(cls); } CORINFO_CLASS_HANDLE interceptor_ICJI::getArgClass( diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index e633a1ab385af8..a502eacdb5f401 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1050,16 +1050,29 @@ CORINFO_ARG_LIST_HANDLE MyICJI::getArgNext(CORINFO_ARG_LIST_HANDLE args /* IN */ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE* vcTypeRet /* OUT */ +#if defined(TARGET_LOONGARCH64) + ,int *flags +#endif ) { DWORD exceptionCode = 0; jitInstance->mc->cr->AddCall("getArgType"); +#if defined(TARGET_LOONGARCH64) + CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, flags, &exceptionCode); +#else CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, &exceptionCode); +#endif if (exceptionCode != 0) ThrowException(exceptionCode); return value; } +uint32_t MyICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + jitInstance->mc->cr->AddCall("getFieldTypeByHnd"); + return 0;//jitInstance->mc->repGetFieldTypeByHnd(cls); +} + // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it CORINFO_CLASS_HANDLE MyICJI::getArgClass(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args /* IN */ diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 602bfc74c1a684..f45cc1d9f23492 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -417,7 +417,13 @@ CORINFO_ARG_LIST_HANDLE getArgNext( CorInfoTypeWithMod getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet) override; + CORINFO_CLASS_HANDLE* vcTypeRet +#if defined(TARGET_LOONGARCH64) + ,int *flags = NULL +#endif +) override; + + uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) override; CORINFO_CLASS_HANDLE getArgClass( CORINFO_SIG_INFO* sig, diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index df4e985fda1e6a..5bf4d315d48b34 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9293,6 +9293,9 @@ CorInfoTypeWithMod CEEInfo::getArgType ( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet +#if defined(TARGET_LOONGARCH64) + ,int *flags +#endif ) { CONTRACTL { @@ -9346,6 +9349,12 @@ CorInfoTypeWithMod CEEInfo::getArgType ( { type = normType; } +#if defined(TARGET_LOONGARCH64) + if ((flags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) + { + *flags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); + } +#endif } break; @@ -9384,6 +9393,422 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } +//Only used for LoongArch64-ABI. +uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + JIT_TO_EE_TRANSITION_LEAF(); + + TypeHandle th(cls); + + DWORD size = 0; + bool useNativeLayout = false; + MethodTable* methodTablePtr = nullptr; + + if (!th.IsTypeDesc()) + { + methodTablePtr = th.AsMethodTable(); + if (methodTablePtr->HasLayout()) + useNativeLayout = true; + else if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) + { + DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); + + if (numIntroducedFields == 1) + { + FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + + CorElementType fieldType = pFieldStart[0].GetFieldType(); + + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) + size = 1; + } + } + else if (numIntroducedFields == 2) + { + FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + + CorElementType fieldType = pFieldStart[0].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = 2; + else if (fieldType == ELEMENT_TYPE_R8) + size = 0x12; + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + } + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + fieldType = pFieldStart[1].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + goto _End_arg; + } + } + else + { + _ASSERTE(th.IsNativeValueType()); + + useNativeLayout = true; + methodTablePtr = th.AsNativeValueType(); + } + _ASSERTE(methodTablePtr != nullptr); + + if (useNativeLayout) + { + if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) + { + //MethodTable* methodTablePtr = th.AsMethodTable(); + //assert(methodTablePtr->GetNumInstanceFieldBytes() <= 16 /*MAX_PASS_MULTIREG_BYTES*/); + + DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); + FieldDesc *pFieldStart = nullptr; + + if (numIntroducedFields == 1) + { + pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + +_fields_1: + CorElementType fieldType = pFieldStart[0].GetFieldType(); + + bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) + || fieldType == ELEMENT_TYPE_VALUETYPE) + && (pFieldStart->GetOffset() == 0) + && methodTablePtr->HasLayout() + && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + + if (isFixedBuffer) + { + numIntroducedFields = methodTablePtr->GetNumInstanceFieldBytes() / pFieldStart->GetSize(); + if (numIntroducedFields > 2) + goto _End_arg; + if (fieldType == ELEMENT_TYPE_R4) + { + if (numIntroducedFields == 1) + size = 1; + else if (numIntroducedFields == 2) + size = 8; + goto _End_arg; + } + else if (fieldType == ELEMENT_TYPE_R8) + { + if (numIntroducedFields == 1) + size = 1; + else if (numIntroducedFields == 2) + size = 0x38; + goto _End_arg; + } + } + + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) + size = 1; + } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); + //if ((size == 1) && (methodTablePtr->GetNumInstanceFieldBytes() > 8)) + // size = 0; + return size; + } + else + { + if (pNativeFieldDescs->GetNumElements() == 1) + { + pFieldStart = pNativeFieldDescs->GetFieldDesc(); + goto _fields_1; + } + else if (pNativeFieldDescs->GetNumElements() == 2) + { + pFieldStart = pNativeFieldDescs->GetFieldDesc(); + goto _fields_2; + } + //CorElementType fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); + //if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) + // size = 1; + } + } + //else + //{ + // assert(!"------------should amend for LOONGARCH64!!!"); + // //goto _End_arg; + //} + } + else if (numIntroducedFields == 2) + { + pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + +_fields_2: + 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 = 2; + else if (fieldType == ELEMENT_TYPE_R8) + size = 0x12; + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + fieldType = pFieldStart[1].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = size & 0x2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 0x2 ? (size ^ 0x2a) : (size | 0x24); + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + goto _End_arg; + } + } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + + //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) + // || fieldType == ELEMENT_TYPE_VALUETYPE) + // && (pFieldStart->GetOffset() == 0) + // && methodTablePtr->HasLayout() + // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); + + if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) + goto _End_arg; + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + else + size = 0; + //else if (methodTablePtr2->GetNumIntroducedInstanceFields() != 1) + // goto _End_arg; + } + else + { + MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) + { + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + else + size = 0; + } + else + goto _End_arg; + } + } + else if (fieldType == ELEMENT_TYPE_CLASS) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + + //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) + // || fieldType == ELEMENT_TYPE_VALUETYPE) + // && (pFieldStart->GetOffset() == 0) + // && methodTablePtr->HasLayout() + // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + + if (pNativeFieldDescs->NativeSize() > 8) + goto _End_arg; + + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); + //MethodTable* methodTablePtr2 = ((FieldMarshaler_NestedValueClass*)pFieldMarshalers)->GetMethodTable(); + + if (methodTablePtr2->GetNumInstanceFieldBytes() > 8) + goto _End_arg; + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + } + else + { + MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) + { + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + else + size = 0; + } + else + goto _End_arg; + } + //else + //{ + // assert(!"------------should amend for LOONGARCH64!!!"); + // goto _End_arg; + //} + } + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + fieldType = pFieldStart[1].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + else if ((fieldType == ELEMENT_TYPE_VALUETYPE) || (fieldType == ELEMENT_TYPE_CLASS)) + { + MethodTable* methodTablePtr2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); + if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) + { + size = 0; + goto _End_arg; + } + if (methodTablePtr2->HasLayout()) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr2->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + + if (pNativeFieldDescs->NativeSize() > 8) + { + size = 0; + goto _End_arg; + } + + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + methodTablePtr = pNativeFieldDescs->GetNestedNativeMethodTable(); + + if (methodTablePtr->GetNumIntroducedInstanceFields() > 1) + { + size = 0; + goto _End_arg; + } + + if (getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr) == 1) + { + if (methodTablePtr->GetNumInstanceFieldBytes() == 4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (methodTablePtr->GetNumInstanceFieldBytes() == 8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + } + else if (methodTablePtr->GetNumInstanceFieldBytes() == 8)//pFieldStart[1].GetSize() + size |= 0x20; + else + { + size = 0; + } + } + else + { + if (pNativeFieldDescs->GetNumElements() == 1) + { + fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); + if (fieldType == ELEMENT_TYPE_R4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + else if (pNativeFieldDescs->NativeSize() == 8) + size |= 0x20; + } + else + { + size = 0; + //goto _End_arg; + } + } + //else + //{ + // assert(!"------------should amend for LOONGARCH64!!!"); + // goto _End_arg; + //} + } + else + { + size |= getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (!(size & 0xf)) + size = 0; + else + assert(!"------------should amend for LOONGARCH64!!!"); + } + } + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + } + } +_End_arg: + + EE_TO_JIT_TRANSITION_LEAF(); + + return size; +} + /*********************************************************************/ CORINFO_CLASS_HANDLE CEEInfo::getArgClass ( @@ -10919,6 +11344,12 @@ void reservePersonalityRoutineSpace(uint32_t &unwindSize) // The JIT passes in a 4-byte aligned block of unwind data. _ASSERTE(IS_ALIGNED(unwindSize, sizeof(ULONG))); + // Add space for personality routine, it must be 4-byte aligned. + unwindSize += sizeof(ULONG); +#elif defined(TARGET_LOONGARCH64) + // The JIT passes in a 4-byte aligned block of unwind data. + _ASSERTE(IS_ALIGNED(unwindSize, sizeof(ULONG))); + // Add space for personality routine, it must be 4-byte aligned. unwindSize += sizeof(ULONG); #else @@ -11136,6 +11567,13 @@ void CEEJitInfo::allocUnwindInfo ( ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG))); *pPersonalityRoutineRW = (TADDR)ProcessCLRException - baseAddress; +#elif defined(TARGET_LOONGARCH64) + + *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit + + ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG))); + *pPersonalityRoutineRW = ExecutionManager::GetCLRPersonalityRoutineValue(); + #endif EE_TO_JIT_TRANSITION(); From 42667b380e08dbf2649163289666064d603228dd Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 17 Dec 2021 10:55:43 +0800 Subject: [PATCH 02/18] [LoongArch64] add new interace for getting ABI-info. (#59561) --- .../superpmi-shared/methodcontext.cpp | 81 ++++++++++++-- .../superpmi/superpmi-shared/methodcontext.h | 13 ++- .../superpmi-shim-collector/icorjitinfo.cpp | 37 ++++-- .../superpmi-shim-counter/icorjitinfo.cpp | 20 ++-- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 23 ++-- src/coreclr/inc/icorjitinfoimpl_generated.h | 6 +- .../ThunkGenerator/ThunkInput.txt | 2 + src/coreclr/vm/jitinterface.cpp | 105 +++++++++++++++++- 8 files changed, 235 insertions(+), 52 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 823e4141c55e56..5ee5c6a5b8ff71 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -2638,9 +2638,6 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, CorInfoTypeWithMod result, -#if defined(TARGET_LOONGARCH64) - int flags, -#endif DWORD exceptionCode) { if (GetArgType == nullptr) @@ -2667,14 +2664,50 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, Agnostic_GetArgType_Value value; value.vcTypeRet = CastHandle(*vcTypeRet); value.result = (DWORD)result; -#if defined(TARGET_LOONGARCH64) + value.exceptionCode = (DWORD)exceptionCode; + + GetArgType->Add(key, value); + DEBUG_REC(dmpGetArgType(key, value)); +} + +void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + CorInfoTypeWithMod result, + int flags, + DWORD exceptionCode) +{ + if (GetArgType == nullptr) + GetArgType = new LightWeightMap(); + + Agnostic_GetArgType_Key key; + ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding + + // Only setting values for CORINFO_SIG_INFO things the EE seems to pay attention to... this is necessary since some of the values + // are unset and fail our precise comparisons ... + // TODO: verify that the above comment is still true (that some of the fields of incoming argument `sig` contain garbage), or + // can we store the whole thing and use StoreAgnostic_CORINFO_SIG_INFO()? + + key.flags = (DWORD)sig->flags; + key.numArgs = (DWORD)sig->numArgs; + + SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap, &key.sigInst_classInstCount, &key.sigInst_classInst_Index); + SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap, &key.sigInst_methInstCount, &key.sigInst_methInst_Index); + + key.methodSignature = CastPointer(sig->methodSignature); + key.scope = CastHandle(sig->scope); + key.args = CastHandle(args); + + Agnostic_GetArgType_Value value; + value.vcTypeRet = CastHandle(*vcTypeRet); + value.result = (DWORD)result; value.flags = flags; -#endif value.exceptionCode = (DWORD)exceptionCode; GetArgType->Add(key, value); DEBUG_REC(dmpGetArgType(key, 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", @@ -2684,12 +2717,10 @@ void MethodContext::dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agno 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); } + CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, -#if defined(TARGET_LOONGARCH64) - int *flags, -#endif DWORD* exceptionCode) { AssertMapExists(GetArgType, ": key %016llX %016llX", CastHandle(sig->scope), CastHandle(args)); @@ -2710,10 +2741,40 @@ CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, AssertKeyExists(GetArgType, key, ": key %016llX %016llX", key.scope, key.args); Agnostic_GetArgType_Value value = GetArgType->Get(key); -#if defined(TARGET_LOONGARCH64) + DEBUG_REP(dmpGetArgType(key, value)); + + *vcTypeRet = (CORINFO_CLASS_HANDLE)value.vcTypeRet; + CorInfoTypeWithMod temp = (CorInfoTypeWithMod)value.result; + *exceptionCode = (DWORD)value.exceptionCode; + return temp; +} + +CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int* flags, + DWORD* exceptionCode) +{ + AssertMapExists(GetArgType, ": key %016llX %016llX", CastHandle(sig->scope), CastHandle(args)); + + Agnostic_GetArgType_Key key; + ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding + key.flags = (DWORD)sig->flags; + key.numArgs = (DWORD)sig->numArgs; + key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; + key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; + key.methodSignature = CastPointer(sig->methodSignature); + key.scope = CastHandle(sig->scope); + key.args = CastHandle(args); + + key.sigInst_classInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap); + key.sigInst_methInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap); + + AssertKeyExists(GetArgType, key, ": key %016llX %016llX", key.scope, key.args); + + Agnostic_GetArgType_Value value = GetArgType->Get(key); if (flags) *flags = value.flags; -#endif DEBUG_REP(dmpGetArgType(key, value)); *vcTypeRet = (CORINFO_CLASS_HANDLE)value.vcTypeRet; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 0bb6981426f8f2..92758f0290d40e 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -362,17 +362,22 @@ class MethodContext CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, CorInfoTypeWithMod result, -#if defined(TARGET_LOONGARCH64) + DWORD exception); + void recGetArgType(CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + CorInfoTypeWithMod result, int flags, -#endif DWORD exception); void dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value); CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, -#if defined(TARGET_LOONGARCH64) + DWORD* exception); + CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, int *flags, -#endif DWORD* exception); void recGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls, DWORD value); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 720fa225cdf876..53d656c51ce9ec 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1186,9 +1186,6 @@ CORINFO_ARG_LIST_HANDLE interceptor_ICJI::getArgNext(CORINFO_ARG_LIST_HANDLE arg CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE* vcTypeRet /* OUT */ -#if defined(TARGET_LOONGARCH64) - ,int *flags -#endif ) { CorInfoTypeWithMod temp = (CorInfoTypeWithMod)CORINFO_TYPE_UNDEF; @@ -1198,11 +1195,7 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, { mc->cr->AddCall("getArgType"); temp = -#if defined(TARGET_LOONGARCH64) - original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); -#else original_ICorJitInfo->getArgType(sig, args, vcTypeRet); -#endif #ifdef fatMC CORINFO_CLASS_HANDLE temp3 = getArgClass(sig, args); @@ -1211,11 +1204,35 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, [&](DWORD exceptionCode) { -#if defined(TARGET_LOONGARCH64) - this->mc->recGetArgType(sig, args, vcTypeRet, temp, flags ? *flags : 0, exceptionCode); -#else this->mc->recGetArgType(sig, args, vcTypeRet, temp, exceptionCode); + }); + + return temp; +} + +CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ + CORINFO_ARG_LIST_HANDLE args, /* IN */ + CORINFO_CLASS_HANDLE* vcTypeRet, /* OUT */ + int* flags /* OUT */ + ) +{ + CorInfoTypeWithMod temp = (CorInfoTypeWithMod)CORINFO_TYPE_UNDEF; + + RunWithErrorExceptionCodeCaptureAndContinue( + [&]() + { + mc->cr->AddCall("getArgType"); + temp = + original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); + +#ifdef fatMC + CORINFO_CLASS_HANDLE temp3 = getArgClass(sig, args); #endif + }, + [&](DWORD exceptionCode) + { + + this->mc->recGetArgType(sig, args, vcTypeRet, temp, flags ? *flags : 0, exceptionCode); }); return temp; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 1fe4ea0296e81d..0ee5969e28bea4 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -808,18 +808,20 @@ CORINFO_ARG_LIST_HANDLE interceptor_ICJI::getArgNext( CorInfoTypeWithMod interceptor_ICJI::getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet -#if defined(TARGET_LOONGARCH64) - ,int *flags -#endif - ) + CORINFO_CLASS_HANDLE* vcTypeRet) { mcs->AddCall("getArgType"); -#if defined(TARGET_LOONGARCH64) - return original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); -#else return original_ICorJitInfo->getArgType(sig, args, vcTypeRet); -#endif +} + +CorInfoTypeWithMod interceptor_ICJI::getArgType( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int *flags) +{ + mcs->AddCall("getArgType"); + return original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); } uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index a502eacdb5f401..4a3e076b4ef21c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1050,18 +1050,25 @@ CORINFO_ARG_LIST_HANDLE MyICJI::getArgNext(CORINFO_ARG_LIST_HANDLE args /* IN */ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE* vcTypeRet /* OUT */ -#if defined(TARGET_LOONGARCH64) - ,int *flags -#endif ) { DWORD exceptionCode = 0; jitInstance->mc->cr->AddCall("getArgType"); -#if defined(TARGET_LOONGARCH64) - CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, flags, &exceptionCode); -#else CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, &exceptionCode); -#endif + if (exceptionCode != 0) + ThrowException(exceptionCode); + return value; +} + +CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ + CORINFO_ARG_LIST_HANDLE args, /* IN */ + CORINFO_CLASS_HANDLE* vcTypeRet,/* OUT */ + int* flags /* OUT */ + ) +{ + DWORD exceptionCode = 0; + jitInstance->mc->cr->AddCall("getArgType"); + CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, flags, &exceptionCode); if (exceptionCode != 0) ThrowException(exceptionCode); return value; @@ -1070,7 +1077,7 @@ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ uint32_t MyICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) { jitInstance->mc->cr->AddCall("getFieldTypeByHnd"); - return 0;//jitInstance->mc->repGetFieldTypeByHnd(cls); + return jitInstance->mc->repGetFieldTypeByHnd(cls); } // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index f45cc1d9f23492..1184bf8ac6b280 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -418,13 +418,9 @@ CorInfoTypeWithMod getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet -#if defined(TARGET_LOONGARCH64) - ,int *flags = NULL -#endif + int *flags = NULL ) override; - uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) override; - CORINFO_CLASS_HANDLE getArgClass( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args) override; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index dbe775e1e0246e..bacd14b4af448f 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -254,6 +254,8 @@ FUNCTIONS void freeArray(void*array); CORINFO_ARG_LIST_HANDLE getArgNext(CORINFO_ARG_LIST_HANDLE args); CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet); + CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int *flags); + uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls); CORINFO_CLASS_HANDLE getArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args); CorInfoHFAElemType getHFAType(CORINFO_CLASS_HANDLE hClass); JITINTERFACE_HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5bf4d315d48b34..aea2ca662af29e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9293,9 +9293,6 @@ CorInfoTypeWithMod CEEInfo::getArgType ( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet -#if defined(TARGET_LOONGARCH64) - ,int *flags -#endif ) { CONTRACTL { @@ -9349,12 +9346,106 @@ CorInfoTypeWithMod CEEInfo::getArgType ( { type = normType; } -#if defined(TARGET_LOONGARCH64) + } + break; + + case ELEMENT_TYPE_PTR: + // Load the type eagerly under debugger to make the eval work + if (!isVerifyOnly() && CORDisableJITOptimizations(pModule->GetDebuggerInfoBits())) + { + // NOTE: in some IJW cases, when the type pointed at is unmanaged, + // the GetTypeHandle may fail, because there is no TypeDef for such type. + // Usage of GetTypeHandleThrowing would lead to class load exception + TypeHandle thPtr = ptr.GetTypeHandleNT(pModule, &typeContext); + if(!thPtr.IsNull()) + { + m_pOverride->classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE(thPtr.AsPtr())); + } + } + break; + + case ELEMENT_TYPE_VOID: + // void is not valid in local sigs + if (sig->flags & CORINFO_SIGFLAG_IS_LOCAL_SIG) + COMPlusThrowHR(COR_E_INVALIDPROGRAM); + break; + + case ELEMENT_TYPE_END: + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + break; + + default: + break; + } + + result = CorInfoTypeWithMod(result | CEEInfo::asCorInfoType(type, typeHnd, vcTypeRet)); + EE_TO_JIT_TRANSITION(); + + return result; +} + +CorInfoTypeWithMod CEEInfo::getArgType ( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int *flags + ) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + CorInfoTypeWithMod result = CorInfoTypeWithMod(CORINFO_TYPE_UNDEF); + + JIT_TO_EE_TRANSITION(); + + _ASSERTE((BYTE*) sig->pSig <= (BYTE*) sig->args && (BYTE*) args < (BYTE*) sig->pSig + sig->cbSig); + _ASSERTE((BYTE*) sig->args <= (BYTE*) args); + INDEBUG(*vcTypeRet = CORINFO_CLASS_HANDLE((size_t)INVALID_POINTER_CC)); + + SigPointer ptr((unsigned __int8*) args); + CorElementType eType; + IfFailThrow(ptr.PeekElemType(&eType)); + while (eType == ELEMENT_TYPE_PINNED) + { + result = CORINFO_TYPE_MOD_PINNED; + IfFailThrow(ptr.GetElemType(NULL)); + IfFailThrow(ptr.PeekElemType(&eType)); + } + + // Now read off the "real" element type after taking any instantiations into consideration + SigTypeContext typeContext; + GetTypeContext(&sig->sigInst,&typeContext); + + Module* pModule = GetModule(sig->scope); + + CorElementType type = ptr.PeekElemTypeClosed(pModule, &typeContext); + + TypeHandle typeHnd = TypeHandle(); + switch (type) { + case ELEMENT_TYPE_VAR : + case ELEMENT_TYPE_MVAR : + case ELEMENT_TYPE_VALUETYPE : + case ELEMENT_TYPE_TYPEDBYREF : + case ELEMENT_TYPE_INTERNAL : + { + typeHnd = ptr.GetTypeHandleThrowing(pModule, &typeContext); + _ASSERTE(!typeHnd.IsNull()); + + CorElementType normType = typeHnd.GetInternalCorElementType(); + + // if we are looking up a value class, don't morph it to a refernece type + // (This can only happen in illegal IL) + if (!CorTypeInfo::IsObjRef(normType) || type != ELEMENT_TYPE_VALUETYPE) + { + type = normType; + } if ((flags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) { *flags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); } -#endif } break; @@ -9393,7 +9484,9 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } -//Only used for LoongArch64-ABI. +// Although this is only used for LoongArch64-ABI now, +// maybe it can be used for other architecture for getting ABI-info +// between JIT/EE if the ABI is similar. uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) { CONTRACTL { From 7e518a8549e0a0c06cb94691b4eb221498bf5faa Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 17 Dec 2021 15:25:09 +0800 Subject: [PATCH 03/18] [LoongArch64] add the linking page for LoongArch64 ABI-info. (#59561) --- docs/design/coreclr/botr/clr-abi.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/design/coreclr/botr/clr-abi.md b/docs/design/coreclr/botr/clr-abi.md index f7b01352de9224..80baca72ea3780 100644 --- a/docs/design/coreclr/botr/clr-abi.md +++ b/docs/design/coreclr/botr/clr-abi.md @@ -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 LoongArch64 ABI documentation is [here](https://github.com/loongson/LoongArch-Documentation/blob/main/docs/LoongArch-ELF-ABI-EN.adoc) + # 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). From db97aa752397f6100f63d26efff81f5006b5359b Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Mon, 20 Dec 2021 09:34:47 +0800 Subject: [PATCH 04/18] [LoongArch64] moved ThunkInput.txt to #62885. --- .../tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index bacd14b4af448f..dbe775e1e0246e 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -254,8 +254,6 @@ FUNCTIONS void freeArray(void*array); CORINFO_ARG_LIST_HANDLE getArgNext(CORINFO_ARG_LIST_HANDLE args); CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet); - CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int *flags); - uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls); CORINFO_CLASS_HANDLE getArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args); CorInfoHFAElemType getHFAType(CORINFO_CLASS_HANDLE hClass); JITINTERFACE_HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers); From 4e3eeb2b20ceb31805453313e97c58dfb81558bf Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Mon, 20 Dec 2021 10:25:20 +0800 Subject: [PATCH 05/18] [LoongArch64] moved vm/jitinterface.cpp to #62885. --- src/coreclr/vm/jitinterface.cpp | 531 -------------------------------- 1 file changed, 531 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index aea2ca662af29e..df4e985fda1e6a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9384,524 +9384,6 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } -CorInfoTypeWithMod CEEInfo::getArgType ( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int *flags - ) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - CorInfoTypeWithMod result = CorInfoTypeWithMod(CORINFO_TYPE_UNDEF); - - JIT_TO_EE_TRANSITION(); - - _ASSERTE((BYTE*) sig->pSig <= (BYTE*) sig->args && (BYTE*) args < (BYTE*) sig->pSig + sig->cbSig); - _ASSERTE((BYTE*) sig->args <= (BYTE*) args); - INDEBUG(*vcTypeRet = CORINFO_CLASS_HANDLE((size_t)INVALID_POINTER_CC)); - - SigPointer ptr((unsigned __int8*) args); - CorElementType eType; - IfFailThrow(ptr.PeekElemType(&eType)); - while (eType == ELEMENT_TYPE_PINNED) - { - result = CORINFO_TYPE_MOD_PINNED; - IfFailThrow(ptr.GetElemType(NULL)); - IfFailThrow(ptr.PeekElemType(&eType)); - } - - // Now read off the "real" element type after taking any instantiations into consideration - SigTypeContext typeContext; - GetTypeContext(&sig->sigInst,&typeContext); - - Module* pModule = GetModule(sig->scope); - - CorElementType type = ptr.PeekElemTypeClosed(pModule, &typeContext); - - TypeHandle typeHnd = TypeHandle(); - switch (type) { - case ELEMENT_TYPE_VAR : - case ELEMENT_TYPE_MVAR : - case ELEMENT_TYPE_VALUETYPE : - case ELEMENT_TYPE_TYPEDBYREF : - case ELEMENT_TYPE_INTERNAL : - { - typeHnd = ptr.GetTypeHandleThrowing(pModule, &typeContext); - _ASSERTE(!typeHnd.IsNull()); - - CorElementType normType = typeHnd.GetInternalCorElementType(); - - // if we are looking up a value class, don't morph it to a refernece type - // (This can only happen in illegal IL) - if (!CorTypeInfo::IsObjRef(normType) || type != ELEMENT_TYPE_VALUETYPE) - { - type = normType; - } - if ((flags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) - { - *flags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); - } - } - break; - - case ELEMENT_TYPE_PTR: - // Load the type eagerly under debugger to make the eval work - if (!isVerifyOnly() && CORDisableJITOptimizations(pModule->GetDebuggerInfoBits())) - { - // NOTE: in some IJW cases, when the type pointed at is unmanaged, - // the GetTypeHandle may fail, because there is no TypeDef for such type. - // Usage of GetTypeHandleThrowing would lead to class load exception - TypeHandle thPtr = ptr.GetTypeHandleNT(pModule, &typeContext); - if(!thPtr.IsNull()) - { - m_pOverride->classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE(thPtr.AsPtr())); - } - } - break; - - case ELEMENT_TYPE_VOID: - // void is not valid in local sigs - if (sig->flags & CORINFO_SIGFLAG_IS_LOCAL_SIG) - COMPlusThrowHR(COR_E_INVALIDPROGRAM); - break; - - case ELEMENT_TYPE_END: - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - break; - - default: - break; - } - - result = CorInfoTypeWithMod(result | CEEInfo::asCorInfoType(type, typeHnd, vcTypeRet)); - EE_TO_JIT_TRANSITION(); - - return result; -} - -// Although this is only used for LoongArch64-ABI now, -// maybe it can be used for other architecture for getting ABI-info -// between JIT/EE if the ABI is similar. -uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - JIT_TO_EE_TRANSITION_LEAF(); - - TypeHandle th(cls); - - DWORD size = 0; - bool useNativeLayout = false; - MethodTable* methodTablePtr = nullptr; - - if (!th.IsTypeDesc()) - { - methodTablePtr = th.AsMethodTable(); - if (methodTablePtr->HasLayout()) - useNativeLayout = true; - else if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) - { - DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); - - if (numIntroducedFields == 1) - { - FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); - - CorElementType fieldType = pFieldStart[0].GetFieldType(); - - if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) - { - if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) - size = 1; - } - } - else if (numIntroducedFields == 2) - { - FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); - - CorElementType fieldType = pFieldStart[0].GetFieldType(); - if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) - { - if (fieldType == ELEMENT_TYPE_R4) - size = 2; - else if (fieldType == ELEMENT_TYPE_R8) - size = 0x12; - else if (pFieldStart[0].GetSize() == 8) - size = 0x10; - - } - else if (pFieldStart[0].GetSize() == 8) - size = 0x10; - - fieldType = pFieldStart[1].GetFieldType(); - if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) - { - if (fieldType == ELEMENT_TYPE_R4) - size = size & 2 ? (size ^ 0xa) : (size | 4); - else if (fieldType == ELEMENT_TYPE_R8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); - else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; - } - else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; - } - goto _End_arg; - } - } - else - { - _ASSERTE(th.IsNativeValueType()); - - useNativeLayout = true; - methodTablePtr = th.AsNativeValueType(); - } - _ASSERTE(methodTablePtr != nullptr); - - if (useNativeLayout) - { - if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) - { - //MethodTable* methodTablePtr = th.AsMethodTable(); - //assert(methodTablePtr->GetNumInstanceFieldBytes() <= 16 /*MAX_PASS_MULTIREG_BYTES*/); - - DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); - FieldDesc *pFieldStart = nullptr; - - if (numIntroducedFields == 1) - { - pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); - -_fields_1: - CorElementType fieldType = pFieldStart[0].GetFieldType(); - - bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) - || fieldType == ELEMENT_TYPE_VALUETYPE) - && (pFieldStart->GetOffset() == 0) - && methodTablePtr->HasLayout() - && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); - - if (isFixedBuffer) - { - numIntroducedFields = methodTablePtr->GetNumInstanceFieldBytes() / pFieldStart->GetSize(); - if (numIntroducedFields > 2) - goto _End_arg; - if (fieldType == ELEMENT_TYPE_R4) - { - if (numIntroducedFields == 1) - size = 1; - else if (numIntroducedFields == 2) - size = 8; - goto _End_arg; - } - else if (fieldType == ELEMENT_TYPE_R8) - { - if (numIntroducedFields == 1) - size = 1; - else if (numIntroducedFields == 2) - size = 0x38; - goto _End_arg; - } - } - - if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) - { - if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) - size = 1; - } - else if (fieldType == ELEMENT_TYPE_VALUETYPE) - { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); - if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) - { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); - //if ((size == 1) && (methodTablePtr->GetNumInstanceFieldBytes() > 8)) - // size = 0; - return size; - } - else - { - if (pNativeFieldDescs->GetNumElements() == 1) - { - pFieldStart = pNativeFieldDescs->GetFieldDesc(); - goto _fields_1; - } - else if (pNativeFieldDescs->GetNumElements() == 2) - { - pFieldStart = pNativeFieldDescs->GetFieldDesc(); - goto _fields_2; - } - //CorElementType fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); - //if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) - // size = 1; - } - } - //else - //{ - // assert(!"------------should amend for LOONGARCH64!!!"); - // //goto _End_arg; - //} - } - else if (numIntroducedFields == 2) - { - pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); - -_fields_2: - 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 = 2; - else if (fieldType == ELEMENT_TYPE_R8) - size = 0x12; - else if (pFieldStart[0].GetSize() == 8) - size = 0x10; - - fieldType = pFieldStart[1].GetFieldType(); - if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) - { - if (fieldType == ELEMENT_TYPE_R4) - size = size & 0x2 ? (size ^ 0xa) : (size | 4); - else if (fieldType == ELEMENT_TYPE_R8) - size = size & 0x2 ? (size ^ 0x2a) : (size | 0x24); - else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; - goto _End_arg; - } - } - else if (fieldType == ELEMENT_TYPE_VALUETYPE) - { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); - - //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) - // || fieldType == ELEMENT_TYPE_VALUETYPE) - // && (pFieldStart->GetOffset() == 0) - // && methodTablePtr->HasLayout() - // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); - - if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) - { - MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); - - if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) - goto _End_arg; - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); - if (size == 1) - { - if (pFieldStart[0].GetSize() == 8) - size = 0x12; - else - size = 0x2; - } - else if (pFieldStart[0].GetSize() == 8) - { - size = 0x10; - } - else - size = 0; - //else if (methodTablePtr2->GetNumIntroducedInstanceFields() != 1) - // goto _End_arg; - } - else - { - MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); - if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) - { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); - if (size == 1) - { - if (pFieldStart[0].GetSize() == 8) - size = 0x12; - else - size = 0x2; - } - else if (pFieldStart[0].GetSize() == 8) - { - size = 0x10; - } - else - size = 0; - } - else - goto _End_arg; - } - } - else if (fieldType == ELEMENT_TYPE_CLASS) - { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); - - //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) - // || fieldType == ELEMENT_TYPE_VALUETYPE) - // && (pFieldStart->GetOffset() == 0) - // && methodTablePtr->HasLayout() - // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); - - if (pNativeFieldDescs->NativeSize() > 8) - goto _End_arg; - - if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) - { - MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); - //MethodTable* methodTablePtr2 = ((FieldMarshaler_NestedValueClass*)pFieldMarshalers)->GetMethodTable(); - - if (methodTablePtr2->GetNumInstanceFieldBytes() > 8) - goto _End_arg; - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); - if (size == 1) - { - if (pFieldStart[0].GetSize() == 8) - size = 0x12; - else - size = 0x2; - } - else if (pFieldStart[0].GetSize() == 8) - { - size = 0x10; - } - } - else - { - MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); - if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) - { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); - if (size == 1) - { - if (pFieldStart[0].GetSize() == 8) - size = 0x12; - else - size = 0x2; - } - else if (pFieldStart[0].GetSize() == 8) - { - size = 0x10; - } - else - size = 0; - } - else - goto _End_arg; - } - //else - //{ - // assert(!"------------should amend for LOONGARCH64!!!"); - // goto _End_arg; - //} - } - else if (pFieldStart[0].GetSize() == 8) - size = 0x10; - - fieldType = pFieldStart[1].GetFieldType(); - if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) - { - if (fieldType == ELEMENT_TYPE_R4) - size = size & 2 ? (size ^ 0xa) : (size | 4); - else if (fieldType == ELEMENT_TYPE_R8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); - else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; - } - else if ((fieldType == ELEMENT_TYPE_VALUETYPE) || (fieldType == ELEMENT_TYPE_CLASS)) - { - MethodTable* methodTablePtr2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); - if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) - { - size = 0; - goto _End_arg; - } - if (methodTablePtr2->HasLayout()) - { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr2->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); - - if (pNativeFieldDescs->NativeSize() > 8) - { - size = 0; - goto _End_arg; - } - - if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) - { - methodTablePtr = pNativeFieldDescs->GetNestedNativeMethodTable(); - - if (methodTablePtr->GetNumIntroducedInstanceFields() > 1) - { - size = 0; - goto _End_arg; - } - - if (getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr) == 1) - { - if (methodTablePtr->GetNumInstanceFieldBytes() == 4) - size = size & 2 ? (size ^ 0xa) : (size | 4); - else if (methodTablePtr->GetNumInstanceFieldBytes() == 8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); - } - else if (methodTablePtr->GetNumInstanceFieldBytes() == 8)//pFieldStart[1].GetSize() - size |= 0x20; - else - { - size = 0; - } - } - else - { - if (pNativeFieldDescs->GetNumElements() == 1) - { - fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); - if (fieldType == ELEMENT_TYPE_R4) - size = size & 2 ? (size ^ 0xa) : (size | 4); - else if (fieldType == ELEMENT_TYPE_R8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); - else if (pNativeFieldDescs->NativeSize() == 8) - size |= 0x20; - } - else - { - size = 0; - //goto _End_arg; - } - } - //else - //{ - // assert(!"------------should amend for LOONGARCH64!!!"); - // goto _End_arg; - //} - } - else - { - size |= getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); - if (!(size & 0xf)) - size = 0; - else - assert(!"------------should amend for LOONGARCH64!!!"); - } - } - else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; - } - } - } -_End_arg: - - EE_TO_JIT_TRANSITION_LEAF(); - - return size; -} - /*********************************************************************/ CORINFO_CLASS_HANDLE CEEInfo::getArgClass ( @@ -11437,12 +10919,6 @@ void reservePersonalityRoutineSpace(uint32_t &unwindSize) // The JIT passes in a 4-byte aligned block of unwind data. _ASSERTE(IS_ALIGNED(unwindSize, sizeof(ULONG))); - // Add space for personality routine, it must be 4-byte aligned. - unwindSize += sizeof(ULONG); -#elif defined(TARGET_LOONGARCH64) - // The JIT passes in a 4-byte aligned block of unwind data. - _ASSERTE(IS_ALIGNED(unwindSize, sizeof(ULONG))); - // Add space for personality routine, it must be 4-byte aligned. unwindSize += sizeof(ULONG); #else @@ -11660,13 +11136,6 @@ void CEEJitInfo::allocUnwindInfo ( ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG))); *pPersonalityRoutineRW = (TADDR)ProcessCLRException - baseAddress; -#elif defined(TARGET_LOONGARCH64) - - *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit - - ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG))); - *pPersonalityRoutineRW = ExecutionManager::GetCLRPersonalityRoutineValue(); - #endif EE_TO_JIT_TRANSITION(); From f722a3b0a7092f4ed55ff06800ce7e11eec1823b Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 24 Dec 2021 17:34:47 +0800 Subject: [PATCH 06/18] remove the JIT/EE interface back from #62885.. --- .../superpmi/superpmi-shared/agnostic.h | 4 +- .../superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 2 +- .../superpmi-shim-collector/icorjitinfo.cpp | 6 +- .../superpmi-shim-counter/icorjitinfo.cpp | 33 +- .../superpmi-shim-simple/icorjitinfo.cpp | 31 +- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 4 +- src/coreclr/inc/corinfo.h | 8 + src/coreclr/inc/icorjitinfoimpl_generated.h | 13 +- src/coreclr/jit/ICorJitInfo_API_names.h | 2 + src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 21 + .../tools/Common/JitInterface/CorInfoBase.cs | 34 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 10 + .../ThunkGenerator/ThunkInput.txt | 2 + .../tools/aot/jitinterface/jitinterface.h | 23 + src/coreclr/vm/jitinterface.cpp | 518 ++++++++++++++++++ 16 files changed, 668 insertions(+), 45 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h index 148ca45fb90bc0..949ee26259cbd0 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h @@ -528,10 +528,8 @@ struct Agnostic_GetArgType_Value { DWORDLONG vcTypeRet; DWORD result; -#if defined(TARGET_LOONGARCH64) - int flags; -#endif DWORD exceptionCode; + int flags;//Now only LoongArch64 used. }; // Agnostic_ConfigIntInfo combines as a single key the name diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index 46f17128435177..1174d24a77d010 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -51,7 +51,6 @@ LWM(GetAddrOfCaptureThreadGlobal, DWORD, DLDL) LWM(GetArgClass, Agnostic_GetArgClass_Key, Agnostic_GetArgClass_Value) LWM(GetArgNext, DWORDLONG, DWORDLONG) LWM(GetArgType, Agnostic_GetArgType_Key, Agnostic_GetArgType_Value) -LWM(GetFieldTypeByHnd, DWORDLONG, DWORD) LWM(GetArrayInitializationData, DLD, DWORDLONG) LWM(GetArrayRank, DWORDLONG, DWORD) LWM(GetArrayIntrinsicID, DWORDLONG, DWORD) @@ -160,6 +159,7 @@ LWM(SatisfiesMethodConstraints, DLDL, DWORD) LWM(GetUnmanagedCallConv, MethodOrSigInfoValue, DD) LWM(DoesFieldBelongToClass, DLDL, DWORD) DENSELWM(SigInstHandleMap, DWORDLONG) +LWM(GetFieldTypeByHnd, DWORDLONG, DWORD) #undef LWM #undef DENSELWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 5ee5c6a5b8ff71..c79b738626381e 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -2796,7 +2796,7 @@ void MethodContext::recGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls, DWORD value) void MethodContext::dmpGetFieldTypeByHnd(DWORDLONG key, DWORD value) { - printf("GetFieldTypeByHnd key %08X value-%X", key, value); + printf("GetFieldTypeByHnd key %016llX value-%08X", key, value); } DWORD MethodContext::repGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 53d656c51ce9ec..4063605fee65bf 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1210,7 +1210,7 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, return temp; } -CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ +CorInfoTypeWithMod interceptor_ICJI::getArgType2(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE* vcTypeRet, /* OUT */ int* flags /* OUT */ @@ -1221,9 +1221,9 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, RunWithErrorExceptionCodeCaptureAndContinue( [&]() { - mc->cr->AddCall("getArgType"); + mc->cr->AddCall("getArgType2"); temp = - original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); + original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, flags); #ifdef fatMC CORINFO_CLASS_HANDLE temp3 = getArgClass(sig, args); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 0ee5969e28bea4..26af3d0fb108f8 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -814,22 +814,6 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType( return original_ICorJitInfo->getArgType(sig, args, vcTypeRet); } -CorInfoTypeWithMod interceptor_ICJI::getArgType( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int *flags) -{ - mcs->AddCall("getArgType"); - return original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); -} - -uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) -{ - mcs->AddCall("getFieldTypeByHnd"); - return original_ICorJitInfo->getFieldTypeByHnd(cls); -} - CORINFO_CLASS_HANDLE interceptor_ICJI::getArgClass( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args) @@ -1413,3 +1397,20 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } +CorInfoTypeWithMod interceptor_ICJI::getArgType2( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int* flags) +{ + mcs->AddCall("getArgType2"); + return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, flags); +} + +uint32_t interceptor_ICJI::getFieldTypeByHnd( + CORINFO_CLASS_HANDLE cls) +{ + mcs->AddCall("getFieldTypeByHnd"); + return original_ICorJitInfo->getFieldTypeByHnd(cls); +} + diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index c0864eac617441..ea403ea97cd0b8 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -708,23 +708,9 @@ CORINFO_ARG_LIST_HANDLE interceptor_ICJI::getArgNext( CorInfoTypeWithMod interceptor_ICJI::getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet -#if defined(TARGET_LOONGARCH64) - ,int *flags -#endif - ) + CORINFO_CLASS_HANDLE* vcTypeRet) { - -#if defined(TARGET_LOONGARCH64) - return original_ICorJitInfo->getArgType(sig, args, vcTypeRet, flags); -#else return original_ICorJitInfo->getArgType(sig, args, vcTypeRet); -#endif -} - -uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) -{ - return original_ICorJitInfo->getFieldTypeByHnd(cls); } CORINFO_CLASS_HANDLE interceptor_ICJI::getArgClass( @@ -1238,3 +1224,18 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } +CorInfoTypeWithMod interceptor_ICJI::getArgType2( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int* flags) +{ + return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, flags); +} + +uint32_t interceptor_ICJI::getFieldTypeByHnd( + CORINFO_CLASS_HANDLE cls) +{ + return original_ICorJitInfo->getFieldTypeByHnd(cls); +} + diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 4a3e076b4ef21c..3a7d508ab22716 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1060,14 +1060,14 @@ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ return value; } -CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ +CorInfoTypeWithMod MyICJI::getArgType2(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE* vcTypeRet,/* OUT */ int* flags /* OUT */ ) { DWORD exceptionCode = 0; - jitInstance->mc->cr->AddCall("getArgType"); + jitInstance->mc->cr->AddCall("getArgType2"); CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, flags, &exceptionCode); if (exceptionCode != 0) ThrowException(exceptionCode); diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index f6f341e56f32a6..ea9854d94b6a85 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2714,6 +2714,13 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */ ) = 0; + virtual CorInfoTypeWithMod getArgType2 ( + CORINFO_SIG_INFO* sig, /* IN */ + CORINFO_ARG_LIST_HANDLE args, /* IN */ + CORINFO_CLASS_HANDLE *vcTypeRet, /* OUT */ + int *flags = NULL + ) = 0; + // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it virtual CORINFO_CLASS_HANDLE getArgClass ( CORINFO_SIG_INFO* sig, /* IN */ @@ -2848,6 +2855,7 @@ class ICorStaticInfo /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr ) = 0; + virtual uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) = 0; }; /***************************************************************************** diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 1184bf8ac6b280..d1728ca0332a95 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -417,9 +417,7 @@ CORINFO_ARG_LIST_HANDLE getArgNext( CorInfoTypeWithMod getArgType( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet - int *flags = NULL -) override; + CORINFO_CLASS_HANDLE* vcTypeRet) override; CORINFO_CLASS_HANDLE getArgClass( CORINFO_SIG_INFO* sig, @@ -716,6 +714,15 @@ bool doesFieldBelongToClass( CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) override; +CorInfoTypeWithMod getArgType2( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int* flags) override; + +uint32_t getFieldTypeByHnd( + CORINFO_CLASS_HANDLE cls) override; + /**********************************************************************************/ // clang-format on /**********************************************************************************/ diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index d373091453220f..1f4de15f480863 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -177,5 +177,7 @@ DEF_CLR_API(getRelocTypeHint) DEF_CLR_API(getExpectedTargetArchitecture) DEF_CLR_API(getJitFlags) DEF_CLR_API(doesFieldBelongToClass) +DEF_CLR_API(getArgType2) +DEF_CLR_API(getFieldTypeByHnd) #undef DEF_CLR_API diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 1e2627ccb3c9ae..21a3d8e46e6082 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -1699,6 +1699,27 @@ bool WrapICorJitInfo::doesFieldBelongToClass( return temp; } +CorInfoTypeWithMod WrapICorJitInfo::getArgType2( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int* flags) +{ + API_ENTER(getArgType2); + CorInfoTypeWithMod temp = wrapHnd->getArgType2(sig, args, vcTypeRet, flags); + API_LEAVE(getArgType2); + return temp; +} + +uint32_t WrapICorJitInfo::getFieldTypeByHnd( + CORINFO_CLASS_HANDLE cls) +{ + API_ENTER(getFieldTypeByHnd); + uint32_t temp = wrapHnd->getFieldTypeByHnd(cls); + API_LEAVE(getFieldTypeByHnd); + return temp; +} + /**********************************************************************************/ // clang-format on /**********************************************************************************/ diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index f660b55ebe192f..a0329e32b3e1bc 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -2563,10 +2563,40 @@ static byte _doesFieldBelongToClass(IntPtr thisHandle, IntPtr* ppException, CORI } } + [UnmanagedCallersOnly] + static CorInfoTypeWithMod _getArgType2(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, int* flags) + { + var _this = GetThis(thisHandle); + try + { + return _this.getArgType2(sig, args, vcTypeRet, ref *flags); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + + [UnmanagedCallersOnly] + static uint _getFieldTypeByHnd(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) + { + var _this = GetThis(thisHandle); + try + { + return _this.getFieldTypeByHnd(cls); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 173); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 175); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2741,6 +2771,8 @@ static IntPtr GetUnmanagedCallbacks() callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; callbacks[171] = (delegate* unmanaged)&_getJitFlags; callbacks[172] = (delegate* unmanaged)&_doesFieldBelongToClass; + callbacks[173] = (delegate* unmanaged)&_getArgType2; + callbacks[174] = (delegate* unmanaged)&_getFieldTypeByHnd; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index f800dadf431591..076db67c3ee109 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2927,6 +2927,16 @@ private CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_ST } } + private CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, ref int flags) + { + throw new NotImplementedException("For LoongArch64, would be implemented later"); + } + + private uint getFieldTypeByHnd(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) { int index = (int)args; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index dbe775e1e0246e..1ff4dbfa24452b 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -326,3 +326,5 @@ FUNCTIONS uint32_t getExpectedTargetArchitecture() uint32_t getJitFlags(CORJIT_FLAGS* flags, uint32_t sizeInBytes) bool doesFieldBelongToClass(CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) + CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int *flags); + uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index f0158199fea1a3..7be0e767d9642d 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -184,6 +184,8 @@ struct JitInterfaceCallbacks uint32_t (* getExpectedTargetArchitecture)(void * thisHandle, CorInfoExceptionClass** ppException); uint32_t (* getJitFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORJIT_FLAGS* flags, uint32_t sizeInBytes); bool (* doesFieldBelongToClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls); + CorInfoTypeWithMod (* getArgType2)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int* flags); + uint32_t (* getFieldTypeByHnd)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); }; @@ -1867,4 +1869,25 @@ class JitInterfaceWrapper : public ICorJitInfo if (pException != nullptr) throw pException; return temp; } + + virtual CorInfoTypeWithMod getArgType2( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int* flags) +{ + CorInfoExceptionClass* pException = nullptr; + CorInfoTypeWithMod temp = _callbacks->getArgType2(_thisHandle, &pException, sig, args, vcTypeRet, flags); + if (pException != nullptr) throw pException; + return temp; +} + + virtual uint32_t getFieldTypeByHnd( + CORINFO_CLASS_HANDLE cls) +{ + CorInfoExceptionClass* pException = nullptr; + uint32_t temp = _callbacks->getFieldTypeByHnd(_thisHandle, &pException, cls); + if (pException != nullptr) throw pException; + return temp; +} }; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index df4e985fda1e6a..cdf4221e10abe2 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9384,6 +9384,524 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } +CorInfoTypeWithMod CEEInfo::getArgType2 ( + CORINFO_SIG_INFO* sig, + CORINFO_ARG_LIST_HANDLE args, + CORINFO_CLASS_HANDLE* vcTypeRet, + int *flags + ) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + CorInfoTypeWithMod result = CorInfoTypeWithMod(CORINFO_TYPE_UNDEF); + + JIT_TO_EE_TRANSITION(); + + _ASSERTE((BYTE*) sig->pSig <= (BYTE*) sig->args && (BYTE*) args < (BYTE*) sig->pSig + sig->cbSig); + _ASSERTE((BYTE*) sig->args <= (BYTE*) args); + INDEBUG(*vcTypeRet = CORINFO_CLASS_HANDLE((size_t)INVALID_POINTER_CC)); + + SigPointer ptr((unsigned __int8*) args); + CorElementType eType; + IfFailThrow(ptr.PeekElemType(&eType)); + while (eType == ELEMENT_TYPE_PINNED) + { + result = CORINFO_TYPE_MOD_PINNED; + IfFailThrow(ptr.GetElemType(NULL)); + IfFailThrow(ptr.PeekElemType(&eType)); + } + + // Now read off the "real" element type after taking any instantiations into consideration + SigTypeContext typeContext; + GetTypeContext(&sig->sigInst,&typeContext); + + Module* pModule = GetModule(sig->scope); + + CorElementType type = ptr.PeekElemTypeClosed(pModule, &typeContext); + + TypeHandle typeHnd = TypeHandle(); + switch (type) { + case ELEMENT_TYPE_VAR : + case ELEMENT_TYPE_MVAR : + case ELEMENT_TYPE_VALUETYPE : + case ELEMENT_TYPE_TYPEDBYREF : + case ELEMENT_TYPE_INTERNAL : + { + typeHnd = ptr.GetTypeHandleThrowing(pModule, &typeContext); + _ASSERTE(!typeHnd.IsNull()); + + CorElementType normType = typeHnd.GetInternalCorElementType(); + + // if we are looking up a value class, don't morph it to a refernece type + // (This can only happen in illegal IL) + if (!CorTypeInfo::IsObjRef(normType) || type != ELEMENT_TYPE_VALUETYPE) + { + type = normType; + } + if ((flags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) + { + *flags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); + } + } + break; + + case ELEMENT_TYPE_PTR: + // Load the type eagerly under debugger to make the eval work + if (!isVerifyOnly() && CORDisableJITOptimizations(pModule->GetDebuggerInfoBits())) + { + // NOTE: in some IJW cases, when the type pointed at is unmanaged, + // the GetTypeHandle may fail, because there is no TypeDef for such type. + // Usage of GetTypeHandleThrowing would lead to class load exception + TypeHandle thPtr = ptr.GetTypeHandleNT(pModule, &typeContext); + if(!thPtr.IsNull()) + { + m_pOverride->classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE(thPtr.AsPtr())); + } + } + break; + + case ELEMENT_TYPE_VOID: + // void is not valid in local sigs + if (sig->flags & CORINFO_SIGFLAG_IS_LOCAL_SIG) + COMPlusThrowHR(COR_E_INVALIDPROGRAM); + break; + + case ELEMENT_TYPE_END: + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + break; + + default: + break; + } + + result = CorInfoTypeWithMod(result | CEEInfo::asCorInfoType(type, typeHnd, vcTypeRet)); + EE_TO_JIT_TRANSITION(); + + return result; +} + +// Although this is only used for LoongArch64-ABI now, +// maybe it can be used for other architecture for getting ABI-info +// between JIT/EE if the ABI is similar. +uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + JIT_TO_EE_TRANSITION_LEAF(); + + TypeHandle th(cls); + + DWORD size = 0; + bool useNativeLayout = false; + MethodTable* methodTablePtr = nullptr; + + if (!th.IsTypeDesc()) + { + methodTablePtr = th.AsMethodTable(); + if (methodTablePtr->HasLayout()) + useNativeLayout = true; + else if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) + { + DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); + + if (numIntroducedFields == 1) + { + FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + + CorElementType fieldType = pFieldStart[0].GetFieldType(); + + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) + size = 1; + } + } + else if (numIntroducedFields == 2) + { + FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + + CorElementType fieldType = pFieldStart[0].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = 2; + else if (fieldType == ELEMENT_TYPE_R8) + size = 0x12; + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + } + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + fieldType = pFieldStart[1].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + goto _End_arg; + } + } + else + { + _ASSERTE(th.IsNativeValueType()); + + useNativeLayout = true; + methodTablePtr = th.AsNativeValueType(); + } + _ASSERTE(methodTablePtr != nullptr); + + if (useNativeLayout) + { + if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) + { + //MethodTable* methodTablePtr = th.AsMethodTable(); + //assert(methodTablePtr->GetNumInstanceFieldBytes() <= 16 /*MAX_PASS_MULTIREG_BYTES*/); + + DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); + FieldDesc *pFieldStart = nullptr; + + if (numIntroducedFields == 1) + { + pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + +_fields_1: + CorElementType fieldType = pFieldStart[0].GetFieldType(); + + bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) + || fieldType == ELEMENT_TYPE_VALUETYPE) + && (pFieldStart->GetOffset() == 0) + && methodTablePtr->HasLayout() + && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + + if (isFixedBuffer) + { + numIntroducedFields = methodTablePtr->GetNumInstanceFieldBytes() / pFieldStart->GetSize(); + if (numIntroducedFields > 2) + goto _End_arg; + if (fieldType == ELEMENT_TYPE_R4) + { + if (numIntroducedFields == 1) + size = 1; + else if (numIntroducedFields == 2) + size = 8; + goto _End_arg; + } + else if (fieldType == ELEMENT_TYPE_R8) + { + if (numIntroducedFields == 1) + size = 1; + else if (numIntroducedFields == 2) + size = 0x38; + goto _End_arg; + } + } + + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) + size = 1; + } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); + //if ((size == 1) && (methodTablePtr->GetNumInstanceFieldBytes() > 8)) + // size = 0; + return size; + } + else + { + if (pNativeFieldDescs->GetNumElements() == 1) + { + pFieldStart = pNativeFieldDescs->GetFieldDesc(); + goto _fields_1; + } + else if (pNativeFieldDescs->GetNumElements() == 2) + { + pFieldStart = pNativeFieldDescs->GetFieldDesc(); + goto _fields_2; + } + //CorElementType fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); + //if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) + // size = 1; + } + } + //else + //{ + // assert(!"------------should amend for LOONGARCH64!!!"); + // //goto _End_arg; + //} + } + else if (numIntroducedFields == 2) + { + pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + +_fields_2: + 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 = 2; + else if (fieldType == ELEMENT_TYPE_R8) + size = 0x12; + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + fieldType = pFieldStart[1].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = size & 0x2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 0x2 ? (size ^ 0x2a) : (size | 0x24); + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + goto _End_arg; + } + } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + + //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) + // || fieldType == ELEMENT_TYPE_VALUETYPE) + // && (pFieldStart->GetOffset() == 0) + // && methodTablePtr->HasLayout() + // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); + + if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) + goto _End_arg; + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + else + size = 0; + //else if (methodTablePtr2->GetNumIntroducedInstanceFields() != 1) + // goto _End_arg; + } + else + { + MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) + { + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + else + size = 0; + } + else + goto _End_arg; + } + } + else if (fieldType == ELEMENT_TYPE_CLASS) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + + //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) + // || fieldType == ELEMENT_TYPE_VALUETYPE) + // && (pFieldStart->GetOffset() == 0) + // && methodTablePtr->HasLayout() + // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + + if (pNativeFieldDescs->NativeSize() > 8) + goto _End_arg; + + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); + //MethodTable* methodTablePtr2 = ((FieldMarshaler_NestedValueClass*)pFieldMarshalers)->GetMethodTable(); + + if (methodTablePtr2->GetNumInstanceFieldBytes() > 8) + goto _End_arg; + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + } + else + { + MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) + { + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (size == 1) + { + if (pFieldStart[0].GetSize() == 8) + size = 0x12; + else + size = 0x2; + } + else if (pFieldStart[0].GetSize() == 8) + { + size = 0x10; + } + else + size = 0; + } + else + goto _End_arg; + } + //else + //{ + // assert(!"------------should amend for LOONGARCH64!!!"); + // goto _End_arg; + //} + } + else if (pFieldStart[0].GetSize() == 8) + size = 0x10; + + fieldType = pFieldStart[1].GetFieldType(); + if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) + { + if (fieldType == ELEMENT_TYPE_R4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + else if ((fieldType == ELEMENT_TYPE_VALUETYPE) || (fieldType == ELEMENT_TYPE_CLASS)) + { + MethodTable* methodTablePtr2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); + if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) + { + size = 0; + goto _End_arg; + } + if (methodTablePtr2->HasLayout()) + { + const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr2->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + + if (pNativeFieldDescs->NativeSize() > 8) + { + size = 0; + goto _End_arg; + } + + if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) + { + methodTablePtr = pNativeFieldDescs->GetNestedNativeMethodTable(); + + if (methodTablePtr->GetNumIntroducedInstanceFields() > 1) + { + size = 0; + goto _End_arg; + } + + if (getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr) == 1) + { + if (methodTablePtr->GetNumInstanceFieldBytes() == 4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (methodTablePtr->GetNumInstanceFieldBytes() == 8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + } + else if (methodTablePtr->GetNumInstanceFieldBytes() == 8)//pFieldStart[1].GetSize() + size |= 0x20; + else + { + size = 0; + } + } + else + { + if (pNativeFieldDescs->GetNumElements() == 1) + { + fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); + if (fieldType == ELEMENT_TYPE_R4) + size = size & 2 ? (size ^ 0xa) : (size | 4); + else if (fieldType == ELEMENT_TYPE_R8) + size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + else if (pNativeFieldDescs->NativeSize() == 8) + size |= 0x20; + } + else + { + size = 0; + //goto _End_arg; + } + } + //else + //{ + // assert(!"------------should amend for LOONGARCH64!!!"); + // goto _End_arg; + //} + } + else + { + size |= getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + if (!(size & 0xf)) + size = 0; + else + assert(!"------------should amend for LOONGARCH64!!!"); + } + } + else if (pFieldStart[1].GetSize() == 8) + size |= 0x20; + } + } + } +_End_arg: + + EE_TO_JIT_TRANSITION_LEAF(); + + return size; +} + /*********************************************************************/ CORINFO_CLASS_HANDLE CEEInfo::getArgClass ( From 948a822a6aa62ee30a6bb7b2d5a2662791452e32 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 12 Jan 2022 18:19:28 +0800 Subject: [PATCH 07/18] [LoongArch64] Fix the compiling error after merge. --- src/coreclr/vm/jitinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f0b4b8ca32d66d..e854aef2c75ff6 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9398,7 +9398,7 @@ CorInfoTypeWithMod CEEInfo::getArgType2 ( TypeHandle thPtr = ptr.GetTypeHandleNT(pModule, &typeContext); if(!thPtr.IsNull()) { - m_pOverride->classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE(thPtr.AsPtr())); + classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE(thPtr.AsPtr())); } } break; From a723e851e9691714f3d52548d59b49bec722e538 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Thu, 13 Jan 2022 11:16:24 +0800 Subject: [PATCH 08/18] [LoongArch64] add comments for the returned value of `getFieldTypeByHnd`. --- src/coreclr/vm/jitinterface.cpp | 134 +++++++++++++++++--------------- 1 file changed, 71 insertions(+), 63 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e854aef2c75ff6..2941beb4f984b5 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9323,11 +9323,16 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } +// The only difference between `CEEInfo::getArgType2` and `CEEInfo::getArgType` is +// the arg `int *pFloatFieldFlags` which denoting whether a struct-arg using float registers. +// +// The value of `*pFloatFieldFlags` is returned by `CEEInfo::getFieldTypeByHnd`. +// So the encoding details of `*pFloatFieldFlags` see `CEEInfo::getFieldTypeByHnd`. CorInfoTypeWithMod CEEInfo::getArgType2 ( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, - int *flags + int *pFloatFieldFlags ) { CONTRACTL { @@ -9381,9 +9386,9 @@ CorInfoTypeWithMod CEEInfo::getArgType2 ( { type = normType; } - if ((flags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) + if ((pFloatFieldFlags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) { - *flags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); + *pFloatFieldFlags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); } } break; @@ -9423,9 +9428,26 @@ CorInfoTypeWithMod CEEInfo::getArgType2 ( return result; } +// NOTE: // Although this is only used for LoongArch64-ABI now, // maybe it can be used for other architecture for getting ABI-info // between JIT/EE if the ABI is similar. +// +// Now the implementation is only focused on the float fields info, +// while a struct-arg has no more than two fiels and total size is no larger than two-pointer-size. +// These depends on the platform's ABI rules. +// +// The returned value's encoding details whether a struct-arg using float regitsters: +// returnd `0` means not using the float register(s). +// +// the lowest four bits denoting 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 float-point type. +// bit_2: `1` means only the second field is float-point type. +// bit_3: `1` means the two fiels are both float-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. uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) { CONTRACTL { @@ -9440,20 +9462,20 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) DWORD size = 0; bool useNativeLayout = false; - MethodTable* methodTablePtr = nullptr; + MethodTable* pMethodTable = nullptr; if (!th.IsTypeDesc()) { - methodTablePtr = th.AsMethodTable(); - if (methodTablePtr->HasLayout()) + pMethodTable = th.AsMethodTable(); + if (pMethodTable->HasLayout()) useNativeLayout = true; else if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) { - DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); + DWORD numIntroducedFields = pMethodTable->GetNumIntroducedInstanceFields(); if (numIntroducedFields == 1) { - FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + FieldDesc *pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); CorElementType fieldType = pFieldStart[0].GetFieldType(); @@ -9465,7 +9487,7 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else if (numIntroducedFields == 2) { - FieldDesc *pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + FieldDesc *pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); CorElementType fieldType = pFieldStart[0].GetFieldType(); if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) @@ -9502,23 +9524,23 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) _ASSERTE(th.IsNativeValueType()); useNativeLayout = true; - methodTablePtr = th.AsNativeValueType(); + pMethodTable = th.AsNativeValueType(); } - _ASSERTE(methodTablePtr != nullptr); + _ASSERTE(pMethodTable != nullptr); if (useNativeLayout) { if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) { - //MethodTable* methodTablePtr = th.AsMethodTable(); - //assert(methodTablePtr->GetNumInstanceFieldBytes() <= 16 /*MAX_PASS_MULTIREG_BYTES*/); + //MethodTable* pMethodTable = th.AsMethodTable(); + //assert(pMethodTable->GetNumInstanceFieldBytes() <= 16 /*MAX_PASS_MULTIREG_BYTES*/); - DWORD numIntroducedFields = methodTablePtr->GetNumIntroducedInstanceFields(); + DWORD numIntroducedFields = pMethodTable->GetNumIntroducedInstanceFields(); FieldDesc *pFieldStart = nullptr; if (numIntroducedFields == 1) { - pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); _fields_1: CorElementType fieldType = pFieldStart[0].GetFieldType(); @@ -9526,12 +9548,12 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) || fieldType == ELEMENT_TYPE_VALUETYPE) && (pFieldStart->GetOffset() == 0) - && methodTablePtr->HasLayout() - && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + && pMethodTable->HasLayout() + && (pMethodTable->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); if (isFixedBuffer) { - numIntroducedFields = methodTablePtr->GetNumInstanceFieldBytes() / pFieldStart->GetSize(); + numIntroducedFields = pMethodTable->GetNumInstanceFieldBytes() / pFieldStart->GetSize(); if (numIntroducedFields > 2) goto _End_arg; if (fieldType == ELEMENT_TYPE_R4) @@ -9559,12 +9581,10 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); - //if ((size == 1) && (methodTablePtr->GetNumInstanceFieldBytes() > 8)) - // size = 0; return size; } else @@ -9579,20 +9599,12 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) pFieldStart = pNativeFieldDescs->GetFieldDesc(); goto _fields_2; } - //CorElementType fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); - //if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) - // size = 1; } } - //else - //{ - // assert(!"------------should amend for LOONGARCH64!!!"); - // //goto _End_arg; - //} } else if (numIntroducedFields == 2) { - pFieldStart = methodTablePtr->GetApproxFieldDescListRaw(); + pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); _fields_2: if (pFieldStart->GetOffset() || !pFieldStart[1].GetOffset() || (pFieldStart[0].GetSize() > pFieldStart[1].GetOffset())) @@ -9624,21 +9636,21 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) // || fieldType == ELEMENT_TYPE_VALUETYPE) // && (pFieldStart->GetOffset() == 0) - // && methodTablePtr->HasLayout() - // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + // && pMethodTable->HasLayout() + // && (pMethodTable->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { - MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); + MethodTable* pMethodTable2 = pNativeFieldDescs->GetNestedNativeMethodTable(); - if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) + if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) goto _End_arg; - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == 1) { if (pFieldStart[0].GetSize() == 8) @@ -9652,15 +9664,13 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else size = 0; - //else if (methodTablePtr2->GetNumIntroducedInstanceFields() != 1) - // goto _End_arg; } else { - MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); - if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) + MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == 1) { if (pFieldStart[0].GetSize() == 8) @@ -9681,25 +9691,24 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else if (fieldType == ELEMENT_TYPE_CLASS) { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) // || fieldType == ELEMENT_TYPE_VALUETYPE) // && (pFieldStart->GetOffset() == 0) - // && methodTablePtr->HasLayout() - // && (methodTablePtr->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); + // && pMethodTable->HasLayout() + // && (pMethodTable->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); if (pNativeFieldDescs->NativeSize() > 8) goto _End_arg; if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { - MethodTable* methodTablePtr2 = pNativeFieldDescs->GetNestedNativeMethodTable(); - //MethodTable* methodTablePtr2 = ((FieldMarshaler_NestedValueClass*)pFieldMarshalers)->GetMethodTable(); + MethodTable* pMethodTable2 = pNativeFieldDescs->GetNestedNativeMethodTable(); - if (methodTablePtr2->GetNumInstanceFieldBytes() > 8) + if (pMethodTable2->GetNumInstanceFieldBytes() > 8) goto _End_arg; - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == 1) { if (pFieldStart[0].GetSize() == 8) @@ -9714,10 +9723,10 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else { - MethodTable* methodTablePtr2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); - if (methodTablePtr2->GetNumIntroducedInstanceFields() == 1) + MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == 1) { if (pFieldStart[0].GetSize() == 8) @@ -9756,15 +9765,15 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else if ((fieldType == ELEMENT_TYPE_VALUETYPE) || (fieldType == ELEMENT_TYPE_CLASS)) { - MethodTable* methodTablePtr2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); - if ((methodTablePtr2->GetNumInstanceFieldBytes() > 8) || (methodTablePtr2->GetNumIntroducedInstanceFields() > 1)) + MethodTable* pMethodTable2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); + if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) { size = 0; goto _End_arg; } - if (methodTablePtr2->HasLayout()) + if (pMethodTable2->HasLayout()) { - const NativeFieldDescriptor *pNativeFieldDescs = methodTablePtr2->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); + const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable2->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); if (pNativeFieldDescs->NativeSize() > 8) { @@ -9774,22 +9783,22 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { - methodTablePtr = pNativeFieldDescs->GetNestedNativeMethodTable(); + pMethodTable = pNativeFieldDescs->GetNestedNativeMethodTable(); - if (methodTablePtr->GetNumIntroducedInstanceFields() > 1) + if (pMethodTable->GetNumIntroducedInstanceFields() > 1) { size = 0; goto _End_arg; } - if (getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr) == 1) + if (getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable) == 1) { - if (methodTablePtr->GetNumInstanceFieldBytes() == 4) + if (pMethodTable->GetNumInstanceFieldBytes() == 4) size = size & 2 ? (size ^ 0xa) : (size | 4); - else if (methodTablePtr->GetNumInstanceFieldBytes() == 8) + else if (pMethodTable->GetNumInstanceFieldBytes() == 8) size = size & 2 ? (size ^ 0x2a) : (size | 0x24); } - else if (methodTablePtr->GetNumInstanceFieldBytes() == 8)//pFieldStart[1].GetSize() + else if (pMethodTable->GetNumInstanceFieldBytes() == 8)//pFieldStart[1].GetSize() size |= 0x20; else { @@ -9811,7 +9820,6 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) else { size = 0; - //goto _End_arg; } } //else @@ -9822,7 +9830,7 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) } else { - size |= getFieldTypeByHnd((CORINFO_CLASS_HANDLE)methodTablePtr2); + size |= getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (!(size & 0xf)) size = 0; else From adb9570184a109180903955fa1382ef4dd7a2780 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Thu, 13 Jan 2022 21:12:36 +0800 Subject: [PATCH 09/18] [LoongArch64] rename getFieldTypeByHnd to getFieldSizeClassificationByHnd. Also add macro define for returned value of `getFieldSizeClassificationByHnd`. --- .../superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 16 +- .../superpmi/superpmi-shared/methodcontext.h | 8 +- .../superpmi-shim-collector/icorjitinfo.cpp | 8 +- .../superpmi-shim-counter/icorjitinfo.cpp | 10 +- .../superpmi-shim-simple/icorjitinfo.cpp | 8 +- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 6 +- src/coreclr/inc/corinfo.h | 4 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 4 +- src/coreclr/jit/ICorJitInfo_API_names.h | 2 +- src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 12 +- .../tools/Common/JitInterface/CorInfoBase.cs | 10 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 4 +- .../ThunkGenerator/ThunkInput.txt | 4 +- .../tools/aot/jitinterface/jitinterface.h | 12 +- src/coreclr/vm/jitinterface.cpp | 268 ++++++++++-------- 16 files changed, 203 insertions(+), 175 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index 1174d24a77d010..3add14c9d81038 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -159,7 +159,7 @@ LWM(SatisfiesMethodConstraints, DLDL, DWORD) LWM(GetUnmanagedCallConv, MethodOrSigInfoValue, DD) LWM(DoesFieldBelongToClass, DLDL, DWORD) DENSELWM(SigInstHandleMap, DWORDLONG) -LWM(GetFieldTypeByHnd, DWORDLONG, DWORD) +LWM(GetFieldSizeClassificationByHnd, DWORDLONG, DWORD) #undef LWM #undef DENSELWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index c79b738626381e..22e5e12e42485b 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -2783,25 +2783,25 @@ CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, return temp; } -void MethodContext::recGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls, DWORD value) +void MethodContext::recGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls, DWORD value) { - if (GetFieldTypeByHnd == nullptr) - GetFieldTypeByHnd = new LightWeightMap(); + if (GetFieldSizeClassificationByHnd == nullptr) + GetFieldSizeClassificationByHnd = new LightWeightMap(); DWORDLONG key = (DWORDLONG)cls; - GetFieldTypeByHnd->Add((DWORDLONG)cls, value); + GetFieldSizeClassificationByHnd->Add((DWORDLONG)cls, value); //DEBUG_REC(dmpGetArgType(key, value)); } -void MethodContext::dmpGetFieldTypeByHnd(DWORDLONG key, DWORD value) +void MethodContext::dmpGetFieldSizeClassificationByHnd(DWORDLONG key, DWORD value) { - printf("GetFieldTypeByHnd key %016llX value-%08X", key, value); + printf("GetFieldSizeClassificationByHnd key %016llX value-%08X", key, value); } -DWORD MethodContext::repGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +DWORD MethodContext::repGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { - return GetFieldTypeByHnd->Get((DWORDLONG)cls); + return GetFieldSizeClassificationByHnd->Get((DWORDLONG)cls); } void MethodContext::recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 92758f0290d40e..71e75b6236a654 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -380,9 +380,9 @@ class MethodContext int *flags, DWORD* exception); - void recGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls, DWORD value); - void dmpGetFieldTypeByHnd(DWORDLONG key, DWORD value); - DWORD repGetFieldTypeByHnd(CORINFO_CLASS_HANDLE cls); + void recGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls, DWORD value); + void dmpGetFieldSizeClassificationByHnd(DWORDLONG key, DWORD value); + DWORD repGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls); void recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result); void dmpGetArgNext(DWORDLONG key, DWORDLONG value); @@ -1112,7 +1112,7 @@ enum mcPackets Packet_GetAssemblyName = 191, Packet_IsIntrinsic = 192, Packet_UpdateEntryPointForTailCall = 193, - Packet_GetFieldTypeByHnd = 194, + Packet_GetFieldSizeClassificationByHnd = 194, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index a620077ab424fe..6af92900ee2afc 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1238,19 +1238,19 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType2(CORINFO_SIG_INFO* sig, return temp; } -uint32_t interceptor_ICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { uint32_t temp = 0; RunWithErrorExceptionCodeCaptureAndContinue( [&]() { - mc->cr->AddCall("getFieldTypeByHnd"); - temp = original_ICorJitInfo->getFieldTypeByHnd(cls); + mc->cr->AddCall("getFieldSizeClassificationByHnd"); + temp = original_ICorJitInfo->getFieldSizeClassificationByHnd(cls); }, [&](DWORD exceptionCode) { - this->mc->recGetFieldTypeByHnd(cls, temp); + this->mc->recGetFieldSizeClassificationByHnd(cls, temp); }); return temp; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 5ab11341e31db6..8d3f26cef204b0 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -1393,16 +1393,16 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType2( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, - int* flags) + int* pFloatFieldFlags) { mcs->AddCall("getArgType2"); - return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, flags); + return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, pFloatFieldFlags); } -uint32_t interceptor_ICJI::getFieldTypeByHnd( +uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { - mcs->AddCall("getFieldTypeByHnd"); - return original_ICorJitInfo->getFieldTypeByHnd(cls); + mcs->AddCall("getFieldSizeClassificationByHnd"); + return original_ICorJitInfo->getFieldSizeClassificationByHnd(cls); } diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 47f8d6a6c7c501..33260c8ae066a1 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -1221,14 +1221,14 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType2( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, - int* flags) + int* pFloatFieldFlags) { - return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, flags); + return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, pFloatFieldFlags); } -uint32_t interceptor_ICJI::getFieldTypeByHnd( +uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { - return original_ICorJitInfo->getFieldTypeByHnd(cls); + return original_ICorJitInfo->getFieldSizeClassificationByHnd(cls); } diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 7440100dcbf308..89ce4642dceca3 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1074,10 +1074,10 @@ CorInfoTypeWithMod MyICJI::getArgType2(CORINFO_SIG_INFO* sig, /* IN * return value; } -uint32_t MyICJI::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) +uint32_t MyICJI::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { - jitInstance->mc->cr->AddCall("getFieldTypeByHnd"); - return jitInstance->mc->repGetFieldTypeByHnd(cls); + jitInstance->mc->cr->AddCall("getFieldSizeClassificationByHnd"); + return jitInstance->mc->repGetFieldSizeClassificationByHnd(cls); } // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 7c20bd7a319eaa..339936a3b79724 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2723,7 +2723,7 @@ class ICorStaticInfo CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args, /* IN */ CORINFO_CLASS_HANDLE *vcTypeRet, /* OUT */ - int *flags = NULL + int *pFloatFieldFlags = NULL ) = 0; // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it @@ -2860,7 +2860,7 @@ class ICorStaticInfo /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr ) = 0; - virtual uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) = 0; + virtual uint32_t getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) = 0; }; /***************************************************************************** diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 9f0eb5c4225d5d..1f0f1d4e710198 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -714,9 +714,9 @@ CorInfoTypeWithMod getArgType2( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, - int* flags) override; + int* pFloatFieldFlags) override; -uint32_t getFieldTypeByHnd( +uint32_t getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) override; /**********************************************************************************/ diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index 6cf52ec7abbfb1..c8c1826cafa16f 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -177,6 +177,6 @@ DEF_CLR_API(getExpectedTargetArchitecture) DEF_CLR_API(getJitFlags) DEF_CLR_API(doesFieldBelongToClass) DEF_CLR_API(getArgType2) -DEF_CLR_API(getFieldTypeByHnd) +DEF_CLR_API(getFieldSizeClassificationByHnd) #undef DEF_CLR_API diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index cd70b72a90d512..e0a4e1dd15c055 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -1694,20 +1694,20 @@ CorInfoTypeWithMod WrapICorJitInfo::getArgType2( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, - int* flags) + int* pFloatFieldFlags) { API_ENTER(getArgType2); - CorInfoTypeWithMod temp = wrapHnd->getArgType2(sig, args, vcTypeRet, flags); + CorInfoTypeWithMod temp = wrapHnd->getArgType2(sig, args, vcTypeRet, pFloatFieldFlags); API_LEAVE(getArgType2); return temp; } -uint32_t WrapICorJitInfo::getFieldTypeByHnd( +uint32_t WrapICorJitInfo::getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { - API_ENTER(getFieldTypeByHnd); - uint32_t temp = wrapHnd->getFieldTypeByHnd(cls); - API_LEAVE(getFieldTypeByHnd); + API_ENTER(getFieldSizeClassificationByHnd); + uint32_t temp = wrapHnd->getFieldSizeClassificationByHnd(cls); + API_LEAVE(getFieldSizeClassificationByHnd); return temp; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 743d5514e42104..430505d3f5fcc7 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -2550,12 +2550,12 @@ static byte _doesFieldBelongToClass(IntPtr thisHandle, IntPtr* ppException, CORI } [UnmanagedCallersOnly] - static CorInfoTypeWithMod _getArgType2(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, int* flags) + static CorInfoTypeWithMod _getArgType2(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, int* pFloatFieldFlags) { var _this = GetThis(thisHandle); try { - return _this.getArgType2(sig, args, vcTypeRet, ref *flags); + return _this.getArgType2(sig, args, vcTypeRet, ref *pFloatFieldFlags); } catch (Exception ex) { @@ -2565,12 +2565,12 @@ static CorInfoTypeWithMod _getArgType2(IntPtr thisHandle, IntPtr* ppException, C } [UnmanagedCallersOnly] - static uint _getFieldTypeByHnd(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) + static uint _getFieldSizeClassificationByHnd(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) { var _this = GetThis(thisHandle); try { - return _this.getFieldTypeByHnd(cls); + return _this.getFieldSizeClassificationByHnd(cls); } catch (Exception ex) { @@ -2757,7 +2757,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[170] = (delegate* unmanaged)&_getJitFlags; callbacks[171] = (delegate* unmanaged)&_doesFieldBelongToClass; callbacks[172] = (delegate* unmanaged)&_getArgType2; - callbacks[173] = (delegate* unmanaged)&_getFieldTypeByHnd; + callbacks[173] = (delegate* unmanaged)&_getFieldSizeClassificationByHnd; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 699b28bb386eaf..0a7794bd259ee3 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2927,12 +2927,12 @@ private CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_ST } } - private CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, ref int flags) + private CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, ref int floatFieldFlags) { throw new NotImplementedException("For LoongArch64, would be implemented later"); } - private uint getFieldTypeByHnd(CORINFO_CLASS_STRUCT_* cls) + private uint getFieldSizeClassificationByHnd(CORINFO_CLASS_STRUCT_* cls) { throw new NotImplementedException("For LoongArch64, would be implemented later"); } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index fde49dc0693823..e6609cc839f72b 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -325,5 +325,5 @@ FUNCTIONS uint32_t getExpectedTargetArchitecture() uint32_t getJitFlags(CORJIT_FLAGS* flags, uint32_t sizeInBytes) bool doesFieldBelongToClass(CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) - CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int *flags); - uint32_t getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls); + CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int *pFloatFieldFlags); + uint32_t getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index 5533fb9d829582..1b7c6393ac2b26 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -183,8 +183,8 @@ struct JitInterfaceCallbacks uint32_t (* getExpectedTargetArchitecture)(void * thisHandle, CorInfoExceptionClass** ppException); uint32_t (* getJitFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORJIT_FLAGS* flags, uint32_t sizeInBytes); bool (* doesFieldBelongToClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls); - CorInfoTypeWithMod (* getArgType2)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int* flags); - uint32_t (* getFieldTypeByHnd)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); + CorInfoTypeWithMod (* getArgType2)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int* pFloatFieldFlags); + uint32_t (* getFieldSizeClassificationByHnd)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); }; @@ -1864,19 +1864,19 @@ class JitInterfaceWrapper : public ICorJitInfo CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, - int* flags) + int* pFloatFieldFlags) { CorInfoExceptionClass* pException = nullptr; - CorInfoTypeWithMod temp = _callbacks->getArgType2(_thisHandle, &pException, sig, args, vcTypeRet, flags); + CorInfoTypeWithMod temp = _callbacks->getArgType2(_thisHandle, &pException, sig, args, vcTypeRet, pFloatFieldFlags); if (pException != nullptr) throw pException; return temp; } - virtual uint32_t getFieldTypeByHnd( + virtual uint32_t getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { CorInfoExceptionClass* pException = nullptr; - uint32_t temp = _callbacks->getFieldTypeByHnd(_thisHandle, &pException, cls); + uint32_t temp = _callbacks->getFieldSizeClassificationByHnd(_thisHandle, &pException, cls); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 2941beb4f984b5..a3709d42021a8e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9326,8 +9326,8 @@ CorInfoTypeWithMod CEEInfo::getArgType ( // The only difference between `CEEInfo::getArgType2` and `CEEInfo::getArgType` is // the arg `int *pFloatFieldFlags` which denoting whether a struct-arg using float registers. // -// The value of `*pFloatFieldFlags` is returned by `CEEInfo::getFieldTypeByHnd`. -// So the encoding details of `*pFloatFieldFlags` see `CEEInfo::getFieldTypeByHnd`. +// The value of `*pFloatFieldFlags` is returned by `CEEInfo::getFieldSizeClassificationByHnd`. +// So the encoding details of `*pFloatFieldFlags` see `CEEInfo::getFieldSizeClassificationByHnd`. CorInfoTypeWithMod CEEInfo::getArgType2 ( CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, @@ -9388,7 +9388,7 @@ CorInfoTypeWithMod CEEInfo::getArgType2 ( } if ((pFloatFieldFlags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) { - *pFloatFieldFlags = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); + *pFloatFieldFlags = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); } } break; @@ -9448,7 +9448,22 @@ CorInfoTypeWithMod CEEInfo::getArgType2 ( // 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. -uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) + +#define STRUCT_FLOAT_FIELD_ONLY_ONE 0x1 +#define STRUCT_FLOAT_FIELD_ONLY_TWO 0x8 +#define STRUCT_FLOAT_FIELD_FIRST 0x2 +#define STRUCT_FLOAT_FIELD_SECOND 0x4 +#define STRUCT_FIRST_FIELD_SIZE_IS8 0x10 +#define STRUCT_SECOND_FIELD_SIZE_IS8 0x20 + +#define STRUCT_FIRST_FIELD_DOUBLE (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FIRST_FIELD_SIZE_IS8) +#define STRUCT_SECOND_FIELD_DOUBLE (STRUCT_FLOAT_FIELD_SECOND | STRUCT_SECOND_FIELD_SIZE_IS8) +#define STRUCT_FIELD_TWO_DOUBLES (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8 | STRUCT_FLOAT_FIELD_ONLY_TWO) + +#define STRUCT_MERGE_FIRST_SECOND (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO) +#define STRUCT_MERGE_FIRST_SECOND_8 (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_SECOND_FIELD_SIZE_IS8) + +uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { CONTRACTL { NOTHROW; @@ -9482,7 +9497,21 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) - size = 1; + size = STRUCT_FLOAT_FIELD_ONLY_ONE; + } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + TypeHandle th2 = pFieldStart->GetApproxFieldTypeHandleThrowing(); + _ASSERTE(!th2.IsNull()); + pMethodTable = th2.GetMethodTable(); + if (pMethodTable->GetNumIntroducedInstanceFields() == 1) + { + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + } + else if (pMethodTable->GetNumIntroducedInstanceFields() == 2) + { + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + } } } else if (numIntroducedFields == 2) @@ -9493,28 +9522,87 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if (fieldType == ELEMENT_TYPE_R4) - size = 2; + size = STRUCT_FLOAT_FIELD_FIRST; else if (fieldType == ELEMENT_TYPE_R8) - size = 0x12; + size = STRUCT_FIRST_FIELD_DOUBLE; else if (pFieldStart[0].GetSize() == 8) - size = 0x10; + size = STRUCT_FIRST_FIELD_SIZE_IS8; } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + TypeHandle th2 = pFieldStart->GetApproxFieldTypeHandleThrowing(); + _ASSERTE(!th2.IsNull()); + pMethodTable = th2.GetMethodTable(); + if (pMethodTable->GetNumIntroducedInstanceFields() == 1) + { + size = getFieldSizeClassificationByHnd((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 == 0) + { + size = pFieldStart[0].GetSize() == 8 ? STRUCT_FIRST_FIELD_SIZE_IS8: 0; + } + else + { + size = 0; + goto _End_arg; + } + } + else + { + size = 0; + goto _End_arg; + } + } else if (pFieldStart[0].GetSize() == 8) - size = 0x10; + size = STRUCT_FIRST_FIELD_SIZE_IS8; fieldType = pFieldStart[1].GetFieldType(); if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if (fieldType == ELEMENT_TYPE_R4) - size = size & 2 ? (size ^ 0xa) : (size | 4); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND); else if (fieldType == ELEMENT_TYPE_R8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE); else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; + size |= STRUCT_SECOND_FIELD_SIZE_IS8; + } + else if (fieldType == ELEMENT_TYPE_VALUETYPE) + { + TypeHandle th2 = pFieldStart[1].GetApproxFieldTypeHandleThrowing(); + _ASSERTE(!th2.IsNull()); + pMethodTable = th2.GetMethodTable(); + if (pMethodTable->GetNumIntroducedInstanceFields() == 1) + { + DWORD size2 = getFieldSizeClassificationByHnd((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 = 0; + goto _End_arg; + } + } + else + { + size = 0; + goto _End_arg; + } } else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; + size |= STRUCT_SECOND_FIELD_SIZE_IS8; } goto _End_arg; } @@ -9542,7 +9630,6 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) { pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); -_fields_1: CorElementType fieldType = pFieldStart[0].GetFieldType(); bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) @@ -9559,17 +9646,17 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if (fieldType == ELEMENT_TYPE_R4) { if (numIntroducedFields == 1) - size = 1; + size = STRUCT_FLOAT_FIELD_ONLY_ONE; else if (numIntroducedFields == 2) - size = 8; + size = STRUCT_FLOAT_FIELD_ONLY_TWO; goto _End_arg; } else if (fieldType == ELEMENT_TYPE_R8) { if (numIntroducedFields == 1) - size = 1; + size = STRUCT_FLOAT_FIELD_ONLY_ONE; else if (numIntroducedFields == 2) - size = 0x38; + size = STRUCT_FIELD_TWO_DOUBLES; goto _End_arg; } } @@ -9577,27 +9664,26 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if ((fieldType == ELEMENT_TYPE_R4) || (fieldType == ELEMENT_TYPE_R8)) - size = 1; + size = STRUCT_FLOAT_FIELD_ONLY_ONE; } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); return size; } else { + pMethodTable = pNativeFieldDescs->GetNestedNativeMethodTable(); if (pNativeFieldDescs->GetNumElements() == 1) { - pFieldStart = pNativeFieldDescs->GetFieldDesc(); - goto _fields_1; + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); } else if (pNativeFieldDescs->GetNumElements() == 2) { - pFieldStart = pNativeFieldDescs->GetFieldDesc(); - goto _fields_2; + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); } } } @@ -9606,7 +9692,6 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) { pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); -_fields_2: if (pFieldStart->GetOffset() || !pFieldStart[1].GetOffset() || (pFieldStart[0].GetSize() > pFieldStart[1].GetOffset())) { goto _End_arg; @@ -9616,21 +9701,21 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if (fieldType == ELEMENT_TYPE_R4) - size = 2; + size = STRUCT_FLOAT_FIELD_FIRST; else if (fieldType == ELEMENT_TYPE_R8) - size = 0x12; + size = STRUCT_FIRST_FIELD_DOUBLE; else if (pFieldStart[0].GetSize() == 8) - size = 0x10; + size = STRUCT_FIRST_FIELD_SIZE_IS8; fieldType = pFieldStart[1].GetFieldType(); if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if (fieldType == ELEMENT_TYPE_R4) - size = size & 0x2 ? (size ^ 0xa) : (size | 4); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND); else if (fieldType == ELEMENT_TYPE_R8) - size = size & 0x2 ? (size ^ 0x2a) : (size | 0x24); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE); else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; + size |= STRUCT_SECOND_FIELD_SIZE_IS8; goto _End_arg; } } @@ -9650,17 +9735,17 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) goto _End_arg; - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == 1) { if (pFieldStart[0].GetSize() == 8) - size = 0x12; + size = STRUCT_FIRST_FIELD_DOUBLE; else - size = 0x2; + size = STRUCT_FLOAT_FIELD_FIRST; } else if (pFieldStart[0].GetSize() == 8) { - size = 0x10; + size = STRUCT_FIRST_FIELD_SIZE_IS8; } else size = 0; @@ -9670,17 +9755,17 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); + size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == 1) { if (pFieldStart[0].GetSize() == 8) - size = 0x12; + size = STRUCT_FIRST_FIELD_DOUBLE; else - size = 0x2; + size = STRUCT_FLOAT_FIELD_FIRST; } else if (pFieldStart[0].GetSize() == 8) { - size = 0x10; + size = STRUCT_FIRST_FIELD_SIZE_IS8; } else size = 0; @@ -9689,81 +9774,20 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) goto _End_arg; } } - else if (fieldType == ELEMENT_TYPE_CLASS) - { - const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); - - //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) - // || fieldType == ELEMENT_TYPE_VALUETYPE) - // && (pFieldStart->GetOffset() == 0) - // && pMethodTable->HasLayout() - // && (pMethodTable->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); - - if (pNativeFieldDescs->NativeSize() > 8) - goto _End_arg; - - if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) - { - MethodTable* pMethodTable2 = pNativeFieldDescs->GetNestedNativeMethodTable(); - - if (pMethodTable2->GetNumInstanceFieldBytes() > 8) - goto _End_arg; - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); - if (size == 1) - { - if (pFieldStart[0].GetSize() == 8) - size = 0x12; - else - size = 0x2; - } - else if (pFieldStart[0].GetSize() == 8) - { - size = 0x10; - } - } - else - { - MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); - if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) - { - size = getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); - if (size == 1) - { - if (pFieldStart[0].GetSize() == 8) - size = 0x12; - else - size = 0x2; - } - else if (pFieldStart[0].GetSize() == 8) - { - size = 0x10; - } - else - size = 0; - } - else - goto _End_arg; - } - //else - //{ - // assert(!"------------should amend for LOONGARCH64!!!"); - // goto _End_arg; - //} - } else if (pFieldStart[0].GetSize() == 8) - size = 0x10; + size = STRUCT_FIRST_FIELD_SIZE_IS8; fieldType = pFieldStart[1].GetFieldType(); if (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType)) { if (fieldType == ELEMENT_TYPE_R4) - size = size & 2 ? (size ^ 0xa) : (size | 4); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND); else if (fieldType == ELEMENT_TYPE_R8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE); else if (pFieldStart[1].GetSize() == 8) - size |= 0x20; + size |= STRUCT_SECOND_FIELD_SIZE_IS8; } - else if ((fieldType == ELEMENT_TYPE_VALUETYPE) || (fieldType == ELEMENT_TYPE_CLASS)) + else if (fieldType == ELEMENT_TYPE_VALUETYPE) { MethodTable* pMethodTable2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) @@ -9791,15 +9815,15 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) goto _End_arg; } - if (getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable) == 1) + if (getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable) == STRUCT_FLOAT_FIELD_ONLY_ONE) { if (pMethodTable->GetNumInstanceFieldBytes() == 4) - size = size & 2 ? (size ^ 0xa) : (size | 4); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND); else if (pMethodTable->GetNumInstanceFieldBytes() == 8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE); } - else if (pMethodTable->GetNumInstanceFieldBytes() == 8)//pFieldStart[1].GetSize() - size |= 0x20; + else if (pMethodTable->GetNumInstanceFieldBytes() == 8) + size |= STRUCT_SECOND_FIELD_SIZE_IS8; else { size = 0; @@ -9811,11 +9835,11 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) { fieldType = pNativeFieldDescs->GetFieldDesc()[0].GetFieldType(); if (fieldType == ELEMENT_TYPE_R4) - size = size & 2 ? (size ^ 0xa) : (size | 4); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND) : (size | STRUCT_FLOAT_FIELD_SECOND); else if (fieldType == ELEMENT_TYPE_R8) - size = size & 2 ? (size ^ 0x2a) : (size | 0x24); + size = size & STRUCT_FLOAT_FIELD_FIRST ? (size ^ STRUCT_MERGE_FIRST_SECOND_8) : (size | STRUCT_SECOND_FIELD_DOUBLE); else if (pNativeFieldDescs->NativeSize() == 8) - size |= 0x20; + size |= STRUCT_SECOND_FIELD_SIZE_IS8; } else { @@ -9829,16 +9853,20 @@ uint32_t CEEInfo::getFieldTypeByHnd(CORINFO_CLASS_HANDLE cls) //} } else - { - size |= getFieldTypeByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); - if (!(size & 0xf)) - size = 0; - else - assert(!"------------should amend for LOONGARCH64!!!"); + {//whether should confirm the nested ? + if (getFieldSizeClassificationByHnd((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 |= 0x20; + size |= STRUCT_SECOND_FIELD_SIZE_IS8; } } } From 02ff4bfa41d7887b151d381e2697ba82ab6a0bca Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 14 Jan 2022 10:02:14 +0800 Subject: [PATCH 10/18] [LoongArch64] Delete the interface `getArgType2`. And refactor the returned values of `getFieldSizeClassificationByHnd`. --- .../superpmi-shim-collector/icorjitinfo.cpp | 28 --- .../superpmi-shim-counter/icorjitinfo.cpp | 10 -- .../superpmi-shim-simple/icorjitinfo.cpp | 9 - .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 14 -- src/coreclr/inc/corinfo.h | 42 ++++- src/coreclr/inc/icorjitinfoimpl_generated.h | 6 - src/coreclr/jit/ICorJitInfo_API_names.h | 1 - src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 12 -- .../tools/Common/JitInterface/CorInfoBase.cs | 20 +-- .../tools/Common/JitInterface/CorInfoImpl.cs | 5 - .../ThunkGenerator/ThunkInput.txt | 1 - .../tools/aot/jitinterface/jitinterface.h | 13 -- src/coreclr/vm/jitinterface.cpp | 167 ++---------------- 13 files changed, 56 insertions(+), 272 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 6af92900ee2afc..00e83dfd5d30a8 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1210,34 +1210,6 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, return temp; } -CorInfoTypeWithMod interceptor_ICJI::getArgType2(CORINFO_SIG_INFO* sig, /* IN */ - CORINFO_ARG_LIST_HANDLE args, /* IN */ - CORINFO_CLASS_HANDLE* vcTypeRet, /* OUT */ - int* flags /* OUT */ - ) -{ - CorInfoTypeWithMod temp = (CorInfoTypeWithMod)CORINFO_TYPE_UNDEF; - - RunWithErrorExceptionCodeCaptureAndContinue( - [&]() - { - mc->cr->AddCall("getArgType2"); - temp = - original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, flags); - -#ifdef fatMC - CORINFO_CLASS_HANDLE temp3 = getArgClass(sig, args); -#endif - }, - [&](DWORD exceptionCode) - { - - this->mc->recGetArgType(sig, args, vcTypeRet, temp, flags ? *flags : 0, exceptionCode); - }); - - return temp; -} - uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 8d3f26cef204b0..12009a2dfac0b6 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -1389,16 +1389,6 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } -CorInfoTypeWithMod interceptor_ICJI::getArgType2( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int* pFloatFieldFlags) -{ - mcs->AddCall("getArgType2"); - return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, pFloatFieldFlags); -} - uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 33260c8ae066a1..e65938eb80305f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -1217,15 +1217,6 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } -CorInfoTypeWithMod interceptor_ICJI::getArgType2( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int* pFloatFieldFlags) -{ - return original_ICorJitInfo->getArgType2(sig, args, vcTypeRet, pFloatFieldFlags); -} - uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 89ce4642dceca3..005356787d64b4 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1060,20 +1060,6 @@ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ return value; } -CorInfoTypeWithMod MyICJI::getArgType2(CORINFO_SIG_INFO* sig, /* IN */ - CORINFO_ARG_LIST_HANDLE args, /* IN */ - CORINFO_CLASS_HANDLE* vcTypeRet,/* OUT */ - int* flags /* OUT */ - ) -{ - DWORD exceptionCode = 0; - jitInstance->mc->cr->AddCall("getArgType2"); - CorInfoTypeWithMod value = jitInstance->mc->repGetArgType(sig, args, vcTypeRet, flags, &exceptionCode); - if (exceptionCode != 0) - ThrowException(exceptionCode); - return value; -} - uint32_t MyICJI::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { jitInstance->mc->cr->AddCall("getFieldSizeClassificationByHnd"); diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 339936a3b79724..91a8103225c88c 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -316,6 +316,41 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR } }; +// NOTE: +// 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. +// +// `STRUCT_NO_FLOAT_FIELD`=0 means not using the float register(s). +// +// the lowest four bits denoting 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 float-point type. +// bit_2: `1` means only the second field is float-point type. +// bit_3: `1` means the two fields are both float-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. +enum StructFloatFieldInfoFlags : uint8_t +{ + 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" // CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn()) @@ -2719,13 +2754,6 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */ ) = 0; - virtual CorInfoTypeWithMod getArgType2 ( - CORINFO_SIG_INFO* sig, /* IN */ - CORINFO_ARG_LIST_HANDLE args, /* IN */ - CORINFO_CLASS_HANDLE *vcTypeRet, /* OUT */ - int *pFloatFieldFlags = NULL - ) = 0; - // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it virtual CORINFO_CLASS_HANDLE getArgClass ( CORINFO_SIG_INFO* sig, /* IN */ diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 1f0f1d4e710198..a2712946b7ac6b 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -710,12 +710,6 @@ bool doesFieldBelongToClass( CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) override; -CorInfoTypeWithMod getArgType2( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int* pFloatFieldFlags) override; - uint32_t getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) override; diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index c8c1826cafa16f..3b95239d128654 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -176,7 +176,6 @@ DEF_CLR_API(getRelocTypeHint) DEF_CLR_API(getExpectedTargetArchitecture) DEF_CLR_API(getJitFlags) DEF_CLR_API(doesFieldBelongToClass) -DEF_CLR_API(getArgType2) DEF_CLR_API(getFieldSizeClassificationByHnd) #undef DEF_CLR_API diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index e0a4e1dd15c055..35986c5146c4c4 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -1690,18 +1690,6 @@ bool WrapICorJitInfo::doesFieldBelongToClass( return temp; } -CorInfoTypeWithMod WrapICorJitInfo::getArgType2( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int* pFloatFieldFlags) -{ - API_ENTER(getArgType2); - CorInfoTypeWithMod temp = wrapHnd->getArgType2(sig, args, vcTypeRet, pFloatFieldFlags); - API_LEAVE(getArgType2); - return temp; -} - uint32_t WrapICorJitInfo::getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 430505d3f5fcc7..fd9b070ee943b2 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -2549,21 +2549,6 @@ static byte _doesFieldBelongToClass(IntPtr thisHandle, IntPtr* ppException, CORI } } - [UnmanagedCallersOnly] - static CorInfoTypeWithMod _getArgType2(IntPtr thisHandle, IntPtr* ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, int* pFloatFieldFlags) - { - var _this = GetThis(thisHandle); - try - { - return _this.getArgType2(sig, args, vcTypeRet, ref *pFloatFieldFlags); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] static uint _getFieldSizeClassificationByHnd(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) { @@ -2582,7 +2567,7 @@ static uint _getFieldSizeClassificationByHnd(IntPtr thisHandle, IntPtr* ppExcept static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 174); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 173); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2756,8 +2741,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[169] = (delegate* unmanaged)&_getExpectedTargetArchitecture; callbacks[170] = (delegate* unmanaged)&_getJitFlags; callbacks[171] = (delegate* unmanaged)&_doesFieldBelongToClass; - callbacks[172] = (delegate* unmanaged)&_getArgType2; - callbacks[173] = (delegate* unmanaged)&_getFieldSizeClassificationByHnd; + callbacks[172] = (delegate* unmanaged)&_getFieldSizeClassificationByHnd; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 0a7794bd259ee3..553b9a033b7f3a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2927,11 +2927,6 @@ private CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_ST } } - private CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args, CORINFO_CLASS_STRUCT_** vcTypeRet, ref int floatFieldFlags) - { - throw new NotImplementedException("For LoongArch64, would be implemented later"); - } - private uint getFieldSizeClassificationByHnd(CORINFO_CLASS_STRUCT_* cls) { throw new NotImplementedException("For LoongArch64, would be implemented later"); diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index e6609cc839f72b..740f2e69555d9e 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -325,5 +325,4 @@ FUNCTIONS uint32_t getExpectedTargetArchitecture() uint32_t getJitFlags(CORJIT_FLAGS* flags, uint32_t sizeInBytes) bool doesFieldBelongToClass(CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) - CorInfoTypeWithMod getArgType2(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int *pFloatFieldFlags); uint32_t getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index 1b7c6393ac2b26..eec6778ffc3b38 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -183,7 +183,6 @@ struct JitInterfaceCallbacks uint32_t (* getExpectedTargetArchitecture)(void * thisHandle, CorInfoExceptionClass** ppException); uint32_t (* getJitFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORJIT_FLAGS* flags, uint32_t sizeInBytes); bool (* doesFieldBelongToClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls); - CorInfoTypeWithMod (* getArgType2)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, int* pFloatFieldFlags); uint32_t (* getFieldSizeClassificationByHnd)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); }; @@ -1860,18 +1859,6 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual CorInfoTypeWithMod getArgType2( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int* pFloatFieldFlags) -{ - CorInfoExceptionClass* pException = nullptr; - CorInfoTypeWithMod temp = _callbacks->getArgType2(_thisHandle, &pException, sig, args, vcTypeRet, pFloatFieldFlags); - if (pException != nullptr) throw pException; - return temp; -} - virtual uint32_t getFieldSizeClassificationByHnd( CORINFO_CLASS_HANDLE cls) { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index a3709d42021a8e..8b0888de3b994b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9323,146 +9323,17 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } -// The only difference between `CEEInfo::getArgType2` and `CEEInfo::getArgType` is -// the arg `int *pFloatFieldFlags` which denoting whether a struct-arg using float registers. -// -// The value of `*pFloatFieldFlags` is returned by `CEEInfo::getFieldSizeClassificationByHnd`. -// So the encoding details of `*pFloatFieldFlags` see `CEEInfo::getFieldSizeClassificationByHnd`. -CorInfoTypeWithMod CEEInfo::getArgType2 ( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int *pFloatFieldFlags - ) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - CorInfoTypeWithMod result = CorInfoTypeWithMod(CORINFO_TYPE_UNDEF); - - JIT_TO_EE_TRANSITION(); - - _ASSERTE((BYTE*) sig->pSig <= (BYTE*) sig->args && (BYTE*) args < (BYTE*) sig->pSig + sig->cbSig); - _ASSERTE((BYTE*) sig->args <= (BYTE*) args); - INDEBUG(*vcTypeRet = CORINFO_CLASS_HANDLE((size_t)INVALID_POINTER_CC)); - - SigPointer ptr((unsigned __int8*) args); - CorElementType eType; - IfFailThrow(ptr.PeekElemType(&eType)); - while (eType == ELEMENT_TYPE_PINNED) - { - result = CORINFO_TYPE_MOD_PINNED; - IfFailThrow(ptr.GetElemType(NULL)); - IfFailThrow(ptr.PeekElemType(&eType)); - } - - // Now read off the "real" element type after taking any instantiations into consideration - SigTypeContext typeContext; - GetTypeContext(&sig->sigInst,&typeContext); - - Module* pModule = GetModule(sig->scope); - - CorElementType type = ptr.PeekElemTypeClosed(pModule, &typeContext); - - TypeHandle typeHnd = TypeHandle(); - switch (type) { - case ELEMENT_TYPE_VAR : - case ELEMENT_TYPE_MVAR : - case ELEMENT_TYPE_VALUETYPE : - case ELEMENT_TYPE_TYPEDBYREF : - case ELEMENT_TYPE_INTERNAL : - { - typeHnd = ptr.GetTypeHandleThrowing(pModule, &typeContext); - _ASSERTE(!typeHnd.IsNull()); - - CorElementType normType = typeHnd.GetInternalCorElementType(); - - // if we are looking up a value class, don't morph it to a refernece type - // (This can only happen in illegal IL) - if (!CorTypeInfo::IsObjRef(normType) || type != ELEMENT_TYPE_VALUETYPE) - { - type = normType; - } - if ((pFloatFieldFlags != NULL) && (type == ELEMENT_TYPE_VALUETYPE)) - { - *pFloatFieldFlags = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)typeHnd.AsTAddr()); - } - } - break; - - case ELEMENT_TYPE_PTR: - // Load the type eagerly under debugger to make the eval work - if (!isVerifyOnly() && CORDisableJITOptimizations(pModule->GetDebuggerInfoBits())) - { - // NOTE: in some IJW cases, when the type pointed at is unmanaged, - // the GetTypeHandle may fail, because there is no TypeDef for such type. - // Usage of GetTypeHandleThrowing would lead to class load exception - TypeHandle thPtr = ptr.GetTypeHandleNT(pModule, &typeContext); - if(!thPtr.IsNull()) - { - classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE(thPtr.AsPtr())); - } - } - break; - - case ELEMENT_TYPE_VOID: - // void is not valid in local sigs - if (sig->flags & CORINFO_SIGFLAG_IS_LOCAL_SIG) - COMPlusThrowHR(COR_E_INVALIDPROGRAM); - break; - - case ELEMENT_TYPE_END: - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - break; - - default: - break; - } - - result = CorInfoTypeWithMod(result | CEEInfo::asCorInfoType(type, typeHnd, vcTypeRet)); - EE_TO_JIT_TRANSITION(); - - return result; -} - // NOTE: // Although this is only used for LoongArch64-ABI now, // maybe it can be used for other architecture for getting ABI-info // between JIT/EE if the ABI is similar. // // Now the implementation is only focused on the float fields info, -// while a struct-arg has no more than two fiels and total size is no larger than two-pointer-size. +// 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 whether a struct-arg using float regitsters: -// returnd `0` means not using the float register(s). -// -// the lowest four bits denoting 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 float-point type. -// bit_2: `1` means only the second field is float-point type. -// bit_3: `1` means the two fiels are both float-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. - -#define STRUCT_FLOAT_FIELD_ONLY_ONE 0x1 -#define STRUCT_FLOAT_FIELD_ONLY_TWO 0x8 -#define STRUCT_FLOAT_FIELD_FIRST 0x2 -#define STRUCT_FLOAT_FIELD_SECOND 0x4 -#define STRUCT_FIRST_FIELD_SIZE_IS8 0x10 -#define STRUCT_SECOND_FIELD_SIZE_IS8 0x20 - -#define STRUCT_FIRST_FIELD_DOUBLE (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FIRST_FIELD_SIZE_IS8) -#define STRUCT_SECOND_FIELD_DOUBLE (STRUCT_FLOAT_FIELD_SECOND | STRUCT_SECOND_FIELD_SIZE_IS8) -#define STRUCT_FIELD_TWO_DOUBLES (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8 | STRUCT_FLOAT_FIELD_ONLY_TWO) - -#define STRUCT_MERGE_FIRST_SECOND (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO) -#define STRUCT_MERGE_FIRST_SECOND_8 (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_SECOND_FIELD_SIZE_IS8) - +// see the enum `StructFloatFieldInfoFlags`. uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { CONTRACTL { @@ -9475,9 +9346,9 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) TypeHandle th(cls); - DWORD size = 0; - bool useNativeLayout = false; - MethodTable* pMethodTable = nullptr; + bool useNativeLayout = false; + uint32_t size = STRUCT_NO_FLOAT_FIELD; + MethodTable* pMethodTable = nullptr; if (!th.IsTypeDesc()) { @@ -9541,19 +9412,19 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) { size = pFieldStart[0].GetSize() == 8 ? STRUCT_FIRST_FIELD_DOUBLE : STRUCT_FLOAT_FIELD_FIRST; } - else if (size == 0) + else if (size == STRUCT_NO_FLOAT_FIELD) { size = pFieldStart[0].GetSize() == 8 ? STRUCT_FIRST_FIELD_SIZE_IS8: 0; } else { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } } else { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } } @@ -9591,13 +9462,13 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) } else { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } } else { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } } @@ -9736,7 +9607,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) goto _End_arg; size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); - if (size == 1) + if (size == STRUCT_FLOAT_FIELD_ONLY_ONE) { if (pFieldStart[0].GetSize() == 8) size = STRUCT_FIRST_FIELD_DOUBLE; @@ -9748,7 +9619,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) size = STRUCT_FIRST_FIELD_SIZE_IS8; } else - size = 0; + size = STRUCT_NO_FLOAT_FIELD; } else { @@ -9756,7 +9627,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) { size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); - if (size == 1) + if (size == STRUCT_FLOAT_FIELD_ONLY_ONE) { if (pFieldStart[0].GetSize() == 8) size = STRUCT_FIRST_FIELD_DOUBLE; @@ -9768,7 +9639,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) size = STRUCT_FIRST_FIELD_SIZE_IS8; } else - size = 0; + size = STRUCT_NO_FLOAT_FIELD; } else goto _End_arg; @@ -9792,7 +9663,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) MethodTable* pMethodTable2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } if (pMethodTable2->HasLayout()) @@ -9801,7 +9672,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) if (pNativeFieldDescs->NativeSize() > 8) { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } @@ -9811,7 +9682,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) if (pMethodTable->GetNumIntroducedInstanceFields() > 1) { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; goto _End_arg; } @@ -9826,7 +9697,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) size |= STRUCT_SECOND_FIELD_SIZE_IS8; else { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; } } else @@ -9843,7 +9714,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) } else { - size = 0; + size = STRUCT_NO_FLOAT_FIELD; } } //else From f28774a3063bed4b4d6d2d217304f3baf52e2d18 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 14 Jan 2022 12:54:48 +0800 Subject: [PATCH 11/18] [LoongArch64] delete `GetArgType` within `ToolBox/superpmi`. --- .../ToolBox/superpmi/mcs/verbildump.cpp | 5 -- .../superpmi/superpmi-shared/agnostic.h | 1 - .../superpmi/superpmi-shared/callutils.cpp | 10 --- .../superpmi-shared/methodcontext.cpp | 72 ------------------- .../superpmi/superpmi-shared/methodcontext.h | 11 --- 5 files changed, 99 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp index b49d615df9fee7..506d14e587f992 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp @@ -90,12 +90,7 @@ void DumpSigToConsoleBare(MethodContext* mc, CORINFO_SIG_INFO* pSig) for (int i = 0; i < (int)pSig->numArgs; i++) { DWORDLONG dl; -#if defined(TARGET_LOONGARCH64) - int flags; - CorInfoTypeWithMod type = mc->repGetArgType(pSig, currentItem, (CORINFO_CLASS_HANDLE*)&dl, &flags, &exceptionCode); -#else CorInfoTypeWithMod type = mc->repGetArgType(pSig, currentItem, (CORINFO_CLASS_HANDLE*)&dl, &exceptionCode); -#endif CorInfoType cit = strip(type); if (cit == CORINFO_TYPE_CLASS) dl = CastHandle(mc->repGetArgClass(pSig, currentItem, &exceptionCode)); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h index 949ee26259cbd0..fd2a35093c7dec 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h @@ -529,7 +529,6 @@ struct Agnostic_GetArgType_Value DWORDLONG vcTypeRet; DWORD result; DWORD exceptionCode; - int flags;//Now only LoongArch64 used. }; // Agnostic_ConfigIntInfo combines as a single key the name diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp index 403fd88b003215..75bbf2a55c76ec 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp @@ -282,12 +282,7 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL // Tweaked to use EE types instead of JIT-specific types CORINFO_CLASS_HANDLE typeHandle; DWORD exception; -#if defined(TARGET_LOONGARCH64) - int flags; - CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &flags, &exception)); -#else CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &exception)); -#endif length += strlen(TypeUtils::GetCorInfoTypeName(type)); argList = mc->repGetArgNext(argList); @@ -344,12 +339,7 @@ const char* CallUtils::GetMethodFullName(MethodContext* mc, CORINFO_METHOD_HANDL // Tweaked to use EE types instead of JIT-specific types CORINFO_CLASS_HANDLE typeHandle; DWORD exception; -#if defined(TARGET_LOONGARCH64) - int flags; - CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &flags, &exception)); -#else CorInfoType type = strip(mc->repGetArgType(&sig, argList, &typeHandle, &exception)); -#endif strcat_s(retName, length, TypeUtils::GetCorInfoTypeName(type)); argList = mc->repGetArgNext(argList); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 22e5e12e42485b..0b289993bc585e 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -2670,44 +2670,6 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, DEBUG_REC(dmpGetArgType(key, value)); } -void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - CorInfoTypeWithMod result, - int flags, - DWORD exceptionCode) -{ - if (GetArgType == nullptr) - GetArgType = new LightWeightMap(); - - Agnostic_GetArgType_Key key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - - // Only setting values for CORINFO_SIG_INFO things the EE seems to pay attention to... this is necessary since some of the values - // are unset and fail our precise comparisons ... - // TODO: verify that the above comment is still true (that some of the fields of incoming argument `sig` contain garbage), or - // can we store the whole thing and use StoreAgnostic_CORINFO_SIG_INFO()? - - key.flags = (DWORD)sig->flags; - key.numArgs = (DWORD)sig->numArgs; - - SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap, &key.sigInst_classInstCount, &key.sigInst_classInst_Index); - SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap, &key.sigInst_methInstCount, &key.sigInst_methInst_Index); - - key.methodSignature = CastPointer(sig->methodSignature); - key.scope = CastHandle(sig->scope); - key.args = CastHandle(args); - - Agnostic_GetArgType_Value value; - value.vcTypeRet = CastHandle(*vcTypeRet); - value.result = (DWORD)result; - value.flags = flags; - value.exceptionCode = (DWORD)exceptionCode; - - GetArgType->Add(key, value); - DEBUG_REC(dmpGetArgType(key, 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", @@ -2749,40 +2711,6 @@ CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, return temp; } -CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int* flags, - DWORD* exceptionCode) -{ - AssertMapExists(GetArgType, ": key %016llX %016llX", CastHandle(sig->scope), CastHandle(args)); - - Agnostic_GetArgType_Key key; - ZeroMemory(&key, sizeof(key)); // Zero key including any struct padding - key.flags = (DWORD)sig->flags; - key.numArgs = (DWORD)sig->numArgs; - key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; - key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; - key.methodSignature = CastPointer(sig->methodSignature); - key.scope = CastHandle(sig->scope); - key.args = CastHandle(args); - - key.sigInst_classInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap); - key.sigInst_methInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap); - - AssertKeyExists(GetArgType, key, ": key %016llX %016llX", key.scope, key.args); - - Agnostic_GetArgType_Value value = GetArgType->Get(key); - if (flags) - *flags = value.flags; - DEBUG_REP(dmpGetArgType(key, value)); - - *vcTypeRet = (CORINFO_CLASS_HANDLE)value.vcTypeRet; - CorInfoTypeWithMod temp = (CorInfoTypeWithMod)value.result; - *exceptionCode = (DWORD)value.exceptionCode; - return temp; -} - void MethodContext::recGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls, DWORD value) { if (GetFieldSizeClassificationByHnd == nullptr) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 71e75b6236a654..75c31f5ce7c3a6 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -363,22 +363,11 @@ class MethodContext CORINFO_CLASS_HANDLE* vcTypeRet, CorInfoTypeWithMod result, DWORD exception); - void recGetArgType(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - CorInfoTypeWithMod result, - int flags, - DWORD exception); void dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value); CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, DWORD* exception); - CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE* vcTypeRet, - int *flags, - DWORD* exception); void recGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls, DWORD value); void dmpGetFieldSizeClassificationByHnd(DWORDLONG key, DWORD value); From 73d158a2b2a581bd70a5e53c1f893fbec908193e Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 14 Jan 2022 14:25:39 +0800 Subject: [PATCH 12/18] [LoongArch64] rename `getFieldSizeClassificationByHnd` to `getLoongArch64PassStructInRegisterFlags`. --- .../superpmi-shim-collector/icorjitinfo.cpp | 6 ++--- .../superpmi-shim-counter/icorjitinfo.cpp | 6 ++--- .../superpmi-shim-simple/icorjitinfo.cpp | 4 ++-- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 4 ++-- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 2 +- src/coreclr/jit/ICorJitInfo_API_names.h | 2 +- src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 8 +++---- .../tools/Common/JitInterface/CorInfoBase.cs | 6 ++--- .../tools/Common/JitInterface/CorInfoImpl.cs | 2 +- .../ThunkGenerator/ThunkInput.txt | 2 +- .../tools/aot/jitinterface/jitinterface.h | 6 ++--- src/coreclr/vm/jitinterface.cpp | 24 +++++++++---------- 13 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 00e83dfd5d30a8..fe8cbcd702b4e0 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1210,15 +1210,15 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, return temp; } -uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) +uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) { uint32_t temp = 0; RunWithErrorExceptionCodeCaptureAndContinue( [&]() { - mc->cr->AddCall("getFieldSizeClassificationByHnd"); - temp = original_ICorJitInfo->getFieldSizeClassificationByHnd(cls); + mc->cr->AddCall("getLoongArch64PassStructInRegisterFlags"); + temp = original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(cls); }, [&](DWORD exceptionCode) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 12009a2dfac0b6..f79e782fd0104d 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -1389,10 +1389,10 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } -uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd( +uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags( CORINFO_CLASS_HANDLE cls) { - mcs->AddCall("getFieldSizeClassificationByHnd"); - return original_ICorJitInfo->getFieldSizeClassificationByHnd(cls); + mcs->AddCall("getLoongArch64PassStructInRegisterFlags"); + return original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(cls); } diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index e65938eb80305f..aacea09f00ef86 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -1217,9 +1217,9 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } -uint32_t interceptor_ICJI::getFieldSizeClassificationByHnd( +uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags( CORINFO_CLASS_HANDLE cls) { - return original_ICorJitInfo->getFieldSizeClassificationByHnd(cls); + return original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(cls); } diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 005356787d64b4..b8245017486cea 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1060,9 +1060,9 @@ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ return value; } -uint32_t MyICJI::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) +uint32_t MyICJI::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) { - jitInstance->mc->cr->AddCall("getFieldSizeClassificationByHnd"); + jitInstance->mc->cr->AddCall("getLoongArch64PassStructInRegisterFlags"); return jitInstance->mc->repGetFieldSizeClassificationByHnd(cls); } diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 91a8103225c88c..c902eed2705d2e 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2888,7 +2888,7 @@ class ICorStaticInfo /* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr ) = 0; - virtual uint32_t getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) = 0; + virtual uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0; }; /***************************************************************************** diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index a2712946b7ac6b..c150acdcfd849d 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -710,7 +710,7 @@ bool doesFieldBelongToClass( CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) override; -uint32_t getFieldSizeClassificationByHnd( +uint32_t getLoongArch64PassStructInRegisterFlags( CORINFO_CLASS_HANDLE cls) override; /**********************************************************************************/ diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index 3b95239d128654..1b48be79ded0d4 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -176,6 +176,6 @@ DEF_CLR_API(getRelocTypeHint) DEF_CLR_API(getExpectedTargetArchitecture) DEF_CLR_API(getJitFlags) DEF_CLR_API(doesFieldBelongToClass) -DEF_CLR_API(getFieldSizeClassificationByHnd) +DEF_CLR_API(getLoongArch64PassStructInRegisterFlags) #undef DEF_CLR_API diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 35986c5146c4c4..387091e6cff2f6 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -1690,12 +1690,12 @@ bool WrapICorJitInfo::doesFieldBelongToClass( return temp; } -uint32_t WrapICorJitInfo::getFieldSizeClassificationByHnd( +uint32_t WrapICorJitInfo::getLoongArch64PassStructInRegisterFlags( CORINFO_CLASS_HANDLE cls) { - API_ENTER(getFieldSizeClassificationByHnd); - uint32_t temp = wrapHnd->getFieldSizeClassificationByHnd(cls); - API_LEAVE(getFieldSizeClassificationByHnd); + API_ENTER(getLoongArch64PassStructInRegisterFlags); + uint32_t temp = wrapHnd->getLoongArch64PassStructInRegisterFlags(cls); + API_LEAVE(getLoongArch64PassStructInRegisterFlags); return temp; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index fd9b070ee943b2..0eb1332dbebb7b 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -2550,12 +2550,12 @@ static byte _doesFieldBelongToClass(IntPtr thisHandle, IntPtr* ppException, CORI } [UnmanagedCallersOnly] - static uint _getFieldSizeClassificationByHnd(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) + static uint _getLoongArch64PassStructInRegisterFlags(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) { var _this = GetThis(thisHandle); try { - return _this.getFieldSizeClassificationByHnd(cls); + return _this.getLoongArch64PassStructInRegisterFlags(cls); } catch (Exception ex) { @@ -2741,7 +2741,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[169] = (delegate* unmanaged)&_getExpectedTargetArchitecture; callbacks[170] = (delegate* unmanaged)&_getJitFlags; callbacks[171] = (delegate* unmanaged)&_doesFieldBelongToClass; - callbacks[172] = (delegate* unmanaged)&_getFieldSizeClassificationByHnd; + callbacks[172] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 553b9a033b7f3a..1eb709641615bd 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2927,7 +2927,7 @@ private CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_ST } } - private uint getFieldSizeClassificationByHnd(CORINFO_CLASS_STRUCT_* cls) + private uint getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_STRUCT_* cls) { throw new NotImplementedException("For LoongArch64, would be implemented later"); } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 740f2e69555d9e..caaa8cac4fab6d 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -325,4 +325,4 @@ FUNCTIONS uint32_t getExpectedTargetArchitecture() uint32_t getJitFlags(CORJIT_FLAGS* flags, uint32_t sizeInBytes) bool doesFieldBelongToClass(CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) - uint32_t getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls); + uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index eec6778ffc3b38..e6d27299a100d7 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -183,7 +183,7 @@ struct JitInterfaceCallbacks uint32_t (* getExpectedTargetArchitecture)(void * thisHandle, CorInfoExceptionClass** ppException); uint32_t (* getJitFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORJIT_FLAGS* flags, uint32_t sizeInBytes); bool (* doesFieldBelongToClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls); - uint32_t (* getFieldSizeClassificationByHnd)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); + uint32_t (* getLoongArch64PassStructInRegisterFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); }; @@ -1859,11 +1859,11 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } - virtual uint32_t getFieldSizeClassificationByHnd( + virtual uint32_t getLoongArch64PassStructInRegisterFlags( CORINFO_CLASS_HANDLE cls) { CorInfoExceptionClass* pException = nullptr; - uint32_t temp = _callbacks->getFieldSizeClassificationByHnd(_thisHandle, &pException, cls); + uint32_t temp = _callbacks->getLoongArch64PassStructInRegisterFlags(_thisHandle, &pException, cls); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 8b0888de3b994b..9acb2fa60452a0 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9334,7 +9334,7 @@ CorInfoTypeWithMod CEEInfo::getArgType ( // // The returned value's encoding details whether a struct-arg using float regitsters: // see the enum `StructFloatFieldInfoFlags`. -uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) +uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) { CONTRACTL { NOTHROW; @@ -9377,11 +9377,11 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) pMethodTable = th2.GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); } else if (pMethodTable->GetNumIntroducedInstanceFields() == 2) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); } } } @@ -9407,7 +9407,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) pMethodTable = th2.GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + 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; @@ -9448,7 +9448,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) pMethodTable = th2.GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { - DWORD size2 = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + DWORD size2 = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); if (size2 == STRUCT_FLOAT_FIELD_ONLY_ONE) { if (pFieldStart[1].GetSize() == 8) @@ -9542,7 +9542,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pNativeFieldDescs->GetNestedNativeMethodTable()); return size; } else @@ -9550,11 +9550,11 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) pMethodTable = pNativeFieldDescs->GetNestedNativeMethodTable(); if (pNativeFieldDescs->GetNumElements() == 1) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); } else if (pNativeFieldDescs->GetNumElements() == 2) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); } } } @@ -9606,7 +9606,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) goto _End_arg; - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == STRUCT_FLOAT_FIELD_ONLY_ONE) { if (pFieldStart[0].GetSize() == 8) @@ -9626,7 +9626,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) { - size = getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2); + size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2); if (size == STRUCT_FLOAT_FIELD_ONLY_ONE) { if (pFieldStart[0].GetSize() == 8) @@ -9686,7 +9686,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) goto _End_arg; } - if (getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable) == STRUCT_FLOAT_FIELD_ONLY_ONE) + 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); @@ -9725,7 +9725,7 @@ uint32_t CEEInfo::getFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) } else {//whether should confirm the nested ? - if (getFieldSizeClassificationByHnd((CORINFO_CLASS_HANDLE)pMethodTable2) == 1) + 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); From 7d5d052bc1b46b978cef9ee63cc9520606ec85c1 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Mon, 17 Jan 2022 20:31:12 +0800 Subject: [PATCH 13/18] [LoongArch64] amend the floating-ABI for native-struct. --- src/coreclr/vm/jitinterface.cpp | 70 +++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 9acb2fa60452a0..a2e7fcaea997a3 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9372,9 +9372,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - TypeHandle th2 = pFieldStart->GetApproxFieldTypeHandleThrowing(); - _ASSERTE(!th2.IsNull()); - pMethodTable = th2.GetMethodTable(); + pMethodTable = pFieldStart->LookupApproxFieldTypeHandle().GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); @@ -9402,9 +9400,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - TypeHandle th2 = pFieldStart->GetApproxFieldTypeHandleThrowing(); - _ASSERTE(!th2.IsNull()); - pMethodTable = th2.GetMethodTable(); + pMethodTable = pFieldStart->LookupApproxFieldTypeHandle().GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); @@ -9443,9 +9439,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - TypeHandle th2 = pFieldStart[1].GetApproxFieldTypeHandleThrowing(); - _ASSERTE(!th2.IsNull()); - pMethodTable = th2.GetMethodTable(); + pMethodTable = pFieldStart->LookupApproxFieldTypeHandle().GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { DWORD size2 = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); @@ -9491,9 +9485,6 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c { if (th.GetSize() <= 16 /*MAX_PASS_MULTIREG_BYTES*/) { - //MethodTable* pMethodTable = th.AsMethodTable(); - //assert(pMethodTable->GetNumInstanceFieldBytes() <= 16 /*MAX_PASS_MULTIREG_BYTES*/); - DWORD numIntroducedFields = pMethodTable->GetNumIntroducedInstanceFields(); FieldDesc *pFieldStart = nullptr; @@ -9501,7 +9492,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c { pFieldStart = pMethodTable->GetApproxFieldDescListRaw(); - CorElementType fieldType = pFieldStart[0].GetFieldType(); + CorElementType fieldType = pFieldStart->GetFieldType(); bool isFixedBuffer = (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) || fieldType == ELEMENT_TYPE_VALUETYPE) @@ -9545,6 +9536,22 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c 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----"); + //size = STRUCT_NO_FLOAT_FIELD; + } + } else { pMethodTable = pNativeFieldDescs->GetNestedNativeMethodTable(); @@ -9621,6 +9628,22 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c 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"); + //size = STRUCT_NO_FLOAT_FIELD; + } + } else { MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); @@ -9700,6 +9723,22 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c 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"); + //size = STRUCT_NO_FLOAT_FIELD; + } + } else { if (pNativeFieldDescs->GetNumElements() == 1) @@ -9709,6 +9748,11 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c 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; } From b8534b2fa590187f137c20abe79baab7dfebe37b Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 19 Jan 2022 12:50:00 +0800 Subject: [PATCH 14/18] [LoongArch64] update all related `GetFieldSizeClassificationByHnd` by `GetLoongArch64PassStructInRegisterFlags` and amend some comments. --- .../superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 46 +++--- .../superpmi/superpmi-shared/methodcontext.h | 10 +- .../superpmi-shim-collector/icorjitinfo.cpp | 26 +--- .../superpmi-shim-counter/icorjitinfo.cpp | 14 +- .../superpmi-shim-simple/icorjitinfo.cpp | 12 +- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 12 +- src/coreclr/inc/corinfo.h | 28 ++-- src/coreclr/inc/icorjitinfoimpl_generated.h | 6 +- src/coreclr/jit/ICorJitInfo_API_names.h | 2 +- src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 18 +-- .../tools/Common/JitInterface/CorInfoBase.cs | 140 +++++++++--------- .../ThunkGenerator/ThunkInput.txt | 2 +- .../tools/aot/jitinterface/jitinterface.h | 20 +-- 14 files changed, 168 insertions(+), 170 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index 3add14c9d81038..4c0ebcc086d12c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -127,6 +127,7 @@ LWM(GetExpectedTargetArchitecture, DWORD, DWORD) LWM(GetSharedCCtorHelper, DWORDLONG, DWORD) LWM(GetStringConfigValue, DWORD, DWORD) LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor) +LWM(GetLoongArch64PassStructInRegisterFlags, DWORDLONG, DWORD) LWM(GetTailCallHelpers, Agnostic_GetTailCallHelpers, Agnostic_CORINFO_TAILCALL_HELPERS) LWM(UpdateEntryPointForTailCall, Agnostic_CORINFO_CONST_LOOKUP, Agnostic_CORINFO_CONST_LOOKUP) LWM(GetThreadTLSIndex, DWORD, DLD) @@ -159,7 +160,6 @@ LWM(SatisfiesMethodConstraints, DLDL, DWORD) LWM(GetUnmanagedCallConv, MethodOrSigInfoValue, DD) LWM(DoesFieldBelongToClass, DLDL, DWORD) DENSELWM(SigInstHandleMap, DWORDLONG) -LWM(GetFieldSizeClassificationByHnd, DWORDLONG, DWORD) #undef LWM #undef DENSELWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 0b289993bc585e..b21dace5f40f52 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -2711,27 +2711,6 @@ CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, return temp; } -void MethodContext::recGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls, DWORD value) -{ - if (GetFieldSizeClassificationByHnd == nullptr) - GetFieldSizeClassificationByHnd = new LightWeightMap(); - - DWORDLONG key = (DWORDLONG)cls; - - GetFieldSizeClassificationByHnd->Add((DWORDLONG)cls, value); - //DEBUG_REC(dmpGetArgType(key, value)); -} - -void MethodContext::dmpGetFieldSizeClassificationByHnd(DWORDLONG key, DWORD value) -{ - printf("GetFieldSizeClassificationByHnd key %016llX value-%08X", key, value); -} - -DWORD MethodContext::repGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls) -{ - return GetFieldSizeClassificationByHnd->Get((DWORDLONG)cls); -} - void MethodContext::recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result) { if (GetArgNext == nullptr) @@ -6151,6 +6130,31 @@ bool MethodContext::repGetSystemVAmd64PassStructInRegisterDescriptor( return value.result ? true : false; } +void MethodContext::recGetLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd, DWORD value) +{ + if (GetLoongArch64PassStructInRegisterFlags == nullptr) + GetLoongArch64PassStructInRegisterFlags = new LightWeightMap(); + + 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) { if (GetRelocTypeHint == nullptr) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 75c31f5ce7c3a6..97a77c011bb60f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -369,10 +369,6 @@ class MethodContext CORINFO_CLASS_HANDLE* vcTypeRet, DWORD* exception); - void recGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls, DWORD value); - void dmpGetFieldSizeClassificationByHnd(DWORDLONG key, DWORD value); - DWORD repGetFieldSizeClassificationByHnd(CORINFO_CLASS_HANDLE cls); - void recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result); void dmpGetArgNext(DWORDLONG key, DWORDLONG value); CORINFO_ARG_LIST_HANDLE repGetArgNext(CORINFO_ARG_LIST_HANDLE args); @@ -757,6 +753,10 @@ class MethodContext bool repGetSystemVAmd64PassStructInRegisterDescriptor( 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 dmpGetRelocTypeHint(DWORDLONG key, DWORD value); WORD repGetRelocTypeHint(void* target); @@ -1101,7 +1101,7 @@ enum mcPackets Packet_GetAssemblyName = 191, Packet_IsIntrinsic = 192, Packet_UpdateEntryPointForTailCall = 193, - Packet_GetFieldSizeClassificationByHnd = 194, + Packet_GetLoongArch64PassStructInRegisterFlags = 194, }; void SetDebugDumpVariables(); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index fe8cbcd702b4e0..de597bdd3df647 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1210,24 +1210,6 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, return temp; } -uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) -{ - - uint32_t temp = 0; - RunWithErrorExceptionCodeCaptureAndContinue( - [&]() - { - mc->cr->AddCall("getLoongArch64PassStructInRegisterFlags"); - temp = original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(cls); - }, - [&](DWORD exceptionCode) - { - this->mc->recGetFieldSizeClassificationByHnd(cls, temp); - }); - - return temp; -} - // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it CORINFO_CLASS_HANDLE interceptor_ICJI::getArgClass(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args /* IN */ @@ -1407,6 +1389,14 @@ bool interceptor_ICJI::getSystemVAmd64PassStructInRegisterDescriptor( 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 uint32_t interceptor_ICJI::getThreadTLSIndex(void** ppIndirection) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index f79e782fd0104d..08fe084a5591da 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -944,6 +944,13 @@ bool interceptor_ICJI::getSystemVAmd64PassStructInRegisterDescriptor( 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( void** ppIndirection) { @@ -1389,10 +1396,3 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } -uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags( - CORINFO_CLASS_HANDLE cls) -{ - mcs->AddCall("getLoongArch64PassStructInRegisterFlags"); - return original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(cls); -} - diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index aacea09f00ef86..cf262a2878a8f3 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -826,6 +826,12 @@ bool interceptor_ICJI::getSystemVAmd64PassStructInRegisterDescriptor( 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( void** ppIndirection) { @@ -1217,9 +1223,3 @@ bool interceptor_ICJI::doesFieldBelongToClass( return original_ICorJitInfo->doesFieldBelongToClass(fldHnd, cls); } -uint32_t interceptor_ICJI::getLoongArch64PassStructInRegisterFlags( - CORINFO_CLASS_HANDLE cls) -{ - return original_ICorJitInfo->getLoongArch64PassStructInRegisterFlags(cls); -} - diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index b8245017486cea..095aeedd3dd74c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1060,12 +1060,6 @@ CorInfoTypeWithMod MyICJI::getArgType(CORINFO_SIG_INFO* sig, /* IN */ return value; } -uint32_t MyICJI::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) -{ - jitInstance->mc->cr->AddCall("getLoongArch64PassStructInRegisterFlags"); - return jitInstance->mc->repGetFieldSizeClassificationByHnd(cls); -} - // If the Arg is a CORINFO_TYPE_CLASS fetch the class handle associated with it CORINFO_CLASS_HANDLE MyICJI::getArgClass(CORINFO_SIG_INFO* sig, /* IN */ CORINFO_ARG_LIST_HANDLE args /* IN */ @@ -1236,6 +1230,12 @@ bool MyICJI::getSystemVAmd64PassStructInRegisterDescriptor( 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 uint32_t MyICJI::getThreadTLSIndex(void** ppIndirection) { diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index c902eed2705d2e..ecc4a1a2c85128 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -316,20 +316,24 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR } }; -// NOTE: -// 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. +// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` API +// to convey struct argument passing information. // -// `STRUCT_NO_FLOAT_FIELD`=0 means not using the float register(s). +// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s). // -// the lowest four bits denoting 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 float-point type. -// bit_2: `1` means only the second field is float-point type. -// bit_3: `1` means the two fields are both float-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. +// 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 : uint8_t { STRUCT_NO_FLOAT_FIELD = 0x0, diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index c150acdcfd849d..e4defab57fc8e5 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -481,6 +481,9 @@ bool getSystemVAmd64PassStructInRegisterDescriptor( CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr) override; +uint32_t getLoongArch64PassStructInRegisterFlags( + CORINFO_CLASS_HANDLE structHnd) override; + uint32_t getThreadTLSIndex( void** ppIndirection) override; @@ -710,9 +713,6 @@ bool doesFieldBelongToClass( CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) override; -uint32_t getLoongArch64PassStructInRegisterFlags( - CORINFO_CLASS_HANDLE cls) override; - /**********************************************************************************/ // clang-format on /**********************************************************************************/ diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index 1b48be79ded0d4..fec05d5c398f1c 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -122,6 +122,7 @@ DEF_CLR_API(getMethodNameFromMetadata) DEF_CLR_API(getMethodHash) DEF_CLR_API(findNameOfToken) DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor) +DEF_CLR_API(getLoongArch64PassStructInRegisterFlags) DEF_CLR_API(getThreadTLSIndex) DEF_CLR_API(getInlinedCallFrameVptr) DEF_CLR_API(getAddrOfCaptureThreadGlobal) @@ -176,6 +177,5 @@ DEF_CLR_API(getRelocTypeHint) DEF_CLR_API(getExpectedTargetArchitecture) DEF_CLR_API(getJitFlags) DEF_CLR_API(doesFieldBelongToClass) -DEF_CLR_API(getLoongArch64PassStructInRegisterFlags) #undef DEF_CLR_API diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 387091e6cff2f6..ba190f0bc7a7c0 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -1155,6 +1155,15 @@ bool WrapICorJitInfo::getSystemVAmd64PassStructInRegisterDescriptor( 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( void** ppIndirection) { @@ -1690,15 +1699,6 @@ bool WrapICorJitInfo::doesFieldBelongToClass( return temp; } -uint32_t WrapICorJitInfo::getLoongArch64PassStructInRegisterFlags( - CORINFO_CLASS_HANDLE cls) -{ - API_ENTER(getLoongArch64PassStructInRegisterFlags); - uint32_t temp = wrapHnd->getLoongArch64PassStructInRegisterFlags(cls); - API_LEAVE(getLoongArch64PassStructInRegisterFlags); - return temp; -} - /**********************************************************************************/ // clang-format on /**********************************************************************************/ diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 0eb1332dbebb7b..9f3ded304fed3c 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -1757,6 +1757,21 @@ static byte _getSystemVAmd64PassStructInRegisterDescriptor(IntPtr thisHandle, In } } + [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] static uint _getThreadTLSIndex(IntPtr thisHandle, IntPtr* ppException, void** ppIndirection) { @@ -2549,21 +2564,6 @@ static byte _doesFieldBelongToClass(IntPtr thisHandle, IntPtr* ppException, CORI } } - [UnmanagedCallersOnly] - static uint _getLoongArch64PassStructInRegisterFlags(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLASS_STRUCT_* cls) - { - var _this = GetThis(thisHandle); - try - { - return _this.getLoongArch64PassStructInRegisterFlags(cls); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - static IntPtr GetUnmanagedCallbacks() { @@ -2687,61 +2687,61 @@ static IntPtr GetUnmanagedCallbacks() callbacks[115] = (delegate* unmanaged)&_getMethodHash; callbacks[116] = (delegate* unmanaged)&_findNameOfToken; callbacks[117] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[118] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[119] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[120] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[121] = (delegate* unmanaged)&_getHelperFtn; - callbacks[122] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[123] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[124] = (delegate* unmanaged)&_getMethodSync; - callbacks[125] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[126] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[127] = (delegate* unmanaged)&_embedClassHandle; - callbacks[128] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[129] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[130] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[131] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[132] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[133] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[134] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[135] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[136] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[137] = (delegate* unmanaged)&_getCallInfo; - callbacks[138] = (delegate* unmanaged)&_canAccessFamily; - callbacks[139] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[140] = (delegate* unmanaged)&_getClassDomainID; - callbacks[141] = (delegate* unmanaged)&_getFieldAddress; - callbacks[142] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[143] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[144] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[145] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[146] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[147] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[148] = (delegate* unmanaged)&_addActiveDependency; - callbacks[149] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[150] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[151] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[152] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[153] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[154] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[155] = (delegate* unmanaged)&_allocMem; - callbacks[156] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[157] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[158] = (delegate* unmanaged)&_allocGCInfo; - callbacks[159] = (delegate* unmanaged)&_setEHcount; - callbacks[160] = (delegate* unmanaged)&_setEHinfo; - callbacks[161] = (delegate* unmanaged)&_logMsg; - callbacks[162] = (delegate* unmanaged)&_doAssert; - callbacks[163] = (delegate* unmanaged)&_reportFatalError; - callbacks[164] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[165] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[166] = (delegate* unmanaged)&_recordCallSite; - callbacks[167] = (delegate* unmanaged)&_recordRelocation; - callbacks[168] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[169] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[170] = (delegate* unmanaged)&_getJitFlags; - callbacks[171] = (delegate* unmanaged)&_doesFieldBelongToClass; - callbacks[172] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[118] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[119] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[120] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[121] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[122] = (delegate* unmanaged)&_getHelperFtn; + callbacks[123] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[124] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[125] = (delegate* unmanaged)&_getMethodSync; + callbacks[126] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[127] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[128] = (delegate* unmanaged)&_embedClassHandle; + callbacks[129] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[130] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[131] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[132] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[133] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[134] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[135] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[136] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[137] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[138] = (delegate* unmanaged)&_getCallInfo; + callbacks[139] = (delegate* unmanaged)&_canAccessFamily; + callbacks[140] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[141] = (delegate* unmanaged)&_getClassDomainID; + callbacks[142] = (delegate* unmanaged)&_getFieldAddress; + callbacks[143] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[144] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[145] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[146] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[147] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[148] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[149] = (delegate* unmanaged)&_addActiveDependency; + callbacks[150] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[151] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[152] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[153] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[154] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[155] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[156] = (delegate* unmanaged)&_allocMem; + callbacks[157] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[158] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[159] = (delegate* unmanaged)&_allocGCInfo; + callbacks[160] = (delegate* unmanaged)&_setEHcount; + callbacks[161] = (delegate* unmanaged)&_setEHinfo; + callbacks[162] = (delegate* unmanaged)&_logMsg; + callbacks[163] = (delegate* unmanaged)&_doAssert; + callbacks[164] = (delegate* unmanaged)&_reportFatalError; + callbacks[165] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[166] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[167] = (delegate* unmanaged)&_recordCallSite; + callbacks[168] = (delegate* unmanaged)&_recordRelocation; + callbacks[169] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[171] = (delegate* unmanaged)&_getJitFlags; + callbacks[172] = (delegate* unmanaged)&_doesFieldBelongToClass; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index caaa8cac4fab6d..fd3024aa9d6b1b 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -271,6 +271,7 @@ FUNCTIONS unsigned getMethodHash(CORINFO_METHOD_HANDLE ftn); 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); + uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE structHnd); uint32_t getThreadTLSIndex(void **ppIndirection); const void * getInlinedCallFrameVptr(void **ppIndirection); int32_t * getAddrOfCaptureThreadGlobal(void **ppIndirection); @@ -325,4 +326,3 @@ FUNCTIONS uint32_t getExpectedTargetArchitecture() uint32_t getJitFlags(CORJIT_FLAGS* flags, uint32_t sizeInBytes) bool doesFieldBelongToClass(CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls) - uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index e6d27299a100d7..36e3bdb62a3578 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -129,6 +129,7 @@ struct JitInterfaceCallbacks 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); 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); const void* (* getInlinedCallFrameVptr)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); int32_t* (* getAddrOfCaptureThreadGlobal)(void * thisHandle, CorInfoExceptionClass** ppException, void** ppIndirection); @@ -183,7 +184,6 @@ struct JitInterfaceCallbacks uint32_t (* getExpectedTargetArchitecture)(void * thisHandle, CorInfoExceptionClass** ppException); uint32_t (* getJitFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORJIT_FLAGS* flags, uint32_t sizeInBytes); bool (* doesFieldBelongToClass)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_FIELD_HANDLE fldHnd, CORINFO_CLASS_HANDLE cls); - uint32_t (* getLoongArch64PassStructInRegisterFlags)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE cls); }; @@ -1324,6 +1324,15 @@ class JitInterfaceWrapper : public ICorJitInfo 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( void** ppIndirection) { @@ -1858,13 +1867,4 @@ class JitInterfaceWrapper : public ICorJitInfo if (pException != nullptr) throw pException; return temp; } - - virtual uint32_t getLoongArch64PassStructInRegisterFlags( - CORINFO_CLASS_HANDLE cls) -{ - CorInfoExceptionClass* pException = nullptr; - uint32_t temp = _callbacks->getLoongArch64PassStructInRegisterFlags(_thisHandle, &pException, cls); - if (pException != nullptr) throw pException; - return temp; -} }; From a3688bf549e1118400fe778e47a3287a661d2ee7 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 15 Feb 2022 16:17:24 +0800 Subject: [PATCH 15/18] [LoongArch64] replace `LookupApproxFieldTypeHandle()` by `GetFieldTypeHandleThrowing()`. --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/vm/jitinterface.cpp | 26 ++++++-------------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index ecc4a1a2c85128..111d070969ae73 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -334,7 +334,7 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR // bit 5: `1` means the second field's size is 8. // // Note that bit 0 and 3 cannot both be set. -enum StructFloatFieldInfoFlags : uint8_t +enum StructFloatFieldInfoFlags { STRUCT_NO_FLOAT_FIELD = 0x0, STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1, diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index a2e7fcaea997a3..93ffa5bb7708a9 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9372,7 +9372,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - pMethodTable = pFieldStart->LookupApproxFieldTypeHandle().GetMethodTable(); + pMethodTable = pFieldStart->GetFieldTypeHandleThrowing().GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); @@ -9400,7 +9400,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - pMethodTable = pFieldStart->LookupApproxFieldTypeHandle().GetMethodTable(); + pMethodTable = pFieldStart->GetFieldTypeHandleThrowing().GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); @@ -9439,7 +9439,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - pMethodTable = pFieldStart->LookupApproxFieldTypeHandle().GetMethodTable(); + pMethodTable = pFieldStart[1].GetFieldTypeHandleThrowing().GetMethodTable(); if (pMethodTable->GetNumIntroducedInstanceFields() == 1) { DWORD size2 = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable); @@ -9549,7 +9549,6 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c else { UNREACHABLE_MSG("Invalid NativeFieldCategory.----LoongArch64----"); - //size = STRUCT_NO_FLOAT_FIELD; } } else @@ -9601,12 +9600,6 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c { const NativeFieldDescriptor *pNativeFieldDescs = pMethodTable->GetNativeLayoutInfo()->GetNativeFieldDescriptors(); - //bool isFixedBuffer = numIntroducedFields == 1 && (CorTypeInfo::IsPrimitiveType_NoThrow(fieldType) - // || fieldType == ELEMENT_TYPE_VALUETYPE) - // && (pFieldStart->GetOffset() == 0) - // && pMethodTable->HasLayout() - // && (pMethodTable->GetNumInstanceFieldBytes() % pFieldStart->GetSize() == 0); - if (pNativeFieldDescs->GetCategory() == NativeFieldCategory::NESTED) { MethodTable* pMethodTable2 = pNativeFieldDescs->GetNestedNativeMethodTable(); @@ -9641,12 +9634,11 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c else { UNREACHABLE_MSG("Invalid NativeFieldCategory.----LoongArch64----2"); - //size = STRUCT_NO_FLOAT_FIELD; } } else { - MethodTable* pMethodTable2 = pFieldStart[0].LookupApproxFieldTypeHandle().AsMethodTable(); + MethodTable* pMethodTable2 = pFieldStart[0].GetFieldTypeHandleThrowing().AsMethodTable(); if (pMethodTable2->GetNumIntroducedInstanceFields() == 1) { size = getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2); @@ -9683,7 +9675,7 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c } else if (fieldType == ELEMENT_TYPE_VALUETYPE) { - MethodTable* pMethodTable2 = pFieldStart[1].LookupApproxFieldTypeHandle().AsMethodTable(); + MethodTable* pMethodTable2 = pFieldStart[1].GetFieldTypeHandleThrowing().AsMethodTable(); if ((pMethodTable2->GetNumInstanceFieldBytes() > 8) || (pMethodTable2->GetNumIntroducedInstanceFields() > 1)) { size = STRUCT_NO_FLOAT_FIELD; @@ -9736,7 +9728,6 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c else { UNREACHABLE_MSG("Invalid NativeFieldCategory.----LoongArch64----3"); - //size = STRUCT_NO_FLOAT_FIELD; } } else @@ -9761,14 +9752,9 @@ uint32_t CEEInfo::getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE c size = STRUCT_NO_FLOAT_FIELD; } } - //else - //{ - // assert(!"------------should amend for LOONGARCH64!!!"); - // goto _End_arg; - //} } else - {//whether should confirm the nested ? + { if (getLoongArch64PassStructInRegisterFlags((CORINFO_CLASS_HANDLE)pMethodTable2) == 1) { if (pMethodTable2->GetNumInstanceFieldBytes() == 4) From b05a2b90e8d8a2f6d1cf7f101ddfc9d4ed8d984e Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Tue, 15 Feb 2022 16:37:29 +0800 Subject: [PATCH 16/18] [LoongArch64] implements the crossgen2 for LoongArch64. --- .../DependencyAnalysis/AssemblyStubNode.cs | 8 + .../DependencyAnalysis/ObjectDataBuilder.cs | 2 + .../Compiler/DependencyAnalysis/Relocation.cs | 96 +++++++++ .../Target_LoongArch64/AddrMode.cs | 34 ++++ .../Target_LoongArch64/LoongArch64Emitter.cs | 70 +++++++ .../Target_LoongArch64/Register.cs | 50 +++++ .../Target_LoongArch64/TargetRegisterMap.cs | 38 ++++ .../Common/Compiler/InstructionSetSupport.cs | 4 + .../tools/Common/JitInterface/CorInfoImpl.cs | 27 ++- .../tools/Common/JitInterface/CorInfoTypes.cs | 40 ++++ .../Common/JitInterface/JitConfigProvider.cs | 1 + .../LoongArch64PassStructInRegister.cs | 168 ++++++++++++++++ .../TypeSystem/Common/TargetArchitecture.cs | 1 + .../Common/TypeSystem/Common/TargetDetails.cs | 8 + .../ReadyToRun/ArgIterator.cs | 187 +++++++++++++++++- .../ReadyToRun/MethodGCInfoNode.cs | 2 +- .../Target_LoongArch64/ImportThunk.cs | 71 +++++++ .../ReadyToRun/TransitionBlock.cs | 44 +++++ .../ReadyToRunMetadataFieldLayoutAlgorithm.cs | 9 + .../ILCompiler.ReadyToRun.csproj | 6 + .../ObjectWriter/RelocationHelper.cs | 8 + .../ReadyToRunReader.cs | 8 + .../TransitionBlock.cs | 15 ++ src/coreclr/tools/aot/crossgen2/Program.cs | 5 + .../tools/aot/crossgen2/crossgen2.props | 2 +- 25 files changed, 899 insertions(+), 5 deletions(-) create mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs create mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs create mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs create mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs create mode 100644 src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs create mode 100644 src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs index b95daf56f0b45e..b289ff347063db 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs @@ -68,6 +68,13 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly) arm64Emitter.Builder.AddSymbol(this); return arm64Emitter.Builder.ToObjectData(); + case TargetArchitecture.LoongArch64: + LoongArch64.LoongArch64Emitter loongarch64Emitter = new LoongArch64.LoongArch64Emitter(factory, relocsOnly); + EmitCode(factory, ref loongarch64Emitter, relocsOnly); + loongarch64Emitter.Builder.RequireInitialAlignment(alignment); + loongarch64Emitter.Builder.AddSymbol(this); + return loongarch64Emitter.Builder.ToObjectData(); + default: throw new NotImplementedException(); } @@ -77,5 +84,6 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly) protected abstract void EmitCode(NodeFactory factory, ref X86.X86Emitter instructionEncoder, bool relocsOnly); protected abstract void EmitCode(NodeFactory factory, ref ARM.ARMEmitter instructionEncoder, bool relocsOnly); protected abstract void EmitCode(NodeFactory factory, ref ARM64.ARM64Emitter instructionEncoder, bool relocsOnly); + protected abstract void EmitCode(NodeFactory factory, ref LoongArch64.LoongArch64Emitter instructionEncoder, bool relocsOnly); } } diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs index da20de18b9f87c..f20020ad71051a 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs @@ -303,6 +303,8 @@ public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0) case RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21: case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12L: case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: + case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: + case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: Debug.Assert(delta == 0); // Do not vacate space for this kind of relocation, because // the space is embedded in the instruction. diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index eda9378acc36d4..bc31c9aa744abb 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -16,6 +16,8 @@ public enum RelocType IMAGE_REL_BASED_THUMB_BRANCH24 = 0x13, // Thumb2: based B, BL IMAGE_REL_BASED_THUMB_MOV32_PCREL = 0x14, // Thumb2: based MOVW/MOVT IMAGE_REL_BASED_ARM64_BRANCH26 = 0x15, // Arm64: B, BL + IMAGE_REL_BASED_LOONGARCH64_PC = 0x16, // LoongArch64: pcaddu12i+imm12 + IMAGE_REL_BASED_LOONGARCH64_JIR = 0x17, // LoongArch64: pcaddu18i+jirl IMAGE_REL_BASED_RELPTR32 = 0x7C, // 32-bit relative address from byte starting reloc // This is a special NGEN-specific relocation type // for relative pointer (used to make NGen relocation @@ -294,7 +296,91 @@ private static unsafe void PutArm64Rel28(uint* pCode, long imm28) Debug.Assert(GetArm64Rel28(pCode) == imm28); } + private static unsafe int GetLoongArch64PC12(uint* pCode) + { + uint pcInstr = *pCode; + + // first shift 6 bits left to set the sign bit, + // then arithmetic shift right by 4 bits + int imm = (int)(((pcInstr >> 5) & 0xFFFFF) << 12); + + pcInstr = *(pCode + 1); + imm += ((short)(((pcInstr >> 10) & 0xFFF) << 4)) >> 4; + + return imm; + } + + private static unsafe void PutLoongArch64PC12(uint* pCode, long imm32) + { + // Verify that we got a valid offset + Debug.Assert((int)imm32 == imm32); + + uint pcInstr = *pCode; + Debug.Assert((pcInstr & 0xFE000000) == 0x1c000000); // Must be pcaddu12i + + int relOff = (int)imm32 & 0x800; + int imm = (int)imm32 + relOff; + relOff = ((imm & 0x7ff) - relOff) & 0xfff; + + // Assemble the pc-relative hight20bits of 'imm32' into the pcaddu12i instruction + pcInstr |= (uint)(((imm >> 12) & 0xFFFFF) << 5); + + *pCode = pcInstr; // write the assembled instruction + + pcInstr = *(pCode + 1); + + // Assemble the pc-relative low12bits of 'imm32' into the addid or ld instruction + pcInstr |= (uint)(relOff << 10); + + *(pCode + 1) = pcInstr; // write the assembled instruction + + Debug.Assert(GetLoongArch64PC12(pCode) == imm32); + } + + private static unsafe long GetLoongArch64JIR(uint* pCode) + { + uint pcInstr = *pCode; + + // first shift 6 bits left to set the sign bit, + // then arithmetic shift right by 4 bits + long imm = ((long)((pcInstr >> 5) & 0xFFFFF) << 18); + + pcInstr = *(pCode + 1); + imm += ((long)((short)((pcInstr >> 10) & 0xFFFF))) << 2; + + return imm; + } + + private static unsafe void PutLoongArch64JIR(uint* pCode, long imm38) + { + // Verify that we got a valid offset + Debug.Assert((imm38 >= -0x2000000000L) && (imm38 < 0x2000000000L)); + + Debug.Assert((imm38 & 0x3) == 0); // the low two bits must be zero + + uint pcInstr = *pCode; + + Debug.Assert(pcInstr == 0x1e00000e); // Must be pcaddu18i R14, 0 + + long relOff = imm38 & 0x20000; + long imm = imm38 + relOff; + relOff = (((imm & 0x1ffff) - relOff) >> 2) & 0xffff; + + // Assemble the pc-relative hight20bits of 'imm38' into the pcaddu12i instruction + pcInstr |= (uint)(((imm >> 18) & 0xFFFFF) << 5); + + *pCode = pcInstr; // write the assembled instruction + + pcInstr = *(pCode + 1); + + // Assemble the pc-relative low18bits of 'imm38' into the addid or ld instruction + pcInstr |= (uint)(relOff << 10); + + *(pCode + 1) = pcInstr; // write the assembled instruction + + Debug.Assert(GetLoongArch64JIR(pCode) == imm38); + } public Relocation(RelocType relocType, int offset, ISymbolNode target) { @@ -334,6 +420,12 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: PutArm64Rel12((uint*)location, (int)value); break; + case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: + PutLoongArch64PC12((uint*)location, value); + break; + case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: + PutLoongArch64JIR((uint*)location, value); + break; default: Debug.Fail("Invalid RelocType: " + relocType); break; @@ -366,6 +458,10 @@ public static unsafe long ReadValue(RelocType relocType, void* location) return GetArm64Rel21((uint*)location); case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: return GetArm64Rel12((uint*)location); + case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: + return 0; // (long)GetLoongArch64PC12((uint*)location); + case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: + return 0; // (long)GetLoongArch64JIR((uint*)location); default: Debug.Fail("Invalid RelocType: " + relocType); return 0; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs new file mode 100644 index 00000000000000..5616941cae238f --- /dev/null +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace ILCompiler.DependencyAnalysis.LoongArch64 +{ + public enum AddrModeSize + { + Int8 = 1, + Int16 = 2, + Int32 = 4, + Int64 = 8, + Int128 = 16 + } + + public struct AddrMode + { + public readonly Register BaseReg; + public readonly Register? IndexReg; + public readonly int Offset; + public readonly byte Scale; + public readonly AddrModeSize Size; + + public AddrMode(Register baseRegister, Register? indexRegister, int offset, byte scale, AddrModeSize size) + { + BaseReg = baseRegister; + IndexReg = indexRegister; + Offset = offset; + Scale = scale; + Size = size; + } + } +} diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs new file mode 100644 index 00000000000000..b7e24442aec83b --- /dev/null +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Diagnostics; + +namespace ILCompiler.DependencyAnalysis.LoongArch64 +{ + public struct LoongArch64Emitter + { + public LoongArch64Emitter(NodeFactory factory, bool relocsOnly) + { + Builder = new ObjectDataBuilder(factory, relocsOnly); + TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem); + } + + public ObjectDataBuilder Builder; + public TargetRegisterMap TargetRegister; + + // Assembly stub creation api. TBD, actually make this general purpose + + public void EmitMOV(Register regDst, ushort imm16) + { + Debug.Assert((uint)regDst <= 0x1f); + Debug.Assert(imm16 <= 0xfff); + uint instruction = 0x03800000u | (uint)((imm16 & 0xfff) << 10) | (uint)regDst; + Builder.EmitUInt(instruction); + } + + // pcaddi regDst, 0 + public void EmitPC(Register regDst) + { + Debug.Assert((uint)regDst > 0 && (uint)regDst < 32); + Builder.EmitUInt(0x18000000 | (uint)regDst); + } + + // ld_d regDst, regAddr, offset + public void EmitLD(Register regDst, Register regSrc, int offset) + { + Debug.Assert(offset >= -2048 && offset <= 2047); + + Builder.EmitUInt((uint)(0x28c00000 | (uint)((offset & 0xfff) << 12) | ((uint)regSrc << 5) | (uint)regDst)); + } + + public void EmitJMP(ISymbolNode symbol) + { + if (symbol.RepresentsIndirectionCell) + { + // pcaddi R21, 0 + EmitPC(Register.R21); + + EmitLD(Register.R21, Register.R21, 0x10); + + // ld_d R21, R21, 0 + EmitLD(Register.R21, Register.R21, 0); + + // jirl R0,R21,0 + Builder.EmitUInt(0x4c0002a0); + + Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_DIR64); + } + else + { + //Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_LOONGARCH64_PC); + Builder.EmitUInt(0xffffffff); // bad code. + throw new NotImplementedException(); + } + } + } +} diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs new file mode 100644 index 00000000000000..1ce65e76622878 --- /dev/null +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs @@ -0,0 +1,50 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ILCompiler.DependencyAnalysis.LoongArch64 +{ + public enum Register + { + R0 = 0, + R1 = 1, + R2 = 2, + R3 = 3, + R4 = 4, + R5 = 5, + R6 = 6, + R7 = 7, + R8 = 8, + R9 = 9, + R10 = 10, + R11 = 11, + R12 = 12, + R13 = 13, + R14 = 14, + R15 = 15, + R16 = 16, + R17 = 17, + R18 = 18, + R19 = 19, + R20 = 20, + R21 = 21, + R22 = 22, + R23 = 23, + R24 = 24, + R25 = 25, + R26 = 26, + R27 = 27, + R28 = 28, + R29 = 29, + R30 = 30, + R31 = 31, + + None = 32, + NoIndex = 128, + } +} diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs new file mode 100644 index 00000000000000..fdfdddf2170457 --- /dev/null +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +using Internal.TypeSystem; + +namespace ILCompiler.DependencyAnalysis.LoongArch64 +{ + /// + /// Maps logical registers to physical registers on a specified OS. + /// + public struct TargetRegisterMap + { + public readonly Register Arg0; + public readonly Register Arg1; + public readonly Register Arg2; + public readonly Register Arg3; + public readonly Register Arg4; + public readonly Register Arg5; + public readonly Register Arg6; + public readonly Register Arg7; + public readonly Register Result; + + public TargetRegisterMap(TargetOS os) + { + Arg0 = Register.R4; + Arg1 = Register.R5; + Arg2 = Register.R6; + Arg3 = Register.R7; + Arg4 = Register.R8; + Arg5 = Register.R9; + Arg6 = Register.R11; + Arg7 = Register.R12; + Result = Register.R4; // TODO: ??? + } + } +} diff --git a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs index 2f35f083f24d2e..d21276726b7f56 100644 --- a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs +++ b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs @@ -110,6 +110,10 @@ public SimdVectorLength GetVectorTSimdVector() { return SimdVectorLength.None; } + else if (_targetArchitecture == TargetArchitecture.LoongArch64) + { + return SimdVectorLength.None; + } else { Debug.Assert(false); // Unknown architecture diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 1eb709641615bd..43fa97a94bbc39 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -46,6 +46,7 @@ private enum ImageFileMachine AMD64 = 0x8664, ARM = 0x01c4, ARM64 = 0xaa64, + LoongArch64 = 0x6264, } internal const string JitLibrary = "clrjitilc"; @@ -2929,7 +2930,8 @@ private CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_ST private uint getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_STRUCT_* cls) { - throw new NotImplementedException("For LoongArch64, would be implemented later"); + TypeDesc typeDesc = HandleToObject(cls); + return LoongArch64PassStructInRegister.GetLoongArch64PassStructInRegisterFlags(typeDesc); } private CORINFO_CLASS_STRUCT_* getArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args) @@ -3530,7 +3532,26 @@ private ref ArrayBuilder findRelocBlock(BlockType blockType, out int private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ushort fRelocType) { if (targetArchitecture != TargetArchitecture.ARM64) - return (RelocType)fRelocType; + { + if (targetArchitecture == TargetArchitecture.LoongArch64) + { + const ushort IMAGE_REL_LOONGARCH64_PC = 3; + const ushort IMAGE_REL_LOONGARCH64_JIR = 4; + + switch (fRelocType) + { + case IMAGE_REL_LOONGARCH64_PC: + return RelocType.IMAGE_REL_BASED_LOONGARCH64_PC; + case IMAGE_REL_LOONGARCH64_JIR: + return RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR; + default: + Debug.Fail("Invalid RelocType: " + fRelocType); + return 0; + } + } + else + return (RelocType)fRelocType; + } const ushort IMAGE_REL_ARM64_BRANCH26 = 3; const ushort IMAGE_REL_ARM64_PAGEBASE_REL21 = 4; @@ -3642,6 +3663,8 @@ private uint getExpectedTargetArchitecture() return (uint)ImageFileMachine.ARM; case TargetArchitecture.ARM64: return (uint)ImageFileMachine.ARM64; + case TargetArchitecture.LoongArch64: + return (uint)ImageFileMachine.LoongArch64; default: throw new NotImplementedException("Expected target architecture is not supported"); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 4a7d254d583fcf..e22151f48c56d6 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -1204,6 +1204,46 @@ public struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR public byte eightByteOffsets1; }; + // 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. + public enum LAFlags + { + 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_ONE_FLOAT_MASK = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_SECOND), + 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), + }; + // DEBUGGER DATA public enum MappingTypes { diff --git a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs index 0fad745ec6701e..898ec59e5a5d38 100644 --- a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs +++ b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs @@ -138,6 +138,7 @@ private static string GetTargetSpec(TargetDetails target) TargetArchitecture.X64 => "x64", TargetArchitecture.ARM => "arm", TargetArchitecture.ARM64 => "arm64", + TargetArchitecture.LoongArch64 => "loongarch64", _ => throw new NotImplementedException(target.Architecture.ToString()) }; diff --git a/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs b/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs new file mode 100644 index 00000000000000..187847a7842472 --- /dev/null +++ b/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs @@ -0,0 +1,168 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; +using System.Diagnostics; +using ILCompiler; +using Internal.TypeSystem; + +namespace Internal.JitInterface +{ + + internal static class LoongArch64PassStructInRegister + { + public static uint GetLoongArch64PassStructInRegisterFlags(TypeDesc typeDesc) + { + FieldDesc firstField = null; + uint floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + int numIntroducedFields = 0; + foreach (FieldDesc field in typeDesc.GetFields()) + { + if (!field.IsStatic) + { + if (firstField == null) + { + firstField = field; + } + numIntroducedFields++; + } + } + + if ((numIntroducedFields == 0) || (numIntroducedFields > 2) || (typeDesc.GetElementSize().AsInt > 16)) + { + return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + } + + //// The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers + if (typeDesc.IsIntrinsic) + { + throw new NotImplementedException("For LoongArch64, SIMD would be implemented later"); + } + + MetadataType mdType = typeDesc as MetadataType; + Debug.Assert(mdType != null); + + TypeDesc firstFieldElementType = firstField.FieldType; + int firstFieldSize = firstFieldElementType.GetElementSize().AsInt; + + // A fixed buffer type is always a value type that has exactly one value type field at offset 0 + // and who's size is an exact multiple of the size of the field. + // It is possible that we catch a false positive with this check, but that chance is extremely slim + // and the user can always change their structure to something more descriptive of what they want + // instead of adding additional padding at the end of a one-field structure. + // We do this check here to save looking up the FixedBufferAttribute when loading the field + // from metadata. + bool isFixedBuffer = numIntroducedFields == 1 + && firstFieldElementType.IsValueType + && firstField.Offset.AsInt == 0 + && mdType.HasLayout() + && ((typeDesc.GetElementSize().AsInt % firstFieldSize) == 0); + + if (isFixedBuffer) + { + numIntroducedFields = typeDesc.GetElementSize().AsInt / firstFieldSize; + if (numIntroducedFields > 2) + { + return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + } + } + + int fieldIndex = 0; + foreach (FieldDesc field in typeDesc.GetFields()) + { + if (fieldIndex > 1) + { + return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + } + + Debug.Assert(fieldIndex < numIntroducedFields); + + switch (field.FieldType.Category) + { + case TypeFlags.Double: + { + if (numIntroducedFields == 1) + floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE; + else if (fieldIndex == 0) + floatFieldFlags = (uint)LAFlags.STRUCT_FIRST_FIELD_DOUBLE; + else if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) + floatFieldFlags = floatFieldFlags ^ (uint)LAFlags.STRUCT_MERGE_FIRST_SECOND_8; + else + floatFieldFlags |= (uint)LAFlags.STRUCT_SECOND_FIELD_DOUBLE; + } + break; + + case TypeFlags.Single: + { + if (numIntroducedFields == 1) + floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE; + else if (fieldIndex == 0) + floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST; + else if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) + floatFieldFlags ^= (uint)LAFlags.STRUCT_MERGE_FIRST_SECOND; + else + floatFieldFlags |= (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND; + } + break; + + case TypeFlags.ValueType: + //case TypeFlags.Class: + //case TypeFlags.Array: + //case TypeFlags.SzArray: + { + uint floatFieldFlags2 = GetLoongArch64PassStructInRegisterFlags(field.FieldType); + if (numIntroducedFields == 1) + floatFieldFlags = floatFieldFlags2; + else if (field.FieldType.GetElementSize().AsInt > 8) + return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + else if (fieldIndex == 0) + { + if ((floatFieldFlags2 & (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0) + floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST; + if (field.FieldType.GetElementSize().AsInt == 8) + floatFieldFlags |= (uint)LAFlags.STRUCT_FIRST_FIELD_SIZE_IS8; + } + else + { + Debug.Assert(fieldIndex == 1); + if ((floatFieldFlags2 & (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0) + floatFieldFlags |= (uint)LAFlags.STRUCT_MERGE_FIRST_SECOND; + if (field.FieldType.GetElementSize().AsInt == 8) + floatFieldFlags |= (uint)LAFlags.STRUCT_SECOND_FIELD_SIZE_IS8; + + floatFieldFlags2 = floatFieldFlags & ((uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND); + if (floatFieldFlags2 == 0) + floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + else if (floatFieldFlags2 == ((uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND)) + floatFieldFlags ^= ((uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_TWO | (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND); + } + } + break; + + default: + { + if (field.FieldType.GetElementSize().AsInt == 8) + { + if (numIntroducedFields > 1) + { + if (fieldIndex == 0) + floatFieldFlags = (uint)LAFlags.STRUCT_FIRST_FIELD_SIZE_IS8; + else if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) + floatFieldFlags |= (uint)LAFlags.STRUCT_SECOND_FIELD_SIZE_IS8; + else + floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + } + } + else if (fieldIndex == 1) + floatFieldFlags = (floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) > 0 ? floatFieldFlags : (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + break; + } + } + + fieldIndex++; + } + + return floatFieldFlags; + } + } +} diff --git a/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs b/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs index b3b587d1432f48..160ff674f8d71a 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs @@ -17,5 +17,6 @@ public enum TargetArchitecture X64, X86, Wasm32, + LoongArch64, } } diff --git a/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs b/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs index e5626ed8f976d3..b8b28f5fb7b440 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs @@ -80,6 +80,7 @@ public int PointerSize { case TargetArchitecture.ARM64: case TargetArchitecture.X64: + case TargetArchitecture.LoongArch64: return 8; case TargetArchitecture.ARM: case TargetArchitecture.X86: @@ -116,6 +117,10 @@ public int MaximumAlignment // Corresponds to alignmet required for __m256 return 16; } + else if (Architecture == TargetArchitecture.LoongArch64) + { + return 16; + } // 256-bit vector is the type with the higest alignment we support return 32; @@ -172,6 +177,7 @@ public int MinimumCodeAlignment case TargetArchitecture.ARM: return 2; case TargetArchitecture.ARM64: + case TargetArchitecture.LoongArch64: return 4; default: return 1; @@ -276,6 +282,7 @@ public LayoutInt GetObjectAlignment(LayoutInt fieldAlignment) return new LayoutInt(8); case TargetArchitecture.X64: case TargetArchitecture.ARM64: + case TargetArchitecture.LoongArch64: return new LayoutInt(8); case TargetArchitecture.X86: return new LayoutInt(4); @@ -318,6 +325,7 @@ public int MaxHomogeneousAggregateElementCount // and Procedure Call Standard for the Arm 64-bit Architecture. Debug.Assert(Architecture == TargetArchitecture.ARM || Architecture == TargetArchitecture.ARM64 || + Architecture == TargetArchitecture.LoongArch64 || Architecture == TargetArchitecture.X64 || Architecture == TargetArchitecture.X86); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs index 28d10f23a28f06..86c63c517b3fb0 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs @@ -233,6 +233,7 @@ internal struct ArgLocDesc public int m_byteStackIndex; // Stack offset in bytes (or -1) public int m_byteStackSize; // Stack size in bytes + public uint m_floatFlags; // struct with two-fields can be passed by registers. // Initialize to represent a non-placed argument (no register or stack slots referenced). public void Init() { @@ -242,6 +243,7 @@ public void Init() m_cGenReg = 0; m_byteStackIndex = -1; m_byteStackSize = 0; + m_floatFlags = 0; m_fRequires64BitAlignment = false; } @@ -836,6 +838,13 @@ public int GetNextOffset() _arm64IdxFPReg = 0; break; + case TargetArchitecture.LoongArch64: + _loongarch64IdxGenReg = numRegistersUsed; + _loongarch64OfsStack = 0; + + _loongarch64IdxFPReg = 0; + break; + default: throw new NotImplementedException(); } @@ -1325,6 +1334,120 @@ public int GetNextOffset() return argOfs; } + case TargetArchitecture.LoongArch64: + { + int cFPRegs = 0; + uint floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; + _hasArgLocDescForStructInRegs = false; + + switch (argType) + { + case CorElementType.ELEMENT_TYPE_R4: + // 32-bit floating point argument. + cFPRegs = 1; + break; + + case CorElementType.ELEMENT_TYPE_R8: + // 64-bit floating point argument. + cFPRegs = 1; + break; + + case CorElementType.ELEMENT_TYPE_VALUETYPE: + { + // Composite greater than 16 bytes should be passed by reference + if (argSize > _transitionBlock.EnregisteredParamTypeMaxSize) + { + argSize = _transitionBlock.PointerSize; + } + else + { + floatFieldFlags = LoongArch64PassStructInRegister.GetLoongArch64PassStructInRegisterFlags(_argTypeHandle.GetRuntimeTypeHandle()); + if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_TWO) != 0) + cFPRegs = 2; + else if ((floatFieldFlags & (uint)LAFlags.STRUCT_HAS_FLOAT_FIELDS_MASK) != 0) + cFPRegs = 1; + } + + break; + } + + default: + break; + } + + bool isValueType = (argType == CorElementType.ELEMENT_TYPE_VALUETYPE); + int cbArg = _transitionBlock.StackElemSize(argSize, isValueType, false); + + if (cFPRegs > 0 && !IsVarArg) + { + if (isValueType && ((floatFieldFlags & (uint)LAFlags.STRUCT_HAS_ONE_FLOAT_MASK) != 0)) + { + if ((_loongarch64IdxFPReg < 8) && (_loongarch64IdxGenReg < 8)) + { + _argLocDescForStructInRegs = new ArgLocDesc(); + _argLocDescForStructInRegs.m_idxFloatReg = _loongarch64IdxFPReg; + _argLocDescForStructInRegs.m_cFloatReg = 1; + + _argLocDescForStructInRegs.m_idxGenReg = _loongarch64IdxGenReg; + _argLocDescForStructInRegs.m_cGenReg = 1; + + _hasArgLocDescForStructInRegs = true; + _argLocDescForStructInRegs.m_floatFlags = floatFieldFlags; + + int argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8; + _loongarch64IdxFPReg++; + _loongarch64IdxGenReg++; + return argOfsInner; + } + else + { + _loongarch64IdxFPReg = 8; + } + } + else if (cFPRegs + _loongarch64IdxFPReg <= 8) + { + // Each floating point register in the argument area is 8 bytes. + int argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8; + _loongarch64IdxFPReg += cFPRegs; + return argOfsInner; + } + else + { + _loongarch64IdxFPReg = 8; + } + } + + { + Debug.Assert((cbArg % _transitionBlock.PointerSize) == 0); + + int regSlots = ALIGN_UP(cbArg, _transitionBlock.PointerSize) / _transitionBlock.PointerSize; + // Only R4-R11 are valid argument registers. + if (_loongarch64IdxGenReg + regSlots <= 8) + { + // The entirety of the arg fits in the register slots. + int argOfsInner = _transitionBlock.OffsetOfArgumentRegisters + _loongarch64IdxGenReg * 8; + _loongarch64IdxGenReg += regSlots; + return argOfsInner; + } + else if (_loongarch64IdxGenReg < 8) + { + int argOfsInner = _transitionBlock.OffsetOfArgumentRegisters + _loongarch64IdxGenReg * 8; + _loongarch64IdxGenReg = 8; + _loongarch64OfsStack += 8; + return argOfsInner; + } + else + { + // Don't use reg slots for this. It will be passed purely on the stack arg space. + _loongarch64IdxGenReg = 8; + } + } + + argOfs = _transitionBlock.OffsetOfArgs + _loongarch64OfsStack; + _loongarch64OfsStack += cbArg; + return argOfs; + } + default: throw new NotImplementedException(); } @@ -1625,6 +1748,64 @@ private void ForceSigWalk() return pLoc; } + case TargetArchitecture.LoongArch64: + { + if (_hasArgLocDescForStructInRegs) + { + return _argLocDescForStructInRegs; + } + + // LIMITED_METHOD_CONTRACT; + + ArgLocDesc pLoc = new ArgLocDesc(); + + if (_transitionBlock.IsFloatArgumentRegisterOffset(argOffset)) + { + int floatRegOfsInBytes = argOffset - _transitionBlock.OffsetOfFloatArgumentRegisters; + Debug.Assert((floatRegOfsInBytes % _transitionBlock.FloatRegisterSize) == 0); + pLoc.m_idxFloatReg = floatRegOfsInBytes / _transitionBlock.FloatRegisterSize; + + if (!_argTypeHandle.IsNull() && _argTypeHandle.IsHomogeneousAggregate()) + { + int haElementSize = _argTypeHandle.GetHomogeneousAggregateElementSize(); + pLoc.m_cFloatReg = GetArgSize() / haElementSize; + } + else + { + pLoc.m_cFloatReg = 1; + } + return pLoc; + } + + int byteArgSize = GetArgSize(); + + // Composites greater than 16bytes are passed by reference + TypeHandle dummy; + if (GetArgType(out dummy) == CorElementType.ELEMENT_TYPE_VALUETYPE && GetArgSize() > _transitionBlock.EnregisteredParamTypeMaxSize) + { + byteArgSize = _transitionBlock.PointerSize; + } + + if (!_transitionBlock.IsStackArgumentOffset(argOffset)) + { + pLoc.m_idxGenReg = _transitionBlock.GetArgumentIndexFromOffset(argOffset); + if ((pLoc.m_idxGenReg == 7) && (byteArgSize > _transitionBlock.PointerSize)) + { + pLoc.m_cGenReg = 1; + pLoc.m_byteStackIndex = 0; + pLoc.m_byteStackSize = 8; + } + else + pLoc.m_cGenReg = (short)(ALIGN_UP(byteArgSize, _transitionBlock.PointerSize) / _transitionBlock.PointerSize); + } + else + { + pLoc.m_byteStackIndex = _transitionBlock.GetStackArgumentByteIndexFromOffset(argOffset); + pLoc.m_byteStackSize = _transitionBlock.StackElemSize(byteArgSize, IsValueType(), IsFloatHfa()); + } + return pLoc; + } + case TargetArchitecture.X64: if (_transitionBlock.IsX64UnixABI) { @@ -1710,6 +1891,10 @@ private void ForceSigWalk() private int _arm64OfsStack; // Offset of next stack location to be assigned a value private int _arm64IdxFPReg; // Next FP register to be assigned a value + private int _loongarch64IdxGenReg; // Next general register to be assigned a value + private int _loongarch64OfsStack; // Offset of next stack location to be assigned a value + private int _loongarch64IdxFPReg; // Next FP register to be assigned a value + // These are enum flags in CallingConventions.h, but that's really ugly in C#, so I've changed them to bools. private bool _ITERATION_STARTED; // Started iterating over arguments private bool _SIZE_OF_ARG_STACK_COMPUTED; @@ -1738,7 +1923,7 @@ private enum ParamTypeLocation // METHOD_INVOKE_NEEDS_ACTIVATION = 0x0040, // Flag used by ArgIteratorForMethodInvoke // RETURN_FP_SIZE_SHIFT = 8, // The rest of the flags is cached value of GetFPReturnSize - // }; + // {}; private void ComputeReturnFlags() { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs index a43ad0335ccc1c..3246b5a143ca3c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs @@ -138,7 +138,7 @@ private IEnumerable EncodeDataCore(NodeFactory factory) unwindInfo[0] |= (byte)((UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER) << FlagsShift); } - else if ((targetArch == TargetArchitecture.ARM) || (targetArch == TargetArchitecture.ARM64)) + else if ((targetArch == TargetArchitecture.ARM) || (targetArch == TargetArchitecture.ARM64) || (targetArch == TargetArchitecture.LoongArch64)) { // Set the 'X' bit to indicate that there is a personality routine associated with this method unwindInfo[2] |= 1 << 4; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs new file mode 100644 index 00000000000000..5e0a8751d472b3 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +using ILCompiler.DependencyAnalysis.LoongArch64; + +namespace ILCompiler.DependencyAnalysis.ReadyToRun +{ + /// + /// This node emits a thunk calling DelayLoad_Helper with a given instance signature + /// to populate its indirection cell. + /// + public partial class ImportThunk + { + protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter instructionEncoder, bool relocsOnly) + { + + switch (_thunkKind) + { + case Kind.Eager: + break; + + case Kind.DelayLoadHelper: + case Kind.VirtualStubDispatch: + // T8 contains indirection cell + // Do nothing T8=R20 contains our first param + + if (!relocsOnly) + { + // movz T0=R12, #index + int index = _containingImportSection.IndexFromBeginningOfArray; + instructionEncoder.EmitMOV(Register.R12, checked((ushort)index)); + } + + // get pc + // pcaddi T1=R13, 0 + instructionEncoder.EmitPC(Register.R13); + + // load Module* -> T1 + instructionEncoder.EmitLD(Register.R13, Register.R13, 0x24); + + // ld_d R13, R13, 0 + instructionEncoder.EmitLD(Register.R13, Register.R13, 0); + break; + + case Kind.Lazy: + // get pc + // pcaddi R5, 0 + instructionEncoder.EmitPC(Register.R5); + + // load Module* -> R5=A1 + instructionEncoder.EmitLD(Register.R5, Register.R5, 0x24); + + // ld_d R5, R5, 0 + instructionEncoder.EmitLD(Register.R5, Register.R5, 0); + break; + + default: + throw new NotImplementedException(); + } + + // branch to helper + instructionEncoder.EmitJMP(_helperCell); + + // Emit relocation for the Module* load above + if (_thunkKind != Kind.Eager) + instructionEncoder.Builder.EmitReloc(factory.ModuleImport, RelocType.IMAGE_REL_BASED_DIR64); + } + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs index a044a42b1d2dd1..d76413ff0a58d6 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs @@ -43,6 +43,9 @@ public static TransitionBlock FromTarget(TargetDetails target) AppleArm64TransitionBlock.Instance : Arm64TransitionBlock.Instance; + case TargetArchitecture.LoongArch64: + return LoongArch64TransitionBlock.Instance; + default: throw new NotImplementedException(target.Architecture.ToString()); } @@ -60,6 +63,7 @@ public static TransitionBlock FromTarget(TargetDetails target) public bool IsX64 => Architecture == TargetArchitecture.X64; public bool IsARM => Architecture == TargetArchitecture.ARM; public bool IsARM64 => Architecture == TargetArchitecture.ARM64; + public bool IsLoongArch64 => Architecture == TargetArchitecture.LoongArch64; /// /// This property is only overridden in AMD64 Unix variant of the transition block. @@ -650,5 +654,45 @@ public sealed override int StackElemSize(int parmSize, bool isValueType = false, return base.StackElemSize(parmSize, isValueType, isFloatHfa); } } + + private class LoongArch64TransitionBlock : TransitionBlock + { + public static TransitionBlock Instance = new LoongArch64TransitionBlock(); + public override TargetArchitecture Architecture => TargetArchitecture.LoongArch64; + public override int PointerSize => 8; + public override int FloatRegisterSize => 8; // TODO: for SIMD. + // R4 .. R11 + public override int NumArgumentRegisters => 8; + // fp=R22,ra=R1,s0-s8(R23-R31),tp=R2 + public override int NumCalleeSavedRegisters => 12; + // Callee-saves, padding, argument registers + public override int SizeOfTransitionBlock => SizeOfCalleeSavedRegisters + SizeOfArgumentRegisters; + public override int OffsetOfArgumentRegisters => SizeOfCalleeSavedRegisters; + public override int OffsetOfFirstGCRefMapSlot => OffsetOfArgumentRegisters; + + // F0..F7 + public override int OffsetOfFloatArgumentRegisters => 8 * sizeof(double); + public override int EnregisteredParamTypeMaxSize => 16; + public override int EnregisteredReturnTypeIntegerMaxSize => 16; + + public override bool IsArgPassedByRef(TypeHandle th) + { + Debug.Assert(!th.IsNull()); + Debug.Assert(th.IsValueType()); + + // Composites greater than 16 bytes are passed by reference + return (th.GetSize() > EnregisteredParamTypeMaxSize) && !th.IsHomogeneousAggregate(); + } + + public override int GetRetBuffArgOffset(bool hasThis) => OffsetOfX8Register; + + public override bool IsRetBuffPassedAsFirstArg => false; + + public override int StackElemSize(int parmSize, bool isValueType = false, bool isFloatHfa = false) + { + int stackSlotSize = 8; + return ALIGN_UP(parmSize, stackSlotSize); + } + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs index f507cabb4d3e3c..f37305a1149a93 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs @@ -116,6 +116,11 @@ private class ModuleFieldLayoutMap : LockFreeReaderHashtable private const int DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobArm = 8; + /// + /// CoreCLR DomainLocalModule::NormalDynamicEntry::OffsetOfDataBlob for LoongArch64 + /// + private const int DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobLoongArch64 = 8; + protected override bool CompareKeyToValue(EcmaModule key, ModuleFieldLayout value) { return key == value.Module; @@ -414,6 +419,10 @@ public FieldAndOffset[] GetOrAddDynamicLayout(DefType defType, ModuleFieldLayout nonGcOffset = DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobArm; break; + case TargetArchitecture.LoongArch64: + nonGcOffset = DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobLoongArch64; + break; + default: throw new NotImplementedException(); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index 5154db358a8b8e..9724e451000de4 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -77,6 +77,10 @@ + + + + @@ -102,6 +106,7 @@ + @@ -179,6 +184,7 @@ + diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs index 09f9244aeffcf1..8cab279b2d7680 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs @@ -220,6 +220,14 @@ public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targe break; } + case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: + case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: + { + relocationLength = 4; + delta = targetRVA - sourceRVA; + break; + } + default: throw new NotSupportedException(); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 4eab54b43b8628..8925043b7ac513 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -200,6 +200,9 @@ public TargetArchitecture TargetArchitecture case Machine.Arm64: return TargetArchitecture.ARM64; + case Machine.LoongArch64: + return TargetArchitecture.LoongArch64; + default: throw new NotImplementedException(_machine.ToString()); } @@ -642,6 +645,11 @@ private unsafe void EnsureHeader() _pointerSize = 8; break; + case Machine.LoongArch64: + _architecture = Architecture.LoongArch64; + _pointerSize = 8; + break; + default: throw new NotImplementedException(Machine.ToString()); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs index 3f0bef94f8e40f..96f4108f7910ac 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs @@ -149,5 +149,20 @@ private sealed class Arm64TransitionBlock : TransitionBlock private int OffsetOfX8Register => OffsetOfArgumentRegisters - PointerSize; public override int OffsetOfFirstGCRefMapSlot => OffsetOfX8Register; } + + private sealed class LoongArch64TransitionBlock : TransitionBlock + { + public static readonly TransitionBlock Instance = new LoongArch64TransitionBlock(); + + public override int PointerSize => 8; + // R4 .. R11 + public override int NumArgumentRegisters => 8; + // fp=R22,ra=R1,s0-s8(R23-R31),tp=R2 + public override int NumCalleeSavedRegisters => 12; + // Callee-saves, padding, argument registers + public override int SizeOfTransitionBlock => SizeOfCalleeSavedRegisters + SizeOfArgumentRegisters; + public override int OffsetOfArgumentRegisters => SizeOfCalleeSavedRegisters; + public override int OffsetOfFirstGCRefMapSlot => OffsetOfArgumentRegisters; + } } } diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs index ff538c05fd64c4..fe2bb27e89b795 100644 --- a/src/coreclr/tools/aot/crossgen2/Program.cs +++ b/src/coreclr/tools/aot/crossgen2/Program.cs @@ -76,6 +76,9 @@ public static void ComputeDefaultOptions(out TargetOS os, out TargetArchitecture case Architecture.Arm64: arch = TargetArchitecture.ARM64; break; + case Architecture.LoongArch64: + arch = TargetArchitecture.LoongArch64; + break; default: throw new NotImplementedException(); } @@ -194,6 +197,8 @@ public static TargetArchitecture GetTargetArchitectureFromArg(string archArg, ou } else if (archArg.Equals("arm64", StringComparison.OrdinalIgnoreCase)) return TargetArchitecture.ARM64; + else if (archArg.Equals("loongarch64", StringComparison.OrdinalIgnoreCase)) + return TargetArchitecture.LoongArch64; else throw new CommandLineException(SR.TargetArchitectureUnsupported); } diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.props b/src/coreclr/tools/aot/crossgen2/crossgen2.props index 2d6e9dff4072d9..af6617589c696d 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.props +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.props @@ -5,7 +5,7 @@ Exe $(NetCoreAppToolCurrent) 8002,NU1701 - x64;x86;arm64;arm + x64;x86;arm64;arm;loongarch64 AnyCPU false true From 6a179ff8dc6900a7f69b66aeb234770fb8afee2f Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 16 Feb 2022 09:53:37 +0800 Subject: [PATCH 17/18] Revert "[LoongArch64] implements the crossgen2 for LoongArch64." This reverts commit b05a2b90e8d8a2f6d1cf7f101ddfc9d4ed8d984e. The crossgen2 for LoongArch64 will be submitted by a new PR. --- .../DependencyAnalysis/AssemblyStubNode.cs | 8 - .../DependencyAnalysis/ObjectDataBuilder.cs | 2 - .../Compiler/DependencyAnalysis/Relocation.cs | 96 --------- .../Target_LoongArch64/AddrMode.cs | 34 ---- .../Target_LoongArch64/LoongArch64Emitter.cs | 70 ------- .../Target_LoongArch64/Register.cs | 50 ----- .../Target_LoongArch64/TargetRegisterMap.cs | 38 ---- .../Common/Compiler/InstructionSetSupport.cs | 4 - .../tools/Common/JitInterface/CorInfoImpl.cs | 27 +-- .../tools/Common/JitInterface/CorInfoTypes.cs | 40 ---- .../Common/JitInterface/JitConfigProvider.cs | 1 - .../LoongArch64PassStructInRegister.cs | 168 ---------------- .../TypeSystem/Common/TargetArchitecture.cs | 1 - .../Common/TypeSystem/Common/TargetDetails.cs | 8 - .../ReadyToRun/ArgIterator.cs | 187 +----------------- .../ReadyToRun/MethodGCInfoNode.cs | 2 +- .../Target_LoongArch64/ImportThunk.cs | 71 ------- .../ReadyToRun/TransitionBlock.cs | 44 ----- .../ReadyToRunMetadataFieldLayoutAlgorithm.cs | 9 - .../ILCompiler.ReadyToRun.csproj | 6 - .../ObjectWriter/RelocationHelper.cs | 8 - .../ReadyToRunReader.cs | 8 - .../TransitionBlock.cs | 15 -- src/coreclr/tools/aot/crossgen2/Program.cs | 5 - .../tools/aot/crossgen2/crossgen2.props | 2 +- 25 files changed, 5 insertions(+), 899 deletions(-) delete mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs delete mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs delete mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs delete mode 100644 src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs delete mode 100644 src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs delete mode 100644 src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs index b289ff347063db..b95daf56f0b45e 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/AssemblyStubNode.cs @@ -68,13 +68,6 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly) arm64Emitter.Builder.AddSymbol(this); return arm64Emitter.Builder.ToObjectData(); - case TargetArchitecture.LoongArch64: - LoongArch64.LoongArch64Emitter loongarch64Emitter = new LoongArch64.LoongArch64Emitter(factory, relocsOnly); - EmitCode(factory, ref loongarch64Emitter, relocsOnly); - loongarch64Emitter.Builder.RequireInitialAlignment(alignment); - loongarch64Emitter.Builder.AddSymbol(this); - return loongarch64Emitter.Builder.ToObjectData(); - default: throw new NotImplementedException(); } @@ -84,6 +77,5 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly) protected abstract void EmitCode(NodeFactory factory, ref X86.X86Emitter instructionEncoder, bool relocsOnly); protected abstract void EmitCode(NodeFactory factory, ref ARM.ARMEmitter instructionEncoder, bool relocsOnly); protected abstract void EmitCode(NodeFactory factory, ref ARM64.ARM64Emitter instructionEncoder, bool relocsOnly); - protected abstract void EmitCode(NodeFactory factory, ref LoongArch64.LoongArch64Emitter instructionEncoder, bool relocsOnly); } } diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs index f20020ad71051a..da20de18b9f87c 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs @@ -303,8 +303,6 @@ public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0) case RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21: case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12L: case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: - case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: - case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: Debug.Assert(delta == 0); // Do not vacate space for this kind of relocation, because // the space is embedded in the instruction. diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index bc31c9aa744abb..eda9378acc36d4 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -16,8 +16,6 @@ public enum RelocType IMAGE_REL_BASED_THUMB_BRANCH24 = 0x13, // Thumb2: based B, BL IMAGE_REL_BASED_THUMB_MOV32_PCREL = 0x14, // Thumb2: based MOVW/MOVT IMAGE_REL_BASED_ARM64_BRANCH26 = 0x15, // Arm64: B, BL - IMAGE_REL_BASED_LOONGARCH64_PC = 0x16, // LoongArch64: pcaddu12i+imm12 - IMAGE_REL_BASED_LOONGARCH64_JIR = 0x17, // LoongArch64: pcaddu18i+jirl IMAGE_REL_BASED_RELPTR32 = 0x7C, // 32-bit relative address from byte starting reloc // This is a special NGEN-specific relocation type // for relative pointer (used to make NGen relocation @@ -296,91 +294,7 @@ private static unsafe void PutArm64Rel28(uint* pCode, long imm28) Debug.Assert(GetArm64Rel28(pCode) == imm28); } - private static unsafe int GetLoongArch64PC12(uint* pCode) - { - uint pcInstr = *pCode; - - // first shift 6 bits left to set the sign bit, - // then arithmetic shift right by 4 bits - int imm = (int)(((pcInstr >> 5) & 0xFFFFF) << 12); - - pcInstr = *(pCode + 1); - imm += ((short)(((pcInstr >> 10) & 0xFFF) << 4)) >> 4; - - return imm; - } - - private static unsafe void PutLoongArch64PC12(uint* pCode, long imm32) - { - // Verify that we got a valid offset - Debug.Assert((int)imm32 == imm32); - - uint pcInstr = *pCode; - Debug.Assert((pcInstr & 0xFE000000) == 0x1c000000); // Must be pcaddu12i - - int relOff = (int)imm32 & 0x800; - int imm = (int)imm32 + relOff; - relOff = ((imm & 0x7ff) - relOff) & 0xfff; - - // Assemble the pc-relative hight20bits of 'imm32' into the pcaddu12i instruction - pcInstr |= (uint)(((imm >> 12) & 0xFFFFF) << 5); - - *pCode = pcInstr; // write the assembled instruction - - pcInstr = *(pCode + 1); - - // Assemble the pc-relative low12bits of 'imm32' into the addid or ld instruction - pcInstr |= (uint)(relOff << 10); - - *(pCode + 1) = pcInstr; // write the assembled instruction - - Debug.Assert(GetLoongArch64PC12(pCode) == imm32); - } - - private static unsafe long GetLoongArch64JIR(uint* pCode) - { - uint pcInstr = *pCode; - - // first shift 6 bits left to set the sign bit, - // then arithmetic shift right by 4 bits - long imm = ((long)((pcInstr >> 5) & 0xFFFFF) << 18); - - pcInstr = *(pCode + 1); - imm += ((long)((short)((pcInstr >> 10) & 0xFFFF))) << 2; - - return imm; - } - - private static unsafe void PutLoongArch64JIR(uint* pCode, long imm38) - { - // Verify that we got a valid offset - Debug.Assert((imm38 >= -0x2000000000L) && (imm38 < 0x2000000000L)); - - Debug.Assert((imm38 & 0x3) == 0); // the low two bits must be zero - - uint pcInstr = *pCode; - - Debug.Assert(pcInstr == 0x1e00000e); // Must be pcaddu18i R14, 0 - - long relOff = imm38 & 0x20000; - long imm = imm38 + relOff; - relOff = (((imm & 0x1ffff) - relOff) >> 2) & 0xffff; - - // Assemble the pc-relative hight20bits of 'imm38' into the pcaddu12i instruction - pcInstr |= (uint)(((imm >> 18) & 0xFFFFF) << 5); - - *pCode = pcInstr; // write the assembled instruction - - pcInstr = *(pCode + 1); - - // Assemble the pc-relative low18bits of 'imm38' into the addid or ld instruction - pcInstr |= (uint)(relOff << 10); - - *(pCode + 1) = pcInstr; // write the assembled instruction - - Debug.Assert(GetLoongArch64JIR(pCode) == imm38); - } public Relocation(RelocType relocType, int offset, ISymbolNode target) { @@ -420,12 +334,6 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: PutArm64Rel12((uint*)location, (int)value); break; - case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: - PutLoongArch64PC12((uint*)location, value); - break; - case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: - PutLoongArch64JIR((uint*)location, value); - break; default: Debug.Fail("Invalid RelocType: " + relocType); break; @@ -458,10 +366,6 @@ public static unsafe long ReadValue(RelocType relocType, void* location) return GetArm64Rel21((uint*)location); case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: return GetArm64Rel12((uint*)location); - case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: - return 0; // (long)GetLoongArch64PC12((uint*)location); - case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: - return 0; // (long)GetLoongArch64JIR((uint*)location); default: Debug.Fail("Invalid RelocType: " + relocType); return 0; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs deleted file mode 100644 index 5616941cae238f..00000000000000 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/AddrMode.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace ILCompiler.DependencyAnalysis.LoongArch64 -{ - public enum AddrModeSize - { - Int8 = 1, - Int16 = 2, - Int32 = 4, - Int64 = 8, - Int128 = 16 - } - - public struct AddrMode - { - public readonly Register BaseReg; - public readonly Register? IndexReg; - public readonly int Offset; - public readonly byte Scale; - public readonly AddrModeSize Size; - - public AddrMode(Register baseRegister, Register? indexRegister, int offset, byte scale, AddrModeSize size) - { - BaseReg = baseRegister; - IndexReg = indexRegister; - Offset = offset; - Scale = scale; - Size = size; - } - } -} diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs deleted file mode 100644 index b7e24442aec83b..00000000000000 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/LoongArch64Emitter.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Diagnostics; - -namespace ILCompiler.DependencyAnalysis.LoongArch64 -{ - public struct LoongArch64Emitter - { - public LoongArch64Emitter(NodeFactory factory, bool relocsOnly) - { - Builder = new ObjectDataBuilder(factory, relocsOnly); - TargetRegister = new TargetRegisterMap(factory.Target.OperatingSystem); - } - - public ObjectDataBuilder Builder; - public TargetRegisterMap TargetRegister; - - // Assembly stub creation api. TBD, actually make this general purpose - - public void EmitMOV(Register regDst, ushort imm16) - { - Debug.Assert((uint)regDst <= 0x1f); - Debug.Assert(imm16 <= 0xfff); - uint instruction = 0x03800000u | (uint)((imm16 & 0xfff) << 10) | (uint)regDst; - Builder.EmitUInt(instruction); - } - - // pcaddi regDst, 0 - public void EmitPC(Register regDst) - { - Debug.Assert((uint)regDst > 0 && (uint)regDst < 32); - Builder.EmitUInt(0x18000000 | (uint)regDst); - } - - // ld_d regDst, regAddr, offset - public void EmitLD(Register regDst, Register regSrc, int offset) - { - Debug.Assert(offset >= -2048 && offset <= 2047); - - Builder.EmitUInt((uint)(0x28c00000 | (uint)((offset & 0xfff) << 12) | ((uint)regSrc << 5) | (uint)regDst)); - } - - public void EmitJMP(ISymbolNode symbol) - { - if (symbol.RepresentsIndirectionCell) - { - // pcaddi R21, 0 - EmitPC(Register.R21); - - EmitLD(Register.R21, Register.R21, 0x10); - - // ld_d R21, R21, 0 - EmitLD(Register.R21, Register.R21, 0); - - // jirl R0,R21,0 - Builder.EmitUInt(0x4c0002a0); - - Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_DIR64); - } - else - { - //Builder.EmitReloc(symbol, RelocType.IMAGE_REL_BASED_LOONGARCH64_PC); - Builder.EmitUInt(0xffffffff); // bad code. - throw new NotImplementedException(); - } - } - } -} diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs deleted file mode 100644 index 1ce65e76622878..00000000000000 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/Register.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ILCompiler.DependencyAnalysis.LoongArch64 -{ - public enum Register - { - R0 = 0, - R1 = 1, - R2 = 2, - R3 = 3, - R4 = 4, - R5 = 5, - R6 = 6, - R7 = 7, - R8 = 8, - R9 = 9, - R10 = 10, - R11 = 11, - R12 = 12, - R13 = 13, - R14 = 14, - R15 = 15, - R16 = 16, - R17 = 17, - R18 = 18, - R19 = 19, - R20 = 20, - R21 = 21, - R22 = 22, - R23 = 23, - R24 = 24, - R25 = 25, - R26 = 26, - R27 = 27, - R28 = 28, - R29 = 29, - R30 = 30, - R31 = 31, - - None = 32, - NoIndex = 128, - } -} diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs deleted file mode 100644 index fdfdddf2170457..00000000000000 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Target_LoongArch64/TargetRegisterMap.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -using Internal.TypeSystem; - -namespace ILCompiler.DependencyAnalysis.LoongArch64 -{ - /// - /// Maps logical registers to physical registers on a specified OS. - /// - public struct TargetRegisterMap - { - public readonly Register Arg0; - public readonly Register Arg1; - public readonly Register Arg2; - public readonly Register Arg3; - public readonly Register Arg4; - public readonly Register Arg5; - public readonly Register Arg6; - public readonly Register Arg7; - public readonly Register Result; - - public TargetRegisterMap(TargetOS os) - { - Arg0 = Register.R4; - Arg1 = Register.R5; - Arg2 = Register.R6; - Arg3 = Register.R7; - Arg4 = Register.R8; - Arg5 = Register.R9; - Arg6 = Register.R11; - Arg7 = Register.R12; - Result = Register.R4; // TODO: ??? - } - } -} diff --git a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs index d21276726b7f56..2f35f083f24d2e 100644 --- a/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs +++ b/src/coreclr/tools/Common/Compiler/InstructionSetSupport.cs @@ -110,10 +110,6 @@ public SimdVectorLength GetVectorTSimdVector() { return SimdVectorLength.None; } - else if (_targetArchitecture == TargetArchitecture.LoongArch64) - { - return SimdVectorLength.None; - } else { Debug.Assert(false); // Unknown architecture diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 43fa97a94bbc39..1eb709641615bd 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -46,7 +46,6 @@ private enum ImageFileMachine AMD64 = 0x8664, ARM = 0x01c4, ARM64 = 0xaa64, - LoongArch64 = 0x6264, } internal const string JitLibrary = "clrjitilc"; @@ -2930,8 +2929,7 @@ private CorInfoTypeWithMod getArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_ST private uint getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_STRUCT_* cls) { - TypeDesc typeDesc = HandleToObject(cls); - return LoongArch64PassStructInRegister.GetLoongArch64PassStructInRegisterFlags(typeDesc); + throw new NotImplementedException("For LoongArch64, would be implemented later"); } private CORINFO_CLASS_STRUCT_* getArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_STRUCT_* args) @@ -3532,26 +3530,7 @@ private ref ArrayBuilder findRelocBlock(BlockType blockType, out int private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ushort fRelocType) { if (targetArchitecture != TargetArchitecture.ARM64) - { - if (targetArchitecture == TargetArchitecture.LoongArch64) - { - const ushort IMAGE_REL_LOONGARCH64_PC = 3; - const ushort IMAGE_REL_LOONGARCH64_JIR = 4; - - switch (fRelocType) - { - case IMAGE_REL_LOONGARCH64_PC: - return RelocType.IMAGE_REL_BASED_LOONGARCH64_PC; - case IMAGE_REL_LOONGARCH64_JIR: - return RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR; - default: - Debug.Fail("Invalid RelocType: " + fRelocType); - return 0; - } - } - else - return (RelocType)fRelocType; - } + return (RelocType)fRelocType; const ushort IMAGE_REL_ARM64_BRANCH26 = 3; const ushort IMAGE_REL_ARM64_PAGEBASE_REL21 = 4; @@ -3663,8 +3642,6 @@ private uint getExpectedTargetArchitecture() return (uint)ImageFileMachine.ARM; case TargetArchitecture.ARM64: return (uint)ImageFileMachine.ARM64; - case TargetArchitecture.LoongArch64: - return (uint)ImageFileMachine.LoongArch64; default: throw new NotImplementedException("Expected target architecture is not supported"); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index e22151f48c56d6..4a7d254d583fcf 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -1204,46 +1204,6 @@ public struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR public byte eightByteOffsets1; }; - // 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. - public enum LAFlags - { - 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_ONE_FLOAT_MASK = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_SECOND), - 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), - }; - // DEBUGGER DATA public enum MappingTypes { diff --git a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs index 898ec59e5a5d38..0fad745ec6701e 100644 --- a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs +++ b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs @@ -138,7 +138,6 @@ private static string GetTargetSpec(TargetDetails target) TargetArchitecture.X64 => "x64", TargetArchitecture.ARM => "arm", TargetArchitecture.ARM64 => "arm64", - TargetArchitecture.LoongArch64 => "loongarch64", _ => throw new NotImplementedException(target.Architecture.ToString()) }; diff --git a/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs b/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs deleted file mode 100644 index 187847a7842472..00000000000000 --- a/src/coreclr/tools/Common/JitInterface/LoongArch64PassStructInRegister.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.Diagnostics; -using ILCompiler; -using Internal.TypeSystem; - -namespace Internal.JitInterface -{ - - internal static class LoongArch64PassStructInRegister - { - public static uint GetLoongArch64PassStructInRegisterFlags(TypeDesc typeDesc) - { - FieldDesc firstField = null; - uint floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - int numIntroducedFields = 0; - foreach (FieldDesc field in typeDesc.GetFields()) - { - if (!field.IsStatic) - { - if (firstField == null) - { - firstField = field; - } - numIntroducedFields++; - } - } - - if ((numIntroducedFields == 0) || (numIntroducedFields > 2) || (typeDesc.GetElementSize().AsInt > 16)) - { - return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - } - - //// The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers - if (typeDesc.IsIntrinsic) - { - throw new NotImplementedException("For LoongArch64, SIMD would be implemented later"); - } - - MetadataType mdType = typeDesc as MetadataType; - Debug.Assert(mdType != null); - - TypeDesc firstFieldElementType = firstField.FieldType; - int firstFieldSize = firstFieldElementType.GetElementSize().AsInt; - - // A fixed buffer type is always a value type that has exactly one value type field at offset 0 - // and who's size is an exact multiple of the size of the field. - // It is possible that we catch a false positive with this check, but that chance is extremely slim - // and the user can always change their structure to something more descriptive of what they want - // instead of adding additional padding at the end of a one-field structure. - // We do this check here to save looking up the FixedBufferAttribute when loading the field - // from metadata. - bool isFixedBuffer = numIntroducedFields == 1 - && firstFieldElementType.IsValueType - && firstField.Offset.AsInt == 0 - && mdType.HasLayout() - && ((typeDesc.GetElementSize().AsInt % firstFieldSize) == 0); - - if (isFixedBuffer) - { - numIntroducedFields = typeDesc.GetElementSize().AsInt / firstFieldSize; - if (numIntroducedFields > 2) - { - return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - } - } - - int fieldIndex = 0; - foreach (FieldDesc field in typeDesc.GetFields()) - { - if (fieldIndex > 1) - { - return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - } - - Debug.Assert(fieldIndex < numIntroducedFields); - - switch (field.FieldType.Category) - { - case TypeFlags.Double: - { - if (numIntroducedFields == 1) - floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE; - else if (fieldIndex == 0) - floatFieldFlags = (uint)LAFlags.STRUCT_FIRST_FIELD_DOUBLE; - else if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) - floatFieldFlags = floatFieldFlags ^ (uint)LAFlags.STRUCT_MERGE_FIRST_SECOND_8; - else - floatFieldFlags |= (uint)LAFlags.STRUCT_SECOND_FIELD_DOUBLE; - } - break; - - case TypeFlags.Single: - { - if (numIntroducedFields == 1) - floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE; - else if (fieldIndex == 0) - floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST; - else if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) - floatFieldFlags ^= (uint)LAFlags.STRUCT_MERGE_FIRST_SECOND; - else - floatFieldFlags |= (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND; - } - break; - - case TypeFlags.ValueType: - //case TypeFlags.Class: - //case TypeFlags.Array: - //case TypeFlags.SzArray: - { - uint floatFieldFlags2 = GetLoongArch64PassStructInRegisterFlags(field.FieldType); - if (numIntroducedFields == 1) - floatFieldFlags = floatFieldFlags2; - else if (field.FieldType.GetElementSize().AsInt > 8) - return (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - else if (fieldIndex == 0) - { - if ((floatFieldFlags2 & (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0) - floatFieldFlags = (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST; - if (field.FieldType.GetElementSize().AsInt == 8) - floatFieldFlags |= (uint)LAFlags.STRUCT_FIRST_FIELD_SIZE_IS8; - } - else - { - Debug.Assert(fieldIndex == 1); - if ((floatFieldFlags2 & (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0) - floatFieldFlags |= (uint)LAFlags.STRUCT_MERGE_FIRST_SECOND; - if (field.FieldType.GetElementSize().AsInt == 8) - floatFieldFlags |= (uint)LAFlags.STRUCT_SECOND_FIELD_SIZE_IS8; - - floatFieldFlags2 = floatFieldFlags & ((uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND); - if (floatFieldFlags2 == 0) - floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - else if (floatFieldFlags2 == ((uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND)) - floatFieldFlags ^= ((uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_TWO | (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)LAFlags.STRUCT_FLOAT_FIELD_SECOND); - } - } - break; - - default: - { - if (field.FieldType.GetElementSize().AsInt == 8) - { - if (numIntroducedFields > 1) - { - if (fieldIndex == 0) - floatFieldFlags = (uint)LAFlags.STRUCT_FIRST_FIELD_SIZE_IS8; - else if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) - floatFieldFlags |= (uint)LAFlags.STRUCT_SECOND_FIELD_SIZE_IS8; - else - floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - } - } - else if (fieldIndex == 1) - floatFieldFlags = (floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_FIRST) > 0 ? floatFieldFlags : (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - break; - } - } - - fieldIndex++; - } - - return floatFieldFlags; - } - } -} diff --git a/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs b/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs index 160ff674f8d71a..b3b587d1432f48 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/TargetArchitecture.cs @@ -17,6 +17,5 @@ public enum TargetArchitecture X64, X86, Wasm32, - LoongArch64, } } diff --git a/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs b/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs index b8b28f5fb7b440..e5626ed8f976d3 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/TargetDetails.cs @@ -80,7 +80,6 @@ public int PointerSize { case TargetArchitecture.ARM64: case TargetArchitecture.X64: - case TargetArchitecture.LoongArch64: return 8; case TargetArchitecture.ARM: case TargetArchitecture.X86: @@ -117,10 +116,6 @@ public int MaximumAlignment // Corresponds to alignmet required for __m256 return 16; } - else if (Architecture == TargetArchitecture.LoongArch64) - { - return 16; - } // 256-bit vector is the type with the higest alignment we support return 32; @@ -177,7 +172,6 @@ public int MinimumCodeAlignment case TargetArchitecture.ARM: return 2; case TargetArchitecture.ARM64: - case TargetArchitecture.LoongArch64: return 4; default: return 1; @@ -282,7 +276,6 @@ public LayoutInt GetObjectAlignment(LayoutInt fieldAlignment) return new LayoutInt(8); case TargetArchitecture.X64: case TargetArchitecture.ARM64: - case TargetArchitecture.LoongArch64: return new LayoutInt(8); case TargetArchitecture.X86: return new LayoutInt(4); @@ -325,7 +318,6 @@ public int MaxHomogeneousAggregateElementCount // and Procedure Call Standard for the Arm 64-bit Architecture. Debug.Assert(Architecture == TargetArchitecture.ARM || Architecture == TargetArchitecture.ARM64 || - Architecture == TargetArchitecture.LoongArch64 || Architecture == TargetArchitecture.X64 || Architecture == TargetArchitecture.X86); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs index 86c63c517b3fb0..28d10f23a28f06 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/ArgIterator.cs @@ -233,7 +233,6 @@ internal struct ArgLocDesc public int m_byteStackIndex; // Stack offset in bytes (or -1) public int m_byteStackSize; // Stack size in bytes - public uint m_floatFlags; // struct with two-fields can be passed by registers. // Initialize to represent a non-placed argument (no register or stack slots referenced). public void Init() { @@ -243,7 +242,6 @@ public void Init() m_cGenReg = 0; m_byteStackIndex = -1; m_byteStackSize = 0; - m_floatFlags = 0; m_fRequires64BitAlignment = false; } @@ -838,13 +836,6 @@ public int GetNextOffset() _arm64IdxFPReg = 0; break; - case TargetArchitecture.LoongArch64: - _loongarch64IdxGenReg = numRegistersUsed; - _loongarch64OfsStack = 0; - - _loongarch64IdxFPReg = 0; - break; - default: throw new NotImplementedException(); } @@ -1334,120 +1325,6 @@ public int GetNextOffset() return argOfs; } - case TargetArchitecture.LoongArch64: - { - int cFPRegs = 0; - uint floatFieldFlags = (uint)LAFlags.STRUCT_NO_FLOAT_FIELD; - _hasArgLocDescForStructInRegs = false; - - switch (argType) - { - case CorElementType.ELEMENT_TYPE_R4: - // 32-bit floating point argument. - cFPRegs = 1; - break; - - case CorElementType.ELEMENT_TYPE_R8: - // 64-bit floating point argument. - cFPRegs = 1; - break; - - case CorElementType.ELEMENT_TYPE_VALUETYPE: - { - // Composite greater than 16 bytes should be passed by reference - if (argSize > _transitionBlock.EnregisteredParamTypeMaxSize) - { - argSize = _transitionBlock.PointerSize; - } - else - { - floatFieldFlags = LoongArch64PassStructInRegister.GetLoongArch64PassStructInRegisterFlags(_argTypeHandle.GetRuntimeTypeHandle()); - if ((floatFieldFlags & (uint)LAFlags.STRUCT_FLOAT_FIELD_ONLY_TWO) != 0) - cFPRegs = 2; - else if ((floatFieldFlags & (uint)LAFlags.STRUCT_HAS_FLOAT_FIELDS_MASK) != 0) - cFPRegs = 1; - } - - break; - } - - default: - break; - } - - bool isValueType = (argType == CorElementType.ELEMENT_TYPE_VALUETYPE); - int cbArg = _transitionBlock.StackElemSize(argSize, isValueType, false); - - if (cFPRegs > 0 && !IsVarArg) - { - if (isValueType && ((floatFieldFlags & (uint)LAFlags.STRUCT_HAS_ONE_FLOAT_MASK) != 0)) - { - if ((_loongarch64IdxFPReg < 8) && (_loongarch64IdxGenReg < 8)) - { - _argLocDescForStructInRegs = new ArgLocDesc(); - _argLocDescForStructInRegs.m_idxFloatReg = _loongarch64IdxFPReg; - _argLocDescForStructInRegs.m_cFloatReg = 1; - - _argLocDescForStructInRegs.m_idxGenReg = _loongarch64IdxGenReg; - _argLocDescForStructInRegs.m_cGenReg = 1; - - _hasArgLocDescForStructInRegs = true; - _argLocDescForStructInRegs.m_floatFlags = floatFieldFlags; - - int argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8; - _loongarch64IdxFPReg++; - _loongarch64IdxGenReg++; - return argOfsInner; - } - else - { - _loongarch64IdxFPReg = 8; - } - } - else if (cFPRegs + _loongarch64IdxFPReg <= 8) - { - // Each floating point register in the argument area is 8 bytes. - int argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8; - _loongarch64IdxFPReg += cFPRegs; - return argOfsInner; - } - else - { - _loongarch64IdxFPReg = 8; - } - } - - { - Debug.Assert((cbArg % _transitionBlock.PointerSize) == 0); - - int regSlots = ALIGN_UP(cbArg, _transitionBlock.PointerSize) / _transitionBlock.PointerSize; - // Only R4-R11 are valid argument registers. - if (_loongarch64IdxGenReg + regSlots <= 8) - { - // The entirety of the arg fits in the register slots. - int argOfsInner = _transitionBlock.OffsetOfArgumentRegisters + _loongarch64IdxGenReg * 8; - _loongarch64IdxGenReg += regSlots; - return argOfsInner; - } - else if (_loongarch64IdxGenReg < 8) - { - int argOfsInner = _transitionBlock.OffsetOfArgumentRegisters + _loongarch64IdxGenReg * 8; - _loongarch64IdxGenReg = 8; - _loongarch64OfsStack += 8; - return argOfsInner; - } - else - { - // Don't use reg slots for this. It will be passed purely on the stack arg space. - _loongarch64IdxGenReg = 8; - } - } - - argOfs = _transitionBlock.OffsetOfArgs + _loongarch64OfsStack; - _loongarch64OfsStack += cbArg; - return argOfs; - } - default: throw new NotImplementedException(); } @@ -1748,64 +1625,6 @@ private void ForceSigWalk() return pLoc; } - case TargetArchitecture.LoongArch64: - { - if (_hasArgLocDescForStructInRegs) - { - return _argLocDescForStructInRegs; - } - - // LIMITED_METHOD_CONTRACT; - - ArgLocDesc pLoc = new ArgLocDesc(); - - if (_transitionBlock.IsFloatArgumentRegisterOffset(argOffset)) - { - int floatRegOfsInBytes = argOffset - _transitionBlock.OffsetOfFloatArgumentRegisters; - Debug.Assert((floatRegOfsInBytes % _transitionBlock.FloatRegisterSize) == 0); - pLoc.m_idxFloatReg = floatRegOfsInBytes / _transitionBlock.FloatRegisterSize; - - if (!_argTypeHandle.IsNull() && _argTypeHandle.IsHomogeneousAggregate()) - { - int haElementSize = _argTypeHandle.GetHomogeneousAggregateElementSize(); - pLoc.m_cFloatReg = GetArgSize() / haElementSize; - } - else - { - pLoc.m_cFloatReg = 1; - } - return pLoc; - } - - int byteArgSize = GetArgSize(); - - // Composites greater than 16bytes are passed by reference - TypeHandle dummy; - if (GetArgType(out dummy) == CorElementType.ELEMENT_TYPE_VALUETYPE && GetArgSize() > _transitionBlock.EnregisteredParamTypeMaxSize) - { - byteArgSize = _transitionBlock.PointerSize; - } - - if (!_transitionBlock.IsStackArgumentOffset(argOffset)) - { - pLoc.m_idxGenReg = _transitionBlock.GetArgumentIndexFromOffset(argOffset); - if ((pLoc.m_idxGenReg == 7) && (byteArgSize > _transitionBlock.PointerSize)) - { - pLoc.m_cGenReg = 1; - pLoc.m_byteStackIndex = 0; - pLoc.m_byteStackSize = 8; - } - else - pLoc.m_cGenReg = (short)(ALIGN_UP(byteArgSize, _transitionBlock.PointerSize) / _transitionBlock.PointerSize); - } - else - { - pLoc.m_byteStackIndex = _transitionBlock.GetStackArgumentByteIndexFromOffset(argOffset); - pLoc.m_byteStackSize = _transitionBlock.StackElemSize(byteArgSize, IsValueType(), IsFloatHfa()); - } - return pLoc; - } - case TargetArchitecture.X64: if (_transitionBlock.IsX64UnixABI) { @@ -1891,10 +1710,6 @@ private void ForceSigWalk() private int _arm64OfsStack; // Offset of next stack location to be assigned a value private int _arm64IdxFPReg; // Next FP register to be assigned a value - private int _loongarch64IdxGenReg; // Next general register to be assigned a value - private int _loongarch64OfsStack; // Offset of next stack location to be assigned a value - private int _loongarch64IdxFPReg; // Next FP register to be assigned a value - // These are enum flags in CallingConventions.h, but that's really ugly in C#, so I've changed them to bools. private bool _ITERATION_STARTED; // Started iterating over arguments private bool _SIZE_OF_ARG_STACK_COMPUTED; @@ -1923,7 +1738,7 @@ private enum ParamTypeLocation // METHOD_INVOKE_NEEDS_ACTIVATION = 0x0040, // Flag used by ArgIteratorForMethodInvoke // RETURN_FP_SIZE_SHIFT = 8, // The rest of the flags is cached value of GetFPReturnSize - // {}; + // }; private void ComputeReturnFlags() { diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs index 3246b5a143ca3c..a43ad0335ccc1c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodGCInfoNode.cs @@ -138,7 +138,7 @@ private IEnumerable EncodeDataCore(NodeFactory factory) unwindInfo[0] |= (byte)((UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER) << FlagsShift); } - else if ((targetArch == TargetArchitecture.ARM) || (targetArch == TargetArchitecture.ARM64) || (targetArch == TargetArchitecture.LoongArch64)) + else if ((targetArch == TargetArchitecture.ARM) || (targetArch == TargetArchitecture.ARM64)) { // Set the 'X' bit to indicate that there is a personality routine associated with this method unwindInfo[2] |= 1 << 4; diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs deleted file mode 100644 index 5e0a8751d472b3..00000000000000 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/Target_LoongArch64/ImportThunk.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -using ILCompiler.DependencyAnalysis.LoongArch64; - -namespace ILCompiler.DependencyAnalysis.ReadyToRun -{ - /// - /// This node emits a thunk calling DelayLoad_Helper with a given instance signature - /// to populate its indirection cell. - /// - public partial class ImportThunk - { - protected override void EmitCode(NodeFactory factory, ref LoongArch64Emitter instructionEncoder, bool relocsOnly) - { - - switch (_thunkKind) - { - case Kind.Eager: - break; - - case Kind.DelayLoadHelper: - case Kind.VirtualStubDispatch: - // T8 contains indirection cell - // Do nothing T8=R20 contains our first param - - if (!relocsOnly) - { - // movz T0=R12, #index - int index = _containingImportSection.IndexFromBeginningOfArray; - instructionEncoder.EmitMOV(Register.R12, checked((ushort)index)); - } - - // get pc - // pcaddi T1=R13, 0 - instructionEncoder.EmitPC(Register.R13); - - // load Module* -> T1 - instructionEncoder.EmitLD(Register.R13, Register.R13, 0x24); - - // ld_d R13, R13, 0 - instructionEncoder.EmitLD(Register.R13, Register.R13, 0); - break; - - case Kind.Lazy: - // get pc - // pcaddi R5, 0 - instructionEncoder.EmitPC(Register.R5); - - // load Module* -> R5=A1 - instructionEncoder.EmitLD(Register.R5, Register.R5, 0x24); - - // ld_d R5, R5, 0 - instructionEncoder.EmitLD(Register.R5, Register.R5, 0); - break; - - default: - throw new NotImplementedException(); - } - - // branch to helper - instructionEncoder.EmitJMP(_helperCell); - - // Emit relocation for the Module* load above - if (_thunkKind != Kind.Eager) - instructionEncoder.Builder.EmitReloc(factory.ModuleImport, RelocType.IMAGE_REL_BASED_DIR64); - } - } -} diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs index d76413ff0a58d6..a044a42b1d2dd1 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/TransitionBlock.cs @@ -43,9 +43,6 @@ public static TransitionBlock FromTarget(TargetDetails target) AppleArm64TransitionBlock.Instance : Arm64TransitionBlock.Instance; - case TargetArchitecture.LoongArch64: - return LoongArch64TransitionBlock.Instance; - default: throw new NotImplementedException(target.Architecture.ToString()); } @@ -63,7 +60,6 @@ public static TransitionBlock FromTarget(TargetDetails target) public bool IsX64 => Architecture == TargetArchitecture.X64; public bool IsARM => Architecture == TargetArchitecture.ARM; public bool IsARM64 => Architecture == TargetArchitecture.ARM64; - public bool IsLoongArch64 => Architecture == TargetArchitecture.LoongArch64; /// /// This property is only overridden in AMD64 Unix variant of the transition block. @@ -654,45 +650,5 @@ public sealed override int StackElemSize(int parmSize, bool isValueType = false, return base.StackElemSize(parmSize, isValueType, isFloatHfa); } } - - private class LoongArch64TransitionBlock : TransitionBlock - { - public static TransitionBlock Instance = new LoongArch64TransitionBlock(); - public override TargetArchitecture Architecture => TargetArchitecture.LoongArch64; - public override int PointerSize => 8; - public override int FloatRegisterSize => 8; // TODO: for SIMD. - // R4 .. R11 - public override int NumArgumentRegisters => 8; - // fp=R22,ra=R1,s0-s8(R23-R31),tp=R2 - public override int NumCalleeSavedRegisters => 12; - // Callee-saves, padding, argument registers - public override int SizeOfTransitionBlock => SizeOfCalleeSavedRegisters + SizeOfArgumentRegisters; - public override int OffsetOfArgumentRegisters => SizeOfCalleeSavedRegisters; - public override int OffsetOfFirstGCRefMapSlot => OffsetOfArgumentRegisters; - - // F0..F7 - public override int OffsetOfFloatArgumentRegisters => 8 * sizeof(double); - public override int EnregisteredParamTypeMaxSize => 16; - public override int EnregisteredReturnTypeIntegerMaxSize => 16; - - public override bool IsArgPassedByRef(TypeHandle th) - { - Debug.Assert(!th.IsNull()); - Debug.Assert(th.IsValueType()); - - // Composites greater than 16 bytes are passed by reference - return (th.GetSize() > EnregisteredParamTypeMaxSize) && !th.IsHomogeneousAggregate(); - } - - public override int GetRetBuffArgOffset(bool hasThis) => OffsetOfX8Register; - - public override bool IsRetBuffPassedAsFirstArg => false; - - public override int StackElemSize(int parmSize, bool isValueType = false, bool isFloatHfa = false) - { - int stackSlotSize = 8; - return ALIGN_UP(parmSize, stackSlotSize); - } - } } } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs index f37305a1149a93..f507cabb4d3e3c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs @@ -116,11 +116,6 @@ private class ModuleFieldLayoutMap : LockFreeReaderHashtable private const int DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobArm = 8; - /// - /// CoreCLR DomainLocalModule::NormalDynamicEntry::OffsetOfDataBlob for LoongArch64 - /// - private const int DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobLoongArch64 = 8; - protected override bool CompareKeyToValue(EcmaModule key, ModuleFieldLayout value) { return key == value.Module; @@ -419,10 +414,6 @@ public FieldAndOffset[] GetOrAddDynamicLayout(DefType defType, ModuleFieldLayout nonGcOffset = DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobArm; break; - case TargetArchitecture.LoongArch64: - nonGcOffset = DomainLocalModuleNormalDynamicEntryOffsetOfDataBlobLoongArch64; - break; - default: throw new NotImplementedException(); } diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index 9724e451000de4..5154db358a8b8e 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -77,10 +77,6 @@ - - - - @@ -106,7 +102,6 @@ - @@ -184,7 +179,6 @@ - diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs index 8cab279b2d7680..09f9244aeffcf1 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/ObjectWriter/RelocationHelper.cs @@ -220,14 +220,6 @@ public void ProcessRelocation(RelocType relocationType, int sourceRVA, int targe break; } - case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: - case RelocType.IMAGE_REL_BASED_LOONGARCH64_JIR: - { - relocationLength = 4; - delta = targetRVA - sourceRVA; - break; - } - default: throw new NotSupportedException(); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 8925043b7ac513..4eab54b43b8628 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -200,9 +200,6 @@ public TargetArchitecture TargetArchitecture case Machine.Arm64: return TargetArchitecture.ARM64; - case Machine.LoongArch64: - return TargetArchitecture.LoongArch64; - default: throw new NotImplementedException(_machine.ToString()); } @@ -645,11 +642,6 @@ private unsafe void EnsureHeader() _pointerSize = 8; break; - case Machine.LoongArch64: - _architecture = Architecture.LoongArch64; - _pointerSize = 8; - break; - default: throw new NotImplementedException(Machine.ToString()); } diff --git a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs index 96f4108f7910ac..3f0bef94f8e40f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs +++ b/src/coreclr/tools/aot/ILCompiler.Reflection.ReadyToRun/TransitionBlock.cs @@ -149,20 +149,5 @@ private sealed class Arm64TransitionBlock : TransitionBlock private int OffsetOfX8Register => OffsetOfArgumentRegisters - PointerSize; public override int OffsetOfFirstGCRefMapSlot => OffsetOfX8Register; } - - private sealed class LoongArch64TransitionBlock : TransitionBlock - { - public static readonly TransitionBlock Instance = new LoongArch64TransitionBlock(); - - public override int PointerSize => 8; - // R4 .. R11 - public override int NumArgumentRegisters => 8; - // fp=R22,ra=R1,s0-s8(R23-R31),tp=R2 - public override int NumCalleeSavedRegisters => 12; - // Callee-saves, padding, argument registers - public override int SizeOfTransitionBlock => SizeOfCalleeSavedRegisters + SizeOfArgumentRegisters; - public override int OffsetOfArgumentRegisters => SizeOfCalleeSavedRegisters; - public override int OffsetOfFirstGCRefMapSlot => OffsetOfArgumentRegisters; - } } } diff --git a/src/coreclr/tools/aot/crossgen2/Program.cs b/src/coreclr/tools/aot/crossgen2/Program.cs index fe2bb27e89b795..ff538c05fd64c4 100644 --- a/src/coreclr/tools/aot/crossgen2/Program.cs +++ b/src/coreclr/tools/aot/crossgen2/Program.cs @@ -76,9 +76,6 @@ public static void ComputeDefaultOptions(out TargetOS os, out TargetArchitecture case Architecture.Arm64: arch = TargetArchitecture.ARM64; break; - case Architecture.LoongArch64: - arch = TargetArchitecture.LoongArch64; - break; default: throw new NotImplementedException(); } @@ -197,8 +194,6 @@ public static TargetArchitecture GetTargetArchitectureFromArg(string archArg, ou } else if (archArg.Equals("arm64", StringComparison.OrdinalIgnoreCase)) return TargetArchitecture.ARM64; - else if (archArg.Equals("loongarch64", StringComparison.OrdinalIgnoreCase)) - return TargetArchitecture.LoongArch64; else throw new CommandLineException(SR.TargetArchitectureUnsupported); } diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.props b/src/coreclr/tools/aot/crossgen2/crossgen2.props index af6617589c696d..2d6e9dff4072d9 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.props +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.props @@ -5,7 +5,7 @@ Exe $(NetCoreAppToolCurrent) 8002,NU1701 - x64;x86;arm64;arm;loongarch64 + x64;x86;arm64;arm AnyCPU false true From a6cbbccb9c107488c7d44a778c30576a1d38d8ea Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Fri, 18 Feb 2022 12:06:52 +0800 Subject: [PATCH 18/18] [LoongArch64] update the `GUID JITEEVersionIdentifier`. Also delete some unused comments. --- src/coreclr/inc/jiteeversionguid.h | 10 +++++----- .../superpmi/superpmi-shim-collector/icorjitinfo.cpp | 1 - src/coreclr/vm/jitinterface.cpp | 7 +------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index e7b8884419e5a6..303f97b6e7779a 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 323185e9-208a-4b35-a413-23f9aac2d5f7 */ - 0x323185e9, - 0x208a, - 0x4b35, - {0xa4, 0x13, 0x23, 0xf9, 0xaa, 0xc2, 0xd5, 0xf7} +constexpr GUID JITEEVersionIdentifier = { /* 80a6aaf7-7fb3-44b2-8fe5-95fd47308798 */ + 0x80a6aaf7, + 0x7fb3, + 0x44b2, + {0x8f, 0xe5, 0x95, 0xfd, 0x47, 0x30, 0x87, 0x98} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index de597bdd3df647..bd3ca05f5c20b2 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1203,7 +1203,6 @@ CorInfoTypeWithMod interceptor_ICJI::getArgType(CORINFO_SIG_INFO* sig, }, [&](DWORD exceptionCode) { - this->mc->recGetArgType(sig, args, vcTypeRet, temp, exceptionCode); }); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 93ffa5bb7708a9..a4120aaccfa029 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9323,16 +9323,11 @@ CorInfoTypeWithMod CEEInfo::getArgType ( return result; } -// NOTE: -// Although this is only used for LoongArch64-ABI now, -// maybe it can be used for other architecture for getting ABI-info -// between JIT/EE if the ABI is similar. -// // 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 whether a struct-arg using float regitsters: +// 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) {