Beispiel #1
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xType = aOpCode.StackPopTypes[0];
            var xSize = SizeOfType(xType);

            if (xSize <= 4)
            {
                XS.Not(ESP, isIndirect: true, size: RegisterSize.Int32);
            }
            else if (xSize <= 8)
            {
                XS.Not(ESP, isIndirect: true, size: RegisterSize.Int32);
                XS.Not(ESP, displacement: 4, size: RegisterSize.Int32);
            }
            else
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Not.cs->Error: StackSize > 8 not supported");
            }
        }
Beispiel #2
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 #3
0
 public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
 {
     XS.Pop(XSRegisters.EAX);
     XS.Not(XSRegisters.EAX);
     XS.Push(XSRegisters.EAX);
 }
Beispiel #4
0
        public static void CheckOverflowForLong(uint xResultSize, bool xSourceIsSigned, bool xResultIsSigned, Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode, string xSuccessLabel, string xOverflowLabel, string xPositiveLabel, string xNegativeLabel)
        {
            // long is
            // low
            // high
            XS.Set(EAX, ESP, sourceIsIndirect: true, sourceDisplacement: 4); // read high
            if (xSourceIsSigned)
            {
                XS.ShiftRight(EAX, 31); // get highest bit of high to determine sign
                XS.Compare(EAX, 0);
                XS.Jump(ConditionalTestEnum.Equal, xPositiveLabel);
                XS.Compare(EAX, 1);
                XS.Jump(ConditionalTestEnum.Equal, xResultIsSigned ? xNegativeLabel : xOverflowLabel);
            }
            else
            {
                XS.Compare(EAX, 0); // as unsigned high must be positive
                XS.Jump(ConditionalTestEnum.Equal, xPositiveLabel);
            }
            XS.Label(xOverflowLabel);
            XS.Pop(EAX); //remove long from stack
            XS.Pop(EAX);
            Call.DoExecute(assembler, aMethod, ExceptionHelperRefs.ThrowOverflowExceptionRef, aOpCode, xSuccessLabel, false);

            // Positive check
            XS.Label(xPositiveLabel);
            XS.Set(EAX, ESP, sourceIsIndirect: true, sourceDisplacement: 4); // read high to refresh
            XS.Set(EBX, ESP, sourceIsIndirect: true);                        // read low
            XS.Compare(EAX, 0);
            XS.Jump(ConditionalTestEnum.NotEqual, xOverflowLabel);
            if (xResultSize == 4 && !xResultIsSigned)
            {
                XS.Jump(xSuccessLabel);
            }
            else
            {
                var v = xResultSize * 8;
                if (xResultIsSigned)
                {
                    v -= 1;
                }
                XS.ShiftRight(EBX, (byte)v); // now check if low does not overflow
                XS.Compare(EBX, 0);
                XS.Jump(ConditionalTestEnum.NotEqual, xOverflowLabel);
                XS.Jump(xSuccessLabel);
            }

            //Negative check
            if (xSourceIsSigned)
            {
                XS.Label(xNegativeLabel);
                if (!xResultIsSigned)
                {
                    XS.Jump(xOverflowLabel);
                }
                XS.Set(EAX, ESP, sourceIsIndirect: true, sourceDisplacement: 4); // read high to refresh
                XS.Compare(EAX, 0xffff_ffff);                                    // high should be fully set
                XS.Jump(ConditionalTestEnum.NotEqual, xOverflowLabel);
                XS.Set(EBX, ESP, sourceIsIndirect: true);                        // read low
                XS.ShiftRight(EBX, (byte)(xResultSize * 8));                     // now check if low does not overflow
                XS.Not(EBX);
                XS.Compare(EBX, 0);
                XS.Jump(ConditionalTestEnum.NotEqual, xOverflowLabel);
            }

            XS.Label(xSuccessLabel);
        }