コード例 #1
0
            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());
            }
コード例 #2
0
ファイル: TransitionBlock.cs プロジェクト: mikem8361/runtime
            public override bool IsArgPassedByRef(TypeHandle th)
            {
                Debug.Assert(!th.IsNull());
                Debug.Assert(th.IsValueType());

                // Composites greater than 16 bytes are passed by reference
                if (th.GetSize() > EnregisteredParamTypeMaxSize)
                {
                    return(true);
                }
                else
                {
                    int numIntroducedFields = 0;
                    foreach (FieldDesc field in th.GetRuntimeTypeHandle().GetFields())
                    {
                        if (!field.IsStatic)
                        {
                            numIntroducedFields++;
                        }
                    }
                    return((numIntroducedFields == 0) || (numIntroducedFields > 2));
                }
            }
コード例 #3
0
 public override bool IsArgPassedByRef(TypeHandle th)
 {
     Debug.Assert(!th.IsNull());
     Debug.Assert(th.IsValueType());
     return(IsArgPassedByRef((int)th.GetSize()));
 }
コード例 #4
0
        public void ComputeReturnValueTreatment(CorElementType type, TypeHandle thRetType, bool isVarArgMethod, out bool usesRetBuffer, out uint fpReturnSize)
        {
            usesRetBuffer = false;
            fpReturnSize  = 0;

            switch (type)
            {
            case CorElementType.ELEMENT_TYPE_TYPEDBYREF:
                throw new NotSupportedException();

            case CorElementType.ELEMENT_TYPE_R4:
                fpReturnSize = sizeof(float);
                break;

            case CorElementType.ELEMENT_TYPE_R8:
                fpReturnSize = sizeof(double);
                break;

            case CorElementType.ELEMENT_TYPE_VALUETYPE:
            {
                Debug.Assert(!thRetType.IsNull() && thRetType.IsValueType());

                if ((Architecture == TargetArchitecture.X64) && IsX64UnixABI)
                {
                    SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR descriptor;
                    SystemVStructClassificator.GetSystemVAmd64PassStructInRegisterDescriptor(thRetType.GetRuntimeTypeHandle(), out descriptor);

                    if (descriptor.passedInRegisters)
                    {
                        if (descriptor.eightByteCount == 1)
                        {
                            if (descriptor.eightByteClassifications0 == SystemVClassificationType.SystemVClassificationTypeSSE)
                            {
                                // Structs occupying just one eightbyte are treated as int / double
                                fpReturnSize = sizeof(double);
                            }
                        }
                        else
                        {
                            // Size of the struct is 16 bytes
                            fpReturnSize = 16;
                            // The lowest two bits of the size encode the order of the int and SSE fields
                            if (descriptor.eightByteClassifications0 == SystemVClassificationType.SystemVClassificationTypeSSE)
                            {
                                fpReturnSize += 1;
                            }

                            if (descriptor.eightByteClassifications0 == SystemVClassificationType.SystemVClassificationTypeSSE)
                            {
                                fpReturnSize += 2;
                            }
                        }

                        break;
                    }
                }
                else
                {
                    if (thRetType.IsHomogeneousAggregate() && !isVarArgMethod)
                    {
                        int haElementSize = thRetType.GetHomogeneousAggregateElementSize();
                        fpReturnSize = 4 * (uint)haElementSize;
                        break;
                    }

                    uint size = (uint)thRetType.GetSize();

                    if (IsX86 || IsX64)
                    {
                        // Return value types of size which are not powers of 2 using a RetBuffArg
                        if ((size & (size - 1)) != 0)
                        {
                            usesRetBuffer = true;
                            break;
                        }
                    }

                    if (size <= EnregisteredReturnTypeIntegerMaxSize)
                    {
                        break;
                    }
                }
            }

                // Value types are returned using return buffer by default
                usesRetBuffer = true;
                break;

            default:
                break;
            }
        }
コード例 #5
0
        public void ComputeReturnValueTreatment(CorElementType type, TypeHandle thRetType, bool isVarArgMethod, out bool usesRetBuffer, out uint fpReturnSize)
        {
            usesRetBuffer = false;
            fpReturnSize  = 0;

            switch (type)
            {
            case CorElementType.ELEMENT_TYPE_TYPEDBYREF:
                throw new NotSupportedException();

            case CorElementType.ELEMENT_TYPE_R4:
                fpReturnSize = sizeof(float);
                break;

            case CorElementType.ELEMENT_TYPE_R8:
                fpReturnSize = sizeof(double);
                break;

            case CorElementType.ELEMENT_TYPE_VALUETYPE:
            {
                Debug.Assert(!thRetType.IsNull() && thRetType.IsValueType());

                if ((Architecture == TargetArchitecture.X64) && IsX64UnixABI)
                {
                    SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR descriptor;
                    SystemVStructClassificator.GetSystemVAmd64PassStructInRegisterDescriptor(thRetType.GetRuntimeTypeHandle(), out descriptor);

                    if (descriptor.passedInRegisters)
                    {
                        if (descriptor.eightByteCount == 1)
                        {
                            if (descriptor.eightByteClassifications0 == SystemVClassificationType.SystemVClassificationTypeSSE)
                            {
                                fpReturnSize = sizeof(double);
                            }
                        }
                        else
                        {
                            fpReturnSize = 16;
                            if (descriptor.eightByteClassifications0 == SystemVClassificationType.SystemVClassificationTypeSSE)
                            {
                                fpReturnSize += 1;
                            }

                            if (descriptor.eightByteClassifications0 == SystemVClassificationType.SystemVClassificationTypeSSE)
                            {
                                fpReturnSize += 2;
                            }
                        }

                        break;
                    }
                }
                else
                {
                    if (thRetType.IsHFA() && !isVarArgMethod)
                    {
                        CorElementType hfaType = thRetType.GetHFAType();

                        switch (Architecture)
                        {
                        case TargetArchitecture.ARM:
                            fpReturnSize = (hfaType == CorElementType.ELEMENT_TYPE_R4) ?
                                           (4 * (uint)sizeof(float)) :
                                           (4 * (uint)sizeof(double));
                            break;

                        case TargetArchitecture.ARM64:
                            // DESKTOP BEHAVIOR fpReturnSize = (hfaType == CorElementType.ELEMENT_TYPE_R4) ? (4 * (uint)sizeof(float)) : (4 * (uint)sizeof(double));
                            // S and D registers overlap. Since we copy D registers in the UniversalTransitionThunk, we'll
                            // treat floats like doubles during copying.
                            fpReturnSize = 4 * (uint)sizeof(double);
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                        break;
                    }

                    uint size = (uint)thRetType.GetSize();

                    if (IsX86 || IsX64)
                    {
                        // Return value types of size which are not powers of 2 using a RetBuffArg
                        if ((size & (size - 1)) != 0)
                        {
                            usesRetBuffer = true;
                            break;
                        }
                    }

                    if (size <= EnregisteredReturnTypeIntegerMaxSize)
                    {
                        break;
                    }
                }
            }

                // Value types are returned using return buffer by default
                usesRetBuffer = true;
                break;

            default:
                break;
            }
        }
コード例 #6
0
ファイル: TransitionBlock.cs プロジェクト: pgovind/runtime
        public void ComputeReturnValueTreatment(CorElementType type, TypeHandle thRetType, bool isVarArgMethod, out bool usesRetBuffer, out uint fpReturnSize)
        {
            usesRetBuffer = false;
            fpReturnSize  = 0;

            switch (type)
            {
            case CorElementType.ELEMENT_TYPE_TYPEDBYREF:
                throw new NotSupportedException();

            case CorElementType.ELEMENT_TYPE_R4:
                fpReturnSize = sizeof(float);
                break;

            case CorElementType.ELEMENT_TYPE_R8:
                fpReturnSize = sizeof(double);
                break;

            case CorElementType.ELEMENT_TYPE_VALUETYPE:
            {
                Debug.Assert(!thRetType.IsNull() && thRetType.IsValueType());

                if (thRetType.IsHFA() && !isVarArgMethod)
                {
                    CorElementType hfaType = thRetType.GetHFAType();

                    switch (Architecture)
                    {
                    case TargetArchitecture.ARM:
                        fpReturnSize = (hfaType == CorElementType.ELEMENT_TYPE_R4) ?
                                       (4 * (uint)sizeof(float)) :
                                       (4 * (uint)sizeof(double));
                        break;

                    case TargetArchitecture.ARM64:
                        // DESKTOP BEHAVIOR fpReturnSize = (hfaType == CorElementType.ELEMENT_TYPE_R4) ? (4 * (uint)sizeof(float)) : (4 * (uint)sizeof(double));
                        // S and D registers overlap. Since we copy D registers in the UniversalTransitionThunk, we'll
                        // thread floats like doubles during copying.
                        fpReturnSize = 4 * (uint)sizeof(double);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                    break;
                }

                uint size = (uint)thRetType.GetSize();

                if (IsX86 || IsX64)
                {
                    // Return value types of size which are not powers of 2 using a RetBuffArg
                    if ((size & (size - 1)) != 0)
                    {
                        usesRetBuffer = true;
                        break;
                    }
                }

                if (size <= EnregisteredReturnTypeIntegerMaxSize)
                {
                    break;
                }
            }

                // Value types are returned using return buffer by default
                usesRetBuffer = true;
                break;

            default:
                break;
            }
        }