From 4cfc7aabe70a52ddb8df249a45bdd43ea475011a Mon Sep 17 00:00:00 2001 From: Matthijs ter Woord Date: Fri, 17 Jun 2016 08:23:48 -0400 Subject: [PATCH] . --- source/Cosmos.IL2CPU/IL/Div.cs | 75 ++++++++++++++-------------- source/Cosmos.IL2CPU/IL/Div_Un.cs | 70 +++++++++++++------------- source/Cosmos.IL2CPU/IL/Rem.cs | 83 ++++++++++++++++--------------- source/Cosmos.IL2CPU/IL/Rem_Un.cs | 83 ++++++++++++++++--------------- source/Cosmos.IL2CPU/IL/Shl.cs | 10 ++-- source/Cosmos.IL2CPU/IL/Shr.cs | 2 +- source/XSharp.Compiler/XS.cs | 68 +++++++++++++++++++++++++ 7 files changed, 233 insertions(+), 158 deletions(-) diff --git a/source/Cosmos.IL2CPU/IL/Div.cs b/source/Cosmos.IL2CPU/IL/Div.cs index ea138d7c1..da6994f88 100644 --- a/source/Cosmos.IL2CPU/IL/Div.cs +++ b/source/Cosmos.IL2CPU/IL/Div.cs @@ -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)); } } } diff --git a/source/Cosmos.IL2CPU/IL/Div_Un.cs b/source/Cosmos.IL2CPU/IL/Div_Un.cs index db4163067..7ceb0aeed 100644 --- a/source/Cosmos.IL2CPU/IL/Div_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Div_Un.cs @@ -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)); } } } diff --git a/source/Cosmos.IL2CPU/IL/Rem.cs b/source/Cosmos.IL2CPU/IL/Rem.cs index f7efae64d..eb4bea225 100644 --- a/source/Cosmos.IL2CPU/IL/Rem.cs +++ b/source/Cosmos.IL2CPU/IL/Rem.cs @@ -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)); } } } diff --git a/source/Cosmos.IL2CPU/IL/Rem_Un.cs b/source/Cosmos.IL2CPU/IL/Rem_Un.cs index fb63e76c5..81df86e7a 100644 --- a/source/Cosmos.IL2CPU/IL/Rem_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Rem_Un.cs @@ -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)); } } } diff --git a/source/Cosmos.IL2CPU/IL/Shl.cs b/source/Cosmos.IL2CPU/IL/Shl.cs index c48cd74a1..4f83ef5ea 100644 --- a/source/Cosmos.IL2CPU/IL/Shl.cs +++ b/source/Cosmos.IL2CPU/IL/Shl.cs @@ -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 }; diff --git a/source/Cosmos.IL2CPU/IL/Shr.cs b/source/Cosmos.IL2CPU/IL/Shr.cs index 27bba07cd..4b817784d 100644 --- a/source/Cosmos.IL2CPU/IL/Shr.cs +++ b/source/Cosmos.IL2CPU/IL/Shr.cs @@ -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); diff --git a/source/XSharp.Compiler/XS.cs b/source/XSharp.Compiler/XS.cs index a7dc23588..eeece0e5f 100644 --- a/source/XSharp.Compiler/XS.cs +++ b/source/XSharp.Compiler/XS.cs @@ -1146,5 +1146,73 @@ namespace XSharp.Compiler { Do(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 + }; + } } }