Beispiel #1
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, _MethodInfo aMethod, ushort aParam)
        {
            var  xDisplacement = GetArgumentDisplacement(aMethod, aParam);
            var  xType         = GetArgumentType(aMethod, aParam);
            uint xArgRealSize  = SizeOfType(xType);
            uint xArgSize      = Align(xArgRealSize, 4);

            XS.Comment("Arg idx = " + aParam);
            XS.Comment("Arg type = " + xType);
            XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);
            if (xArgRealSize < 4)
            {
                if (xArgRealSize == 1)
                {
                    XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: xDisplacement, size: RegisterSize.Byte8);
                }
                else
                {
                    XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: xDisplacement, size: RegisterSize.Short16);
                }
                XS.Push(EAX);
            }
            else
            {
                for (int i = 0; i < (xArgSize / 4); i++)
                {
                    XS.Push(EBP, isIndirect: true, displacement: (xDisplacement - (i * 4)));
                }
            }
        }
Beispiel #2
0
        public static void DoExecute(XSharp.Assembler.Assembler Assembler, _MethodInfo aMethod, ushort aParam)
        {
            var  xDisplacement = GetArgumentDisplacement(aMethod, aParam);
            var  xType         = GetArgumentType(aMethod, aParam);
            uint xArgRealSize  = SizeOfType(xType);
            uint xArgSize      = Align(xArgRealSize, 4);

            XS.Comment("Arg idx = " + aParam);
            XS.Comment("Arg type = " + xType);
            XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);
            if (IsIntegralType(xType) && xArgRealSize == 1 || xArgRealSize == 2)
            {
                if (TypeIsSigned(xType))
                {
                    XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: xDisplacement, size: (RegisterSize)(8 * xArgRealSize));
                }
                else
                {
                    XS.MoveZeroExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: xDisplacement, size: (RegisterSize)(8 * xArgRealSize));
                }

                XS.Push(EAX);
            }
            else
            {
                for (int i = 0; i < (xArgSize / 4); i++)
                {
                    XS.Push(EBP, isIndirect: true, displacement: (xDisplacement - (i * 4)));
                }
            }
        }
Beispiel #3
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);
                    }
                }
            }
        }
Beispiel #4
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aMethod, ushort aParam)
        {
            var  xDisplacement = GetArgumentDisplacement(aMethod, aParam);
            var  xType         = GetArgumentType(aMethod, aParam);
            uint xArgRealSize  = SizeOfType(xType);
            uint xArgSize      = Align(xArgRealSize, 4);

            XS.Comment("Arg idx = " + aParam);
            XS.Comment("Arg type = " + xType);
            XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);
            if (xArgRealSize < 4)
            {
                new MoveSignExtend
                {
                    DestinationReg     = RegistersEnum.EAX,
                    Size               = (byte)(xArgRealSize * 8),
                    SourceReg          = RegistersEnum.EBP,
                    SourceIsIndirect   = true,
                    SourceDisplacement = xDisplacement
                };
                XS.Push(XSRegisters.EAX);
            }
            else
            {
                for (int i = 0; i < (xArgSize / 4); i++)
                {
                    XS.Push(XSRegisters.EBP, isIndirect: true, displacement: (xDisplacement - (i * 4)));
                }
            }
        }
Beispiel #5
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);
        }
Beispiel #6
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 #7
0
        public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
        {
            // method signature: $this, object @object, IntPtr method
            var xAssembler  = aAssembler;
            var xMethodInfo = (_MethodInfo)aMethodInfo;

            XS.Comment("Save target ($this) to field");
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 1");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 1);
            XS.Comment("-- stfld _target");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.Object System.Delegate._target", xMethodInfo.MethodBase.DeclaringType, true, false);
            XS.Comment("Save method pointer to field");
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 2");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 2);
            XS.Comment("-- stfld _methodPtr");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.IntPtr System.Delegate._methodPtr", xMethodInfo.MethodBase.DeclaringType, true, false);
            XS.Comment("Saving ArgSize to field");
            uint xSize = 0;

            foreach (var xArg in xMethodInfo.MethodBase.DeclaringType.GetMethod("Invoke").GetParameters())
            {
                xSize += ILOp.Align(ILOp.SizeOfType(xArg.ParameterType), 4);
            }

            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- push argsize");
            XS.Push(xSize);
            XS.Comment("-- stfld ArgSize");
            Stfld.DoExecute(xAssembler, xMethodInfo, "$$ArgSize$$", xMethodInfo.MethodBase.DeclaringType, true, false);
        }
        // unsafe private static void Copy64Bytes(byte* dest, byte* src)
        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);

            // move 128 bytes of src to 8 XMM register
            // move first 16 bytes of data from src to registers
            XS.SSE.MoveDQU(XMM0, ESI, sourceIsIndirect: true);
            // move second 16 bytes of data from src to registers
            XS.SSE.MoveDQU(XMM1, ESI, sourceIsIndirect: true, sourceDisplacement: 16);
            // move third 16 bytes of data from src to registers
            XS.SSE.MoveDQU(XMM2, ESI, sourceIsIndirect: true, sourceDisplacement: 32);
            // move fourth 16 bytes of data from src to registers
            XS.SSE.MoveDQU(XMM3, ESI, sourceIsIndirect: true, sourceDisplacement: 48);

            // move data from 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);
        }
Beispiel #9
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpCode = (ILOpCodes.OpField)aOpCode;
            var xField  = xOpCode.Value;

            XS.Comment("Operand type: " + aOpCode.StackPopTypes[1].ToString());
            DoExecute(Assembler, aMethod, xField, DebugEnabled, TypeIsReferenceType(aOpCode.StackPopTypes[1]));
        }
Beispiel #10
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 #11
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpVar      = (OpVar)aOpCode;
            var xVar        = aMethod.MethodBase.GetMethodBody().LocalVariables[xOpVar.Value];
            var xStackCount = GetStackCountForLocal(aMethod, xVar);
            var xEBPOffset  = ((int)GetEBPOffsetForLocal(aMethod, xOpVar.Value));
            var xSize       = SizeOfType(xVar.LocalType);

            XS.Comment("EBPOffset = " + xEBPOffset);
            if (xStackCount > 1)
            {
                for (int i = 0; i < xStackCount; i++)
                {
                    XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: (int)(0 - (xEBPOffset + (i * 4))));
                    XS.Push(XSRegisters.EAX);
                }
            }
            else
            {
                switch (xSize)
                {
                case 1:
                case 2:
                {
                    bool signed = IsIntegerSigned(xVar.LocalType);
                    if (signed)
                    {
                        new CPUx86.MoveSignExtend {
                            DestinationReg = CPUx86.RegistersEnum.EAX, Size = (byte)(xSize * 8), SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset
                        }
                    }
                    ;
                    else
                    {
                        new CPUx86.MoveZeroExtend {
                            DestinationReg = CPUx86.RegistersEnum.EAX, Size = (byte)(xSize * 8), SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset
                        }
                    };
                    XS.Push(XSRegisters.EAX);
                    break;
                }

                case 4:
                {
                    new CPUx86.Push {
                        DestinationReg = CPUx86.RegistersEnum.EBP, DestinationIsIndirect = true, DestinationDisplacement = 0 - xEBPOffset
                    };
                    break;
                }
                }
            }
        }
Beispiel #12
0
        private void DoExecute(Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled)
        {
            var xType = aTargetType.Value;

            XS.Comment($"Type = {aTargetType.Value}");
            if (xType.GetTypeInfo().BaseType == typeof(ValueType))
            {
            }
            else if (xType.GetTypeInfo().BaseType == typeof(object))
            {
                throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}");
            }
        }
Beispiel #13
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);
        }
Beispiel #14
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xField     = aOpCode as ILOpCodes.OpVar;
            var xFieldInfo = aMethod.MethodBase.GetMethodBody().LocalVariables[xField.Value];
            var xEBPOffset = ((int)GetEBPOffsetForLocal(aMethod, xField.Value));

            XS.Comment("EBPOffset = " + xEBPOffset);
            for (int i = (int)GetStackCountForLocal(aMethod, xFieldInfo) - 1; i >= 0; i--)
            {
                XS.Pop(XSRegisters.EAX);
                XS.Set(XSRegisters.EBP, XSRegisters.EAX, destinationDisplacement: (int)((0 - (xEBPOffset + (i * 4)))));
            }
        }
Beispiel #15
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, int aSize, bool debugEnabled)
        {
            int xAlignedSize = (int)Align((uint)aSize, 4);

            XS.Comment("address at: [esp]");
            DoNullReferenceCheck(aAssembler, debugEnabled, 0);

            XS.Pop(XSRegisters.EAX);
            for (int i = xAlignedSize - 4; i >= 0; i -= 4)
            {
                XS.Push(XSRegisters.EAX, isIndirect: true, displacement: i);
            }
        }
Beispiel #16
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aMethod, ushort aParam)
        {
            var  xDisplacement = GetArgumentDisplacement(aMethod, aParam);
            Type xArgType;

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

            XS.Comment("Arg idx = " + aParam);
            uint xArgRealSize = SizeOfType(xArgType);
            uint xArgSize     = Align(xArgRealSize, 4);

            XS.Comment("Arg type = " + xArgType.ToString());
            XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);
            if (xArgRealSize < 4)
            {
                new CPUx86.MoveSignExtend {
                    DestinationReg = CPUx86.RegistersEnum.EAX, Size = (byte)(xArgRealSize * 8), SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = xDisplacement
                };
                XS.Push(XSRegisters.EAX);
            }
            else
            {
                for (int i = 0; i < (xArgSize / 4); i++)
                {
                    new Push
                    {
                        DestinationReg          = RegistersEnum.EBP,
                        DestinationIsIndirect   = true,
                        DestinationDisplacement = xDisplacement - (i * 4)
                    };
                }
            }
        }
Beispiel #17
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 ]");
        }
Beispiel #18
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
#if false
            var xOpVar = (OpVar)aOpCode;

            var xDisplacement = Ldarg.GetArgumentDisplacement(aMethod, xOpVar.Value);

            /*
             * The function GetArgumentDisplacement() does not give the correct displacement for the Ldarga opcode
             * we need to "fix" it subtracting the argSize and 4
             */
            Type xArgType;
            if (aMethod.MethodBase.IsStatic)
            {
                xArgType = aMethod.MethodBase.GetParameters()[xOpVar.Value].ParameterType;
            }
            else
            {
                if (xOpVar.Value == 0u)
                {
                    xArgType = aMethod.MethodBase.DeclaringType;
                    if (xArgType.IsValueType)
                    {
                        xArgType = xArgType.MakeByRefType();
                    }
                }
                else
                {
                    xArgType = aMethod.MethodBase.GetParameters()[xOpVar.Value - 1].ParameterType;
                }
            }

            uint xArgRealSize = SizeOfType(xArgType);
            uint xArgSize     = Align(xArgRealSize, 4);
            XS.Comment("Arg type = " + xArgType.ToString());
            XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);

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

            XS.Set(XSRegisters.EBX, (uint)(xDisplacement));
            XS.Set(XSRegisters.EAX, XSRegisters.EBP);
            XS.Add(XSRegisters.EAX, XSRegisters.EBX);
            XS.Push(XSRegisters.EAX);
#endif

            var xOpVar = (OpVar)aOpCode;
            DoExecute(Assembler, aMethod, xOpVar.Value);
        }
Beispiel #19
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpVar     = (OpVar)aOpCode;
            var xVar       = aMethod.MethodBase.GetLocalVariables()[xOpVar.Value];
            var xEBPOffset = GetEBPOffsetForLocal(aMethod, xOpVar.Value);

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

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

            XS.Set(EAX, EBP);
            XS.Sub(EAX, xEBPOffset);
            XS.Push(EAX);
        }
Beispiel #20
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, int aSize, bool debugEnabled)
        {
            int xAlignedSize = (int)Align((uint)aSize, 4);

            XS.Comment($"address at: [esp+{xAlignedSize}]");
            DoNullReferenceCheck(aAssembler, debugEnabled, xAlignedSize);

            XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true, sourceDisplacement: xAlignedSize);
            for (int i = 0; i < xAlignedSize; i += 4)
            {
                XS.Pop(XSRegisters.EBX);
                XS.Set(XSRegisters.EAX, XSRegisters.EBX, destinationIsIndirect: true, destinationDisplacement: i);
            }
            XS.Add(XSRegisters.ESP, 4);
        }
Beispiel #21
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var  xOpVar      = (OpVar)aOpCode;
            var  xVar        = aMethod.MethodBase.GetLocalVariables()[xOpVar.Value];
            var  xStackCount = (int)GetStackCountForLocal(aMethod, xVar.LocalType);
            var  xEBPOffset  = (int)GetEBPOffsetForLocal(aMethod, xOpVar.Value);
            var  xSize       = SizeOfType(xVar.LocalType);
            bool xSigned     = IsIntegerSigned(xVar.LocalType);

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

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

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

            default:
                for (int i = 0; i < xStackCount; i++)
                {
                    XS.Set(EAX, EBP, sourceDisplacement: 0 - (xEBPOffset + (i * 4)));
                    XS.Push(EAX);
                }
                break;
            }
        }
Beispiel #22
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);

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

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

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

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

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

            XS.Set(XSRegisters.EAX, XSRegisters.EBP);
            XS.Set(XSRegisters.EBX, (uint)(xDisplacement));
            XS.Add(XSRegisters.EAX, XSRegisters.EBX);
            XS.Push(XSRegisters.EAX);
        }
Beispiel #23
0
        public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
        {
            // method signature: $this, object @object, IntPtr method
            var xMethodInfo = (MethodInfo)aMethodInfo;
            var xAssembler  = (NewAssembler)aAssembler;

            XS.Comment("Save target ($this) to field");
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            //Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 1");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 1);
            XS.Comment("-- stfld _target");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.Object System.Delegate._target", xMethodInfo.MethodBase.DeclaringType, true, false);
            XS.Comment("Save method pointer to field");
            //Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 2");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 2);
            XS.Comment("-- stfld _methodPtr");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.IntPtr System.Delegate._methodPtr", xMethodInfo.MethodBase.DeclaringType, true, false);
            XS.Comment("Saving ArgSize to field");
            uint xSize = 0;

            foreach (var xArg in xMethodInfo.MethodBase.DeclaringType.GetMethod("Invoke").GetParameters())
            {
                xSize += ILOp.Align(ILOp.SizeOfType(xArg.ParameterType), 4);
            }
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            if (xMethodInfo.MethodBase.DeclaringType.FullName.Contains("InterruptDelegate"))
            {
                Console.Write("");
            }
            XS.Comment("-- push argsize");
            XS.Push(xSize);
            XS.Comment("-- stfld ArgSize");
            Stfld.DoExecute(xAssembler, xMethodInfo, "$$ArgSize$$", xMethodInfo.MethodBase.DeclaringType, true, false);


            //public static void Ctor(Delegate aThis, object aObject, IntPtr aMethod,
            //[FieldAccess(Name = "System.Object System.Delegate._target")] ref object aFldTarget,
            //[FieldAccess(Name = "System.IntPtr System.Delegate._methodPtr")] ref IntPtr aFldMethod) {
        }
Beispiel #24
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpVar      = (OpVar)aOpCode;
            var xVar        = aMethod.MethodBase.GetMethodBody().LocalVariables[xOpVar.Value];
            var xStackCount = (int)GetStackCountForLocal(aMethod, xVar);
            var xEBPOffset  = (int)GetEBPOffsetForLocal(aMethod, xOpVar.Value);
            var xSize       = SizeOfType(xVar.LocalType);

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

            for (int i = xStackCount - 1; i >= 0; i--)
            {
                XS.Pop(EAX);
                XS.Set(EBP, EAX, destinationDisplacement: 0 - (xEBPOffset + (i * 4)));
            }
        }
Beispiel #25
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 #26
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 #27
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, 8);
            // calculate element offset into array memory (including header)
            XS.Pop(EAX);
            XS.Set(EDX, aElementSize);
            XS.Multiply(EDX);
            XS.Add(EAX, (uint)(ObjectImpl.FieldDataOffset + 4));

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

            XS.Add(EDX, EAX);
            XS.Push(EDX);
        }
Beispiel #28
0
        public static void DoExecute(XSharp.Assembler.Assembler Assembler, _MethodInfo aMethod, Type aDeclaringType, _FieldInfo aField, bool aDerefValue, bool aDebugEnabled, Type aTypeOnStack)
        {
            XS.Comment("Field: " + aField.Id);
            int xExtraOffset = 0;

            bool xNeedsGC = aDeclaringType.IsClass && !aDeclaringType.IsValueType;

            if (xNeedsGC)
            {
                xExtraOffset = 12;
            }

            if ((!aTypeOnStack.IsPointer) && (aDeclaringType.IsClass))
            {
                DoNullReferenceCheck(Assembler, aDebugEnabled, 4);
                XS.Add(ESP, 4);
            }
            else
            {
                DoNullReferenceCheck(Assembler, aDebugEnabled, 0);
            }

            if (aDerefValue && aField.IsExternalValue)
            {
                XS.Set(ESP, EAX, destinationIsIndirect: true);
            }
            else
            {
                XS.Pop(EAX);
                if (aDeclaringType.Name == "RawArrayData" && aField.Field.Name == "Data")
                {
                    // if we accidently load 64bit assemblies, we get an incorrect extra 4 bytes of offset, so we just hardcode the offset
                    XS.Add(EAX, (uint)(4 + xExtraOffset));
                }
                else
                {
                    XS.Add(EAX, (uint)(aField.Offset + xExtraOffset));
                }
                XS.Push(EAX);
            }
        }
Beispiel #29
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xOpVar      = (OpVar)aOpCode;
            var xVar        = aMethod.MethodBase.GetMethodBody().LocalVariables[xOpVar.Value];
            var xStackCount = (int)GetStackCountForLocal(aMethod, xVar);
            var xEBPOffset  = (int)GetEBPOffsetForLocal(aMethod, xOpVar.Value);
            var xSize       = SizeOfType(xVar.LocalType);

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

            switch (xSize)
            {
            case 1:
            case 2:
                bool xSigned = IsIntegerSigned(xVar.LocalType);
                if (xSigned)
                {
                    new CPUx86.MoveSignExtend {
                        DestinationReg = CPUx86.RegistersEnum.EAX, Size = (byte)(xSize * 8), SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = (int)(0 - xEBPOffset)
                    };
                }
                else
                {
                    new CPUx86.MoveZeroExtend {
                        DestinationReg = CPUx86.RegistersEnum.EAX, Size = (byte)(xSize * 8), SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = (int)(0 - xEBPOffset)
                    };
                }
                XS.Push(EAX);
                break;

            default:
                for (int i = 0; i < xStackCount; i++)
                {
                    XS.Set(EAX, EBP, sourceDisplacement: 0 - (xEBPOffset + (i * 4)));
                    XS.Push(EAX);
                }
                break;
            }
        }
Beispiel #30
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");
        }