예제 #1
0
        /// <summary>
        /// Visitation function for StoreInstruction.
        /// </summary>
        /// <param name="context">The context.</param>
        void IIRVisitor.Store(Context context)
        {
            Operand baseOperand   = context.Operand1;
            Operand offsetOperand = context.Operand2;
            Operand value         = context.Operand3;

            MosaType storeType = context.MosaType;
            var      type      = baseOperand.Type;
            var      size      = context.Size;

            if (value.IsR8 && type.IsR4)             //&& size == InstructionSize.Size32)
            {
                Operand xmm1 = AllocateVirtualRegister(TypeSystem.BuiltIn.R4);
                context.InsertBefore().AppendInstruction(X86.Cvtsd2ss, size, xmm1, value);
                value = xmm1;
            }
            else if (value.IsMemoryAddress)
            {
                Operand v2 = AllocateVirtualRegister(value.Type);
                context.InsertBefore().AppendInstruction(X86.Mov, size, v2, value);
                value = v2;
            }

            if (offsetOperand.IsConstant)
            {
                if (baseOperand.IsField)
                {
                    Debug.Assert(offsetOperand.IsConstantZero);
                    Debug.Assert(baseOperand.Field.IsStatic);

                    context.SetInstruction(GetMove(baseOperand, value), size, baseOperand, value);
                }
                else
                {
                    var mem = Operand.CreateMemoryAddress(storeType, baseOperand, offsetOperand.ConstantSignedLongInteger);
                    context.SetInstruction(GetMove(mem, value), size, mem, value);
                }
            }
            else
            {
                if (type.IsUnmanagedPointer)
                {
                    type = storeType.ToUnmanagedPointer();
                }
                else if (type.IsManagedPointer)
                {
                    type = storeType.ToManagedPointer();
                }

                Operand v1  = AllocateVirtualRegister(type);
                Operand mem = Operand.CreateMemoryAddress(storeType, v1, 0);

                context.SetInstruction(X86.Mov, v1, baseOperand);
                context.AppendInstruction(X86.Add, v1, v1, offsetOperand);
                context.AppendInstruction(GetMove(mem, value), size, mem, value);
            }
        }
예제 #2
0
        private MosaType Load(TypeSig typeSig)
        {
            if (typeSig is LeafSig)
            {
                if (typeSig is TypeDefOrRefSig)
                {
                    throw new AssemblyLoadException();                      // Should have been loaded in MetadataLoader
                }
                else if (typeSig is GenericInstSig)
                {
                    return(LoadGenericTypeInstanceSig((GenericInstSig)typeSig));
                }
                else if (typeSig is GenericSig)
                {
                    return(LoadGenericParam((GenericSig)typeSig));
                }
                else if (typeSig is FnPtrSig)
                {
                    MethodSig            fnPtr      = (MethodSig)((FnPtrSig)typeSig).MethodSig;
                    MosaType             returnType = GetType(fnPtr.RetType);
                    List <MosaParameter> pars       = new List <MosaParameter>();
                    for (int i = 0; i < fnPtr.Params.Count; i++)
                    {
                        var parameter = metadata.Controller.CreateParameter();

                        using (var mosaParameter = metadata.Controller.MutateParameter(parameter))
                        {
                            mosaParameter.Name = "A_" + i;
                            mosaParameter.ParameterAttributes = MosaParameterAttributes.In;
                            mosaParameter.ParameterType       = GetType(fnPtr.Params[i]);
                        }

                        pars.Add(parameter);
                    }
                    return(metadata.TypeSystem.ToFnPtr(new MosaMethodSignature(returnType, pars)));
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            else                // Non-leaf signature
            {
                MosaType elementType = GetType(typeSig.Next);
                MosaType result;
                switch (typeSig.ElementType)
                {
                case ElementType.Ptr:
                    result = elementType.ToUnmanagedPointer();
                    using (var ptrType = metadata.Controller.MutateType(result))
                        ptrType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig);
                    break;

                case ElementType.ByRef:
                    result = elementType.ToManagedPointer();
                    using (var ptrType = metadata.Controller.MutateType(result))
                        ptrType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig);
                    break;

                case ElementType.CModReqd:
                case ElementType.CModOpt:
                    result = metadata.Controller.CreateType(elementType);
                    using (var modType = metadata.Controller.MutateType(result))
                    {
                        modType.Modifier         = GetType(((ModifierSig)typeSig).Modifier.ToTypeSig());
                        modType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig);
                        modType.ElementType      = elementType;
                    }
                    break;

                case ElementType.Pinned:
                    result = elementType;                                // Pinned types are indicated in MosaLocal
                    return(result);                                      // Don't add again to controller

                case ElementType.SZArray:
                    GetType(new GenericInstSig(szHelperSig, typeSig.Next));
                    GetType(new GenericInstSig(iListSig, typeSig.Next));
                    result = elementType.ToSZArray();
                    using (var arrayType = metadata.Controller.MutateType(result))
                        arrayType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig);
                    metadata.Resolver.EnqueueForArrayResolve(result);
                    return(result);

                case ElementType.Array:
                    ArraySig      array     = (ArraySig)typeSig;
                    MosaArrayInfo arrayInfo = new MosaArrayInfo(array.LowerBounds, array.Rank, array.Sizes);
                    result = elementType.ToArray(arrayInfo);
                    using (var arrayType = metadata.Controller.MutateType(result))
                        arrayType.UnderlyingObject = elementType.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >().Clone(typeSig);
                    break;

                default:
                    throw new AssemblyLoadException();
                }
                metadata.Controller.AddType(result);
                return(result);
            }
        }