diff --git a/source/Cosmos.IL2CPU/IL/Neg.cs b/source/Cosmos.IL2CPU/IL/Neg.cs index e9573adc3..27a750adc 100644 --- a/source/Cosmos.IL2CPU/IL/Neg.cs +++ b/source/Cosmos.IL2CPU/IL/Neg.cs @@ -9,7 +9,9 @@ namespace Cosmos.IL2CPU.X86.IL [Cosmos.IL2CPU.OpCode( ILOpCode.Code.Neg )] public class Neg : ILOp { - public Neg( Cosmos.Assembler.Assembler aAsmblr ) + static bool varDone = false; + + public Neg( Cosmos.Assembler.Assembler aAsmblr ) : base( aAsmblr ) { } @@ -25,8 +27,7 @@ namespace Cosmos.IL2CPU.X86.IL { // There is no direct double negate instruction in SSE simply we do a XOR with 0x8000000000 to flip the sign bit XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true); - //XS.LiteralCode(@"pxor XMM0, [__doublesignbit]"); - XS.LiteralCode(@"xorpd XMM0, [__doublesignbit]"); + XS.SSE2.XorPD(XMM0, "__doublesignbit", sourceIsIndirect: true); XS.SSE2.MoveSD(ESP, XMM0, destinationIsIndirect: true); #if false @@ -50,13 +51,19 @@ namespace Cosmos.IL2CPU.X86.IL { if (xStackContentIsFloat) { -#if true - // There is no direct float negate instruction in SSE simply we do a XOR with 0x8000000000 to flip the sign bit - XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); - XS.LiteralCode("movss XMM1, [__floatsignbit]"); - XS.LiteralCode(@"xorps XMM0, XMM1"); - XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); +#if false + if (varDone == false) + { + XS.DataMember("__floatsignbit", 0x80000000); + varDone = true; + } #endif + + // There is no direct float negate instruction in SSE simply we do a XOR with 0x80000000 to flip the sign bit + XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); + XS.SSE.MoveSS(XMM1, "__floatsignbit", sourceIsIndirect: true); + XS.SSE.XorPS(XMM0, XMM1); + XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); #if false XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Int32); XS.FPU.FloatNegate(); diff --git a/source/XSharp.Compiler/XS.SSE.cs b/source/XSharp.Compiler/XS.SSE.cs index 21a793a12..933cedc13 100644 --- a/source/XSharp.Compiler/XS.SSE.cs +++ b/source/XSharp.Compiler/XS.SSE.cs @@ -1,4 +1,5 @@ -using Cosmos.Assembler.x86.SSE; +using System; +using Cosmos.Assembler.x86.SSE; using Cosmos.Assembler.x86.x87; using static XSharp.Compiler.XSRegisters; @@ -90,6 +91,11 @@ namespace XSharp.Compiler }; } + public static void MoveSS(RegisterXMM 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 ConvertSS2SD(RegisterXMM destination, Register32 source, bool sourceIsIndirect = false) { new ConvertSS2SD() diff --git a/source/XSharp.Compiler/XS.SSE2.cs b/source/XSharp.Compiler/XS.SSE2.cs index 99aec1588..354f9322d 100644 --- a/source/XSharp.Compiler/XS.SSE2.cs +++ b/source/XSharp.Compiler/XS.SSE2.cs @@ -124,6 +124,16 @@ namespace XSharp.Compiler SourceReg = source }; } + + public static void XorPD(RegisterXMM destination, RegisterXMM source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + + public static void XorPD(RegisterXMM destination, String sourceLabel, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, sourceLabel, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } } } }