Exemple #1
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            if (xSourceSize <= 4)
            {
                if (!xSourceIsFloat)
                {
                    if (xSourceSize <= 2 || IsIntegerSigned(xSource))
                    {
                        XS.SSE.ConvertSI2SS(XMM0, ESP, sourceIsIndirect: true);
                        XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            else if (xSourceSize <= 8)
            {
                if (xSourceIsFloat)
                {
                    XS.SSE2.ConvertSD2SS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 4);
                    XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true);
                }
                else
                {
                    if (IsIntegerSigned(xSource))
                    {
                        /*
                         * Again there is no SSE instruction in x86 to do this conversion as we need a 64 Bit register to do this! So we are forced
                         * to use the legacy x87 FPU to do this operation. In x64 the SSE instruction ConvertSIQ2SS should exist.
                         */
                        XS.FPU.IntLoad(ESP, isIndirect: true, size: RegisterSize.Long64);
                        XS.Add(ESP, 4);
                        /* This instruction is not needed FloatStoreAndPop does already the conversion */
                        // XS.SSE2.ConvertSD2SS(XMM0, ESP, sourceIsIndirect: true);
                        XS.FPU.FloatStoreAndPop(ESP, isIndirect: true, size: RegisterSize.Int32);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            else
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_R4.cs->Error: StackSize > 8 not supported");
            }
        }
Exemple #2
0
 public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
 {
     // TODO: Implement exception
     DoNullReferenceCheck(Assembler, DebugEnabled, 4);
     XS.Add(ESP, 4);
     XS.Pop(EAX);
     XS.Set(DataMember.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef), EAX, destinationIsIndirect: true);
     XS.Call("SystemExceptionOccurred");
     XS.Set(ECX, 3);
     EmitExceptionLogic(Assembler, aMethod, aOpCode, false, null);
 }
Exemple #3
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            OpDouble xOp = (OpDouble)aOpCode;

            byte[] xBytes = BitConverter.GetBytes(xOp.Value);
            new CPU.Push {
                DestinationValue = BitConverter.ToUInt32(xBytes, 4)
            };
            new CPU.Push {
                DestinationValue = BitConverter.ToUInt32(xBytes, 0)
            };
        }
Exemple #4
0
 public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
 {
     ILOpCodes.OpSwitch OpSw = (ILOpCodes.OpSwitch)aOpCode;
     XS.Pop(XSRegisters.EAX);
     for (int i = 0; i < OpSw.BranchLocations.Length; i++)
     {
         XS.Compare(XSRegisters.EAX, ( uint )i);
         //string DestLabel = AssemblerNasm.TmpBranchLabel( aMethod, new ILOpCodes.OpBranch( ILOpCode.Code.Jmp, aOpCode.Position, OpSw.BranchLocations[ i ] ) );
         string xDestLabel = AppAssembler.TmpPosLabel(aMethod, OpSw.BranchLocations[i]);
         XS.Jump(CPUx86.ConditionalTestEnum.Equal, xDestLabel);
     }
 }
Exemple #5
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            // apparently, Roslyn changed something to the output. We now have to figure out where to jump to.
            if (aOpCode.CurrentExceptionRegion.Kind.HasFlag(ExceptionRegionKind.Finally) &&
                aOpCode.CurrentExceptionRegion.HandlerOffset > aOpCode.Position)
            {
                XS.Set(aMethod.MethodBase.GetFullName() + "_" + "LeaveAddress_" + aOpCode.CurrentExceptionRegion.HandlerOffset.ToString("X2"), Assembler.CurrentIlLabel + "." + (Assembler.AsmIlIdx + 2).ToString("X2"), destinationIsIndirect: true, size: RegisterSize.Int32);
                XS.Jump(AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionRegion.HandlerOffset));
            }

            XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode));
        }
Exemple #6
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackContent     = aOpCode.StackPopTypes[0];
            var xStackContentSize = SizeOfType(xStackContent);
            var StackSize         = (int)((xStackContentSize / 4) + (xStackContentSize % 4 == 0 ? 0 : 1));

            for (int i = StackSize; i > 0; i--)
            {
                XS.Push(ESP, true, (StackSize - 1) * 4);
                //new CPUx86.Push { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)((StackSize - 1) * 4) };
            }
        }
Exemple #7
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            // MtW: for now, disable this instruction. To me, it's unclear in what context it's being used.
            uint mObjSize = 0;

            Type mType = ((Cosmos.IL2CPU.ILOpCodes.OpType)aOpCode).Value;

            mObjSize = SizeOfType(mType);

            XS.Pop(XSRegisters.EAX);
            for (int i = 0; i < (mObjSize / 4); i++)
            {
                XS.Set(EAX, 0, destinationDisplacement: i * 4, size: RegisterSize.Int32);
            }
            switch (mObjSize % 4)
            {
            case 1:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )((mObjSize / 4) * 4), SourceValue = 0, Size = 8
                };
                break;
            }

            case 2:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )((mObjSize / 4) * 4), SourceValue = 0, Size = 16
                };
                break;
            }

            case 3:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )((mObjSize / 4) * 4), SourceValue = 0, Size = 8
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )(((mObjSize / 4) * 4) + 1), SourceValue = 0, Size = 16
                };
                break;
            }

            case 0:
                break;

            default:
            {
                throw new NotImplementedException("Remainder size " + mObjSize % 4 + " not supported yet! (Type = '" + mType.FullName + "')");
            }
            }
        }
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            if (xSourceIsFloat)
            {
                if (xSourceSize == 4)
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }
                else if (xSourceSize == 8)
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }
                else
                {
                    throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->Unknown size of floating point value.");
                }
            }

            switch (xSourceSize)
            {
            case 1:
                throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->The size 1 could not exist, because always is pushed Int32 or Int64!");

            case 2:
                throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->The size 2 could not exist, because always is pushed Int32 or Int64!");

            case 4:
                XS.Pop(XSRegisters.EAX);
                XS.MoveSignExtend(XSRegisters.EAX, XSRegisters.AL);
                XS.Push(XSRegisters.EAX);
                break;

            case 8:
                XS.Pop(XSRegisters.EAX);
                XS.Pop(XSRegisters.EBX);
                XS.MoveSignExtend(XSRegisters.EAX, XSRegisters.AL);
                XS.Push(XSRegisters.EAX);
                break;

            default:
                //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_I1: SourceSize " + xSource + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel );
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->Unknown size of variable on the top of the stack.");
            }
        }
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpType = (OpType)aOpCode;
            var xSize   = SizeOfType(xOpType.Value);

            if (xOpType.Value.GetTypeInfo().IsValueType&& !xOpType.Value.GetTypeInfo().IsPrimitive)
            {
                Ldelema.Assemble(Assembler, xOpType, xSize, DebugEnabled);
                Ldobj.DoAssemble(xOpType.Value);
                return;
            }
            Ldelem_Ref.Assemble(Assembler, xSize, false, aMethod, aOpCode, DebugEnabled);
        }
Exemple #10
0
        /// <summary> Draws the parameters of the passed object into the screen </summary>
        public void drawDebug(object obj, int x, int y)
        {
            Type        type          = obj.GetType();
            object      classInstance = Activator.CreateInstance(type, null);
            _MethodInfo methodInfo    = type.GetMethod("getAttr");

            object[] parametersArray = new object[] { obj };

            object result = methodInfo.Invoke(classInstance, parametersArray);

            Console.SetCursorPosition(x, y);
            Console.Write(type.Name + (string)result);
        }
Exemple #11
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOp = (OpInt64)aOpCode;

            // push high part
            new CPUx86.Push {
                DestinationValue = BitConverter.ToUInt32(BitConverter.GetBytes(xOp.Value), 4)
            };
            // push low part
            new CPUx86.Push {
                DestinationValue = BitConverter.ToUInt32(BitConverter.GetBytes(xOp.Value), 0)
            };
        }
Exemple #12
0
        /// <summary>
        /// Sucht einfach nur die Parameternamen der aktuell übergebenen Methode heraus und setzt noch den passenden Typ
        /// für TypeScript hinter den Namen z.B.: "alter: number, name: string, ..."
        /// </summary>
        public string GetFunctionParametersWithType(_MethodInfo methodInfo)
        {
            StringBuilder builder = new StringBuilder();

            //Zusammenbauen der PrameterInfos für die übergebene Methode.
            foreach (ParameterInfo info in methodInfo.GetParameters())
            {
                //Die Parameterliste inkl. des Typen zurückgeben
                builder.Append(string.Format("{0}: {1}", info.Name, GetTsType(info.ParameterType))).Append(",");
            }

            return(builder.ToString().TrimEnd(','));
        }
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
#warning TODO: Implement exception
            DoNullReferenceCheck(Assembler, DebugEnabled, 4);
            XS.Add(XSRegisters.ESP, 4);
            XS.Pop(XSRegisters.EAX);
            new CPUx86.Mov {
                DestinationRef = Cosmos.Assembler.ElementReference.New(DataMember.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef)), DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.EAX
            };
            XS.Call("SystemExceptionOccurred");
            XS.Set(XSRegisters.ECX, 3);
            Call.EmitExceptionLogic(Assembler, aMethod, aOpCode, false, null);
        }
Exemple #14
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            // destination address
            XS.Pop(EDI);
            // source address
            XS.Pop(ESI);
            // byte count
            XS.Pop(ECX);

            new Movs {
                Prefixes = InstructionPrefixes.Repeat, Size = 8
            };
        }
Exemple #15
0
        private void DoExecute(Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled)
        {
            var xType = aTargetType.Value;

            XS.Comment($"Type = {aTargetType.Value}");
            if (xType.GetTypeInfo().BaseType == typeof(ValueType))
            {
            }
            else if (xType.GetTypeInfo().BaseType == typeof(object))
            {
                throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}");
            }
        }
Exemple #16
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            if (IsReferenceType(xSource))
            {
                // todo: Stop GC tracking
                XS.Add(ESP, SizeOfType(typeof(UIntPtr)));

                // todo: x64
                XS.Pop(EAX);
                XS.Push(0);
                XS.Push(EAX);
            }
            else if (IsByRef(xSource))
            {
                // todo: Stop GC tracking
                throw new NotImplementedException($"Error compiling '{GetLabel(aMethod)}': conv.u8 not implemented for byref types!");
            }
            else if (xSourceSize <= 4)
            {
                if (xSourceIsFloat)
                {
                    XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Int32);
                    XS.Sub(ESP, 4);
                    XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64);
                }
                else
                {
                    XS.Pop(EAX);
                    XS.Push(0);
                    XS.Push(EAX);
                }
            }
            else if (xSourceSize <= 8)
            {
                if (xSourceIsFloat)
                {
                    XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Long64);
                    /* The sign of the value should not be changed a negative value is simply converted to its corresponding ulong value */
                    //XS.FPU.FloatAbs();
                    XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64);
                }
            }
            else
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U8.cs->Error: StackSize > 8 not supported");
            }
        }
Exemple #17
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            switch (xSourceSize)
            {
            case 1:
                throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I8.cs->The size 1 could not exist, because always is pushed Int32 or Int64!");

            case 2:
                throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I8.cs->The size 2 could not exist, because always is pushed Int32 or Int64!");

            case 4:
                if (xSourceIsFloat)
                {
                    /*
                     * Sadly for x86 there is no way using SSE to convert a float to an Int64... in x64 we could use ConvertPD2DQAndTruncate with
                     * x64 register as a destination... so this one of the few cases in which we need the legacy FPU!
                     */
                    XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Int32);
                    XS.Sub(XSRegisters.ESP, 4);
                    XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64);
                }
                else
                {
                    XS.Pop(XSRegisters.EAX);
                    XS.SignExtendAX(RegisterSize.Int32);
                    XS.Push(XSRegisters.EDX);
                    XS.Push(XSRegisters.EAX);
                }
                break;

            case 8:
                if (xSourceIsFloat)
                {
                    /*
                     * Sadly for x86 there is no way using SSE to convert a double to an Int64... in x64 we could use ConvertPD2DQAndTruncate with
                     * x64 register as a destination... so only in this case we need the legacy FPU!
                     */
                    XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Long64);
                    XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64);
                }
                break;

            default:
                //EmitNotImplementedException(Assembler, GetServiceProvider(), "Conv_I8: SourceSize " + xSource + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel);
                throw new NotImplementedException();
            }
        }
Exemple #18
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            OpType xType                     = (OpType)aOpCode;
            string xTypeID                   = GetTypeIDLabel(xType.Value);
            string xCurrentMethodLabel       = GetLabel(aMethod, aOpCode);
            string xAfterIsInstanceCallLabel = xCurrentMethodLabel + "_After_IsInstance_Call";
            string xReturnNullLabel          = xCurrentMethodLabel + "_ReturnNull";
            string xNextPositionLabel        = GetLabel(aMethod, aOpCode.NextPosition);

            XS.Set(EAX, ESP, sourceDisplacement: 4);

            XS.Compare(EAX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.Zero, xReturnNullLabel);
            XS.Push(EAX, isIndirect: true);
            XS.Push(xTypeID, isIndirect: true);
            XS.Push(Convert.ToUInt32(xType.Value.IsInterface));

            MethodBase xMethodIsInstance = VTablesImplRefs.IsInstanceRef;

            Call.DoExecute(Assembler, aMethod, xMethodIsInstance, aOpCode, xCurrentMethodLabel, xAfterIsInstanceCallLabel, DebugEnabled);

            XS.Label(xAfterIsInstanceCallLabel);

            XS.Pop(EAX);

            XS.Compare(EAX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.Equal, xReturnNullLabel);

            XS.Jump(xNextPositionLabel);
            XS.Label(xReturnNullLabel);
            XS.Add(ESP, 8);

            //string xAllocInfoLabelName = LabelName.Get( GCImplementationRefs.AllocNewObjectRef );
            // TODO: Emit new exceptions
            //new Newobj( Assembler ).Execute( aMethod, aOpCode );

            //Newobj.Assemble( Assembler,
            //                typeof( InvalidCastException ).GetConstructor( new Type[ 0 ] ),
            //                GetService<IMetaDataInfoService>().GetTypeIdLabel( typeof( InvalidCastException ) ),
            //                mThisLabel,
            //                mMethodInfo,
            //                mCurrentILOffset,
            //                mThisLabel + "_After_NewException",
            //                GetService<IMetaDataInfoService>().GetTypeInfo( typeof( InvalidCastException ) ),
            //                GetService<IMetaDataInfoService>().GetMethodInfo( typeof( InvalidCastException ).GetConstructor( new Type[ 0 ] ), false ),
            //                GetServiceProvider(),
            //                xAllocInfo.LabelName );
            XS.Label(xCurrentMethodLabel + "_After_NewException");
            //Call.EmitExceptionLogic( Assembler, ( uint )mCurrentILOffset, mMethodInfo, mNextOpLabel, false, null );
        }
Exemple #19
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            switch (xSourceSize)
            {
            case 1:
            case 2:
            case 4:
            {
                if (xSourceIsFloat)
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }
                break;
            }

            case 8:
            {
                if (xSourceIsFloat)
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }

                if (IsReferenceType(xSource))
                {
                    XS.Add(ESP, 4);
                }
                else
                {
                    XS.Pop(EAX);
                    XS.Add(ESP, 4);
                    XS.Push(EAX);
                }

                break;
            }

            default:
                //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_I4: SourceSize " + xSource + " not yet supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel );
                throw new NotImplementedException();
            }
        }
Exemple #20
0
        public void Execute(_MethodInfo aMethod, ILOpCode aOpCode, bool aFromNewObj = false)
        {
            Type mType    = ((ILOpCodes.OpType)aOpCode).Value;
            uint mObjSize = SizeOfType(mType);

            XS.Pop(EAX);

            for (int i = 0; i < (mObjSize / 4); i++)
            {
                XS.Set(EAX, 0, destinationDisplacement: i * 4, size: RegisterSize.Int32);
            }
            switch (mObjSize % 4)
            {
            case 1:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)((mObjSize / 4) * 4), SourceValue = 0, Size = 8
                };
                break;
            }

            case 2:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)((mObjSize / 4) * 4), SourceValue = 0, Size = 16
                };
                break;
            }

            case 3:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)((mObjSize / 4) * 4), SourceValue = 0, Size = 8
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)(((mObjSize / 4) * 4) + 1), SourceValue = 0, Size = 16
                };
                break;
            }

            case 0:
                break;

            default:
            {
                throw new NotImplementedException("Remainder size " + mObjSize % 4 + " not supported yet! (Type = '" + mType.FullName + "')");
            }
            }
        }
Exemple #21
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpVar     = (OpVar)aOpCode;
            var xVar       = aMethod.MethodBase.GetLocalVariables()[xOpVar.Value];
            var xEBPOffset = GetEBPOffsetForLocal(aMethod, xOpVar.Value);

            xEBPOffset += (uint)(((int)GetStackCountForLocal(aMethod, xVar.Type) - 1) * 4);

            XS.Comment("Local type = " + xVar.Type);
            XS.Comment("Local EBP offset = " + xEBPOffset);

            XS.Set(EAX, EBP);
            XS.Sub(EAX, xEBPOffset);
            XS.Push(EAX);
        }
Exemple #22
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xType    = aOpCode.StackPopTypes[0];
            var xSize    = SizeOfType(xType);
            var xIsFloat = TypeIsFloat(xType);

            if (xIsFloat)
            {
                throw new Exception("Cosmos.IL2CPU.x86->IL->Sub_Ovf.cs->Error: Expected signed integer operands but get float!");
            }

            if (xSize > 8)
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Sub_Ovf.cs->Error: StackSize > 8 not supported");
            }
            else
            {
                var xBaseLabel    = GetLabel(aMethod, aOpCode) + ".";
                var xSuccessLabel = xBaseLabel + "Success";
                if (xSize > 4)   // long
                {
                    XS.Pop(EAX); //low part
                    XS.Pop(EDX); //high part
                    XS.Sub(ESP, EAX, destinationIsIndirect: true);
                    XS.SubWithCarry(ESP, EDX, destinationDisplacement: 4);
                }
                else //integer
                {
                    XS.Pop(ECX);//first integer
                    XS.Pop(EAX);  //second integer
                    XS.Sub(EAX, ECX);
                    XS.Push(EAX); //push result on stack
                }

                // Let's check if we add overflow and if so throw OverflowException
                XS.Jump(ConditionalTestEnum.NoOverflow, xSuccessLabel);
                if (xSize > 4) // Hack to stop stack corruption
                {
                    XS.Add(ESP, 8);
                }
                else
                {
                    XS.Add(ESP, 4);
                }
                Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled);
                XS.Label(xSuccessLabel);
            }
        }
Exemple #23
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var  xOpVar      = (OpVar)aOpCode;
            var  xVar        = aMethod.MethodBase.GetLocalVariables()[xOpVar.Value];
            var  xStackCount = (int)GetStackCountForLocal(aMethod, xVar.LocalType);
            var  xEBPOffset  = (int)GetEBPOffsetForLocal(aMethod, xOpVar.Value);
            var  xSize       = SizeOfType(xVar.LocalType);
            bool xSigned     = IsIntegerSigned(xVar.LocalType);

            XS.Comment("Local type = " + xVar.LocalType);
            XS.Comment("Local EBP offset = " + xEBPOffset);
            XS.Comment("Local size = " + xSize);

            switch (xSize)
            {
            case 1:
                if (xSigned)
                {
                    XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Byte8);
                }
                else
                {
                    XS.MoveZeroExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Byte8);
                }
                XS.Push(EAX);
                break;

            case 2:
                if (xSigned)
                {
                    XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Short16);
                }
                else
                {
                    XS.MoveZeroExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Short16);
                }
                XS.Push(EAX);
                break;

            default:
                for (int i = 0; i < xStackCount; i++)
                {
                    XS.Set(EAX, EBP, sourceDisplacement: 0 - (xEBPOffset + (i * 4)));
                    XS.Push(EAX);
                }
                break;
            }
        }
Exemple #24
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            // TODO overflow check for float
            var xType    = aOpCode.StackPopTypes[0];
            var xSize    = SizeOfType(xType);
            var xIsFloat = TypeIsFloat(xType);

            if (xIsFloat)
            {
                throw new Exception("Cosmos.IL2CPU.x86->IL->Add_Ovf_Un.cs->Error: Expected unsigned integer operands but get float!");
            }

            if (xSize > 8)
            {
                //EmitNotImplementedException( Assembler, aServiceProvider, "Size '" + xSize.Size + "' not supported (add)", aCurrentLabel, aCurrentMethodInfo, aCurrentOffset, aNextLabel );
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Add_Ovf_Un.cs->Error: StackSize > 8 not supported");
            }
            else
            {
                var xBaseLabel    = GetLabel(aMethod, aOpCode) + ".";
                var xSuccessLabel = xBaseLabel + "Success";
                if (xSize > 4)                 // long
                {
                    XS.Pop(EDX);               // low part
                    XS.Pop(EAX);               // high part
                    XS.Sub(ESP, EDX, destinationIsIndirect: true);
                    XS.SubWithCarry(ESP, EAX, destinationDisplacement: 4);
                }
                else                 //integer
                {
                    XS.Pop(EAX);
                    XS.Sub(ESP, EAX, destinationIsIndirect: true);
                }

                // Let's check if we add overflow and if so throw OverflowException
                XS.Jump(ConditionalTestEnum.NotCarry, xSuccessLabel);
                if (xSize > 4)                 // Hack to stop stack corruption
                {
                    XS.Add(ESP, 8);
                }
                else
                {
                    XS.Add(ESP, 4);
                }
                Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled);
                XS.Label(xSuccessLabel);
            }
        }
Exemple #25
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            if (xSourceSize <= 4)
            {
                if (xSourceIsFloat)
                {
                    XS.SSE.ConvertSS2SD(XMM0, ESP, sourceIsIndirect: true);
                    XS.Sub(ESP, 4);
                    XS.SSE2.MoveSD(ESP, XMM0, destinationIsIndirect: true);
                }
                else
                {
                    if (IsIntegerSigned(xSource))
                    {
                        XS.SSE2.ConvertSI2SD(XMM0, ESP, sourceIsIndirect: true);
                        XS.Sub(ESP, 4);
                        XS.SSE2.MoveSD(ESP, XMM0, destinationIsIndirect: true);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            else if (xSourceSize <= 8)
            {
                if (!xSourceIsFloat)
                {
                    if (IsIntegerSigned(xSource))
                    {
                        XS.FPU.IntLoad(ESP, isIndirect: true, size: RegisterSize.Long64);
                        XS.FPU.FloatStoreAndPop(ESP, isIndirect: true, size: RegisterSize.Long64);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            else
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_R8.cs->Error: StackSize > 8 not supported");
            }
        }
Exemple #26
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource     = aOpCode.StackPopTypes[0];
            var xSourceSize = SizeOfType(xSource);

            switch (xSourceSize)
            {
            case 1:
                throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->The size 1 could not exist, because always is pushed Int32 or Int64!");

            case 2:
                throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->The size 2 could not exist, because always is pushed Int32 or Int64!");

            case 4:
                if (TypeIsFloat(xSource))
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }
                break;

            case 8:
                if (TypeIsFloat(xSource))
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0);
                    // We need to move the stack pointer of 4 Byte to "eat" the second double that is yet in the stack or we get a corrupted stack!
                    XS.Add(ESP, 4);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                    // Is this really needed? Conv.U2 and Conv.U1 did not this! In reality they should call the same code...
                    //XS.Push(EAX);
                    break;
                }
                else
                {
                    XS.Pop(EAX);
                    XS.Pop(ECX);
                    XS.Push(EAX);
                    break;
                }

            default:
                //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_U4: SourceSize " + xStackItem.Size + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel );
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->Unknown size of variable on the top of the stack.");
            }
        }
Exemple #27
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            if (aOpCode.OpCode == ILOpCode.Code.Stind_I8 ||
                aOpCode.OpCode == ILOpCode.Code.Stind_R8 ||
                aOpCode.OpCode == ILOpCode.Code.Stind_Ref)
            {
                DoNullReferenceCheck(Assembler, DebugEnabled, 8);
            }
            else
            {
                DoNullReferenceCheck(Assembler, DebugEnabled, 4);
            }

            switch (aOpCode.OpCode)
            {
            case ILOpCode.Code.Stind_I1:
                XS.Pop(ECX);
                XS.Pop(EAX);
                XS.Set(EAX, CL, destinationIsIndirect: true);
                break;

            case ILOpCode.Code.Stind_I2:
                XS.Pop(ECX);
                XS.Pop(EAX);
                XS.Set(EAX, CX, destinationIsIndirect: true);
                break;

            case ILOpCode.Code.Stind_I:
            case ILOpCode.Code.Stind_I4:
            case ILOpCode.Code.Stind_R4:
                XS.Pop(ECX);
                XS.Pop(EAX);
                XS.Set(EAX, ECX, destinationIsIndirect: true);
                break;

            case ILOpCode.Code.Stind_I8:
            case ILOpCode.Code.Stind_R8:
            case ILOpCode.Code.Stind_Ref:
                XS.Pop(ECX);
                XS.Pop(EBX);
                XS.Pop(EAX);
                XS.Set(EAX, ECX, destinationIsIndirect: true);
                XS.Set(EAX, EBX, destinationDisplacement: 4);
                break;
            }
        }
Exemple #28
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            if (xSourceSize <= 4)
            {
                if (xSourceIsFloat)
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0);
                    XS.MoveZeroExtend(EAX, AX);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(EAX);
                    XS.MoveZeroExtend(EAX, AX);
                    XS.Push(EAX);
                }
            }
            else if (xSourceSize <= 8)
            {
                if (xSourceIsFloat)
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 4);
                    XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0);
                    XS.MoveZeroExtend(EAX, AX);
                    XS.Set(ESP, EAX, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(EAX);
                    XS.Add(ESP, 4);
                    XS.MoveZeroExtend(EAX, AX);
                    XS.Push(EAX);
                }
            }
            else
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U2.cs->Error: StackSize > 8 not supported");
            }
        }
Exemple #29
0
        public static void DoExecute(XSharp.Assembler.Assembler Assembler, _MethodInfo aMethod, ushort aParam)
        {
            var xDisplacement = Ldarg.GetArgumentDisplacement(aMethod, aParam);

            /*
             * The function GetArgumentDisplacement() does not give the correct displacement for the Ldarga opcode
             * we need to "fix" it subtracting the argSize and 4
             */
            Type xArgType;

            if (aMethod.MethodBase.IsStatic)
            {
                xArgType = aMethod.MethodBase.GetParameters()[aParam].ParameterType;
            }
            else
            {
                if (aParam == 0u)
                {
                    xArgType = aMethod.MethodBase.DeclaringType;
                    if (xArgType.IsValueType)
                    {
                        xArgType = xArgType.MakeByRefType();
                    }
                }
                else
                {
                    xArgType = aMethod.MethodBase.GetParameters()[aParam - 1].ParameterType;
                }
            }

            uint xArgRealSize = SizeOfType(xArgType);
            uint xArgSize     = Align(xArgRealSize, 4);

            XS.Comment("Arg idx = " + aParam);
            XS.Comment("Arg type = " + xArgType);
            XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);

            xDisplacement -= (int)(xArgSize - 4);
            XS.Comment("Real displacement " + xDisplacement);

            XS.Set(EAX, EBP);
            XS.Set(EBX, (uint)(xDisplacement));
            XS.Add(EAX, EBX);
            XS.Push(EAX);
        }
Exemple #30
0
        public static void DoExecute(Cosmos.Assembler.Assembler assembler, _MethodInfo aMethod, string field, Type declaringType, ILOpCode aCurrentOpCode)
        {
            // call cctor:
            var xCctor = (declaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault();

            if (xCctor != null)
            {
                XS.Call(LabelName.Get(xCctor));
                if (aCurrentOpCode != null)
                {
                    ILOp.EmitExceptionLogic(assembler, aMethod, aCurrentOpCode, true, null, ".AfterCCTorExceptionCheck");
                    XS.Label(".AfterCCTorExceptionCheck");
                }
            }
            string xDataName = field;

            XS.Push(xDataName);
        }