-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[VM] Add getRISCV64PassStructInRegisterFlags
- Loading branch information
Showing
18 changed files
with
394 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 69 additions & 53 deletions
122
src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
207 changes: 207 additions & 0 deletions
207
src/coreclr/tools/Common/JitInterface/RISCV64PassStructInRegister.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
// 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; | ||
using Internal.TypeSystem; | ||
|
||
namespace Internal.JitInterface | ||
{ | ||
|
||
internal static class RISCV64PassStructInRegister | ||
{ | ||
public static uint GetRISCV64PassStructInRegisterFlags(TypeDesc typeDesc) | ||
{ | ||
FieldDesc firstField = null; | ||
uint floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
int numIntroducedFields = 0; | ||
foreach (FieldDesc field in typeDesc.GetFields()) | ||
{ | ||
if (!field.IsStatic) | ||
{ | ||
firstField ??= field; | ||
numIntroducedFields++; | ||
} | ||
} | ||
|
||
if ((numIntroducedFields == 0) || (numIntroducedFields > 2) || (typeDesc.GetElementSize().AsInt > 16)) | ||
{ | ||
return (uint)StructFloatFieldInfoFlags.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 RISCV64, 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)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
} | ||
} | ||
|
||
int fieldIndex = 0; | ||
foreach (FieldDesc field in typeDesc.GetFields()) | ||
{ | ||
if (fieldIndex > 1) | ||
{ | ||
return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
} | ||
else if (field.IsStatic) | ||
{ | ||
continue; | ||
} | ||
|
||
Debug.Assert(fieldIndex < numIntroducedFields); | ||
|
||
switch (field.FieldType.Category) | ||
{ | ||
case TypeFlags.Double: | ||
{ | ||
if (numIntroducedFields == 1) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE; | ||
} | ||
else if (fieldIndex == 0) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FIRST_FIELD_DOUBLE; | ||
} | ||
else if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) | ||
{ | ||
floatFieldFlags ^= (uint)StructFloatFieldInfoFlags.STRUCT_MERGE_FIRST_SECOND_8; | ||
} | ||
else | ||
{ | ||
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_SECOND_FIELD_DOUBLE; | ||
} | ||
} | ||
break; | ||
|
||
case TypeFlags.Single: | ||
{ | ||
if (numIntroducedFields == 1) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE; | ||
} | ||
else if (fieldIndex == 0) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST; | ||
} | ||
else if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) | ||
{ | ||
floatFieldFlags ^= (uint)StructFloatFieldInfoFlags.STRUCT_MERGE_FIRST_SECOND; | ||
} | ||
else | ||
{ | ||
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND; | ||
} | ||
} | ||
break; | ||
|
||
case TypeFlags.ValueType: | ||
//case TypeFlags.Class: | ||
//case TypeFlags.Array: | ||
//case TypeFlags.SzArray: | ||
{ | ||
uint floatFieldFlags2 = GetRISCV64PassStructInRegisterFlags(field.FieldType); | ||
if (numIntroducedFields == 1) | ||
{ | ||
floatFieldFlags = floatFieldFlags2; | ||
} | ||
else if (field.FieldType.GetElementSize().AsInt > 8) | ||
{ | ||
return (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
} | ||
else if (fieldIndex == 0) | ||
{ | ||
if ((floatFieldFlags2 & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST; | ||
} | ||
if (field.FieldType.GetElementSize().AsInt == 8) | ||
{ | ||
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_FIRST_FIELD_SIZE_IS8; | ||
} | ||
} | ||
else | ||
{ | ||
Debug.Assert(fieldIndex == 1); | ||
if ((floatFieldFlags2 & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_ONE) != 0) | ||
{ | ||
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_MERGE_FIRST_SECOND; | ||
} | ||
if (field.FieldType.GetElementSize().AsInt == 8) | ||
{ | ||
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_SECOND_FIELD_SIZE_IS8; | ||
} | ||
|
||
floatFieldFlags2 = floatFieldFlags & ((uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND); | ||
if (floatFieldFlags2 == 0) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
} | ||
else if (floatFieldFlags2 == ((uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND)) | ||
{ | ||
floatFieldFlags ^= ((uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_ONLY_TWO | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST | (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND); | ||
} | ||
} | ||
} | ||
break; | ||
|
||
default: | ||
{ | ||
if (field.FieldType.GetElementSize().AsInt == 8) | ||
{ | ||
if (numIntroducedFields > 1) | ||
{ | ||
if (fieldIndex == 0) | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_FIRST_FIELD_SIZE_IS8; | ||
} | ||
else if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) != 0) | ||
{ | ||
floatFieldFlags |= (uint)StructFloatFieldInfoFlags.STRUCT_SECOND_FIELD_SIZE_IS8; | ||
} | ||
else | ||
{ | ||
floatFieldFlags = (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
} | ||
} | ||
} | ||
else if (fieldIndex == 1) | ||
{ | ||
floatFieldFlags = (floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_FIRST) > 0 ? floatFieldFlags : (uint)StructFloatFieldInfoFlags.STRUCT_NO_FLOAT_FIELD; | ||
} | ||
break; | ||
} | ||
} | ||
|
||
fieldIndex++; | ||
} | ||
|
||
return floatFieldFlags; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.