Cosmos/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Neg.cs
Trivalik_cp 51e893eb74 add movsx, fchs
implement neg CIL (needed for Abs())
fix floor and ceiling in range of int
add sign extension to LdArg and LdLoc
remove unneeded math functions, like min,max,abs
2011-09-02 21:03:14 +00:00

53 lines
1.8 KiB
C#

using System;
using CPUx86 = Cosmos.Compiler.Assembler.X86;
namespace Cosmos.IL2CPU.X86.IL
{
[Cosmos.IL2CPU.OpCode( ILOpCode.Code.Neg )]
public class Neg : ILOp
{
public Neg( Cosmos.Compiler.Assembler.Assembler aAsmblr )
: base( aAsmblr )
{
}
public override void Execute( MethodInfo aMethod, ILOpCode aOpCode )
{
var xStackContent = Assembler.Stack.Peek();
if (xStackContent.Size > 4)
{
if (xStackContent.IsFloat)
{
new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
new CPUx86.x87.FloatNegate { };
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
}
else
{
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EBX }; // low
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; // high
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EBX }; // set carry if EBX != 0
new CPUx86.AddWithCarry { DestinationReg = CPUx86.Registers.EAX, SourceValue = 0 };
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Push { DestinationReg = CPUx86.Registers.EBX };
}
}
else
{
if (xStackContent.IsFloat)
{
new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.ESP, Size = 32, DestinationIsIndirect = true };
new CPUx86.x87.FloatNegate { };
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 32, DestinationIsIndirect = true };
}
else
{
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
}
}
}
}
}