Beispiel #1
0
 public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.Set(XSRegisters.EAX, "MultiBootInfo_Memory_High", sourceIsIndirect: true);
     XS.Xor(XSRegisters.EDX, XSRegisters.EDX);
     XS.Set(XSRegisters.ECX, 1024);
     XS.Divide(XSRegisters.ECX);
     XS.Add(XSRegisters.EAX, 1);
     XS.Push(XSRegisters.EAX);
 }
 public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.Mov(XSRegisters.EAX, CPUAll.ElementReference.New("MultiBootInfo_Memory_High"), sourceIsIndirect: true);
     XS.Xor(XSRegisters.EDX, XSRegisters.CPUx86.Registers.EDX);
     XS.Mov(XSRegisters.ECX, 1024);
     XS.Divide(XSRegisters.ECX);
     XS.Add(XSRegisters.EAX, 1);
     XS.Push(XSRegisters.EAX);
 }
Beispiel #3
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackItem     = aOpCode.StackPopTypes[0];
            var xStackItemSize = SizeOfType(xStackItem);
            var xSize          = Math.Max(xStackItemSize, SizeOfType(aOpCode.StackPopTypes[1]));

            if (xSize > 4)
            {
                if (TypeIsFloat(xStackItem))
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(XSRegisters.ESP, 8);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE.XorPS(XMM2, XMM2);
                    XS.SSE.DivPS(XMM1, XMM0);
                    XS.SSE.MoveSS(ESP, XMM2, destinationIsIndirect: true);
                }
                else
                {
                    string BaseLabel       = GetLabel(aMethod, aOpCode) + ".";
                    string LabelShiftRight = BaseLabel + "ShiftRightLoop";
                    string LabelNoLoop     = BaseLabel + "NoLoop";
                    string LabelEnd        = BaseLabel + "End";

                    // divisor
                    //low
                    XS.Set(ESI, ESP, sourceIsIndirect: true);
                    //high
                    XS.Set(XSRegisters.EDI, XSRegisters.ESP, sourceDisplacement: 4);

                    //dividend
                    // low
                    XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: 8);
                    //high
                    XS.Set(XSRegisters.EDX, XSRegisters.ESP, sourceDisplacement: 12);

                    // pop both 8 byte values
                    XS.Add(XSRegisters.ESP, 16);

                    // set flags
                    XS.Or(XSRegisters.EDI, XSRegisters.EDI);
                    // if high dword of divisor is already zero, we dont need the loop
                    XS.Jump(CPUx86.ConditionalTestEnum.Zero, LabelNoLoop);

                    // set ecx to zero for counting the shift operations
                    XS.Xor(XSRegisters.ECX, XSRegisters.ECX);

                    XS.Label(LabelShiftRight);

                    // shift divisor 1 bit right
                    XS.ShiftRightDouble(ESI, EDI, 1);
                    XS.ShiftRight(XSRegisters.EDI, 1);

                    // increment shift counter
                    XS.Increment(XSRegisters.ECX);

                    // set flags
                    XS.Or(XSRegisters.EDI, XSRegisters.EDI);
                    // loop while high dword of divisor till it is zero
                    XS.Jump(CPUx86.ConditionalTestEnum.NotZero, LabelShiftRight);

                    // shift the divident now in one step
                    // shift divident CL bits right
                    XS.ShiftRightDouble(EAX, EDX, CL);
                    XS.ShiftRight(XSRegisters.EDX, CL);

                    // so we shifted both, so we have near the same relation as original values
                    // divide this
                    XS.Divide(XSRegisters.ESI);

                    // save remainder to stack
                    XS.Push(0);
                    XS.Push(XSRegisters.EDX);

                    //TODO: implement proper derivation correction and overflow detection

                    XS.Jump(LabelEnd);

                    XS.Label(LabelNoLoop);

                    //save high dividend
                    XS.Set(XSRegisters.ECX, XSRegisters.EAX);
                    XS.Set(XSRegisters.EAX, XSRegisters.EDX);
                    // zero EDX, so that high part is zero -> reduce overflow case
                    XS.Xor(XSRegisters.EDX, XSRegisters.EDX);
                    // divide high part
                    XS.Divide(XSRegisters.ESI);
                    XS.Set(XSRegisters.EAX, XSRegisters.ECX);
                    // divide low part
                    XS.Divide(XSRegisters.ESI);
                    // save remainder result
                    XS.Push(0);
                    XS.Push(XSRegisters.EDX);

                    XS.Label(LabelEnd);
                }
            }
            else
            {
                if (TypeIsFloat(xStackItem))
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(XSRegisters.ESP, 4);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    XS.Add(XSRegisters.ESP, 4);
                    XS.SSE.XorPS(XMM2, XMM2);
                    XS.SSE.DivPS(XMM1, XMM0);
                    XS.Sub(XSRegisters.ESP, 4);
                    XS.SSE.MoveSS(ESP, XMM2, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(XSRegisters.ECX);
                    XS.Pop(XSRegisters.EAX); // gets devised by ecx
                    XS.Xor(XSRegisters.EDX, XSRegisters.EDX);

                    XS.Divide(XSRegisters.ECX); // => EAX / ECX
                    XS.Push(XSRegisters.EDX);
                }
            }
        }
Beispiel #4
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackItem      = aOpCode.StackPopTypes[0];
            var xStackItemSize  = SizeOfType(xStackItem);
            var xStackItem2     = aOpCode.StackPopTypes[1];
            var xStackItem2Size = SizeOfType(xStackItem2);

            if (xStackItemSize == 8)
            {
                // there seem to be an error in MS documentation, there is pushed an int32, but IL shows else
                if (xStackItem2Size != 8)
                {
                    throw new Exception("Cosmos.IL2CPU.x86->IL->Div.cs->Error: Expected a size of 8 for Div!");
                }
                if (TypeIsFloat(xStackItem))
                {
                    // TODO add 0/0 infinity/infinity X/infinity
                    // value 1
                    new CPUx86.x87.FloatLoad {
                        DestinationReg = CPUx86.RegistersEnum.ESP, Size = 64, DestinationIsIndirect = true, DestinationDisplacement = 8
                    };
                    // value 2
                    new CPUx86.x87.FloatDivide {
                        DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, Size = 64
                    };
                    // override value 1
                    new CPUx86.x87.FloatStoreAndPop {
                        DestinationReg = CPUx86.RegistersEnum.ESP, Size = 64, DestinationIsIndirect = true, DestinationDisplacement = 8
                    };
                    // pop value 2
                    XS.Add(XSRegisters.ESP, 8);
                }
                else
                {
                    string BaseLabel       = GetLabel(aMethod, aOpCode) + ".";
                    string LabelShiftRight = BaseLabel + "ShiftRightLoop";
                    string LabelNoLoop     = BaseLabel + "NoLoop";
                    string LabelEnd        = BaseLabel + "End";

                    // divisor
                    //low
                    XS.Set(ESI, ESP, sourceIsIndirect: true);
                    //high
                    XS.Set(XSRegisters.EDI, XSRegisters.ESP, sourceDisplacement: 4);

                    //dividend
                    // low
                    XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: 8);
                    //high
                    XS.Set(XSRegisters.EDX, XSRegisters.ESP, sourceDisplacement: 12);

                    // pop both 8 byte values
                    XS.Add(XSRegisters.ESP, 16);

                    // set flags
                    XS.Or(XSRegisters.EDI, XSRegisters.EDI);
                    // if high dword of divisor is already zero, we dont need the loop
                    XS.Jump(CPUx86.ConditionalTestEnum.Zero, LabelNoLoop);

                    // set ecx to zero for counting the shift operations
                    XS.Xor(XSRegisters.ECX, XSRegisters.ECX);

                    XS.Label(LabelShiftRight);

                    // shift divisor 1 bit right
                    XS.ShiftRightDouble(ESI, EDI, 1);

                    XS.ShiftRight(XSRegisters.EDI, 1);

                    // increment shift counter
                    XS.Increment(XSRegisters.ECX);

                    // set flags
                    XS.Or(XSRegisters.EDI, XSRegisters.EDI);
                    // loop while high dword of divisor till it is zero
                    XS.Jump(CPUx86.ConditionalTestEnum.NotZero, LabelShiftRight);

                    // shift the divident now in one step
                    // shift divident CL bits right
                    XS.ShiftRightDouble(EAX, EDX, CL);
                    XS.ShiftRight(XSRegisters.EDX, CL);

                    // so we shifted both, so we have near the same relation as original values
                    // divide this
                    XS.Divide(XSRegisters.ESI);

                    // save result to stack
                    XS.Push(0);
                    XS.Push(XSRegisters.EAX);

                    //TODO: implement proper derivation correction and overflow detection

                    XS.Jump(LabelEnd);

                    XS.Label(LabelNoLoop);

                    //save high dividend
                    XS.Set(XSRegisters.ECX, XSRegisters.EAX);
                    XS.Set(XSRegisters.EAX, XSRegisters.EDX);
                    // zero EDX, so that high part is zero -> reduce overflow case
                    XS.Xor(XSRegisters.EDX, XSRegisters.EDX);
                    // divide high part
                    XS.Divide(XSRegisters.ESI);
                    // save high result
                    XS.Push(XSRegisters.EAX);
                    XS.Set(XSRegisters.EAX, XSRegisters.ECX);
                    // divide low part
                    XS.Divide(XSRegisters.ESI);
                    // save low result
                    XS.Push(XSRegisters.EAX);

                    XS.Label(LabelEnd);
                }
            }
            else
            {
                if (TypeIsFloat(xStackItem))
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(XSRegisters.ESP, 4);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE.MulSS(XMM0, XMM1);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                }
                else
                {
                    XS.Xor(XSRegisters.EDX, XSRegisters.EDX);
                    XS.Pop(XSRegisters.ECX);
                    XS.Pop(XSRegisters.EAX);
                    XS.Divide(XSRegisters.ECX);
                    XS.Push(XSRegisters.EAX);
                }
            }
        }
Beispiel #5
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackItem      = aOpCode.StackPopTypes[0];
            var xStackItemSize  = SizeOfType(xStackItem);
            var xStackItem2     = aOpCode.StackPopTypes[0];
            var xStackItem2Size = SizeOfType(xStackItem2);

            if (xStackItemSize == 8)
            {
                // there seem to be an error in MS documentation, there is pushed an int32, but IL shows else
                if (xStackItem2Size != 8)
                {
                    throw new Exception("Cosmos.IL2CPU.x86->IL->Div.cs->Error: Expected a size of 8 for Div!");
                }
                if (TypeIsFloat(xStackItem))
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 8);
                    XS.SSE2.MoveSD(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE2.DivSD(XMM1, XMM0);
                    XS.SSE2.MoveSD(ESP, XMM1, destinationIsIndirect: true);
                }
                else
                {
                    string BaseLabel       = GetLabel(aMethod, aOpCode) + ".";
                    string LabelShiftRight = BaseLabel + "ShiftRightLoop";
                    string LabelNoLoop     = BaseLabel + "NoLoop";
                    string LabelEnd        = BaseLabel + "End";

                    // divisor
                    //low
                    XS.Set(ESI, ESP, sourceIsIndirect: true);
                    //high
                    XS.Set(EDI, ESP, sourceDisplacement: 4);

                    // pop both 8 byte values
                    XS.Add(ESP, 8);

                    //dividend
                    // low
                    XS.Set(EAX, ESP, sourceIsIndirect: true);
                    //high
                    XS.Set(EDX, ESP, sourceDisplacement: 4);

                    XS.Add(ESP, 8);

                    // set flags
                    XS.Or(EDI, EDI);
                    // if high dword of divisor is already zero, we dont need the loop
                    XS.Jump(CPUx86.ConditionalTestEnum.Zero, LabelNoLoop);

                    // set ecx to zero for counting the shift operations
                    XS.Xor(ECX, ECX);

                    XS.Label(LabelShiftRight);

                    // shift divisor 1 bit right
                    XS.ShiftRightDouble(ESI, EDI, 1);
                    XS.ShiftRight(EDI, 1);

                    // increment shift counter
                    XS.Increment(ECX);

                    // set flags
                    XS.Or(EDI, EDI);
                    // loop while high dword of divisor till it is zero
                    XS.Jump(CPUx86.ConditionalTestEnum.NotZero, LabelShiftRight);

                    // shift the divident now in one step
                    // shift divident CL bits right
                    XS.ShiftRightDouble(EAX, EDX, CL);
                    XS.ShiftRight(EDX, CL);

                    // so we shifted both, so we have near the same relation as original values
                    // divide this
                    XS.IntegerDivide(ESI);

                    // sign extend
                    XS.SignExtendAX(RegisterSize.Int32);

                    // save result to stack
                    XS.Push(EDX);
                    XS.Push(EAX);

                    //TODO: implement proper derivation correction and overflow detection

                    XS.Jump(LabelEnd);

                    XS.Label(LabelNoLoop);
                    //save high dividend
                    XS.Set(ECX, EAX);
                    XS.Set(EAX, EDX);
                    // extend that sign is in edx
                    XS.SignExtendAX(RegisterSize.Int32);
                    // divide high part
                    XS.IntegerDivide(ESI);
                    // save high result
                    XS.Push(EAX);
                    XS.Set(EAX, ECX);
                    // divide low part
                    XS.Divide(ESI);
                    // save low result
                    XS.Push(EAX);

                    XS.Label(LabelEnd);
                }
            }
            else
            {
                if (TypeIsFloat(xStackItem))
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(XSRegisters.ESP, 4);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE.DivSS(XMM1, XMM0);
                    XS.SSE.MoveSS(ESP, XMM1, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(XSRegisters.ECX);
                    XS.Pop(XSRegisters.EAX);
                    XS.SignExtendAX(RegisterSize.Int32);
                    XS.IntegerDivide(XSRegisters.ECX);
                    XS.Push(XSRegisters.EAX);
                }
            }
        }
Beispiel #6
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackItem = aOpCode.StackPopTypes[0];
            var xSize      = Math.Max(SizeOfType(xStackItem), SizeOfType(aOpCode.StackPopTypes[1]));
            var xIsFloat   = TypeIsFloat(xStackItem);
            var xBaseLabel = GetLabel(aMethod, aOpCode);
            var xNoDivideByZeroExceptionLabel = xBaseLabel + "_NoDivideByZeroException";

            if (xSize > 8)
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Div.cs->Error: StackSize > 8 not supported");
            }
            else if (xSize > 4)
            {
                if (xIsFloat)
                {
                    XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 8);
                    XS.SSE2.MoveSD(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE2.DivSD(XMM1, XMM0);
                    XS.SSE2.MoveSD(ESP, XMM1, destinationIsIndirect: true);
                }
                else
                {
                    string BaseLabel       = GetLabel(aMethod, aOpCode) + ".";
                    string LabelShiftRight = BaseLabel + "ShiftRightLoop";
                    string LabelNoLoop     = BaseLabel + "NoLoop";
                    string LabelEnd        = BaseLabel + "End";

                    // divisor
                    // low
                    XS.Pop(ESI);
                    // high
                    XS.Pop(EDI);

                    XS.Xor(EAX, EAX);
                    XS.Or(EAX, ESI);
                    XS.Or(EAX, EDI);
                    XS.Jump(ConditionalTestEnum.NotZero, xNoDivideByZeroExceptionLabel);

                    XS.Call(GetLabel(ExceptionHelperRefs.ThrowDivideByZeroExceptionRef));

                    XS.Label(xNoDivideByZeroExceptionLabel);

                    // dividend
                    // low
                    XS.Pop(EAX);
                    // high
                    XS.Pop(EDX);

                    // set flags
                    XS.Or(EDI, EDI);
                    // if high dword of divisor is already zero, we dont need the loop
                    XS.Jump(ConditionalTestEnum.Zero, LabelNoLoop);

                    // set ecx to zero for counting the shift operations
                    XS.Xor(ECX, ECX);

                    // push most significant bit of result
                    XS.Set(EBX, EDI);
                    XS.Xor(EBX, EDX);
                    XS.Push(EBX);

                    XS.Compare(EDI, 0x80000000);
                    XS.Jump(ConditionalTestEnum.Below, BaseLabel + "divisor_no_neg");

                    XS.Negate(ESI);
                    XS.AddWithCarry(EDI, 0);
                    XS.Negate(EDI);

                    XS.Label(BaseLabel + "divisor_no_neg");

                    XS.Compare(EDX, 0x80000000);
                    XS.Jump(ConditionalTestEnum.Below, BaseLabel + "dividend_no_neg");

                    XS.Negate(EAX);
                    XS.AddWithCarry(EDX, 0);
                    XS.Negate(EDX);

                    XS.Label(BaseLabel + "dividend_no_neg");

                    XS.Label(LabelShiftRight);

                    // shift divisor 1 bit right
                    XS.ShiftRightDouble(ESI, EDI, 1);
                    XS.ShiftRight(EDI, 1);

                    // increment shift counter
                    XS.Increment(ECX);

                    // set flags
                    //XS.Or(EDI, EDI);
                    XS.Set(EBX, ESI);
                    XS.And(EBX, 0x80000000);
                    XS.Or(EBX, EDI);
                    // loop while high dword of divisor is not zero or most significant bit of low dword of divisor is set
                    XS.Jump(ConditionalTestEnum.NotZero, LabelShiftRight);

                    // shift the dividend now in one step
                    XS.ShiftRightDouble(EAX, EDX, CL);
                    // shift dividend CL bits right
                    XS.ShiftRight(EDX, CL);

                    // so we shifted both, so we have near the same relation as original values
                    // divide this
                    XS.IntegerDivide(ESI);

                    // pop most significant bit of result
                    XS.Pop(EBX);

                    XS.Compare(EBX, 0x80000000);
                    XS.Jump(ConditionalTestEnum.Below, BaseLabel + "_result_no_neg");

                    XS.Negate(EAX);

                    XS.Label(BaseLabel + "_result_no_neg");

                    // sign extend
                    XS.SignExtendAX(RegisterSize.Int32);

                    // save result to stack
                    XS.Push(EDX);
                    XS.Push(EAX);

                    //TODO: implement proper derivation correction and overflow detection

                    XS.Jump(LabelEnd);

                    XS.Label(LabelNoLoop);
                    // save high dividend
                    XS.Set(ECX, EAX);
                    XS.Set(EAX, EDX);

                    // extend that sign is in edx
                    XS.SignExtendAX(RegisterSize.Int32);
                    // divide high part
                    XS.IntegerDivide(ESI);
                    // save high result
                    XS.Push(EAX);
                    XS.Set(EAX, ECX);
                    // divide low part
                    XS.Divide(ESI);
                    // save low result
                    XS.Push(EAX);

                    XS.Label(LabelEnd);
                }
            }
            else
            {
                if (xIsFloat)
                {
                    XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
                    XS.Add(ESP, 4);
                    XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
                    XS.SSE.DivSS(XMM1, XMM0);
                    XS.SSE.MoveSS(ESP, XMM1, destinationIsIndirect: true);
                }
                else
                {
                    XS.Pop(ECX);

                    XS.Test(ECX, ECX);
                    XS.Jump(ConditionalTestEnum.NotZero, xNoDivideByZeroExceptionLabel);

                    XS.Call(GetLabel(ExceptionHelperRefs.ThrowDivideByZeroExceptionRef));

                    XS.Label(xNoDivideByZeroExceptionLabel);

                    XS.Pop(EAX);

                    XS.SignExtendAX(RegisterSize.Int32);

                    XS.IntegerDivide(ECX);
                    XS.Push(EAX);
                }
            }
        }
Beispiel #7
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackItem = aOpCode.StackPopTypes[0];
            var xSize      = Math.Max(SizeOfType(xStackItem), SizeOfType(aOpCode.StackPopTypes[1]));
            var xBaseLabel = GetLabel(aMethod, aOpCode);
            var xNoDivideByZeroExceptionLabel = xBaseLabel + "_NoDivideByZeroException";

            if (TypeIsFloat(xStackItem))
            {
                throw new Exception("Cosmos.IL2CPU.x86->IL->Div_Un.cs->Error: Expected unsigned integer operands but got float!");
            }

            if (xSize > 8)
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Div_Un.cs->Error: StackSize > 8 not supported");
            }
            else if (xSize > 4)
            {
                string BaseLabel       = GetLabel(aMethod, aOpCode) + ".";
                string LabelShiftRight = BaseLabel + "ShiftRightLoop";
                string LabelNoLoop     = BaseLabel + "NoLoop";
                string LabelEnd        = BaseLabel + "End";

                // divisor
                // low
                XS.Pop(ESI);
                // high
                XS.Pop(EDI);

                XS.Xor(EAX, EAX);
                XS.Or(EAX, ESI);
                XS.Or(EAX, EDI);
                XS.Jump(ConditionalTestEnum.NotZero, xNoDivideByZeroExceptionLabel);

                XS.Call(GetLabel(ExceptionHelperRefs.ThrowDivideByZeroExceptionRef));

                XS.Label(xNoDivideByZeroExceptionLabel);

                // dividend
                // low
                XS.Pop(EAX);
                // high
                XS.Pop(EDX);

                // set flags
                XS.Or(EDI, EDI);
                // if high dword of divisor is already zero, we dont need the loop
                XS.Jump(ConditionalTestEnum.Zero, LabelNoLoop);

                // set ecx to zero for counting the shift operations
                XS.Xor(ECX, ECX);

                XS.Label(LabelShiftRight);

                // shift divisor 1 bit right
                XS.ShiftRightDouble(ESI, EDI, 1);
                XS.ShiftRight(EDI, 1);

                // increment shift counter
                XS.Increment(ECX);

                // set flags
                XS.Or(EDI, EDI);
                // loop while high dword of divisor till it is zero
                XS.Jump(ConditionalTestEnum.NotZero, LabelShiftRight);

                // shift the dividend now in one step
                // shift dividend CL bits right
                XS.ShiftRightDouble(EAX, EDX, CL);
                XS.ShiftRight(EDX, CL);

                // so we shifted both, so we have near the same relation as original values
                // divide this
                XS.Divide(ESI);

                // save result to stack
                XS.Push(0);
                XS.Push(EAX);

                //TODO: implement proper derivation correction and overflow detection

                XS.Jump(LabelEnd);

                XS.Label(LabelNoLoop);

                //save high dividend
                XS.Set(ECX, EAX);
                XS.Set(EAX, EDX);
                // zero EDX, so that high part is zero -> reduce overflow case
                XS.Xor(EDX, EDX);
                // divide high part
                XS.Divide(ESI);
                // save high result
                XS.Push(EAX);
                XS.Set(EAX, ECX);
                // divide low part
                XS.Divide(ESI);
                // save low result
                XS.Push(EAX);

                XS.Label(LabelEnd);
            }
            else
            {
                XS.Pop(ECX);

                XS.Test(ECX, ECX);
                XS.Jump(ConditionalTestEnum.NotZero, xNoDivideByZeroExceptionLabel);

                XS.Call(GetLabel(ExceptionHelperRefs.ThrowDivideByZeroExceptionRef));

                XS.Label(xNoDivideByZeroExceptionLabel);

                XS.Pop(EAX);

                XS.Xor(EDX, EDX);

                XS.Divide(ECX);
                XS.Push(EAX);
            }
        }