mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-11 18:51:41 +00:00
.
This commit is contained in:
parent
9d203f141e
commit
4cfc7aabe7
7 changed files with 233 additions and 158 deletions
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Cosmos.Assembler.x86.SSE;
|
||||
using XSharp.Compiler;
|
||||
using static XSharp.Compiler.XSRegisters;
|
||||
using CPUx86 = Cosmos.Assembler.x86;
|
||||
using Label = Cosmos.Assembler.Label;
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
// override value 1
|
||||
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.RegistersEnum.ESP, Size = 64, DestinationIsIndirect = true, DestinationDisplacement = 8 };
|
||||
// pop value 2
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -47,58 +48,58 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
// divisor
|
||||
//low
|
||||
XS.Set(XSRegisters.ESI, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Set(ESI, ESP, sourceIsIndirect: true);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
|
||||
// pop both 8 byte values
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
|
||||
//dividend
|
||||
// low
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Set(EAX, ESP, sourceIsIndirect: true);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
XS.Label(LabelShiftRight);
|
||||
|
||||
// shift divisor 1 bit right
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.ESI, SourceReg = CPUx86.RegistersEnum.EDI, ArgumentValue = 1 };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
XS.ShiftRightDouble(ESI, EDI, 1);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
|
||||
// increment shift counter
|
||||
XS.Increment(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Increment(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EDX, ArgumentReg = CPUx86.RegistersEnum.CL };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.CL);
|
||||
XS.ShiftRightDouble(EAX, EDX, CL);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDX), CL);
|
||||
|
||||
// so we shifted both, so we have near the same relation as original values
|
||||
// divide this
|
||||
XS.IntegerDivide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.IntegerDivide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
|
||||
// sign extend
|
||||
XS.SignExtendAX(XSRegisters.RegisterSize.Int32);
|
||||
XS.SignExtendAX(RegisterSize.Int32);
|
||||
|
||||
// save result to stack
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
|
||||
//TODO: implement proper derivation correction and overflow detection
|
||||
|
||||
|
|
@ -106,19 +107,19 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
XS.Label(LabelNoLoop);
|
||||
//save high dividend
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
// extend that sign is in edx
|
||||
XS.SignExtendAX(XSRegisters.RegisterSize.Int32);
|
||||
XS.SignExtendAX(RegisterSize.Int32);
|
||||
// divide high part
|
||||
XS.IntegerDivide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.IntegerDivide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
// save high result
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
// divide low part
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
// save low result
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
|
||||
XS.Label(LabelEnd);
|
||||
}
|
||||
|
|
@ -127,19 +128,19 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (TypeIsFloat(xStackItem))
|
||||
{
|
||||
XS.SSE.MoveSS(XSRegisters.XMM0, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.SSE.DivSS(XSRegisters.XMM0, XSRegisters.XMM1);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
|
||||
XS.SSE.DivSS(XMM0, XMM1);
|
||||
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.SignExtendAX(XSRegisters.RegisterSize.Int32);
|
||||
XS.IntegerDivide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.SignExtendAX(RegisterSize.Int32);
|
||||
XS.IntegerDivide(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Cosmos.Assembler.x86.SSE;
|
||||
using XSharp.Compiler;
|
||||
using static XSharp.Compiler.XSRegisters;
|
||||
using CPUx86 = Cosmos.Assembler.x86;
|
||||
using Label = Cosmos.Assembler.Label;
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
// override value 1
|
||||
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.RegistersEnum.ESP, Size = 64, DestinationIsIndirect = true, DestinationDisplacement = 8 };
|
||||
// pop value 2
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -48,53 +49,54 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
// divisor
|
||||
//low
|
||||
XS.Set(XSRegisters.ESI, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Set(ESI, ESP, sourceIsIndirect: true);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
|
||||
//dividend
|
||||
// low
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 8);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 8);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 12);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 12);
|
||||
|
||||
// pop both 8 byte values
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 16);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 16);
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
XS.Label(LabelShiftRight);
|
||||
|
||||
// shift divisor 1 bit right
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.ESI, SourceReg = CPUx86.RegistersEnum.EDI, ArgumentValue = 1 };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
XS.ShiftRightDouble(ESI, EDI, 1);
|
||||
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
|
||||
// increment shift counter
|
||||
XS.Increment(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Increment(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EDX, ArgumentReg = CPUx86.RegistersEnum.CL };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.CL);
|
||||
XS.ShiftRightDouble(EAX, EDX, CL);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDX), CL);
|
||||
|
||||
// so we shifted both, so we have near the same relation as original values
|
||||
// divide this
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
|
||||
// save result to stack
|
||||
XS.Push(0);
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
|
||||
//TODO: implement proper derivation correction and overflow detection
|
||||
|
||||
|
|
@ -103,19 +105,19 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
XS.Label(LabelNoLoop);
|
||||
|
||||
//save high dividend
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
// zero EDX, so that high part is zero -> reduce overflow case
|
||||
XS.Xor(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
// divide high part
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
// save high result
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
// divide low part
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
// save low result
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
|
||||
XS.Label(LabelEnd);
|
||||
}
|
||||
|
|
@ -124,19 +126,19 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (TypeIsFloat(xStackItem))
|
||||
{
|
||||
XS.SSE.MoveSS(XSRegisters.XMM0, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.SSE.MulSS(XSRegisters.XMM0, XSRegisters.XMM1);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.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.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using CPUx86 = Cosmos.Assembler.x86;
|
|||
using Cosmos.Assembler;
|
||||
using Cosmos.Assembler.x86.SSE;
|
||||
using XSharp.Compiler;
|
||||
using static XSharp.Compiler.XSRegisters;
|
||||
|
||||
namespace Cosmos.IL2CPU.X86.IL
|
||||
{
|
||||
|
|
@ -22,12 +23,12 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (TypeIsFloat( xStackItem))
|
||||
{
|
||||
XS.SSE.MoveSS(XSRegisters.XMM0, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2);
|
||||
XS.SSE.DivPS(XSRegisters.XMM1, XSRegisters.XMM0);
|
||||
XS.SSE.MoveSS(XSRegisters.ESP, XSRegisters.XMM2, destinationIsIndirect: true);
|
||||
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.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
|
||||
{
|
||||
|
|
@ -38,53 +39,53 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
// divisor
|
||||
//low
|
||||
XS.Test(XSRegisters.ESI, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Test(ESI, ESP, sourceIsIndirect: true);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
|
||||
// pop both 8 byte values
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 16);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 16);
|
||||
|
||||
//dividend
|
||||
// low
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 8);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 8);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 12);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 12);
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
XS.Label(LabelShiftRight);
|
||||
|
||||
// shift divisor 1 bit right
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.ESI, SourceReg = CPUx86.RegistersEnum.EDI, ArgumentValue = 1 };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
XS.ShiftRightDouble(ESI, EDI, 1);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
|
||||
// increment shift counter
|
||||
XS.Increment(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Increment(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EDX, ArgumentReg = CPUx86.RegistersEnum.CL };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.CL);
|
||||
XS.ShiftRightDouble(EAX, EDX, CL);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDX), CL);
|
||||
|
||||
// so we shifted both, so we have near the same relation as original values
|
||||
// divide this
|
||||
XS.IntegerDivide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.IntegerDivide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
|
||||
// save result to stack
|
||||
XS.Push(0);
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
|
||||
//TODO: implement proper derivation correction and overflow detection
|
||||
|
||||
|
|
@ -92,18 +93,18 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
XS.Label(LabelNoLoop);
|
||||
//save high dividend
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
// extend that sign is in edx
|
||||
XS.SignExtendAX(XSRegisters.RegisterSize.Int32);
|
||||
XS.SignExtendAX(RegisterSize.Int32);
|
||||
// divide high part
|
||||
XS.IntegerDivide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.IntegerDivide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
// divide low part
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
// save low result
|
||||
XS.Push(0);
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
|
||||
XS.Label(LabelEnd);
|
||||
}
|
||||
|
|
@ -112,23 +113,23 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (TypeIsFloat(xStackItem))
|
||||
{
|
||||
XS.SSE.MoveSS(XSRegisters.XMM0, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2);
|
||||
XS.SSE.DivSS(XSRegisters.XMM1, XSRegisters.XMM0);
|
||||
XS.Sub(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XSRegisters.ESP, XSRegisters.XMM2, destinationIsIndirect: true);
|
||||
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.XorPS(XMM2, XMM2);
|
||||
XS.SSE.DivSS(XMM1, XMM0);
|
||||
XS.Sub(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(ESP, XMM2, destinationIsIndirect: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); // gets devised by ecx
|
||||
XS.Xor(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX)); // gets devised by ecx
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX)); // => EAX / ECX
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ECX)); // => EAX / ECX
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Cosmos.Assembler.x86.SSE;
|
||||
using XSharp.Compiler;
|
||||
using static XSharp.Compiler.XSRegisters;
|
||||
using CPUx86 = Cosmos.Assembler.x86;
|
||||
using Label = Cosmos.Assembler.Label;
|
||||
|
||||
|
|
@ -26,12 +27,12 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (TypeIsFloat(xStackItem))
|
||||
{
|
||||
XS.SSE.MoveSS(XSRegisters.XMM0, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2);
|
||||
XS.SSE.DivPS(XSRegisters.XMM1, XSRegisters.XMM0);
|
||||
XS.SSE.MoveSS(XSRegisters.ESP, XSRegisters.XMM2, destinationIsIndirect: true);
|
||||
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.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
|
||||
{
|
||||
|
|
@ -42,53 +43,53 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
// divisor
|
||||
//low
|
||||
XS.Set(XSRegisters.ESI, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Set(ESI, ESP, sourceIsIndirect: true);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 4);
|
||||
|
||||
//dividend
|
||||
// low
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 8);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 8);
|
||||
//high
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 12);
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.ESP), sourceDisplacement: 12);
|
||||
|
||||
// pop both 8 byte values
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 16);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 16);
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
XS.Label(LabelShiftRight);
|
||||
|
||||
// shift divisor 1 bit right
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.ESI, SourceReg = CPUx86.RegistersEnum.EDI, ArgumentValue = 1 };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
XS.ShiftRightDouble(ESI, EDI, 1);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDI), 1);
|
||||
|
||||
// increment shift counter
|
||||
XS.Increment(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Increment(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
|
||||
// set flags
|
||||
XS.Or(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI));
|
||||
XS.Or(OldToNewRegister(CPUx86.RegistersEnum.EDI), OldToNewRegister(CPUx86.RegistersEnum.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
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EDX, ArgumentReg = CPUx86.RegistersEnum.CL };
|
||||
XS.ShiftRight(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.CL);
|
||||
XS.ShiftRightDouble(EAX, EDX, CL);
|
||||
XS.ShiftRight(OldToNewRegister(CPUx86.RegistersEnum.EDX), CL);
|
||||
|
||||
// so we shifted both, so we have near the same relation as original values
|
||||
// divide this
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
|
||||
// save remainder to stack
|
||||
XS.Push(0);
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
|
||||
//TODO: implement proper derivation correction and overflow detection
|
||||
|
||||
|
|
@ -97,18 +98,18 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
XS.Label(LabelNoLoop);
|
||||
|
||||
//save high dividend
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.ECX), OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
// zero EDX, so that high part is zero -> reduce overflow case
|
||||
XS.Xor(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
// divide high part
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Set(OldToNewRegister(CPUx86.RegistersEnum.EAX), OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
// divide low part
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ESI));
|
||||
// save remainder result
|
||||
XS.Push(0);
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
|
||||
XS.Label(LabelEnd);
|
||||
}
|
||||
|
|
@ -117,23 +118,23 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (TypeIsFloat(xStackItem))
|
||||
{
|
||||
XS.SSE.MoveSS(XSRegisters.XMM0, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XSRegisters.XMM1, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2);
|
||||
XS.SSE.DivPS(XSRegisters.XMM1, XSRegisters.XMM0);
|
||||
XS.Sub(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XSRegisters.ESP, XSRegisters.XMM2, destinationIsIndirect: true);
|
||||
XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true);
|
||||
XS.Add(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.XorPS(XMM2, XMM2);
|
||||
XS.SSE.DivPS(XMM1, XMM0);
|
||||
XS.Sub(OldToNewRegister(CPUx86.RegistersEnum.ESP), 4);
|
||||
XS.SSE.MoveSS(ESP, XMM2, destinationIsIndirect: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); // gets devised by ecx
|
||||
XS.Xor(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.EAX)); // gets devised by ecx
|
||||
XS.Xor(OldToNewRegister(CPUx86.RegistersEnum.EDX), OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
|
||||
XS.Divide(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX)); // => EAX / ECX
|
||||
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
XS.Divide(OldToNewRegister(CPUx86.RegistersEnum.ECX)); // => EAX / ECX
|
||||
XS.Push(OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using CPUx86 = Cosmos.Assembler.x86;
|
||||
using Cosmos.Assembler;
|
||||
using XSharp.Compiler;
|
||||
using static XSharp.Compiler.XSRegisters;
|
||||
|
||||
namespace Cosmos.IL2CPU.X86.IL
|
||||
{
|
||||
|
|
@ -15,7 +16,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
|
||||
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
|
||||
{
|
||||
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX)); // shift amount
|
||||
XS.Pop(OldToNewRegister(CPUx86.RegistersEnum.ECX)); // shift amount
|
||||
var xStackItem_ShiftAmount = aOpCode.StackPopTypes[0];
|
||||
var xStackItem_Value = aOpCode.StackPopTypes[1];
|
||||
var xStackItem_Value_Size = SizeOfType(xStackItem_Value);
|
||||
|
|
@ -41,13 +42,14 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
// [ESP + 4] is high part
|
||||
|
||||
// move low part to eax
|
||||
XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceIsIndirect: true);
|
||||
XS.Set(EAX, ESP, sourceIsIndirect: true);
|
||||
|
||||
new CPUx86.Compare { DestinationReg = CPUx86.RegistersEnum.CL, SourceValue = 32, Size = 8 };
|
||||
XS.Jump(CPUx86.ConditionalTestEnum.AboveOrEqual, LowPartIsZero);
|
||||
|
||||
// shift higher part
|
||||
new CPUx86.ShiftLeftDouble { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceReg = CPUx86.RegistersEnum.EAX, ArgumentReg = CPUx86.RegistersEnum.CL };
|
||||
|
||||
XS.ShiftLeftDouble(ESP, EAX, CL, destinationDisplacement: 4);
|
||||
// shift lower part
|
||||
new CPUx86.ShiftLeft { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, Size = 32, SourceReg = CPUx86.RegistersEnum.CL };
|
||||
XS.Jump(End_Shl);
|
||||
|
|
@ -57,7 +59,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
new CPUx86.And { DestinationReg = CPUx86.RegistersEnum.CL, SourceValue = 0x1f, Size = 8 };
|
||||
// shift low part in EAX and move it in high part
|
||||
new CPUx86.ShiftLeft { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.CL, Size = 32};
|
||||
XS.Set(XSRegisters.ESP, XSRegisters.EAX, destinationDisplacement: 4);
|
||||
XS.Set(ESP, EAX, destinationDisplacement: 4);
|
||||
// replace unknown low part with a zero, if <= 32
|
||||
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceValue = 0 };
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
XS.Jump(CPU.ConditionalTestEnum.AboveOrEqual, HighPartIsZero);
|
||||
|
||||
// shift lower part
|
||||
new CPUx86.ShiftRightDouble { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.EAX, ArgumentReg = CPUx86.RegistersEnum.CL };
|
||||
XS.ShiftRightDouble(ESP, EAX, CL, destinationIsIndirect: true);
|
||||
// shift higher part
|
||||
XS.ShiftRight(ESP, CL, destinationDisplacement: 4, size: RegisterSize.Int32);
|
||||
XS.Jump(End_Shr);
|
||||
|
|
|
|||
|
|
@ -1146,5 +1146,73 @@ namespace XSharp.Compiler
|
|||
{
|
||||
Do<RotateThroughCarryRight>(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement, size: size);
|
||||
}
|
||||
|
||||
public static void ShiftRightDouble(Register destination, Register source, uint argumentValue)
|
||||
{
|
||||
new ShiftRightDouble()
|
||||
{
|
||||
DestinationReg = destination,
|
||||
SourceReg = source,
|
||||
ArgumentValue = argumentValue
|
||||
};
|
||||
}
|
||||
|
||||
public static void ShiftRightDouble(Register destination, Register source, Register8 argumentReg, bool destinationIsIndirect = false, int? destinationDisplacement = null)
|
||||
{
|
||||
if (argumentReg != CL)
|
||||
{
|
||||
throw new InvalidOperationException("Argument needs to be CL!");
|
||||
}
|
||||
if (destinationDisplacement != null)
|
||||
{
|
||||
destinationIsIndirect = true;
|
||||
if (destinationDisplacement == 0)
|
||||
{
|
||||
destinationDisplacement = null;
|
||||
}
|
||||
}
|
||||
new ShiftLeftDouble()
|
||||
{
|
||||
DestinationReg = destination,
|
||||
DestinationIsIndirect = destinationIsIndirect,
|
||||
DestinationDisplacement = destinationDisplacement,
|
||||
SourceReg = source,
|
||||
ArgumentReg = argumentReg
|
||||
};
|
||||
}
|
||||
|
||||
public static void ShiftLeftDouble(Register destination, Register source, uint argumentValue)
|
||||
{
|
||||
new ShiftRightDouble()
|
||||
{
|
||||
DestinationReg = destination,
|
||||
SourceReg = source,
|
||||
ArgumentValue = argumentValue
|
||||
};
|
||||
}
|
||||
|
||||
public static void ShiftLeftDouble(Register destination, Register source, Register8 argumentReg, bool destinationIsIndirect = false, int? destinationDisplacement = null)
|
||||
{
|
||||
if (argumentReg != CL)
|
||||
{
|
||||
throw new InvalidOperationException("Argument needs to be CL!");
|
||||
}
|
||||
if (destinationDisplacement != null)
|
||||
{
|
||||
destinationIsIndirect = true;
|
||||
if (destinationDisplacement == 0)
|
||||
{
|
||||
destinationDisplacement = null;
|
||||
}
|
||||
}
|
||||
new ShiftLeftDouble()
|
||||
{
|
||||
DestinationReg = destination,
|
||||
DestinationIsIndirect = destinationIsIndirect,
|
||||
DestinationDisplacement = destinationDisplacement,
|
||||
SourceReg = source,
|
||||
ArgumentReg = argumentReg
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue