From bbb8265166eccdcaf41a33b607833aa723d8c53f Mon Sep 17 00:00:00 2001 From: Matthijs ter Woord Date: Wed, 15 Jun 2016 09:55:11 -0400 Subject: [PATCH] . --- .../x86/SSE2/ConvertTruncateSS2SI.cs | 2 +- source/Cosmos.IL2CPU/CosmosAssembler.cs | 12 +- source/Cosmos.IL2CPU/IL/Add.cs | 2 +- source/Cosmos.IL2CPU/IL/Add_Ovf.cs | 2 +- source/Cosmos.IL2CPU/IL/Add_Ovf_Un.cs | 2 +- source/Cosmos.IL2CPU/IL/Ceq.cs | 2 +- source/Cosmos.IL2CPU/IL/Cgt.cs | 2 +- source/Cosmos.IL2CPU/IL/Cgt_Un.cs | 2 +- source/Cosmos.IL2CPU/IL/Clt.cs | 2 +- source/Cosmos.IL2CPU/IL/Conv_I1.cs | 7 +- source/Cosmos.IL2CPU/IL/Conv_I2.cs | 7 +- source/Cosmos.IL2CPU/IL/Conv_I4.cs | 7 +- source/Cosmos.IL2CPU/IL/Conv_R_Un.cs | 5 +- source/Cosmos.IL2CPU/IL/Conv_U1.cs | 7 +- source/Cosmos.IL2CPU/IL/Conv_U2.cs | 7 +- source/Cosmos.IL2CPU/IL/Conv_U4.cs | 7 +- source/Cosmos.IL2CPU/IL/Div.cs | 2 +- source/Cosmos.IL2CPU/IL/Div_Un.cs | 2 +- source/Cosmos.IL2CPU/IL/Mul.cs | 6 +- source/Cosmos.IL2CPU/IL/Rem.cs | 8 +- source/Cosmos.IL2CPU/IL/Rem_Un.cs | 8 +- source/Cosmos.IL2CPU/IL/Sub.cs | 6 +- source/XSharp.Compiler/XS.FPU.cs | 3 +- source/XSharp.Compiler/XS.SSE.cs | 67 ++++++ source/XSharp.Compiler/XS.SSE2.cs | 53 +++++ source/XSharp.Compiler/XS.cs | 212 ++++++++++++++++++ source/XSharp.Compiler/XSRegisters.cs | 27 ++- .../XSTemplate.DestinationSource.txt | 29 +++ source/XSharp.Compiler/XSharp.Compiler.csproj | 3 + 29 files changed, 444 insertions(+), 57 deletions(-) create mode 100644 source/XSharp.Compiler/XS.SSE.cs create mode 100644 source/XSharp.Compiler/XS.SSE2.cs create mode 100644 source/XSharp.Compiler/XSTemplate.DestinationSource.txt diff --git a/source/Cosmos.Assembler/x86/SSE2/ConvertTruncateSS2SI.cs b/source/Cosmos.Assembler/x86/SSE2/ConvertTruncateSS2SI.cs index f1866626a..6a52df02f 100644 --- a/source/Cosmos.Assembler/x86/SSE2/ConvertTruncateSS2SI.cs +++ b/source/Cosmos.Assembler/x86/SSE2/ConvertTruncateSS2SI.cs @@ -4,4 +4,4 @@ public class ConvertSS2SIAndTruncate : InstructionWithDestinationAndSource { } -} \ No newline at end of file +} diff --git a/source/Cosmos.IL2CPU/CosmosAssembler.cs b/source/Cosmos.IL2CPU/CosmosAssembler.cs index 5c5a07bc1..dbaa338bf 100644 --- a/source/Cosmos.IL2CPU/CosmosAssembler.cs +++ b/source/Cosmos.IL2CPU/CosmosAssembler.cs @@ -91,12 +91,12 @@ namespace Cosmos.IL2CPU }; XS.Comment("Set data segments"); - XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.EAX), mGdData); - XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.DS), XSRegisters.OldToNewRegister(RegistersEnum.EAX)); - XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.ES), XSRegisters.OldToNewRegister(RegistersEnum.EAX)); - XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.FS), XSRegisters.OldToNewRegister(RegistersEnum.EAX)); - XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.GS), XSRegisters.OldToNewRegister(RegistersEnum.EAX)); - XS.Set(XSRegisters.OldToNewRegister(RegistersEnum.SS), XSRegisters.OldToNewRegister(RegistersEnum.EAX)); + XS.Set(XSRegisters.EAX, mGdData); + XS.Set(XSRegisters.DS, XSRegisters.AX); + XS.Set(XSRegisters.ES, XSRegisters.AX); + XS.Set(XSRegisters.FS, XSRegisters.AX); + XS.Set(XSRegisters.GS, XSRegisters.AX); + XS.Set(XSRegisters.SS, XSRegisters.AX); XS.Comment("Force reload of code segment"); new JumpToSegment diff --git a/source/Cosmos.IL2CPU/IL/Add.cs b/source/Cosmos.IL2CPU/IL/Add.cs index 083fde890..21610b613 100644 --- a/source/Cosmos.IL2CPU/IL/Add.cs +++ b/source/Cosmos.IL2CPU/IL/Add.cs @@ -55,7 +55,7 @@ namespace Cosmos.IL2CPU.X86.IL new MoveSS { DestinationReg = RegistersEnum.XMM0, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; - new AddSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0 }; + XS.SSE.AddSS(XSRegisters.XMM0, XSRegisters.XMM1); new MoveSS { DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true, SourceReg = RegistersEnum.XMM1 }; } else //integer diff --git a/source/Cosmos.IL2CPU/IL/Add_Ovf.cs b/source/Cosmos.IL2CPU/IL/Add_Ovf.cs index 0b674b723..30380558b 100644 --- a/source/Cosmos.IL2CPU/IL/Add_Ovf.cs +++ b/source/Cosmos.IL2CPU/IL/Add_Ovf.cs @@ -56,7 +56,7 @@ namespace Cosmos.IL2CPU.X86.IL new MoveSS { DestinationReg = RegistersEnum.XMM0, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; - new AddSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0 }; + XS.SSE.AddSS(XSRegisters.XMM0, XSRegisters.XMM1); new MoveSS { DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true, SourceReg = RegistersEnum.XMM1 }; } else //integer diff --git a/source/Cosmos.IL2CPU/IL/Add_Ovf_Un.cs b/source/Cosmos.IL2CPU/IL/Add_Ovf_Un.cs index 38f86f910..33aa3d4ac 100644 --- a/source/Cosmos.IL2CPU/IL/Add_Ovf_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Add_Ovf_Un.cs @@ -56,7 +56,7 @@ namespace Cosmos.IL2CPU.X86.IL new MoveSS { DestinationReg = RegistersEnum.XMM0, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; - new AddSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0 }; + XS.SSE.AddSS(XSRegisters.XMM0, XSRegisters.XMM1); new MoveSS { DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true, SourceReg = RegistersEnum.XMM1 }; } else //integer diff --git a/source/Cosmos.IL2CPU/IL/Ceq.cs b/source/Cosmos.IL2CPU/IL/Ceq.cs index e2ba9c260..b6fcbcbff 100644 --- a/source/Cosmos.IL2CPU/IL/Ceq.cs +++ b/source/Cosmos.IL2CPU/IL/Ceq.cs @@ -38,7 +38,7 @@ namespace Cosmos.IL2CPU.X86.IL { XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; new CompareSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0, pseudoOpcode = (byte)ComparePseudoOpcodes.Equal }; - new MoveD { DestinationReg = RegistersEnum.EBX, SourceReg = RegistersEnum.XMM1 }; + XS.SSE2.MoveD(XSRegisters.XMM1, XSRegisters.EBX); XS.And(XSRegisters.OldToNewRegister(RegistersEnum.EBX), 1); new Mov { SourceReg = RegistersEnum.EBX, DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Cgt.cs b/source/Cosmos.IL2CPU/IL/Cgt.cs index c7651b285..9e6e6853c 100644 --- a/source/Cosmos.IL2CPU/IL/Cgt.cs +++ b/source/Cosmos.IL2CPU/IL/Cgt.cs @@ -84,7 +84,7 @@ namespace Cosmos.IL2CPU.X86.IL XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; new CompareSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0, pseudoOpcode = (byte)ComparePseudoOpcodes.NotLessThanOrEqualTo }; - new MoveD { DestinationReg = RegistersEnum.EBX, SourceReg = RegistersEnum.XMM1 }; + XS.SSE2.MoveD(XSRegisters.XMM1, XSRegisters.EBX); XS.And(XSRegisters.OldToNewRegister(RegistersEnum.EBX), 1); new Mov { SourceReg = RegistersEnum.EBX, DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Cgt_Un.cs b/source/Cosmos.IL2CPU/IL/Cgt_Un.cs index 33a8f5bbf..c56462e7e 100644 --- a/source/Cosmos.IL2CPU/IL/Cgt_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Cgt_Un.cs @@ -86,7 +86,7 @@ namespace Cosmos.IL2CPU.X86.IL XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; new CompareSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0, pseudoOpcode = (byte)ComparePseudoOpcodes.NotLessThanOrEqualTo }; - new MoveD { DestinationReg = RegistersEnum.EBX, SourceReg = RegistersEnum.XMM1 }; + XS.SSE2.MoveD(XSRegisters.XMM1, XSRegisters.EBX); XS.And(XSRegisters.OldToNewRegister(RegistersEnum.EBX), 1); new Mov { SourceReg = RegistersEnum.EBX, DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Clt.cs b/source/Cosmos.IL2CPU/IL/Clt.cs index 2ae344d53..d53c5e436 100644 --- a/source/Cosmos.IL2CPU/IL/Clt.cs +++ b/source/Cosmos.IL2CPU/IL/Clt.cs @@ -79,7 +79,7 @@ namespace Cosmos.IL2CPU.X86.IL XS.Add(XSRegisters.OldToNewRegister(RegistersEnum.ESP), 4); new MoveSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.ESP, SourceIsIndirect = true }; new CompareSS { DestinationReg = RegistersEnum.XMM1, SourceReg = RegistersEnum.XMM0, pseudoOpcode = (byte)ComparePseudoOpcodes.LessThan }; - new MoveD { DestinationReg = RegistersEnum.EBX, SourceReg = RegistersEnum.XMM1 }; + XS.SSE2.MoveD(XSRegisters.XMM1, XSRegisters.EBX); XS.And(XSRegisters.OldToNewRegister(RegistersEnum.EBX), 1); new Mov { SourceReg = RegistersEnum.EBX, DestinationReg = RegistersEnum.ESP, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Conv_I1.cs b/source/Cosmos.IL2CPU/IL/Conv_I1.cs index 5c9fa124c..2aac2fc24 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_I1.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_I1.cs @@ -1,4 +1,5 @@ using System; +using Cosmos.Assembler.x86.SSE; using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; @@ -25,13 +26,13 @@ namespace Cosmos.IL2CPU.X86.IL if (xSourceSize == 4) { new CPUx86.SSE.MoveSS { SourceReg = CPUx86.RegistersEnum.ESP, DestinationReg = CPUx86.RegistersEnum.XMM0, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSS2SIAndTruncate { SourceReg = CPUx86.RegistersEnum.XMM0, DestinationReg = CPUx86.RegistersEnum.EAX }; + XS.SSE.ConvertSS2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else if (xSourceSize == 8) { - new CPUx86.SSE.MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSD2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0, }; + new MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; + XS.SSE2.ConvertSD2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else diff --git a/source/Cosmos.IL2CPU/IL/Conv_I2.cs b/source/Cosmos.IL2CPU/IL/Conv_I2.cs index 13a92325e..0f2587f50 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_I2.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_I2.cs @@ -1,4 +1,5 @@ using System; +using Cosmos.Assembler.x86.SSE; using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; @@ -25,13 +26,13 @@ namespace Cosmos.IL2CPU.X86.IL if (xSourceSize == 4) { new CPUx86.SSE.MoveSS { SourceReg = CPUx86.RegistersEnum.ESP, DestinationReg = CPUx86.RegistersEnum.XMM0, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSS2SIAndTruncate { SourceReg = CPUx86.RegistersEnum.XMM0, DestinationReg = CPUx86.RegistersEnum.EAX }; + XS.SSE.ConvertSS2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else if (xSourceSize == 8) { - new CPUx86.SSE.MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSD2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0, }; + new MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; + XS.SSE2.ConvertSD2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else diff --git a/source/Cosmos.IL2CPU/IL/Conv_I4.cs b/source/Cosmos.IL2CPU/IL/Conv_I4.cs index d8180bb5e..c889ed055 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_I4.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_I4.cs @@ -1,4 +1,5 @@ using System; +using Cosmos.Assembler.x86.SSE; using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; @@ -32,7 +33,7 @@ namespace Cosmos.IL2CPU.X86.IL if (xSourceIsFloat) { new CPUx86.SSE.MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSS2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0 }; + XS.SSE.ConvertSS2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } break; @@ -41,8 +42,8 @@ namespace Cosmos.IL2CPU.X86.IL { if (xSourceIsFloat) { - new CPUx86.SSE.MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSD2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0 }; + new MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; + XS.SSE2.ConvertSD2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Conv_R_Un.cs b/source/Cosmos.IL2CPU/IL/Conv_R_Un.cs index ed0bedd7f..70d239543 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_R_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_R_Un.cs @@ -1,4 +1,5 @@ using System; +using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; namespace Cosmos.IL2CPU.X86.IL @@ -33,7 +34,7 @@ namespace Cosmos.IL2CPU.X86.IL case 2: case 4: new CPUx86.Mov { SourceReg = CPUx86.RegistersEnum.ESP, DestinationReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSI2SS { SourceReg = CPUx86.RegistersEnum.EAX, DestinationReg = CPUx86.RegistersEnum.XMM0 }; + XS.SSE.ConvertSI2SS(XSRegisters.XMM0, XSRegisters.EAX); new CPUx86.SSE.MoveSS { SourceReg = CPUx86.RegistersEnum.XMM0, DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true }; break; case 8: @@ -50,4 +51,4 @@ namespace Cosmos.IL2CPU.X86.IL } } } -} \ No newline at end of file +} diff --git a/source/Cosmos.IL2CPU/IL/Conv_U1.cs b/source/Cosmos.IL2CPU/IL/Conv_U1.cs index 56f931272..336dbdcc5 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_U1.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_U1.cs @@ -1,4 +1,5 @@ using System; +using Cosmos.Assembler.x86.SSE; using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; @@ -25,13 +26,13 @@ namespace Cosmos.IL2CPU.X86.IL if (xSourceSize == 4) { new CPUx86.SSE.MoveSS { SourceReg = CPUx86.RegistersEnum.ESP, DestinationReg = CPUx86.RegistersEnum.XMM0, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSS2SIAndTruncate { SourceReg = CPUx86.RegistersEnum.XMM0, DestinationReg = CPUx86.RegistersEnum.EAX }; + XS.SSE.ConvertSS2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else if (xSourceSize == 8) { - new CPUx86.SSE.MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSD2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0, }; + new MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; + XS.SSE2.ConvertSD2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else diff --git a/source/Cosmos.IL2CPU/IL/Conv_U2.cs b/source/Cosmos.IL2CPU/IL/Conv_U2.cs index f55be82f7..4cf9f77f6 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_U2.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_U2.cs @@ -1,4 +1,5 @@ using System; +using Cosmos.Assembler.x86.SSE; using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; @@ -24,13 +25,13 @@ namespace Cosmos.IL2CPU.X86.IL if (xSourceSize == 4) { new CPUx86.SSE.MoveSS { SourceReg = CPUx86.RegistersEnum.ESP, DestinationReg = CPUx86.RegistersEnum.XMM0, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSS2SIAndTruncate { SourceReg = CPUx86.RegistersEnum.XMM0, DestinationReg = CPUx86.RegistersEnum.EAX }; + XS.SSE.ConvertSS2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else if (xSourceSize == 8) { - new CPUx86.SSE.MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSD2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0, }; + new MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; + XS.SSE2.ConvertSD2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } else diff --git a/source/Cosmos.IL2CPU/IL/Conv_U4.cs b/source/Cosmos.IL2CPU/IL/Conv_U4.cs index 64de2ce5b..db658e367 100644 --- a/source/Cosmos.IL2CPU/IL/Conv_U4.cs +++ b/source/Cosmos.IL2CPU/IL/Conv_U4.cs @@ -1,4 +1,5 @@ using System; +using Cosmos.Assembler.x86.SSE; using XSharp.Compiler; using CPUx86 = Cosmos.Assembler.x86; @@ -30,15 +31,15 @@ namespace Cosmos.IL2CPU.X86.IL if (TypeIsFloat(xSource)) { new CPUx86.SSE.MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSS2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0, }; + XS.SSE.ConvertSS2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; } break; case 8: if (TypeIsFloat(xSource)) { - new CPUx86.SSE.MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.ConvertSD2SIAndTruncate { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.XMM0, }; + new MoveDoubleAndDupplicate { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; + XS.SSE2.ConvertSD2SIAndTruncate(XSRegisters.EAX, XSRegisters.XMM0); new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESP, SourceReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true }; XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); diff --git a/source/Cosmos.IL2CPU/IL/Div.cs b/source/Cosmos.IL2CPU/IL/Div.cs index 7c5824354..a7e1a57a3 100644 --- a/source/Cosmos.IL2CPU/IL/Div.cs +++ b/source/Cosmos.IL2CPU/IL/Div.cs @@ -130,7 +130,7 @@ namespace Cosmos.IL2CPU.X86.IL new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new DivSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.XMM0 }; + XS.SSE.DivSS(XSRegisters.XMM0, XSRegisters.XMM1); new MoveSS { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.XMM1 }; } else diff --git a/source/Cosmos.IL2CPU/IL/Div_Un.cs b/source/Cosmos.IL2CPU/IL/Div_Un.cs index 21e72253d..16ac4979a 100644 --- a/source/Cosmos.IL2CPU/IL/Div_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Div_Un.cs @@ -127,7 +127,7 @@ namespace Cosmos.IL2CPU.X86.IL new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new MulSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.XMM0 }; + XS.SSE.MulSS(XSRegisters.XMM0, XSRegisters.XMM1); new MoveSS { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.XMM1 }; } else diff --git a/source/Cosmos.IL2CPU/IL/Mul.cs b/source/Cosmos.IL2CPU/IL/Mul.cs index 0d1bf9312..e45e4c333 100644 --- a/source/Cosmos.IL2CPU/IL/Mul.cs +++ b/source/Cosmos.IL2CPU/IL/Mul.cs @@ -168,11 +168,7 @@ namespace Cosmos.IL2CPU.X86.IL SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new MulSS - { - DestinationReg = CPUx86.RegistersEnum.XMM1, - SourceReg = CPUx86.RegistersEnum.XMM0 - }; + XS.SSE.MulSS(XSRegisters.XMM0, XSRegisters.XMM1); new MoveSS { DestinationReg = CPUx86.RegistersEnum.ESP, diff --git a/source/Cosmos.IL2CPU/IL/Rem.cs b/source/Cosmos.IL2CPU/IL/Rem.cs index 56589b2fa..6cd6c092f 100644 --- a/source/Cosmos.IL2CPU/IL/Rem.cs +++ b/source/Cosmos.IL2CPU/IL/Rem.cs @@ -25,8 +25,8 @@ namespace Cosmos.IL2CPU.X86.IL new CPUx86.SSE.MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8); new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new XorPS { DestinationReg = CPUx86.RegistersEnum.XMM2, SourceReg = CPUx86.RegistersEnum.XMM2 }; - new DivPS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.XMM1 }; + XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2); + XS.SSE.DivPS(XSRegisters.XMM1, XSRegisters.XMM0); new MoveSS { SourceReg = CPUx86.RegistersEnum.XMM2, DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true }; } else @@ -116,8 +116,8 @@ namespace Cosmos.IL2CPU.X86.IL XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); - new XorPS { DestinationReg = CPUx86.RegistersEnum.XMM2, SourceReg = CPUx86.RegistersEnum.XMM2 }; - new DivSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.XMM1 }; + XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2); + XS.SSE.DivSS(XSRegisters.XMM1, XSRegisters.XMM0); XS.Sub(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); new MoveSS { SourceReg = CPUx86.RegistersEnum.XMM2, DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Rem_Un.cs b/source/Cosmos.IL2CPU/IL/Rem_Un.cs index 669049d8f..a1ef46024 100644 --- a/source/Cosmos.IL2CPU/IL/Rem_Un.cs +++ b/source/Cosmos.IL2CPU/IL/Rem_Un.cs @@ -29,8 +29,8 @@ namespace Cosmos.IL2CPU.X86.IL new CPUx86.SSE.MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 8); new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new XorPS { DestinationReg = CPUx86.RegistersEnum.XMM2, SourceReg = CPUx86.RegistersEnum.XMM2 }; - new DivPS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.XMM1 }; + XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2); + XS.SSE.DivPS(XSRegisters.XMM1, XSRegisters.XMM0); new MoveSS { SourceReg = CPUx86.RegistersEnum.XMM2, DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true }; } else @@ -121,8 +121,8 @@ namespace Cosmos.IL2CPU.X86.IL XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); new MoveSS { DestinationReg = CPUx86.RegistersEnum.XMM1, SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); - new XorPS { DestinationReg = CPUx86.RegistersEnum.XMM2, SourceReg = CPUx86.RegistersEnum.XMM2 }; - new DivPS { DestinationReg = CPUx86.RegistersEnum.XMM0, SourceReg = CPUx86.RegistersEnum.XMM1 }; + XS.SSE.XorPS(XSRegisters.XMM2, XSRegisters.XMM2); + XS.SSE.DivPS(XSRegisters.XMM1, XSRegisters.XMM0); XS.Sub(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESP), 4); new MoveSS { SourceReg = CPUx86.RegistersEnum.XMM2, DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true }; } diff --git a/source/Cosmos.IL2CPU/IL/Sub.cs b/source/Cosmos.IL2CPU/IL/Sub.cs index d591deb40..fc9906366 100644 --- a/source/Cosmos.IL2CPU/IL/Sub.cs +++ b/source/Cosmos.IL2CPU/IL/Sub.cs @@ -47,11 +47,7 @@ namespace Cosmos.IL2CPU.X86.IL SourceReg = CPUx86.RegistersEnum.ESP, SourceIsIndirect = true }; - new CPUx86.SSE.SubSS - { - DestinationReg = CPUx86.RegistersEnum.XMM1, - SourceReg = CPUx86.RegistersEnum.XMM0 - }; + XS.SSE.SubSS(XSRegisters.XMM0, XSRegisters.XMM1); new CPUx86.SSE.MoveSS { DestinationReg = CPUx86.RegistersEnum.ESP, diff --git a/source/XSharp.Compiler/XS.FPU.cs b/source/XSharp.Compiler/XS.FPU.cs index 8d58ddb19..c531fee53 100644 --- a/source/XSharp.Compiler/XS.FPU.cs +++ b/source/XSharp.Compiler/XS.FPU.cs @@ -1,4 +1,5 @@ -using Cosmos.Assembler.x86.x87; +using Cosmos.Assembler.x86.SSE; +using Cosmos.Assembler.x86.x87; using static XSharp.Compiler.XSRegisters; namespace XSharp.Compiler diff --git a/source/XSharp.Compiler/XS.SSE.cs b/source/XSharp.Compiler/XS.SSE.cs new file mode 100644 index 000000000..344aab23d --- /dev/null +++ b/source/XSharp.Compiler/XS.SSE.cs @@ -0,0 +1,67 @@ +using Cosmos.Assembler.x86.SSE; +using static XSharp.Compiler.XSRegisters; + +namespace XSharp.Compiler +{ + partial class XS + { + public static class SSE + { + public static void AddSS(RegisterXMM destination, RegisterXMM source) + { + DoDestinationSource(destination, source); + } + + public static void MulSS(RegisterXMM destination, RegisterXMM source) + { + DoDestinationSource(destination, source); + } + + public static void SubSS(RegisterXMM destination, RegisterXMM source) + { + DoDestinationSource(destination, source); + } + + public static void XorPS(RegisterXMM destination, RegisterXMM source) + { + DoDestinationSource(destination, source); + } + + public static void ConvertSI2SS(RegisterXMM destination, Register32 source) + { + new ConvertSI2SS() + { + DestinationReg = destination, + SourceReg = source + }; + } + + public static void ConvertSS2SIAndTruncate(Register32 destination, RegisterXMM source) + { + new ConvertSS2SIAndTruncate + { + DestinationReg = destination, + SourceReg = source + }; + } + + public static void DivPS(RegisterXMM destination, RegisterXMM source) + { + new DivPS + { + DestinationReg = destination, + SourceReg = source + }; + } + + public static void DivSS(RegisterXMM destination, RegisterXMM source) + { + new DivPS + { + DestinationReg = destination, + SourceReg = source + }; + } + } + } +} diff --git a/source/XSharp.Compiler/XS.SSE2.cs b/source/XSharp.Compiler/XS.SSE2.cs new file mode 100644 index 000000000..9d38ba142 --- /dev/null +++ b/source/XSharp.Compiler/XS.SSE2.cs @@ -0,0 +1,53 @@ +using System; +using Cosmos.Assembler.x86; +using Cosmos.Assembler.x86.SSE; +using static XSharp.Compiler.XSRegisters; + +namespace XSharp.Compiler +{ + partial class XS + { + public static class SSE2 + { + public static void ConvertSD2SIAndTruncate(Register32 destination, RegisterXMM source) + { + new ConvertSD2SIAndTruncate + { + DestinationReg = destination, + SourceReg = source + }; + } + + public static void MoveD(string destination, Register source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void MoveD(string destination, UInt32 value, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, value, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void MoveD(string destination, string source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void MoveD(Register destination, string sourceLabel, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, sourceLabel, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void MoveD(Register destination, uint value, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, value, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void MoveD(Register destination, Register source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + } + } +} diff --git a/source/XSharp.Compiler/XS.cs b/source/XSharp.Compiler/XS.cs index 80601e07a..5301240c2 100644 --- a/source/XSharp.Compiler/XS.cs +++ b/source/XSharp.Compiler/XS.cs @@ -351,6 +351,218 @@ namespace XSharp.Compiler #endregion InstructionWithDestinationAndSize + #region InstructionWithDestinationAndSource + + private static void DoDestinationSource(string destination, Register source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + where T : InstructionWithDestinationAndSource, new() + { + if (destinationDisplacement != null) + { + destinationIsIndirect = true; + if (destinationDisplacement == 0) + { + destinationDisplacement = null; + } + } + if (sourceDisplacement != null) + { + sourceIsIndirect = true; + if (sourceDisplacement == 0) + { + sourceDisplacement = null; + } + } + if (destinationIsIndirect && sourceIsIndirect) + { + throw new Exception("Both destination and source cannot be indirect!"); + } + + new T + { + DestinationRef = ElementReference.New(destination), + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = destinationDisplacement, + SourceReg = source.RegEnum, + SourceIsIndirect = sourceIsIndirect, + SourceDisplacement = sourceDisplacement + }; + } + + private static void DoDestinationSource(string destination, UInt32 value, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + where T : InstructionWithDestinationAndSource, new() + { + if (destinationDisplacement != null) + { + destinationIsIndirect = true; + if (destinationDisplacement == 0) + { + destinationDisplacement = null; + } + } + if (sourceDisplacement != null) + { + sourceIsIndirect = true; + if (sourceDisplacement == 0) + { + sourceDisplacement = null; + } + } + if (destinationIsIndirect && sourceIsIndirect) + { + throw new Exception("Both destination and source cannot be indirect!"); + } + + new T + { + DestinationRef = ElementReference.New(destination), + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = destinationDisplacement, + SourceValue = value, + SourceIsIndirect = sourceIsIndirect, + SourceDisplacement = sourceDisplacement, + }; + } + + private static void DoDestinationSource(string destination, string source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + where T : InstructionWithDestinationAndSource, new() + { + if (destinationDisplacement != null) + { + destinationIsIndirect = true; + if (destinationDisplacement == 0) + { + destinationDisplacement = null; + } + } + if (sourceDisplacement != null) + { + sourceIsIndirect = true; + if (sourceDisplacement == 0) + { + sourceDisplacement = null; + } + } + if (destinationIsIndirect && sourceIsIndirect) + { + throw new Exception("Both destination and source cannot be indirect!"); + } + + new T + { + DestinationRef = ElementReference.New(destination), + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = destinationDisplacement, + SourceRef = ElementReference.New(source), + SourceIsIndirect = sourceIsIndirect, + SourceDisplacement = sourceDisplacement, + }; + } + + private static void DoDestinationSource(Register destination, string sourceLabel, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + where T : InstructionWithDestinationAndSource, new() + { + if (destinationDisplacement != null) + { + destinationIsIndirect = true; + if (destinationDisplacement == 0) + { + destinationDisplacement = null; + } + } + if (sourceDisplacement != null) + { + sourceIsIndirect = true; + if (sourceDisplacement == 0) + { + sourceDisplacement = null; + } + } + + new T + { + DestinationReg = destination.RegEnum, + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = destinationDisplacement, + SourceRef = ElementReference.New(sourceLabel), + SourceIsIndirect = sourceIsIndirect, + SourceDisplacement = sourceDisplacement + }; + } + + private static void DoDestinationSource(Register destination, uint value, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + where T : InstructionWithDestinationAndSource, new() + { + if (destinationDisplacement != null) + { + destinationIsIndirect = true; + if (destinationDisplacement == 0) + { + destinationDisplacement = null; + } + } + + if (sourceDisplacement != null) + { + sourceIsIndirect = true; + if (sourceDisplacement == 0) + { + sourceDisplacement = null; + } + } + + new T + { + DestinationReg = destination.RegEnum, + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = destinationDisplacement, + SourceValue = value, + SourceIsIndirect = sourceIsIndirect, + SourceDisplacement = sourceDisplacement, + }; + } + + private static void DoDestinationSource(Register destination, + Register source, + bool destinationIsIndirect = false, + int? destinationDisplacement = null, + bool sourceIsIndirect = false, + int? sourceDisplacement = null) + where T : InstructionWithDestinationAndSource, new() + { + if (destinationDisplacement != null) + { + destinationIsIndirect = true; + if (destinationDisplacement == 0) + { + destinationDisplacement = null; + } + } + if (sourceDisplacement != null) + { + sourceIsIndirect = true; + if (sourceDisplacement == 0) + { + sourceDisplacement = null; + } + } + if (destinationIsIndirect && sourceIsIndirect) + { + throw new Exception("Both destination and source cannot be indirect!"); + } + + new T + { + DestinationReg = destination.RegEnum, + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = destinationDisplacement, + SourceIsIndirect = sourceIsIndirect, + SourceDisplacement = sourceDisplacement, + SourceReg = source.RegEnum + }; + } + + #endregion InstructionWithDestinationAndSource + #region Mov public static void Set(string destination, Register source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null, RegisterSize? size = null) { diff --git a/source/XSharp.Compiler/XSRegisters.cs b/source/XSharp.Compiler/XSRegisters.cs index db6782046..579435f17 100644 --- a/source/XSharp.Compiler/XSRegisters.cs +++ b/source/XSharp.Compiler/XSRegisters.cs @@ -12,7 +12,8 @@ namespace XSharp.Compiler Byte8 = 8, Short16 = 16, Int32 = 32, - FPU = 128, + FPU = 128, + XMM = 128, } public abstract class Register @@ -27,6 +28,11 @@ namespace XSharp.Compiler Name = name; RegEnum = regEnum; } + + public static implicit operator RegistersEnum(Register register) + { + return register.RegEnum; + } } private static readonly Dictionary mRegisters; @@ -78,9 +84,16 @@ namespace XSharp.Compiler } } + public class RegisterXMM : Register + { + public RegisterXMM(string name, RegistersEnum regEnum) : base(name, regEnum, RegisterSize.XMM) + { + } + } + public class RegisterSegment: Register { - public RegisterSegment(string name, RegistersEnum regEnum): base(name, regEnum, RegisterSize.Int32) + public RegisterSegment(string name, RegistersEnum regEnum): base(name, regEnum, RegisterSize.Short16) { } } @@ -126,5 +139,15 @@ namespace XSharp.Compiler public static readonly RegisterFPU ST5 = new RegisterFPU(nameof(ST5), RegistersEnum.ST5); public static readonly RegisterFPU ST6 = new RegisterFPU(nameof(ST6), RegistersEnum.ST6); public static readonly RegisterFPU ST7 = new RegisterFPU(nameof(ST7), RegistersEnum.ST7); + + public static readonly RegisterXMM XMM0 = new RegisterXMM(nameof(XMM0), RegistersEnum.XMM0); + public static readonly RegisterXMM XMM1 = new RegisterXMM(nameof(XMM1), RegistersEnum.XMM1); + public static readonly RegisterXMM XMM2 = new RegisterXMM(nameof(XMM2), RegistersEnum.XMM2); + public static readonly RegisterXMM XMM3 = new RegisterXMM(nameof(XMM3), RegistersEnum.XMM3); + public static readonly RegisterXMM XMM4 = new RegisterXMM(nameof(XMM4), RegistersEnum.XMM4); + public static readonly RegisterXMM XMM5 = new RegisterXMM(nameof(XMM5), RegistersEnum.XMM5); + public static readonly RegisterXMM XMM6 = new RegisterXMM(nameof(XMM6), RegistersEnum.XMM6); + public static readonly RegisterXMM XMM7 = new RegisterXMM(nameof(XMM7), RegistersEnum.XMM7); + } } diff --git a/source/XSharp.Compiler/XSTemplate.DestinationSource.txt b/source/XSharp.Compiler/XSTemplate.DestinationSource.txt new file mode 100644 index 000000000..365f061b7 --- /dev/null +++ b/source/XSharp.Compiler/XSTemplate.DestinationSource.txt @@ -0,0 +1,29 @@ + public static void $MethodName$(string destination, Register source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource<$InstructionClass$>(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void $MethodName$(string destination, UInt32 value, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource<$InstructionClass$>(destination, value, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void $MethodName$(string destination, string source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource<$InstructionClass$>(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void $MethodName$(Register destination, string sourceLabel, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource<$InstructionClass$>(destination, sourceLabel, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void $MethodName$(Register destination, uint value, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource<$InstructionClass$>(destination, value, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void $MethodName$(Register destination, Register source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource<$InstructionClass$>(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } diff --git a/source/XSharp.Compiler/XSharp.Compiler.csproj b/source/XSharp.Compiler/XSharp.Compiler.csproj index 129fdc826..4ca40122e 100644 --- a/source/XSharp.Compiler/XSharp.Compiler.csproj +++ b/source/XSharp.Compiler/XSharp.Compiler.csproj @@ -102,6 +102,8 @@ + + @@ -127,6 +129,7 @@ +