Beispiel #1
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);
        }
Beispiel #2
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");
        }
Beispiel #3
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);
        }
Beispiel #4
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xEndLabel = GetLabel(aMethod, aOpCode) + ".End";

            // size
            XS.Pop(ECX);
            // value
            XS.Pop(EBX);
            // address
            XS.Pop(EDI);

            XS.Compare(ECX, 0);
            XS.Jump(ConditionalTestEnum.Equal, xEndLabel);

            XS.Set(EDI, BL, destinationIsIndirect: true);

            XS.Compare(ECX, 1);
            XS.Jump(ConditionalTestEnum.Equal, xEndLabel);

            XS.Set(ESI, EDI);
            XS.Increment(EDI);
            XS.Decrement(ECX);

            new Movs {
                Prefixes = InstructionPrefixes.Repeat, Size = 8
            };

            XS.Label(xEndLabel);
        }
Beispiel #5
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xType   = (OpType)aOpCode;
            var xTypeID = GetTypeIDLabel(xType.Value);

            var xCurrentMethodLabel       = GetLabel(aMethod, aOpCode);
            var xAfterIsInstanceCallLabel = xCurrentMethodLabel + "_After_IsInstance_Call";
            var xInvalidCastLabel         = xCurrentMethodLabel + "_InvalidCast";
            var xNextPositionLabel        = GetLabel(aMethod, aOpCode.NextPosition);

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

            XS.Compare(EAX, 0);
            XS.Jump(ConditionalTestEnum.Zero, xNextPositionLabel);
            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(ConditionalTestEnum.Equal, xInvalidCastLabel);

            XS.Jump(xNextPositionLabel);

            XS.Label(xInvalidCastLabel);
            XS.Call(LabelName.Get(ExceptionHelperRefs.ThrowInvalidCastExceptionRef));
        }
Beispiel #6
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);
        }
Beispiel #7
0
 protected static void DoNullReferenceCheck(Assembler.Assembler assembler, bool debugEnabled, int stackOffsetToCheck)
 {
     if (stackOffsetToCheck != SignedAlign(stackOffsetToCheck, 4))
     {
         throw new Exception("Stack offset not aligned!");
     }
     if (debugEnabled)
     {
         if (!CompilerEngine.UseGen3Kernel)
         {
             XS.Compare(XSRegisters.ESP, 0, destinationDisplacement: (int)stackOffsetToCheck);
             XS.Jump(CPU.ConditionalTestEnum.NotEqual, ".AfterNullCheck");
             XS.ClearInterruptFlag();
             // don't remove the call. It seems pointless, but we need it to retrieve the EIP value
             XS.Call(".NullCheck_GetCurrAddress");
             XS.Label(".NullCheck_GetCurrAddress");
             XS.Pop(XSRegisters.EAX);
             new CPU.Mov
             {
                 DestinationRef        = ElementReference.New("DebugStub_CallerEIP"),
                 DestinationIsIndirect = true,
                 SourceReg             = CPU.RegistersEnum.EAX
             };
             XS.Call("DebugStub_SendNullReferenceOccurred");
         }
         XS.Halt();
         XS.Label(".AfterNullCheck");
     }
 }
Beispiel #8
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();
        }
Beispiel #9
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);
            }
        }
Beispiel #10
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            XS.Pop(XSRegisters.ECX); // shift amount
            var xStackItem_ShiftAmount = aOpCode.StackPopTypes[0];
            var xStackItem_Value       = aOpCode.StackPopTypes[1];
            var xStackItem_Value_Size  = SizeOfType(xStackItem_Value);

#if DOTNETCOMPATIBLE
            if (xStackItem_Value.Size == 4)
#else
            if (xStackItem_Value_Size <= 4)
#endif
            {
                XS.ShiftLeft(XSRegisters.ESP, XSRegisters.CL, destinationIsIndirect: true, size: RegisterSize.Int32);
            }
#if DOTNETCOMPATIBLE
            else if (xStackItem_Value.Size == 8)
#else
            else if (xStackItem_Value_Size <= 8)
#endif
            {
                string BaseLabel     = GetLabel(aMethod, aOpCode) + ".";
                string LowPartIsZero = BaseLabel + "LowPartIsZero";
                string End_Shl       = BaseLabel + "End_Shl";

                // [ESP] is low part
                // [ESP + 4] is high part

                // move low part to eax
                XS.Set(EAX, ESP, sourceIsIndirect: true);

                XS.Compare(XSRegisters.CL, 32, size: RegisterSize.Byte8);
                XS.Jump(CPUx86.ConditionalTestEnum.AboveOrEqual, LowPartIsZero);

                // shift higher part
                XS.ShiftLeftDouble(ESP, EAX, CL, destinationDisplacement: 4);
                // shift lower part
                // To retain the sign bit we must use ShiftLeftArithmetic and not ShiftLeft!
                XS.ShiftLeftArithmetic(XSRegisters.ESP, XSRegisters.CL, destinationIsIndirect: true, size: RegisterSize.Int32);
                XS.Jump(End_Shl);

                XS.Label(LowPartIsZero);
                // remove bits >= 32, so that CL max value could be only 31
                XS.And(XSRegisters.CL, 0x1f, size: RegisterSize.Byte8);
                // shift low part in EAX and move it in high part
                // To retain the sign bit we must use ShiftLeftArithmetic and not ShiftLeft!
                XS.ShiftLeftArithmetic(EAX, CL);
                XS.Set(ESP, EAX, destinationDisplacement: 4);
                // replace unknown low part with a zero, if <= 32
                XS.Set(XSRegisters.ESP, 0, destinationIsIndirect: true);

                XS.Label(End_Shl);
            }
            else
            {
                throw new NotSupportedException("A size bigger 8 not supported at Shl!");
            }
        }
        public void CreateIDT()
        {
            new Comment(this, "BEGIN - Create IDT");

            // Create IDT
            UInt16 xIdtSize = 8 * 256;

            DataMembers.Add(new DataMember("_NATIVE_IDT_Contents", new byte[xIdtSize]));

            //
            if (mComPort > 0)
            {
                if (!CompilerEngine.UseGen3Kernel)
                {
                    SetIdtDescriptor(1, "DebugStub_TracerEntry", false);
                    SetIdtDescriptor(3, "DebugStub_TracerEntry", false);
                }

                //for (int i = 0; i < 256; i++)
                //{
                //  if (i == 1 || i == 3)
                //  {
                //    continue;
                //  }

                //  SetIdtDescriptor(i, "DebugStub_Interrupt_" + i.ToString(), true);
                //}
            }

            //SetIdtDescriptor(1, "DebugStub_INT0"); - Change to GPF

            // Set IDT
            DataMembers.Add(new DataMember("_NATIVE_IDT_Pointer", new UInt16[]
            {
                xIdtSize, 0, 0
            }));
            new Mov
            {
                DestinationRef          = ElementReference.New("_NATIVE_IDT_Pointer"),
                DestinationIsIndirect   = true,
                DestinationDisplacement = 2,
                SourceRef = ElementReference.New("_NATIVE_IDT_Contents")
            };

            XS.Set(XSRegisters.EAX, "_NATIVE_IDT_Pointer");

            if (mComPort > 0)
            {
                if (!CompilerEngine.UseGen3Kernel)
                {
                    XS.Set("static_field__Cosmos_Core_CPU_mInterruptsEnabled", 1, destinationIsIndirect: true, size: RegisterSize.Byte8);
                    XS.LoadIdt(XSRegisters.EAX, isIndirect: true);
                }
            }
            XS.Label("AfterCreateIDT");
            new Comment(this, "END - Create IDT");
        }
Beispiel #12
0
        public void CreateGDT()
        {
            new Comment(this, "BEGIN - Create GDT");
            var xGDT = new List <byte>();

            // Null Segment - Selector 0x00
            // Not used, but required by many emulators.
            xGDT.AddRange(new byte[8]
            {
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            });

            // Code Segment
            mGdCode = (byte)xGDT.Count;
            xGDT.AddRange(GdtDescriptor(0x00000000, 0xFFFFFFFF, true));

            // Data Segment - Selector
            mGdData = (byte)xGDT.Count;
            xGDT.AddRange(GdtDescriptor(0x00000000, 0xFFFFFFFF, false));
            DataMembers.Add(new DataMember("_NATIVE_GDT_Contents", xGDT.ToArray()));

            XS.Comment("Tell CPU about GDT");
            var xGdtPtr = new UInt16[3];

            // Size of GDT Table - 1
            xGdtPtr[0] = (UInt16)(xGDT.Count - 1);
            DataMembers.Add(new DataMember("_NATIVE_GDT_Pointer", xGdtPtr));
            new Mov
            {
                DestinationRef          = ElementReference.New("_NATIVE_GDT_Pointer"),
                DestinationIsIndirect   = true,
                DestinationDisplacement = 2,
                SourceRef = ElementReference.New("_NATIVE_GDT_Contents")
            };
            XS.Set(XSRegisters.EAX, "_NATIVE_GDT_Pointer");
            XS.LoadGdt(XSRegisters.EAX, isIndirect: true);

            XS.Comment("Set data segments");
            XS.Set(XSRegisters.EAX, mGdData);
            XS.Set(XSRegisters.DS, XSRegisters.AX);
            XS.Set(XSRegisters.ES, XSRegisters.AX);
            XS.Set(XSRegisters.FS, XSRegisters.AX);
            XS.Set(XSRegisters.GS, XSRegisters.AX);
            XS.Set(XSRegisters.SS, XSRegisters.AX);

            XS.Comment("Force reload of code segment");
            new JumpToSegment
            {
                Segment          = mGdCode,
                DestinationLabel = "Boot_FlushCsGDT"
            };
            XS.Label("Boot_FlushCsGDT");
            new Comment(this, "END - Create GDT");
        }
Beispiel #13
0
 public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
 {
     XS.ClearInterruptFlag();
     XS.Set(XSRegisters.EAX, "_NATIVE_GDT_Pointer");
     XS.LoadGdt(XSRegisters.EAX, isIndirect: true);
     XS.Set(XSRegisters.EAX, XSRegisters.CR0);
     XS.Or(XSRegisters.AL, 1);
     XS.Set(XSRegisters.CR0, XSRegisters.EAX);
     XS.JumpToSegment(0x08, "PMode");
     XS.Label("PMode");
 }
Beispiel #14
0
 public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
 {
     new LiteralAssemblerCode("%ifdef DEBUGSTUB");
     XS.Label(".BeforeArgumentsPrepare");
     new LiteralAssemblerCode("mov EBX, [EBP + 12]");
     new LiteralAssemblerCode("push dword [EBX + 12]");
     new LiteralAssemblerCode("add EBX, 16");
     new LiteralAssemblerCode("push dword EBX");
     XS.Label(".BeforeCall");
     new LiteralAssemblerCode("Call DebugStub_SendText");
     new LiteralAssemblerCode("add ESP, 8");
     new LiteralAssemblerCode("%endif");
 }
Beispiel #15
0
        public void CreateIDT()
        {
            new Comment(this, "BEGIN - Create IDT");

            // Create IDT
            ushort xIdtSize = 8 * 256;

            DataMembers.Add(new DataMember("_NATIVE_IDT_Contents", new byte[xIdtSize]));

            //
            if (mComPort > 0)
            {
                SetIdtDescriptor(1, AsmMarker.Labels[AsmMarker.Type.DebugStub_TracerEntry], false);
                SetIdtDescriptor(3, AsmMarker.Labels[AsmMarker.Type.DebugStub_TracerEntry], false);

                //for (int i = 0; i < 256; i++)
                //{
                //  if (i == 1 || i == 3)
                //  {
                //    continue;
                //  }

                //  SetIdtDescriptor(i, "DebugStub_Interrupt_" + i.ToString(), true);
                //}
            }

            //SetIdtDescriptor(1, "DebugStub_INT0"); - Change to GPF

            // Set IDT
            DataMembers.Add(new DataMember("_NATIVE_IDT_Pointer", new ushort[]
            {
                xIdtSize, 0, 0
            }));
            new Mov
            {
                DestinationRef          = ElementReference.New("_NATIVE_IDT_Pointer"),
                DestinationIsIndirect   = true,
                DestinationDisplacement = 2,
                SourceRef = ElementReference.New("_NATIVE_IDT_Contents")
            };

            XS.Set(EAX, "_NATIVE_IDT_Pointer");

            if (mComPort > 0)
            {
                XS.Set(AsmMarker.Labels[AsmMarker.Type.Processor_IntsEnabled], 1, destinationIsIndirect: true, size: RegisterSize.Byte8);
                XS.LoadIdt(EAX, isIndirect: true);
            }
            XS.Label("AfterCreateIDT");
            new Comment(this, "END - Create IDT");
        }
Beispiel #16
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 );
        }
Beispiel #17
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            string xCurrentMethodLabel = GetLabel(aMethod, aOpCode);
            OpType xType   = ( OpType )aOpCode;
            string xTypeID = GetTypeIDLabel(xType.Value);

            //mTypeId = GetService<IMetaDataInfoService>().GetTypeIdLabel( mCastAsType );
            // todo: throw an exception when the class does not support the cast!
            string mReturnNullLabel = xCurrentMethodLabel + "_ReturnNull";

            XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true);
            XS.Compare(XSRegisters.EAX, 0);
            XS.Jump(CPU.ConditionalTestEnum.Zero, mReturnNullLabel);

            XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true);
            XS.Push(XSRegisters.EAX, isIndirect: true);
            XS.Push(xTypeID, isIndirect: true);
            MethodBase xMethodIsInstance = VTablesImplRefs.IsInstanceRef;

            // new OpMethod( ILOpCode.Code.Call, 0, 0, xMethodIsInstance, aOpCode.CurrentExceptionHandler ) );
            Call.DoExecute(Assembler, aMethod, xMethodIsInstance, aOpCode, xCurrentMethodLabel, xCurrentMethodLabel + "_After_IsInstance_Call", DebugEnabled);
            XS.Label(xCurrentMethodLabel + "_After_IsInstance_Call");
            XS.Pop(XSRegisters.EAX);
            XS.Compare(XSRegisters.EAX, 0);
            XS.Jump(CPU.ConditionalTestEnum.Equal, mReturnNullLabel);
            new CPU.Jump {
                DestinationLabel = GetLabel(aMethod, aOpCode.NextPosition)
            };

            XS.Label(mReturnNullLabel);
            XS.Add(XSRegisters.ESP, 4);
            //string xAllocInfoLabelName = LabelName.Get( GCImplementationRefs.AllocNewObjectRef );
#warning 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 );
        }
Beispiel #18
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);
            }
        }
Beispiel #19
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);
            }
        }
Beispiel #20
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);
        }
Beispiel #21
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            DoNullReferenceCheck(Assembler, DebugEnabled, 0);
            var    xType            = ((OpType)aOpCode).Value;
            string xBaseLabel       = GetLabel(aMethod, aOpCode) + ".";
            string xTypeID          = GetTypeIDLabel(xType);
            uint   xTypeSize        = SizeOfType(xType);
            string mReturnNullLabel = xBaseLabel + "_ReturnNull";

            XS.Compare(XSRegisters.ESP, 0, destinationIsIndirect: true);
            XS.Jump(CPU.ConditionalTestEnum.Zero, mReturnNullLabel);

            XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true);
            XS.Push(XSRegisters.EAX, isIndirect: true);
            XS.Push(xTypeID, isIndirect: true);
            XS.Push(Convert.ToUInt32(xType.IsInterface));
            Call.DoExecute(Assembler, aMethod, VTablesImplRefs.IsInstanceRef, aOpCode, GetLabel(aMethod, aOpCode), xBaseLabel + "_After_IsInstance_Call", DebugEnabled);

            XS.Label(xBaseLabel + "_After_IsInstance_Call");
            XS.Pop(XSRegisters.EAX);
            XS.Compare(XSRegisters.EAX, 0);
            XS.Jump(CPU.ConditionalTestEnum.Equal, mReturnNullLabel);
            XS.Pop(XSRegisters.EAX);
            uint xSize = xTypeSize;

            if (xSize % 4 > 0)
            {
                xSize += 4 - (xSize % 4);
            }
            int xItems = (int)xSize / 4;

            for (int i = xItems - 1; i >= 0; i--)
            {
                new CPU.Push {
                    DestinationReg = CPU.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ((i * 4) + ObjectUtils.FieldDataOffset)
                };
            }
            new CPU.Jump {
                DestinationLabel = GetLabel(aMethod, aOpCode.NextPosition)
            };
            XS.Label(mReturnNullLabel);
            XS.Add(XSRegisters.ESP, 4);
            XS.Push(0);
        }
Beispiel #22
0
        public static void Assemble(XSharp.Assembler.Assembler aAssembler, OpType aOpType, uint aElementSize, bool debugEnabled, _MethodInfo aMethod, ILOpCode aOpCode)
        {
            XS.Comment("Arraytype: " + aOpType.StackPopTypes.Last().FullName);
            XS.Comment("Size: " + aElementSize);

            DoNullReferenceCheck(aAssembler, debugEnabled, 8);

            //Do check for index out of range
            var xBaseLabel = GetLabel(aMethod, aOpCode);
            var xNoIndexOutOfRangeExeptionLabel = xBaseLabel + "_NoIndexOutOfRangeException";
            var xIndexOutOfRangeExeptionLabel   = xBaseLabel + "_IndexOutOfRangeException";

            XS.Pop(EBX);                                     //get Position _, array, 0, index -> _, array, 0
            XS.Push(ESP, true, 4);                           // _, array, 0 => _, array, 0, array
            XS.Push(ESP, true, 12);                          // _, array, 0, array => _, array, 0, array, 0
            Ldlen.Assemble(aAssembler, debugEnabled, false); // _, array, 0, array, 0 -> _, array, 0, length
            XS.Pop(EAX);                                     //Length of array _, array, 0, length -> _, array, 0
            XS.Compare(EAX, EBX);
            XS.Jump(CPUx86.ConditionalTestEnum.LessThanOrEqualTo, xIndexOutOfRangeExeptionLabel);

            XS.Compare(EBX, 0);
            XS.Jump(CPUx86.ConditionalTestEnum.GreaterThanOrEqualTo, xNoIndexOutOfRangeExeptionLabel);

            XS.Label(xIndexOutOfRangeExeptionLabel);
            XS.Pop(EAX);
            XS.Pop(EAX);
            Call.DoExecute(aAssembler, aMethod, ExceptionHelperRefs.ThrowIndexOutOfRangeException, aOpCode, xNoIndexOutOfRangeExeptionLabel, debugEnabled);

            XS.Label(xNoIndexOutOfRangeExeptionLabel);
            XS.Push(EBX); //_, array, 0 -> _, array, 0, index

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

            // pop the array now
            XS.Add(ESP, 4);
            XS.Pop(EDX);

            XS.Add(EDX, EAX);
            XS.Push(EDX);
        }
Beispiel #23
0
 public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.ClearDirectionFlag();
     XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 0xC); //address
     XS.Set(XSRegisters.ECX, XSRegisters.EBP, sourceDisplacement: 0x8); //length
     // set EAX to value of fill (zero)
     XS.Xor(XSRegisters.EAX, XSRegisters.EAX);
     XS.ShiftRight(XSRegisters.ECX, 1);
     XS.Jump(Assembler.x86.ConditionalTestEnum.NotBelow, ".step2");
     XS.StoreByteInString();
     XS.Label(".step2");
     XS.ShiftRight(XSRegisters.ECX, 1);
     XS.Jump(Assembler.x86.ConditionalTestEnum.NotBelow, ".step3");
     XS.StoreWordInString();
     XS.Label(".step3");
     new Assembler.x86.Stos {
         Size = 32, Prefixes = Assembler.x86.InstructionPrefixes.Repeat
     };
 }
Beispiel #24
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xType = (ILOpCodes.OpType)aOpCode;

            uint xSize = SizeOfType(xType.Value.GetElementType() ?? xType.Value);

            string     xTypeID   = GetTypeIDLabel(xType.Value.GetElementType() ?? xType.Value);
            MethodBase xCtor     = typeof(Array).GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)[0];
            string     xCtorName = LabelName.Get(xCtor);

            XS.Comment("Element Size = " + xSize);
            XS.Pop(EAX); // element count
            XS.Push(EAX);
            XS.Set(EDX, xSize);
            XS.Multiply(EDX);                             // total element size
            XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // total array size
            XS.Push(EAX);
            //XS.Push(0x4E3A44A9);
            //XS.LiteralCode("Call DebugStub_SendSimpleNumber");
            //XS.Pop(EAX);
            //XS.Push(".AfterAlloc");
            //XS.LiteralCode("Call DebugStub_SendSimpleNumber");
            //XS.Pop(EAX);
            XS.Call(LabelName.Get(GCImplementationRefs.AllocNewObjectRef));
            XS.Label(".AfterAlloc");
            XS.Pop(EAX); // location
            //XS.LiteralCode("Call DebugStub_SendSimpleNumber");
            XS.Pop(ESI); // element count
            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);    // element count
            XS.Set(EAX, xSize, destinationDisplacement: 12, destinationIsIndirect: true); // element size
            XS.Push(0);
            XS.Call(xCtorName);
            XS.Push(0);
        }
Beispiel #25
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            string xBaseLabel             = GetLabel(aMethod, aOpCode) + ".";
            var    xStackItem_ShiftAmount = aOpCode.StackPopTypes[0];
            var    xStackItem_Value       = aOpCode.StackPopTypes[1];

            if (TypeIsFloat(xStackItem_Value))
            {
                throw new NotImplementedException("Floats not yet supported!");
            }
            var xStackItem_Value_Size = SizeOfType(xStackItem_Value);

            if (xStackItem_Value_Size <= 4)
            {
                XS.Pop(XSRegisters.EAX); // shift amount
                XS.Pop(XSRegisters.EBX); // value
                XS.Set(XSRegisters.CL, XSRegisters.AL);
                XS.ShiftRight(XSRegisters.EBX, CL);
                XS.Push(XSRegisters.EBX);
                return;
            }
            if (xStackItem_Value_Size <= 8)
            {
                XS.Pop(XSRegisters.EDX);
                XS.Set(XSRegisters.EAX, 0);
                XS.Label(xBaseLabel + "__StartLoop");
                XS.Compare(XSRegisters.EDX, XSRegisters.EAX);
                XS.Jump(CPUx86.ConditionalTestEnum.Equal, xBaseLabel + "__EndLoop");
                XS.Set(EBX, ESP, sourceIsIndirect: true);
                XS.Set(XSRegisters.CL, 1);
                XS.ShiftRight(XSRegisters.EBX, CL);
                XS.Set(ESP, EBX, destinationIsIndirect: true);
                XS.Set(XSRegisters.CL, 1);
                XS.RotateThroughCarryRight(ESP, CL, destinationDisplacement: 4, size: RegisterSize.Int32);
                XS.Add(XSRegisters.EAX, 1);
                new CPUx86.Jump {
                    DestinationLabel = xBaseLabel + "__StartLoop"
                };

                XS.Label(xBaseLabel + "__EndLoop");
                return;
            }
        }
Beispiel #26
0
        public static void CheckOverflowForSmall(uint xResultSize, bool xSourceIsSigned, bool xResultIsSigned, Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode, string xSuccessLabel, string xOverflowLabel)
        {
            XS.Set(EAX, ESP, sourceIsIndirect: true);
            // only look at bits which are part of result
            // normally check that they are all either 0 or 1
            // if same size but casting between signed and unsigned, then first bit must be zero
            byte bitCount = (byte)((xResultSize) * 8 - 1);

            XS.ShiftRight(EAX, bitCount);
            XS.Compare(EAX, 0);
            XS.Jump(ConditionalTestEnum.Equal, xSuccessLabel);
            if (xSourceIsSigned)
            {
                if (xResultIsSigned)
                {
                    XS.Not(EAX); // if negative then all must be 1s
                    XS.Compare(EAX, 0);
                    XS.Jump(ConditionalTestEnum.Equal, xSuccessLabel);
                }
                else
                {
                    XS.Jump(xOverflowLabel);
                }
            }
            else // source was unsigned
            {
                if (xResultIsSigned)
                {
                    XS.Jump(xOverflowLabel); //too big
                }
                else
                {
                    XS.Compare(EAX, 1); // only lowest bit is set, which is heighest of next
                    XS.Jump(ConditionalTestEnum.Equal, xSuccessLabel);
                }
            }
            XS.Label(xOverflowLabel);
            XS.Pop(EAX); // clear stack
            Call.DoExecute(assembler, aMethod, ExceptionHelperRefs.ThrowOverflowExceptionRef, aOpCode, xSuccessLabel, false);
            XS.Label(xSuccessLabel);
        }
Beispiel #27
0
        // unsafe private static void Copy128Bytes(byte* dest, byte* src, int blocksNum)
        public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
        {
            XS.Comment("CALLED!");

            // Copy Src to ESI
            XS.Set(ESI, EBP, sourceIsIndirect: true, sourceDisplacement: SrcDisplacement);
            // Copy Dst to EDI
            XS.Set(EDI, EBP, sourceIsIndirect: true, sourceDisplacement: DestDisplacement);
            // Copy BlocksNum to ECX
            XS.Set(ECX, EBP, sourceDisplacement: BlocksNumDisplacement);

            /* Do the 'loop' */
            XS.Label(".loop");

            // move 128 bytes of src to 8 XMM register

            XS.SSE.MoveDQU(XMM0, ESI, sourceIsIndirect: true);
            XS.SSE.MoveDQU(XMM1, ESI, sourceIsIndirect: true, sourceDisplacement: 16);
            XS.SSE.MoveDQU(XMM2, ESI, sourceIsIndirect: true, sourceDisplacement: 32);
            XS.SSE.MoveDQU(XMM3, ESI, sourceIsIndirect: true, sourceDisplacement: 48);
            XS.SSE.MoveDQU(XMM4, ESI, sourceIsIndirect: true, sourceDisplacement: 64);
            XS.SSE.MoveDQU(XMM5, ESI, sourceIsIndirect: true, sourceDisplacement: 80);
            XS.SSE.MoveDQU(XMM6, ESI, sourceIsIndirect: true, sourceDisplacement: 96);
            XS.SSE.MoveDQU(XMM7, ESI, sourceIsIndirect: true, sourceDisplacement: 112);

            // move 128 bytes from the 8 XMM registers to dest
            XS.SSE.MoveDQU(EDI, XMM0, destinationIsIndirect: true);
            XS.SSE.MoveDQU(EDI, XMM1, destinationIsIndirect: true, destinationDisplacement: 16);
            XS.SSE.MoveDQU(EDI, XMM2, destinationIsIndirect: true, destinationDisplacement: 32);
            XS.SSE.MoveDQU(EDI, XMM3, destinationIsIndirect: true, destinationDisplacement: 48);
            XS.SSE.MoveDQU(EDI, XMM4, destinationIsIndirect: true, destinationDisplacement: 64);
            XS.SSE.MoveDQU(EDI, XMM5, destinationIsIndirect: true, destinationDisplacement: 80);
            XS.SSE.MoveDQU(EDI, XMM6, destinationIsIndirect: true, destinationDisplacement: 96);
            XS.SSE.MoveDQU(EDI, XMM7, destinationIsIndirect: true, destinationDisplacement: 112);

            XS.Add(ESI, 128);
            XS.Add(EDI, 128);
            XS.Sub(ECX, 1);

            XS.Jump(ConditionalTestEnum.NotZero, ".loop");
        }
Beispiel #28
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            //TODO: What if the last ILOp in a method was Conv_Ovf_I_Un or an other?
            var xSource        = aOpCode.StackPopTypes[0];
            var xSourceSize    = SizeOfType(xSource);
            var xSourceIsFloat = TypeIsFloat(xSource);

            if (xSourceIsFloat)
            {
                ThrowNotImplementedException("Conv_Ovf_I_Un throws an ArgumentException, because float is not implemented!");
            }

            switch (xSourceSize)
            {
            case 1:
            case 2:
            case 4:
                break;

            case 8:
            {
                string NoOverflowLabel = GetLabel(aMethod, aOpCode) + "__NoOverflow";
                XS.Pop(XSRegisters.EAX);
                // EBX is high part and should be zero for unsigned, so we test it on zero
                {
                    XS.Pop(XSRegisters.EBX);
                    XS.Compare(XSRegisters.EBX, 0);
                    XS.Jump(CPUx86.ConditionalTestEnum.Equal, NoOverflowLabel);
                    ThrowNotImplementedException("Conv_Ovf_I_Un throws an overflow exception, which is not implemented!");
                }
                XS.Label(NoOverflowLabel);
                XS.Push(XSRegisters.EAX);
                break;
            }

            default:
                ThrowNotImplementedException("Conv_Ovf_I_Un not implemented for this size!");
                break;
            }
        }
Beispiel #29
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->Add_Ovf.cs->Error: Expected signed 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.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.Add(ESP, EDX, destinationIsIndirect: true);
                    XS.AddWithCarry(ESP, EAX, destinationDisplacement: 4);
                }
                else //integer
                {
                    XS.Pop(EAX);
                    XS.Add(ESP, EAX, destinationIsIndirect: true);
                }

                // Let's check if we add overflow and if so throw OverflowException
                XS.Jump(ConditionalTestEnum.NoOverflow, xSuccessLabel);
                ThrowOverflowException();
                XS.Label(xSuccessLabel);
            }
        }
Beispiel #30
0
        public static void DoExecute(uint xSourceSize, bool SourceIsSigned, Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xBaseLabel    = GetLabel(aMethod, aOpCode) + ".";
            var xSuccessLabel = xBaseLabel + "Success";

            switch (xSourceSize)
            {
            case 1:
            case 2:
            case 4:
                XS.Pop(EAX);
                XS.SignExtendAX(RegisterSize.Int32);
                XS.Push(EDX);
                XS.Push(EAX);
                break;

            case 8:
                if (SourceIsSigned)
                {
                    XS.Set(EAX, ESP, sourceIsIndirect: true);
                    XS.And(EAX, 0b1000000000000000000000000000);
                    XS.Compare(EAX, 0);
                    XS.Jump(XSharp.Assembler.x86.ConditionalTestEnum.Equal, xSuccessLabel);
                    XS.Pop(EAX); // remove long from stack
                    XS.Pop(EAX);
                    Call.DoExecute(assembler, aMethod, ExceptionHelperRefs.ThrowOverflowExceptionRef, aOpCode, xSuccessLabel, false);
                    XS.Label(xSuccessLabel);
                }
                else
                {
                    XS.Noop();
                }
                break;

            default:
                throw new NotImplementedException();
            }
        }