Ejemplo n.º 1
0
        public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
        {
            var xFieldSize = SizeOfType(aOpCode.StackPopTypes[0]);
            var xRoundedSize = Align(xFieldSize, 4);
            DoNullReferenceCheck(Assembler, DebugEnabled, (int)xRoundedSize);

            XS.Set(XSRegisters.ECX, XSRegisters.ESP, sourceDisplacement: checked((int)xRoundedSize));
            for( int i = 0; i < ( xFieldSize / 4 ); i++ )
            {
                XS.Pop(XSRegisters.EAX);
                XS.Set(XSRegisters.ECX, XSRegisters.EAX, destinationDisplacement: i * 4);
            }
            switch( xFieldSize % 4 )
            {
                case 1:
                    {
                        XS.Pop(XSRegisters.EAX);
                        new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ECX, DestinationIsIndirect = true, DestinationDisplacement = checked((int)( xFieldSize / 4 ) * 4 ), SourceReg = CPUx86.RegistersEnum.AL };
                        break;
                    }
                case 2:
                    {
                        XS.Pop(XSRegisters.EAX);
                        new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ECX, DestinationIsIndirect = true, DestinationDisplacement = checked((int)( xFieldSize / 4 ) * 4 ), SourceReg = CPUx86.RegistersEnum.AX };
                        break;
                    }
                case 0:
                    {
                        break;
                    }
                default:
                    throw new Exception( "Remainder size " + ( xFieldSize % 4 ) + " not supported!" );
            }
            XS.Add(XSRegisters.ESP, 4);
        }
Ejemplo n.º 2
0
 public static void DoExecute(uint aSize, bool aIsFloat)
 {
     if (aSize <= 4)
     {
         if (aIsFloat)
         {
             XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
             XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0);
             XS.Set(ESP, EAX, destinationIsIndirect: true);
         }
     }
     else if (aSize <= 8)
     {
         if (aIsFloat)
         {
             XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
             XS.Add(ESP, 4);
             XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0);
             XS.Set(ESP, EAX, destinationIsIndirect: true);
         }
         else
         {
             XS.Pop(EAX);
             XS.Add(ESP, 4);
             XS.Push(EAX);
         }
     }
     else
     {
         throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->Error: StackSize > 8 not supported");
     }
 }
Ejemplo n.º 3
0
        public static void InitializeArray(Array array, RuntimeFieldHandle fldHandle)
        {
            // Arguments:
            //    Array aArray, RuntimeFieldHandle aFieldHandle
            XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 0xC); // array
            XS.Set(EDI, EDI, sourceIsIndirect: true);
            XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: 8);   // aFieldHandle
            XS.Add(XSRegisters.EDI, 8);
            XS.Push(EDI, isIndirect: true);
            XS.Add(XSRegisters.EDI, 4);
            XS.Set(EAX, EDI, sourceIsIndirect: true);
            XS.Multiply(ESP, isIndirect: true, size: RegisterSize.Int32);
            XS.Pop(XSRegisters.ECX);
            XS.Set(XSRegisters.ECX, XSRegisters.EAX);
            XS.Set(XSRegisters.EAX, 0);
            XS.Add(XSRegisters.EDI, 4);

            XS.Label(".StartLoop");
            XS.Set(DL, ESI, sourceIsIndirect: true);
            XS.Set(EDI, DL, destinationIsIndirect: true);
            XS.Add(XSRegisters.EAX, 1);
            XS.Add(XSRegisters.ESI, 1);
            XS.Add(XSRegisters.EDI, 1);
            XS.Compare(XSRegisters.EAX, XSRegisters.ECX);
            XS.Jump(CPUx86.ConditionalTestEnum.Equal, ".EndLoop");
            XS.Jump(".StartLoop");

            XS.Label(".EndLoop");
        }
Ejemplo n.º 4
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            OpType xType            = ( OpType )aOpCode;
            string xTypeID          = GetTypeIDLabel(xType.Value);
            string mReturnNullLabel = GetLabel(aMethod, aOpCode) + "_ReturnNull";

            XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true);

            XS.Compare(XSRegisters.EAX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.Zero, mReturnNullLabel);

            // EAX contains a memory handle now. Lets convert it to a pointer
            XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true);

            //XS.Mov(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true);
            XS.Push(XSRegisters.EAX, isIndirect: true);
            XS.Push(xTypeID, isIndirect: true);

            SysReflection.MethodBase xMethodIsInstance = ReflectionUtilities.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.UInt32", "System.UInt32");
//, new OpMethod( ILOpCode.Code.Call, aOpCode.Position, aOpCode.NextPosition, xMethodIsInstance, aOpCode.CurrentExceptionHandler));
            Call.DoExecute(Assembler, aMethod, xMethodIsInstance, aOpCode, GetLabel(aMethod, aOpCode), GetLabel(aMethod, aOpCode) + "_After_IsInstance_Call", DebugEnabled);

            new Label(GetLabel(aMethod, aOpCode) + "_After_IsInstance_Call");
            XS.Pop(XSRegisters.EAX);
            XS.Compare(XSRegisters.EAX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.Equal, mReturnNullLabel);
            // push nothing now, as we should return the object instance pointer.
            new CPUx86.Jump {
                DestinationLabel = GetLabel(aMethod, aOpCode.NextPosition)
            };
            XS.Label(mReturnNullLabel);
            XS.Add(XSRegisters.ESP, 4);
            XS.Push(0);
        }
Ejemplo n.º 5
0
        public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
        {
            // load element size into eax
            // load length into ebx
            // calculate entire size into eax and move to exc
            // load start into edi
            // clear ecx bytes starting at edi

            // load element size into eax
            XS.Set(EAX, EBP, sourceDisplacement: SourceArrayDisplacement);
            XS.Add(EAX, 8);
            XS.Set(EAX, EAX, sourceIsIndirect: true);

            // load length into ebx
            XS.Set(EBX, EBP, sourceDisplacement: SourceArrayDisplacement);
            XS.Add(EBX, 12);
            XS.Set(EBX, EBX, sourceIsIndirect: true);

            // calculate size in bytes and move to ecx
            XS.Multiply(EBX);
            XS.Set(ECX, EAX);

            // load start into esi
            XS.Set(EDI, EBP, sourceDisplacement: SourceArrayDisplacement);
            XS.Add(EDI, 16);

            // clear eax bytes starting at esi
            XS.Set(EAX, 0);
            XS.LiteralCode("rep stosb");
        }
Ejemplo n.º 6
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            // todo: implement exception support.
            var xSize = SizeOfType(aOpCode.StackPopTypes[0]);

            XS.Add(ESP, Align(xSize, 4));
        }
Ejemplo n.º 7
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, OpType aOpType, uint aElementSize, bool debugEnabled)
        {
            XS.Comment("Arraytype: " + aOpType.StackPopTypes.Last().FullName);
            XS.Comment("Size: " + aElementSize);

            DoNullReferenceCheck(aAssembler, debugEnabled, 4);
            // calculate element offset into array memory (including header)
            XS.Pop(XSRegisters.EAX);
            XS.Set(XSRegisters.EDX, aElementSize);
            XS.Multiply(XSRegisters.EDX);
            XS.Add(XSRegisters.EAX, (uint)(ObjectImpl.FieldDataOffset + 4));

            // pop the array now
            XS.Pop(XSRegisters.EDX);
            // translate it to actual memory
            XS.Set(XSRegisters.EDX, XSRegisters.EDX, sourceIsIndirect: true);

            if (aOpType.StackPopTypes.Last().GetElementType().IsClass)
            {
                XS.Set(XSRegisters.EDX, XSRegisters.EDX, sourceIsIndirect: true);
            }

            XS.Add(XSRegisters.EDX, XSRegisters.EAX);
            XS.Push(XSRegisters.EDX);
        }
Ejemplo n.º 8
0
        public static void Assemble(Assembler aAssembler, uint aElementSize, _MethodInfo aMethod, ILOpCode aOpCode, bool debugEnabled)
        {
            // stack     == the new value
            // stack + 1 == the index
            // stack + 2 == the array
            DoNullReferenceCheck(aAssembler, debugEnabled, (int)(8 + Align(aElementSize, 4)));

            uint xStackSize = aElementSize;

            if (xStackSize % 4 != 0)
            {
                xStackSize += 4 - xStackSize % 4;
            }

            // calculate element offset into array memory (including header)
            XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize); // the index
            XS.Set(XSRegisters.EDX, aElementSize);
            XS.Multiply(XSRegisters.EDX);
            XS.Add(XSRegisters.EAX, ObjectUtils.FieldDataOffset + 4);

            XS.Set(XSRegisters.EDX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize + 8); // the array
            XS.Add(XSRegisters.EDX, XSRegisters.EAX);
            XS.Push(XSRegisters.EDX);

            XS.Pop(XSRegisters.ECX);
            for (int i = (int)(aElementSize / 4) - 1; i >= 0; i -= 1)
            {
                new Comment(aAssembler, "Start 1 dword");
                XS.Pop(XSRegisters.EBX);
                XS.Set(XSRegisters.ECX, XSRegisters.EBX, destinationIsIndirect: true);
                XS.Add(XSRegisters.ECX, 4);
            }
            switch (aElementSize % 4)
            {
            case 1:
            {
                new Comment(aAssembler, "Start 1 byte");
                XS.Pop(XSRegisters.EBX);
                XS.Set(XSRegisters.ECX, XSRegisters.BL, destinationIsIndirect: true);
                break;
            }

            case 2:
            {
                new Comment(aAssembler, "Start 1 word");
                XS.Pop(XSRegisters.EBX);
                XS.Set(XSRegisters.ECX, XSRegisters.BX, destinationIsIndirect: true);
                break;
            }

            case 0:
            {
                break;
            }

            default:
                throw new Exception("Remainder size " + (aElementSize % 4) + " not supported!");
            }
            XS.Add(XSRegisters.ESP, 12);
        }
Ejemplo n.º 9
0
        /*
         *
         * public static unsafe void Fill16Blocks(
         *                       byte *dest, [ebp + 8]
         *                       int value, [ebp + 12]
         *                       int BlocksNum) [ebp + 16]
         */
        public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
        {
            /* First we copy dest, value and DestSize from EBP (stack) to 3 different registers */
            XS.Comment("Destination (int pointer)");
            XS.Set(EAX, EBP, sourceDisplacement: DestDisplacement);

            XS.Comment("Value");
            XS.Set(EBX, EBP, sourceDisplacement: ValueDisplacement);

            XS.Comment("BlocksNum");
            XS.Set(ECX, EBP, sourceDisplacement: BlocksNumDisplacement);

            /*
             * Now we need to copy 'value' (EBX) to an SSE register but we should not simply do a copy (!)
             * but all the register with 'value' repeating!
             * That is in the 16 byte SSE register should go this repeating pattern:
             * |value|value|value|value
             * luckily we don't need to do a loop for this there is the SSE3 instruction for this shufps
             */
            XS.SSE2.MoveD(XMM0, EBX);
            XS.SSE.Shufps(XMM0, XMM0, 0x0000); // This broadcast the first element of XMM0 on the other 3

            /* Do the 'loop' */
            XS.Xor(EDI, EDI); // EDI is 0
            XS.Label(".loop");
            //XS.SSE.MoveUPS(EAX, XMM0, destinationIsIndirect: true, destinationDisplacement: EDI);
            XS.LiteralCode("movups[EAX + EDI], XMM0");
            XS.Add(EDI, 16);
            XS.Sub(ECX, 1);
            //XS.LiteralCode("jnz .loop");
            XS.Jump(ConditionalTestEnum.NotZero, ".loop");

            //XS.Return();
        }
Ejemplo n.º 10
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            OpType xType                     = (OpType)aOpCode;
            string xTypeID                   = GetTypeIDLabel(xType.Value);
            string xCurrentMethodLabel       = GetLabel(aMethod, aOpCode);
            string xReturnNullLabel          = xCurrentMethodLabel + "_ReturnNull";
            string xAfterIsInstanceCallLabel = xCurrentMethodLabel + "_After_IsInstance_Call";
            string xNextPositionLabel        = GetLabel(aMethod, aOpCode.NextPosition);

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

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

            XS.Push(EAX, isIndirect: true);
            XS.Push(xTypeID, isIndirect: true);
            XS.Push(Convert.ToUInt32(xType.Value.IsInterface));

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

            XS.Label(xAfterIsInstanceCallLabel);

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

            XS.Label(xReturnNullLabel);

            XS.Add(ESP, 8);
            XS.Push(0);
            XS.Push(0);
        }
Ejemplo n.º 11
0
        // this code is mostly copied from Newarr.cs in Il2CPU, just the code to find the size and length is different
        public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
        {
            string     xTypeID   = ILOp.GetTypeIDLabel(typeof(Array));
            MethodBase xCtor     = typeof(Array).GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)[0];
            string     xCtorName = LabelName.Get(xCtor);

            XS.Set(ECX, EBP, sourceDisplacement: 8);  // size
            XS.Set(EDX, EBP, sourceDisplacement: 12); // length



            XS.Push(ECX);                                 // size of element
            XS.Set(EAX, ECX);
            XS.Multiply(EDX);                             // total element size
            XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // total array size
            XS.Push(EAX);
            XS.Call(LabelName.Get(GCImplementationRefs.AllocNewObjectRef));
            XS.Label(".AfterAlloc");
            XS.Pop(EAX);
            XS.Pop(ESI);
            XS.Push(EAX);
            XS.Push(ESP, isIndirect: true);
            XS.Push(ESP, isIndirect: true);
            // it's on the stack 3 times now, once from the return value, twice from the pushes;

            XS.Pop(EAX);
            XS.Set(EBX, xTypeID, sourceIsIndirect: true);  // array type id
            XS.Set(EAX, EBX, destinationIsIndirect: true); // array type id
            XS.Set(EAX, (uint)ObjectUtils.InstanceTypeEnum.Array, destinationDisplacement: 4, destinationIsIndirect: true);
            XS.Set(EAX, ESI, destinationDisplacement: 8, destinationIsIndirect: true);
            XS.Set(EAX, ECX);
            XS.Push(0);
            XS.Call(xCtorName);
            XS.Push(0);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Emits cleanup code for when an exception occurred inside a method call.
        /// </summary>
        public static void EmitExceptionCleanupAfterCall(Assembler.Assembler aAssembler, uint aReturnSize, uint aStackSizeBeforeCall, uint aTotalArgumentSizeOfMethod)
        {
            XS.Comment("aStackSizeBeforeCall = " + aStackSizeBeforeCall);
            XS.Comment("aTotalArgumentSizeOfMethod = " + aTotalArgumentSizeOfMethod);
            XS.Comment("aReturnSize = " + aReturnSize);

            if (aReturnSize != 0)
            {
                // at least pop return size:
                XS.Comment("Cleanup return");

                // cleanup result values
                for (int i = 0; i < aReturnSize / 4; i++)
                {
                    XS.Add(XSRegisters.ESP, 4);
                }
            }

            if (aStackSizeBeforeCall > (aTotalArgumentSizeOfMethod))
            {
                if (aTotalArgumentSizeOfMethod > 0)
                {
                    var xExtraStack = aStackSizeBeforeCall - aTotalArgumentSizeOfMethod;
                    XS.Comment("Cleanup extra stack");

                    // cleanup result values
                    for (int i = 0; i < xExtraStack / 4; i++)
                    {
                        XS.Add(XSRegisters.ESP, 4);
                    }
                }
            }
        }
Ejemplo n.º 13
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackTop      = aOpCode.StackPopTypes[0];
            var xStackTop2     = aOpCode.StackPopTypes[0];
            var xStackTopSize  = SizeOfType(xStackTop);
            var xStackTop2Size = SizeOfType(xStackTop2);

            if (xStackTopSize != xStackTop2Size)
            {
                throw new Exception("Different size for substract: " + aMethod.MethodBase + "!");
            }

            var xStackTopIsFloat = TypeIsFloat(xStackTop);

            switch (xStackTopSize)
            {
            case 1:
            case 2:
            case 4:
                if (xStackTopIsFloat)
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 4);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    //XS.LiteralCode("movss XMM1, [ESP + 4]");
                    XS.SSE.SubSS(XMM1, XMM0);
                    XS.SSE.MoveSS(ESP, XMM1, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(XSRegisters.ECX);
                    XS.Pop(XSRegisters.EAX);
                    XS.Sub(XSRegisters.EAX, XSRegisters.ECX);
                    XS.Push(XSRegisters.EAX);
                }
                break;

            case 8:
                if (xStackTopIsFloat)
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 8);
                    XS.SSE2.MoveSD(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE2.SubSD(XMM1, XMM0);
                    XS.SSE2.MoveSD(ESP, XMM1, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(EAX);
                    XS.Pop(EDX);
                    XS.Sub(ESP, EAX, destinationIsIndirect: true);
                    XS.SubWithCarry(ESP, EDX, destinationDisplacement: 4);
                }
                break;

            default:
                throw new NotImplementedException("not implemented");
            }
        }
Ejemplo n.º 14
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, int aSize, bool debugEnabled)
        {
            DoNullReferenceCheck(aAssembler, debugEnabled, Align((uint)aSize, 4));
            new Comment(aAssembler, "address at: [esp + " + aSize + "]");
            int xStorageSize = aSize;

            if (xStorageSize < 4)
            {
                xStorageSize = 4;
            }
            XS.Set(XSRegisters.EBX, XSRegisters.ESP, sourceDisplacement: xStorageSize);
            for (int i = 0; i < (aSize / 4); i++)
            {
                XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: i * 4);
                XS.Set(XSRegisters.EBX, XSRegisters.EAX, destinationDisplacement: i * 4);
            }
            switch (aSize % 4)
            {
            case 0:
            {
                break;
            }

            case 1:
            {
                XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: ((aSize / 4) * 4));
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EBX, DestinationIsIndirect = true, SourceDisplacement = ((aSize / 4) * 4), SourceReg = CPUx86.RegistersEnum.AL
                };
                break;
            }

            case 2:
            {
                XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: ((aSize / 4) * 4));
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EBX, DestinationIsIndirect = true, DestinationDisplacement = ((aSize / 4) * 4), SourceReg = CPUx86.RegistersEnum.AX
                };
                break;
            }

            case 3:
            {
                XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: ((aSize / 4) * 4));
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EBX, DestinationIsIndirect = true, DestinationDisplacement = ((aSize / 4) * 4), SourceReg = CPUx86.RegistersEnum.AX
                };
                XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: (((aSize / 4) * 4) + 2));
                new CPUx86.Mov {
                    DestinationReg = CPUx86.RegistersEnum.EBX, DestinationIsIndirect = true, DestinationDisplacement = (((aSize / 4) * 4) + 2), SourceReg = CPUx86.RegistersEnum.AL
                };
                break;
            }

            default:
                throw new Exception("Error, shouldn't occur");
            }
            XS.Add(XSRegisters.ESP, ( uint )(xStorageSize + 4));
        }
Ejemplo n.º 15
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 (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)
                {
                    if (xIsFloat)
                    {
                        //TODO overflow check
                        XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Long64);
                        XS.Add(ESP, 8);
                        XS.FPU.FloatAdd(ESP, isIndirect: true, size: RegisterSize.Long64);
                        XS.FPU.FloatStoreAndPop(ESP, isIndirect: true, size: RegisterSize.Long64);
                    }
                    else
                    {
                        XS.Pop(XSRegisters.EDX); // low part
                        XS.Pop(XSRegisters.EAX); // high part
                        XS.Add(ESP, EDX, destinationIsIndirect: true);
                        XS.AddWithCarry(ESP, EAX, destinationDisplacement: 4);
                    }
                }
                else
                {
                    if (xIsFloat) //float
                    {
                        //TODO overflow check
                        XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                        XS.Add(XSRegisters.ESP, 4);
                        XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                        XS.SSE.AddSS(XMM0, XMM1);
                        XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    }
                    else //integer
                    {
                        XS.Pop(XSRegisters.EAX);
                        XS.Add(ESP, EAX, destinationIsIndirect: true);
                    }
                }
                if (false == xIsFloat)
                {
                    XS.Jump(ConditionalTestEnum.NotCarry, xSuccessLabel);
                    ThrowOverflowException();
                }
                XS.Label(xSuccessLabel);
            }
        }
Ejemplo n.º 16
0
 public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
 {
     DoNullReferenceCheck(Assembler, DebugEnabled, 0);
     XS.Pop(XSRegisters.EAX);
     XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true);
     XS.Add(XSRegisters.EAX, 8);
     XS.Push(XSRegisters.EAX, isIndirect: true);
 }
Ejemplo n.º 17
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            DoNullReferenceCheck(Assembler, DebugEnabled, 4);
            XS.Add(XSRegisters.ESP, 4);
            XS.Pop(XSRegisters.EAX);

            XS.Push(XSRegisters.EAX, displacement: 8);
        }
Ejemplo n.º 18
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(IntPtr)));

                // 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.i8 not implemented for byref types!");
            }
            else if (xSourceSize <= 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(ESP, 4);
                    XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64);
                }
                else
                {
                    XS.Pop(EAX);
                    XS.SignExtendAX(RegisterSize.Int32);
                    XS.Push(EDX);
                    XS.Push(EAX);
                }
            }
            else if (xSourceSize <= 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);
                }
            }
            else
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_I8.cs->Error: StackSize > 8 not supported");
            }
        }
Ejemplo n.º 19
0
 public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.Mov(XSRegisters.EAX, CPUAll.ElementReference.New("MultiBootInfo_Memory_High"), sourceIsIndirect: true);
     XS.Xor(XSRegisters.EDX, XSRegisters.CPUx86.Registers.EDX);
     XS.Mov(XSRegisters.ECX, 1024);
     XS.Divide(XSRegisters.ECX);
     XS.Add(XSRegisters.EAX, 1);
     XS.Push(XSRegisters.EAX);
 }
Ejemplo n.º 20
0
 public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.Set(XSRegisters.EAX, "MultiBootInfo_Memory_High", sourceIsIndirect: true);
     XS.Xor(XSRegisters.EDX, XSRegisters.EDX);
     XS.Set(XSRegisters.ECX, 1024);
     XS.Divide(XSRegisters.ECX);
     XS.Add(XSRegisters.EAX, 1);
     XS.Push(XSRegisters.EAX);
 }
Ejemplo n.º 21
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceIsFloat = TypeIsFloat(xSource);
            var xSourceSize    = SizeOfType(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);
                    // 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);
                }
                else
                {
                    throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_U1.cs->Unknown size of floating point value.");
                }
            }
            else
            {
                switch (xSourceSize)
                {
                case 1:
                case 2:
                case 4:
                {
                    XS.Pop(EAX);
                    XS.MoveZeroExtend(EAX, AL);
                    XS.Push(EAX);
                    break;
                }

                case 8:
                {
                    XS.Pop(EAX);
                    XS.Pop(ECX);
                    XS.MoveZeroExtend(EAX, AL);
                    XS.Push(EAX);
                    break;
                }

                default:
                    //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_I1: SourceSize " + xSource + " not supported", mCurLabel, mMethodInformation, mCurOffset, mNextLabel );
                    throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U1.cs->Unknown size of variable on the top of the stack.");
                }
            }
        }
Ejemplo n.º 22
0
        public static void DoExecute(uint xSourceSize, bool xSourceIsFloat, bool xSourceIsSigned, bool checkOverflow, Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xBaseLabel     = GetLabel(aMethod, aOpCode) + ".";
            var xSuccessLabel  = xBaseLabel + "Success";
            var xOverflowLabel = xBaseLabel + "Overflow";
            var xPositiveLabel = xBaseLabel + "Positive";
            var xNegativeLabel = xBaseLabel + "Negative";

            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
                {
                    if (checkOverflow)
                    {
                        ConvOverflowChecks.CheckOverflowForSmall(2, xSourceIsSigned, false, assembler, aMethod, aOpCode, xSuccessLabel, xOverflowLabel);
                    }
                    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
                {
                    if (checkOverflow)
                    {
                        ConvOverflowChecks.CheckOverflowForLong(2, xSourceIsSigned, false, assembler, aMethod, aOpCode, xSuccessLabel, xOverflowLabel, xPositiveLabel, xNegativeLabel);
                    }
                    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");
            }
        }
Ejemplo n.º 23
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(LabelName.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef), EAX, destinationIsIndirect: true);
     XS.Call("SystemExceptionOccurred");
     XS.Set(ECX, 3);
     EmitExceptionLogic(Assembler, aMethod, aOpCode, false, null);
 }
Ejemplo n.º 24
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");
            }
        }
Ejemplo n.º 25
0
        public static void Assemble(Assembler aAssembler, bool debugEnabled, bool doNullReferenceCheck = true)
        {
            if (doNullReferenceCheck)
            {
                DoNullReferenceCheck(aAssembler, debugEnabled, 4);
            }

            XS.Add(ESP, 4);
            XS.Pop(EAX);

            XS.Push(EAX, displacement: 8);
        }
Ejemplo n.º 26
0
        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);
        }
Ejemplo n.º 27
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aMethod, ushort aParam)
        {
            var xDisplacement = Ldarg.GetArgumentDisplacement(aMethod, aParam);
            var xType         = Ldarg.GetArgumentType(aMethod, aParam);

            XS.Comment("Arg idx = " + aParam);
            XS.Comment("Arg type = " + xType);

            XS.Set(XSRegisters.EAX, XSRegisters.EBP);
            XS.Set(XSRegisters.EBX, (uint)(xDisplacement));
            XS.Add(XSRegisters.EAX, XSRegisters.EBX);
            XS.Push(XSRegisters.EAX);
        }
Ejemplo n.º 28
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");
            }
        }
Ejemplo n.º 29
0
 public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 20, sourceIsIndirect: true);
     XS.Push(XSRegisters.EAX);
     XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 16, sourceIsIndirect: true);
     XS.Push(XSRegisters.EAX);
     XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 12, sourceIsIndirect: true);
     XS.Push(XSRegisters.EAX);
     XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 8, sourceIsIndirect: true);
     XS.Push(XSRegisters.EAX);
     XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 24, sourceIsIndirect: true);
     XS.Call(XSRegisters.EAX);
     XS.Add(XSRegisters.ESP, 8);
 }
Ejemplo n.º 30
0
        private static void PushAlignedParameterSize(MethodBase aMethod)
        {
            ParameterInfo[] xParams = aMethod.GetParameters();

            uint xSize;

            XS.Comment("[ Newobj.PushAlignedParameterSize start count = " + xParams.Length.ToString() + " ]");
            for (int i = 0; i < xParams.Length; i++)
            {
                xSize = SizeOfType(xParams[i].ParameterType);
                XS.Add(XSRegisters.ESP, Align(xSize, 4));
            }
            XS.Comment("[ Newobj.PushAlignedParameterSize end ]");
        }