Skip to content

Commit f064eb6

Browse files
committed
Move StructFloatFieldInfoFlags and FpStructInRegistersInfo out of the JIT interface
1 parent 1f16783 commit f064eb6

File tree

2 files changed

+96
-94
lines changed

2 files changed

+96
-94
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -317,100 +317,6 @@ struct SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR
317317
}
318318
};
319319

320-
// StructFloatFieldInfoFlags: used on LoongArch64 and RISC-V architecture as a legacy representation of
321-
// FpStructInRegistersInfo, returned by FpStructInRegistersInfo::ToOldFlags()
322-
//
323-
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
324-
//
325-
// Otherwise, and only for structs with no more than two fields and a total struct size no larger
326-
// than two pointers:
327-
//
328-
// The lowest four bits denote the floating-point info:
329-
// bit 0: `1` means there is only one float or double field within the struct.
330-
// bit 1: `1` means only the first field is floating-point type.
331-
// bit 2: `1` means only the second field is floating-point type.
332-
// bit 3: `1` means the two fields are both floating-point type.
333-
// The bits[5:4] denoting whether the field size is 8-bytes:
334-
// bit 4: `1` means the first field's size is 8.
335-
// bit 5: `1` means the second field's size is 8.
336-
//
337-
// Note that bit 0 and 3 cannot both be set.
338-
enum StructFloatFieldInfoFlags
339-
{
340-
STRUCT_NO_FLOAT_FIELD = 0x0,
341-
STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1,
342-
STRUCT_FLOAT_FIELD_ONLY_TWO = 0x8,
343-
STRUCT_FLOAT_FIELD_FIRST = 0x2,
344-
STRUCT_FLOAT_FIELD_SECOND = 0x4,
345-
STRUCT_FIRST_FIELD_SIZE_IS8 = 0x10,
346-
STRUCT_SECOND_FIELD_SIZE_IS8 = 0x20,
347-
};
348-
349-
// Bitfields for FpStructInRegistersInfo::flags
350-
namespace FpStruct
351-
{
352-
enum Flags
353-
{
354-
// Positions of flags and bitfields
355-
PosOnlyOne = 0,
356-
PosBothFloat = 1,
357-
PosFloatInt = 2,
358-
PosIntFloat = 3,
359-
PosSizeShift1st = 4, // 2 bits
360-
PosSizeShift2nd = 6, // 2 bits
361-
362-
UseIntCallConv = 0, // struct is passed according to integer calling convention
363-
364-
// The flags and bitfields
365-
OnlyOne = 1 << PosOnlyOne, // has only one field, which is floating-point
366-
BothFloat = 1 << PosBothFloat, // has two fields, both are floating-point
367-
FloatInt = 1 << PosFloatInt, // has two fields, 1st is floating and 2nd is integer
368-
IntFloat = 1 << PosIntFloat, // has two fields, 2nd is floating and 1st is integer
369-
SizeShift1stMask = 0b11 << PosSizeShift1st, // log2(size) of 1st field
370-
SizeShift2ndMask = 0b11 << PosSizeShift2nd, // log2(size) of 2nd field
371-
// Note: flags OnlyOne, BothFloat, FloatInt, and IntFloat are mutually exclusive
372-
};
373-
}
374-
375-
// On RISC-V and LoongArch a struct with up to two non-empty fields, at least one of them floating-point,
376-
// can be passed in registers according to hardware FP calling convention. FpStructInRegistersInfo represents
377-
// passing information for such parameters.
378-
struct FpStructInRegistersInfo
379-
{
380-
FpStruct::Flags flags;
381-
uint32_t offset1st;
382-
uint32_t offset2nd;
383-
384-
unsigned SizeShift1st() const { return (flags >> FpStruct::PosSizeShift1st) & 0b11; }
385-
unsigned SizeShift2nd() const { return (flags >> FpStruct::PosSizeShift2nd) & 0b11; }
386-
387-
unsigned Size1st() const { return 1u << SizeShift1st(); }
388-
unsigned Size2nd() const { return 1u << SizeShift2nd(); }
389-
390-
const char* FlagName() const
391-
{
392-
switch (flags & (FpStruct::OnlyOne | FpStruct::BothFloat | FpStruct::FloatInt | FpStruct::IntFloat))
393-
{
394-
case FpStruct::OnlyOne: return "OnlyOne";
395-
case FpStruct::BothFloat: return "BothFloat";
396-
case FpStruct::FloatInt: return "FloatInt";
397-
case FpStruct::IntFloat: return "IntFloat";
398-
default: return "?";
399-
}
400-
}
401-
402-
StructFloatFieldInfoFlags ToOldFlags() const
403-
{
404-
return StructFloatFieldInfoFlags(
405-
((flags & FpStruct::OnlyOne) ? STRUCT_FLOAT_FIELD_ONLY_ONE : 0) |
406-
((flags & FpStruct::BothFloat) ? STRUCT_FLOAT_FIELD_ONLY_TWO : 0) |
407-
((flags & FpStruct::FloatInt) ? STRUCT_FLOAT_FIELD_FIRST : 0) |
408-
((flags & FpStruct::IntFloat) ? STRUCT_FLOAT_FIELD_SECOND : 0) |
409-
((SizeShift1st() == 3) ? STRUCT_FIRST_FIELD_SIZE_IS8 : 0) |
410-
((SizeShift2nd() == 3) ? STRUCT_SECOND_FIELD_SIZE_IS8 : 0));
411-
}
412-
};
413-
414320
#include "corinfoinstructionset.h"
415321

416322
// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())

src/coreclr/vm/methodtable.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,102 @@ typedef DPTR(SystemVStructRegisterPassingHelper) SystemVStructRegisterPassingHel
754754

755755
#endif // UNIX_AMD64_ABI_ITF
756756

757+
#if defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
758+
// StructFloatFieldInfoFlags: used on LoongArch64 and RISC-V architecture as a legacy representation of
759+
// FpStructInRegistersInfo, returned by FpStructInRegistersInfo::ToOldFlags()
760+
//
761+
// `STRUCT_NO_FLOAT_FIELD` means structs are not passed using the float register(s).
762+
//
763+
// Otherwise, and only for structs with no more than two fields and a total struct size no larger
764+
// than two pointers:
765+
//
766+
// The lowest four bits denote the floating-point info:
767+
// bit 0: `1` means there is only one float or double field within the struct.
768+
// bit 1: `1` means only the first field is floating-point type.
769+
// bit 2: `1` means only the second field is floating-point type.
770+
// bit 3: `1` means the two fields are both floating-point type.
771+
// The bits[5:4] denoting whether the field size is 8-bytes:
772+
// bit 4: `1` means the first field's size is 8.
773+
// bit 5: `1` means the second field's size is 8.
774+
//
775+
// Note that bit 0 and 3 cannot both be set.
776+
enum StructFloatFieldInfoFlags
777+
{
778+
STRUCT_NO_FLOAT_FIELD = 0x0,
779+
STRUCT_FLOAT_FIELD_ONLY_ONE = 0x1,
780+
STRUCT_FLOAT_FIELD_ONLY_TWO = 0x8,
781+
STRUCT_FLOAT_FIELD_FIRST = 0x2,
782+
STRUCT_FLOAT_FIELD_SECOND = 0x4,
783+
STRUCT_FIRST_FIELD_SIZE_IS8 = 0x10,
784+
STRUCT_SECOND_FIELD_SIZE_IS8 = 0x20,
785+
};
786+
787+
// Bitfields for FpStructInRegistersInfo::flags
788+
namespace FpStruct
789+
{
790+
enum Flags
791+
{
792+
// Positions of flags and bitfields
793+
PosOnlyOne = 0,
794+
PosBothFloat = 1,
795+
PosFloatInt = 2,
796+
PosIntFloat = 3,
797+
PosSizeShift1st = 4, // 2 bits
798+
PosSizeShift2nd = 6, // 2 bits
799+
800+
UseIntCallConv = 0, // struct is passed according to integer calling convention
801+
802+
// The flags and bitfields
803+
OnlyOne = 1 << PosOnlyOne, // has only one field, which is floating-point
804+
BothFloat = 1 << PosBothFloat, // has two fields, both are floating-point
805+
FloatInt = 1 << PosFloatInt, // has two fields, 1st is floating and 2nd is integer
806+
IntFloat = 1 << PosIntFloat, // has two fields, 2nd is floating and 1st is integer
807+
SizeShift1stMask = 0b11 << PosSizeShift1st, // log2(size) of 1st field
808+
SizeShift2ndMask = 0b11 << PosSizeShift2nd, // log2(size) of 2nd field
809+
// Note: flags OnlyOne, BothFloat, FloatInt, and IntFloat are mutually exclusive
810+
};
811+
}
812+
813+
// On RISC-V and LoongArch a struct with up to two non-empty fields, at least one of them floating-point,
814+
// can be passed in registers according to hardware FP calling convention. FpStructInRegistersInfo represents
815+
// passing information for such parameters.
816+
struct FpStructInRegistersInfo
817+
{
818+
FpStruct::Flags flags;
819+
uint32_t offset1st;
820+
uint32_t offset2nd;
821+
822+
unsigned SizeShift1st() const { return (flags >> FpStruct::PosSizeShift1st) & 0b11; }
823+
unsigned SizeShift2nd() const { return (flags >> FpStruct::PosSizeShift2nd) & 0b11; }
824+
825+
unsigned Size1st() const { return 1u << SizeShift1st(); }
826+
unsigned Size2nd() const { return 1u << SizeShift2nd(); }
827+
828+
const char* FlagName() const
829+
{
830+
switch (flags & (FpStruct::OnlyOne | FpStruct::BothFloat | FpStruct::FloatInt | FpStruct::IntFloat))
831+
{
832+
case FpStruct::OnlyOne: return "OnlyOne";
833+
case FpStruct::BothFloat: return "BothFloat";
834+
case FpStruct::FloatInt: return "FloatInt";
835+
case FpStruct::IntFloat: return "IntFloat";
836+
default: return "?";
837+
}
838+
}
839+
840+
StructFloatFieldInfoFlags ToOldFlags() const
841+
{
842+
return StructFloatFieldInfoFlags(
843+
((flags & FpStruct::OnlyOne) ? STRUCT_FLOAT_FIELD_ONLY_ONE : 0) |
844+
((flags & FpStruct::BothFloat) ? STRUCT_FLOAT_FIELD_ONLY_TWO : 0) |
845+
((flags & FpStruct::FloatInt) ? STRUCT_FLOAT_FIELD_FIRST : 0) |
846+
((flags & FpStruct::IntFloat) ? STRUCT_FLOAT_FIELD_SECOND : 0) |
847+
((SizeShift1st() == 3) ? STRUCT_FIRST_FIELD_SIZE_IS8 : 0) |
848+
((SizeShift2nd() == 3) ? STRUCT_SECOND_FIELD_SIZE_IS8 : 0));
849+
}
850+
};
851+
#endif // defined(TARGET_RISCV64) || defined(TARGET_LOONGARCH64)
852+
757853
//===============================================================================================
758854
//
759855
// GC data appears before the beginning of the MethodTable

0 commit comments

Comments
 (0)