/// <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); } }
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); } }