Skip to content

Commit ff08208

Browse files
tomeksowishushanhf
authored andcommitted
[RISC-V][LoongArch64] New passing info for floating-point structs (#103945)
* Replace StructFloatFieldInfoFlags with FpStructInRegistersInfo which carries also exact field sizes and offsets * Replace StructFloatFieldInfoFlags with FpStruct::Flags in profiler * Remove FpStructInRegistersInfo::FromOldFlags() * Fix duplicating types in HandleInlineArray * Remove signedness from FpStruct::IntKind because most probably we won't need it * Remove old StructFloatFieldInfoFlags calculating routine * Typo in TARGET_LOONGARCH64 * Remove m_returnedFpFieldOffsets from ArgIterator * Add missing ENREGISTERED_PARAMTYPE_MAXSIZE condition to C# version of FpStruct info calculation * Rename RISCV64PassStructInRegister to match settled casing for RiscV in class names * Update hardcoded flags for float and double in ArgIteratorTemplate::ComputeReturnFlags() This fixes JIT/HardwareIntrinsics/General/Vector* tests. * Fix build on other platforms * Update LoongArch to use FpStructInRegistersInfo * Remove unused old flag masks * LoongArch64 typo Co-authored-by: Qiao Pengcheng <qiaopengcheng@loongson.cn> * Missing FpStruct namespace Co-authored-by: Qiao Pengcheng <qiaopengcheng@loongson.cn> * Missing FpStruct namespace Co-authored-by: Qiao Pengcheng <qiaopengcheng@loongson.cn> * Missing FpStruct namespace Co-authored-by: Qiao Pengcheng <qiaopengcheng@loongson.cn> * Use FpStruct namespace everywhere in JIT * JIT review * Update StructFloatFieldInfoFlags description * Revert to hitherto instruction set order as it's not the point of this PR * Unify get{LoongArch,RiscV}64PassFpStructInRegistersInfo JIT interfaces * Use JIT_TO_EE_TRANSITION instead of _LEAF because MethodTable::GetFpStructInRegistersInfo may throw * Remove FpStruct::IntKind, we should have similar info in ClassLayout in JIT * Change JIT interface to return a struct similar to CORINFO_SWIFT_LOWERING to facilitate code unification in the future * Change JIT to use new Swift-like getFpStructLowering * Cache CORINFO_FPSTRUCT_LOWERING * Update LoongArch classifier to use CORINFO_FPSTRUCT_LOWERING * Update StructFloatInfoFlags doc comment on C# * Move StructFloatFieldInfoFlags and FpStructInRegistersInfo out of the JIT interface * Merge LoongArch and RISC-V AOT calculation of FpStructInRegistersInfo because they were identical. Move it to Common\Internal/Runtime because it's no longer exposed in JIT interface. * Don't zero-initialize CORINFO_FPSTRUCT_LOWERING * Add note for CORINFO_FPSTRUCT_LOWERING::loweredElements type --------- Co-authored-by: Qiao Pengcheng <qiaopengcheng@loongson.cn>
1 parent b2e41aa commit ff08208

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1135
-965
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 20 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -307,45 +307,6 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
307307
}
308308
};
309309

310-
// StructFloadFieldInfoFlags: used on LoongArch64 architecture by `getLoongArch64PassStructInRegisterFlags` and
311-
// `getRISCV64PassStructInRegisterFlags` API to convey struct argument passing information.
312-
//
313-
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
314-
//
315-
// Otherwise, and only for structs with no more than two fields and a total struct size no larger
316-
// than two pointers:
317-
//
318-
// The lowest four bits denote the floating-point info:
319-
// bit 0: `1` means there is only one float or double field within the struct.
320-
// bit 1: `1` means only the first field is floating-point type.
321-
// bit 2: `1` means only the second field is floating-point type.
322-
// bit 3: `1` means the two fields are both floating-point type.
323-
// The bits[5:4] denoting whether the field size is 8-bytes:
324-
// bit 4: `1` means the first field's size is 8.
325-
// bit 5: `1` means the second field's size is 8.
326-
//
327-
// Note that bit 0 and 3 cannot both be set.
328-
enum StructFloatFieldInfoFlags
329-
{
330-
STRUCT_NO_FLOAT_FIELD = 0x0,
331-
STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1,
332-
STRUCT_FLOAT_FIELD_ONLY_TWO = 0x8,
333-
STRUCT_FLOAT_FIELD_FIRST = 0x2,
334-
STRUCT_FLOAT_FIELD_SECOND = 0x4,
335-
STRUCT_FIRST_FIELD_SIZE_IS8 = 0x10,
336-
STRUCT_SECOND_FIELD_SIZE_IS8 = 0x20,
337-
338-
STRUCT_FIRST_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FIRST_FIELD_SIZE_IS8),
339-
STRUCT_SECOND_FIELD_DOUBLE = (STRUCT_FLOAT_FIELD_SECOND | STRUCT_SECOND_FIELD_SIZE_IS8),
340-
STRUCT_FIELD_TWO_DOUBLES = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8 | STRUCT_FLOAT_FIELD_ONLY_TWO),
341-
342-
STRUCT_MERGE_FIRST_SECOND = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO),
343-
STRUCT_MERGE_FIRST_SECOND_8 = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_SECOND_FIELD_SIZE_IS8),
344-
345-
STRUCT_HAS_FLOAT_FIELDS_MASK = (STRUCT_FLOAT_FIELD_FIRST | STRUCT_FLOAT_FIELD_SECOND | STRUCT_FLOAT_FIELD_ONLY_TWO | STRUCT_FLOAT_FIELD_ONLY_ONE),
346-
STRUCT_HAS_8BYTES_FIELDS_MASK = (STRUCT_FIRST_FIELD_SIZE_IS8 | STRUCT_SECOND_FIELD_SIZE_IS8),
347-
};
348-
349310
#include "corinfoinstructionset.h"
350311

351312
// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
@@ -1940,6 +1901,23 @@ struct CORINFO_SWIFT_LOWERING
19401901
size_t numLoweredElements;
19411902
};
19421903

1904+
#define MAX_FPSTRUCT_LOWERED_ELEMENTS 2
1905+
1906+
// Lowering information on fields of a struct passed by hardware floating-point calling convention on RISC-V and LoongArch
1907+
struct CORINFO_FPSTRUCT_LOWERING
1908+
{
1909+
// Whether the struct should be passed by integer calling convention (cannot be passed by FP calling convention).
1910+
bool byIntegerCallConv;
1911+
// Types of lowered struct fields.
1912+
// Note: the integer field is denoted with a signed type reflecting size only so e.g. ushort is reported
1913+
// as CORINFO_TYPE_SHORT and object or string is reported as CORINFO_TYPE_LONG.
1914+
CorInfoType loweredElements[MAX_FPSTRUCT_LOWERED_ELEMENTS];
1915+
// Offsets of lowered struct fields.
1916+
uint32_t offsets[MAX_FPSTRUCT_LOWERED_ELEMENTS];
1917+
// Number of lowered struct fields.
1918+
size_t numLoweredElements;
1919+
};
1920+
19431921
#define SIZEOF__CORINFO_Object TARGET_POINTER_SIZE /* methTable */
19441922

19451923
#define CORINFO_Array_MaxLength 0x7FFFFFC7
@@ -3065,8 +3043,9 @@ class ICorStaticInfo
30653043
// Classifies a swift structure into primitives or an implicit byref for ABI purposes.
30663044
virtual void getSwiftLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_SWIFT_LOWERING* pLowering) = 0;
30673045

3068-
virtual uint32_t getLoongArch64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
3069-
virtual uint32_t getRISCV64PassStructInRegisterFlags(CORINFO_CLASS_HANDLE cls) = 0;
3046+
// Returns lowering info for fields of a RISC-V/LoongArch struct passed in registers according to
3047+
// hardware floating-point calling convention.
3048+
virtual void getFpStructLowering(CORINFO_CLASS_HANDLE structHnd, CORINFO_FPSTRUCT_LOWERING* pLowering) = 0;
30703049
};
30713050

30723051
/*****************************************************************************

src/coreclr/inc/icorjitinfoimpl_generated.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,11 +520,9 @@ void getSwiftLowering(
520520
CORINFO_CLASS_HANDLE structHnd,
521521
CORINFO_SWIFT_LOWERING* pLowering) override;
522522

523-
uint32_t getLoongArch64PassStructInRegisterFlags(
524-
CORINFO_CLASS_HANDLE structHnd) override;
525-
526-
uint32_t getRISCV64PassStructInRegisterFlags(
527-
CORINFO_CLASS_HANDLE structHnd) override;
523+
void getFpStructLowering(
524+
CORINFO_CLASS_HANDLE structHnd,
525+
CORINFO_FPSTRUCT_LOWERING* pLowering) override;
528526

529527
uint32_t getThreadTLSIndex(
530528
void** ppIndirection) override;

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
4343
#define GUID_DEFINED
4444
#endif // !GUID_DEFINED
4545

46-
constexpr GUID JITEEVersionIdentifier = { /* 488a17ce-26c9-4ad0-a7b7-79bf320ea4d1 */
47-
0x488a17ce,
48-
0x26c9,
49-
0x4ad0,
50-
{0xa7, 0xb7, 0x79, 0xbf, 0x32, 0x0e, 0xa4, 0xd1}
46+
constexpr GUID JITEEVersionIdentifier = { /* e770e8ad-50d5-4511-a435-a3ed3a847a47 */
47+
0xe770e8ad,
48+
0x50d5,
49+
0x4511,
50+
{0xa4, 0x35, 0xa3, 0xed, 0x3a, 0x84, 0x7a, 0x47}
5151
};
5252

5353
//////////////////////////////////////////////////////////////////////////////////////////////////////////

src/coreclr/jit/ICorJitInfo_names_generated.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ DEF_CLR_API(getMethodNameFromMetadata)
130130
DEF_CLR_API(getMethodHash)
131131
DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor)
132132
DEF_CLR_API(getSwiftLowering)
133-
DEF_CLR_API(getLoongArch64PassStructInRegisterFlags)
134-
DEF_CLR_API(getRISCV64PassStructInRegisterFlags)
133+
DEF_CLR_API(getFpStructLowering)
135134
DEF_CLR_API(getThreadTLSIndex)
136135
DEF_CLR_API(getAddrOfCaptureThreadGlobal)
137136
DEF_CLR_API(getHelperFtn)

src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,22 +1238,13 @@ void WrapICorJitInfo::getSwiftLowering(
12381238
API_LEAVE(getSwiftLowering);
12391239
}
12401240

1241-
uint32_t WrapICorJitInfo::getLoongArch64PassStructInRegisterFlags(
1242-
CORINFO_CLASS_HANDLE structHnd)
1243-
{
1244-
API_ENTER(getLoongArch64PassStructInRegisterFlags);
1245-
uint32_t temp = wrapHnd->getLoongArch64PassStructInRegisterFlags(structHnd);
1246-
API_LEAVE(getLoongArch64PassStructInRegisterFlags);
1247-
return temp;
1248-
}
1249-
1250-
uint32_t WrapICorJitInfo::getRISCV64PassStructInRegisterFlags(
1251-
CORINFO_CLASS_HANDLE structHnd)
1241+
void WrapICorJitInfo::getFpStructLowering(
1242+
CORINFO_CLASS_HANDLE structHnd,
1243+
CORINFO_FPSTRUCT_LOWERING* pLowering)
12521244
{
1253-
API_ENTER(getRISCV64PassStructInRegisterFlags);
1254-
uint32_t temp = wrapHnd->getRISCV64PassStructInRegisterFlags(structHnd);
1255-
API_LEAVE(getRISCV64PassStructInRegisterFlags);
1256-
return temp;
1245+
API_ENTER(getFpStructLowering);
1246+
wrapHnd->getFpStructLowering(structHnd, pLowering);
1247+
API_LEAVE(getFpStructLowering);
12571248
}
12581249

12591250
uint32_t WrapICorJitInfo::getThreadTLSIndex(

src/coreclr/jit/buildstring.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#define STRINGIFY(L) #L
5-
#define MAKESTRING(M, L) M(L)
6-
#define STRINGIZE(X) MAKESTRING(STRINGIFY, X)
4+
#include "utils.h"
75

86
#if defined(__clang__)
97
#define BUILD_COMPILER \
10-
"Clang " STRINGIZE(__clang_major__) "." STRINGIZE(__clang_minor__) "." STRINGIZE(__clang_patchlevel__)
8+
"Clang " STRINGIFY(__clang_major__) "." STRINGIFY(__clang_minor__) "." STRINGIFY(__clang_patchlevel__)
119
#elif defined(_MSC_VER)
12-
#define BUILD_COMPILER "MSVC " STRINGIZE(_MSC_FULL_VER)
10+
#define BUILD_COMPILER "MSVC " STRINGIFY(_MSC_FULL_VER)
1311
#elif defined(__GNUC__)
14-
#define BUILD_COMPILER "GCC " STRINGIZE(__GNUC__) "." STRINGIZE(__GNUC_MINOR__) "." STRINGIZE(__GNUC_PATCHLEVEL__)
12+
#define BUILD_COMPILER "GCC " STRINGIFY(__GNUC__) "." STRINGIFY(__GNUC_MINOR__) "." STRINGIFY(__GNUC_PATCHLEVEL__)
1513
#else
1614
#define BUILD_COMPILER "Unknown"
1715
#endif
@@ -26,6 +24,8 @@
2624
#define TARGET_ARCH_STRING "arm64"
2725
#elif defined(TARGET_LOONGARCH64)
2826
#define TARGET_ARCH_STRING "loongarch64"
27+
#elif defined(TARGET_RISCV64)
28+
#define TARGET_ARCH_STRING "riscv64"
2929
#else
3030
#define TARGET_ARCH_STRING "Unknown"
3131
#endif

src/coreclr/jit/compiler.cpp

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -927,37 +927,24 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
927927
howToReturnStruct = SPK_ByReference;
928928
useType = TYP_UNKNOWN;
929929
}
930-
#elif defined(TARGET_LOONGARCH64)
930+
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
931931
if (structSize <= (TARGET_POINTER_SIZE * 2))
932932
{
933-
uint32_t floatFieldFlags = info.compCompHnd->getLoongArch64PassStructInRegisterFlags(clsHnd);
934-
935-
if ((floatFieldFlags & STRUCT_FLOAT_FIELD_ONLY_ONE) != 0)
936-
{
937-
howToReturnStruct = SPK_PrimitiveType;
938-
useType = (structSize > 4) ? TYP_DOUBLE : TYP_FLOAT;
939-
}
940-
else if (floatFieldFlags & (STRUCT_HAS_FLOAT_FIELDS_MASK ^ STRUCT_FLOAT_FIELD_ONLY_ONE))
941-
{
942-
howToReturnStruct = SPK_ByValue;
943-
useType = TYP_STRUCT;
944-
}
945-
}
946-
947-
#elif defined(TARGET_RISCV64)
948-
if (structSize <= (TARGET_POINTER_SIZE * 2))
949-
{
950-
uint32_t floatFieldFlags = info.compCompHnd->getRISCV64PassStructInRegisterFlags(clsHnd);
951-
952-
if ((floatFieldFlags & STRUCT_FLOAT_FIELD_ONLY_ONE) != 0)
953-
{
954-
howToReturnStruct = SPK_PrimitiveType;
955-
useType = (structSize > 4) ? TYP_DOUBLE : TYP_FLOAT;
956-
}
957-
else if (floatFieldFlags & (STRUCT_HAS_FLOAT_FIELDS_MASK ^ STRUCT_FLOAT_FIELD_ONLY_ONE))
933+
const CORINFO_FPSTRUCT_LOWERING* lowering = GetFpStructLowering(clsHnd);
934+
if (!lowering->byIntegerCallConv)
958935
{
959-
howToReturnStruct = SPK_ByValue;
960-
useType = TYP_STRUCT;
936+
if (lowering->numLoweredElements == 1)
937+
{
938+
useType = JITtype2varType(lowering->loweredElements[0]);
939+
assert(varTypeIsFloating(useType));
940+
howToReturnStruct = SPK_PrimitiveType;
941+
}
942+
else
943+
{
944+
assert(lowering->numLoweredElements == 2);
945+
howToReturnStruct = SPK_ByValue;
946+
useType = TYP_STRUCT;
947+
}
961948
}
962949
}
963950

@@ -1998,6 +1985,9 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
19981985
#ifdef SWIFT_SUPPORT
19991986
m_swiftLoweringCache = nullptr;
20001987
#endif
1988+
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
1989+
m_fpStructLoweringCache = nullptr;
1990+
#endif
20011991

20021992
// check that HelperCallProperties are initialized
20031993

@@ -8301,6 +8291,53 @@ void Compiler::GetStructTypeOffset(
83018291
GetStructTypeOffset(structDesc, type0, type1, offset0, offset1);
83028292
}
83038293

8294+
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
8295+
//------------------------------------------------------------------------
8296+
// GetFpStructLowering: Gets the information on passing of a struct according to hardware floating-point
8297+
// calling convention, i.e. the types and offsets of struct fields lowered for passing.
8298+
//
8299+
// Arguments:
8300+
// structHandle - type handle
8301+
//
8302+
// Return value:
8303+
// Lowering info for the struct fields
8304+
const CORINFO_FPSTRUCT_LOWERING* Compiler::GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle)
8305+
{
8306+
if (m_fpStructLoweringCache == nullptr)
8307+
m_fpStructLoweringCache = new (this, CMK_CallArgs) FpStructLoweringMap(getAllocator(CMK_CallArgs));
8308+
8309+
CORINFO_FPSTRUCT_LOWERING* lowering;
8310+
if (!m_fpStructLoweringCache->Lookup(structHandle, &lowering))
8311+
{
8312+
lowering = new (this, CMK_CallArgs) CORINFO_FPSTRUCT_LOWERING;
8313+
info.compCompHnd->getFpStructLowering(structHandle, lowering);
8314+
m_fpStructLoweringCache->Set(structHandle, lowering);
8315+
#ifdef DEBUG
8316+
if (verbose)
8317+
{
8318+
printf("**** getFpStructInRegistersInfo(0x%x (%s, %u bytes)) =>\n", dspPtr(structHandle),
8319+
eeGetClassName(structHandle), info.compCompHnd->getClassSize(structHandle));
8320+
8321+
if (lowering->byIntegerCallConv)
8322+
{
8323+
printf(" pass by integer calling convention\n");
8324+
}
8325+
else
8326+
{
8327+
printf(" may be passed by floating-point calling convention (%zu fields):\n",
8328+
lowering->numLoweredElements);
8329+
for (size_t i = 0; i < lowering->numLoweredElements; ++i)
8330+
{
8331+
const char* type = varTypeName(JITtype2varType(lowering->loweredElements[i]));
8332+
printf(" * field[%zu]: type %s at offset %u\n", i, type, lowering->offsets[i]);
8333+
}
8334+
}
8335+
}
8336+
#endif // DEBUG
8337+
}
8338+
return lowering;
8339+
}
8340+
83048341
#endif // defined(UNIX_AMD64_ABI)
83058342

83068343
/*****************************************************************************/

src/coreclr/jit/compiler.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -561,17 +561,9 @@ class LclVarDsc
561561
unsigned char lvIsLastUseCopyOmissionCandidate : 1;
562562
#endif // FEATURE_IMPLICIT_BYREFS
563563

564-
#if defined(TARGET_LOONGARCH64)
565-
unsigned char lvIs4Field1 : 1; // Set if the 1st field is int or float within struct for LA-ABI64.
566-
unsigned char lvIs4Field2 : 1; // Set if the 2nd field is int or float within struct for LA-ABI64.
567-
unsigned char lvIsSplit : 1; // Set if the argument is splited.
568-
#endif // defined(TARGET_LOONGARCH64)
569-
570-
#if defined(TARGET_RISCV64)
571-
unsigned char lvIs4Field1 : 1; // Set if the 1st field is int or float within struct for RISCV64.
572-
unsigned char lvIs4Field2 : 1; // Set if the 2nd field is int or float within struct for RISCV64.
573-
unsigned char lvIsSplit : 1; // Set if the argument is splited.
574-
#endif // defined(TARGET_RISCV64)
564+
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
565+
unsigned char lvIsSplit : 1; // Set if the argument is split across last integer register and stack.
566+
#endif // defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
575567

576568
unsigned char lvSingleDef : 1; // variable has a single def. Used to identify ref type locals that can get type
577569
// updates
@@ -11496,6 +11488,11 @@ class Compiler
1149611488
void GetStructTypeOffset(
1149711489
CORINFO_CLASS_HANDLE typeHnd, var_types* type0, var_types* type1, uint8_t* offset0, uint8_t* offset1);
1149811490

11491+
#elif defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
11492+
typedef JitHashTable<CORINFO_CLASS_HANDLE, JitPtrKeyFuncs<struct CORINFO_CLASS_STRUCT_>, CORINFO_FPSTRUCT_LOWERING*>
11493+
FpStructLoweringMap;
11494+
FpStructLoweringMap* m_fpStructLoweringCache;
11495+
const CORINFO_FPSTRUCT_LOWERING* GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle);
1149911496
#endif // defined(UNIX_AMD64_ABI)
1150011497

1150111498
void fgMorphMultiregStructArgs(GenTreeCall* call);

src/coreclr/jit/gentree.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29544,37 +29544,29 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp,
2954429544

2954529545
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
2954629546
assert((structSize >= TARGET_POINTER_SIZE) && (structSize <= (2 * TARGET_POINTER_SIZE)));
29547-
29548-
#ifdef TARGET_LOONGARCH64
29549-
uint32_t floatFieldFlags = comp->info.compCompHnd->getLoongArch64PassStructInRegisterFlags(retClsHnd);
29550-
#else
29551-
uint32_t floatFieldFlags = comp->info.compCompHnd->getRISCV64PassStructInRegisterFlags(retClsHnd);
29552-
#endif
2955329547
BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
2955429548
comp->info.compCompHnd->getClassGClayout(retClsHnd, &gcPtrs[0]);
29555-
29556-
if (floatFieldFlags & STRUCT_FLOAT_FIELD_ONLY_TWO)
29557-
{
29558-
comp->compFloatingPointUsed = true;
29559-
assert((structSize > 8) == ((floatFieldFlags & STRUCT_HAS_8BYTES_FIELDS_MASK) > 0));
29560-
m_regType[0] = (floatFieldFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
29561-
m_regType[1] = (floatFieldFlags & STRUCT_SECOND_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
29562-
}
29563-
else if (floatFieldFlags & STRUCT_FLOAT_FIELD_FIRST)
29564-
{
29565-
comp->compFloatingPointUsed = true;
29566-
assert((structSize > 8) == ((floatFieldFlags & STRUCT_HAS_8BYTES_FIELDS_MASK) > 0));
29567-
m_regType[0] = (floatFieldFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
29568-
m_regType[1] =
29569-
(floatFieldFlags & STRUCT_SECOND_FIELD_SIZE_IS8) ? comp->getJitGCType(gcPtrs[1]) : TYP_INT;
29570-
}
29571-
else if (floatFieldFlags & STRUCT_FLOAT_FIELD_SECOND)
29549+
const CORINFO_FPSTRUCT_LOWERING* lowering = comp->GetFpStructLowering(retClsHnd);
29550+
if (!lowering->byIntegerCallConv)
2957229551
{
2957329552
comp->compFloatingPointUsed = true;
29574-
assert((structSize > 8) == ((floatFieldFlags & STRUCT_HAS_8BYTES_FIELDS_MASK) > 0));
29575-
m_regType[0] =
29576-
(floatFieldFlags & STRUCT_FIRST_FIELD_SIZE_IS8) ? comp->getJitGCType(gcPtrs[0]) : TYP_INT;
29577-
m_regType[1] = (floatFieldFlags & STRUCT_SECOND_FIELD_SIZE_IS8) ? TYP_DOUBLE : TYP_FLOAT;
29553+
assert(lowering->numLoweredElements == MAX_RET_REG_COUNT);
29554+
var_types types[MAX_RET_REG_COUNT] = {JITtype2varType(lowering->loweredElements[0]),
29555+
JITtype2varType(lowering->loweredElements[1])};
29556+
assert(varTypeIsFloating(types[0]) || varTypeIsFloating(types[1]));
29557+
assert((structSize > 8) == ((genTypeSize(types[0]) == 8) || (genTypeSize(types[1]) == 8)));
29558+
for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
29559+
{
29560+
if (varTypeIsFloating(types[i]))
29561+
{
29562+
m_regType[i] = types[i];
29563+
}
29564+
else
29565+
{
29566+
assert(varTypeIsIntegralOrI(types[i]));
29567+
m_regType[i] = (genTypeSize(types[i]) == 8) ? comp->getJitGCType(gcPtrs[i]) : TYP_INT;
29568+
}
29569+
}
2957829570
}
2957929571
else
2958029572
{

src/coreclr/jit/gentree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4544,7 +4544,7 @@ struct CallArgABIInformation
45444544
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR StructDesc;
45454545
#endif // UNIX_AMD64_ABI
45464546
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
4547-
// For LoongArch64's ABI, the struct which has float field(s) and no more than two fields
4547+
// For LoongArch64's and RISC-V 64's ABI, the struct which has float field(s) and no more than two fields
45484548
// may be passed by float register(s).
45494549
// e.g `struct {int a; float b;}` passed by an integer register and a float register.
45504550
var_types StructFloatFieldType[2];

0 commit comments

Comments
 (0)