コード例 #1
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;
            }
        }