mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 12:30:32 +00:00
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
This commit is contained in:
parent
bcd92cf77c
commit
51e893eb74
8 changed files with 127 additions and 208 deletions
|
|
@ -64,6 +64,7 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MoveSignExtend.cs" />
|
||||
<Compile Include="Lgdt.cs" />
|
||||
<Compile Include="Lidt.cs" />
|
||||
<Compile Include="Shrd.cs" />
|
||||
|
|
@ -75,6 +76,7 @@
|
|||
<Compile Include="SignExtendAX.cs" />
|
||||
<Compile Include="CmpXchg.cs" />
|
||||
<Compile Include="CpuId.cs" />
|
||||
<Compile Include="x87\FloatNegate.cs" />
|
||||
<Compile Include="XchgAndAdd.cs" />
|
||||
<Compile Include="Add.cs" />
|
||||
<Compile Include="AddWithCarry.cs" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
namespace Cosmos.Compiler.Assembler.X86 {
|
||||
[OpCode("movsx")]
|
||||
public class MoveSignExtend : InstructionWithDestinationAndSourceAndSize
|
||||
{
|
||||
|
||||
public override void WriteText(Assembler aAssembler, System.IO.TextWriter aOutput)
|
||||
{
|
||||
if (Size == 0)
|
||||
{
|
||||
Size = 32;
|
||||
}
|
||||
aOutput.Write(mMnemonic);
|
||||
if (!DestinationEmpty)
|
||||
{
|
||||
aOutput.Write(" ");
|
||||
aOutput.Write(this.GetDestinationAsString());
|
||||
aOutput.Write(", ");
|
||||
aOutput.Write(SizeToString(Size));
|
||||
aOutput.Write(" ");
|
||||
aOutput.Write(this.GetSourceAsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Cosmos.Compiler.Assembler.X86.x87
|
||||
{
|
||||
[OpCode("fchs")]
|
||||
public class FloatNegate : Instruction
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ using Cosmos.IL2CPU.ILOpCodes;
|
|||
using Cosmos.IL2CPU.X86;
|
||||
using Cosmos.Compiler.Assembler;
|
||||
using Cosmos.Compiler.Assembler.X86;
|
||||
using CPUx86 = Cosmos.Compiler.Assembler.X86;
|
||||
|
||||
namespace Cosmos.IL2CPU.X86.IL
|
||||
{
|
||||
|
|
@ -83,7 +84,6 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
}
|
||||
|
||||
public static void DoExecute(Assembler Assembler, MethodInfo aMethod, ushort aParam) {
|
||||
uint xArgSize = 0u;
|
||||
var xDisplacement = GetArgumentDisplacement(aMethod, aParam);
|
||||
Type xArgType;
|
||||
if (aMethod.MethodBase.IsStatic) {
|
||||
|
|
@ -101,16 +101,25 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
}
|
||||
new Comment("Ldarg");
|
||||
new Comment("Arg idx = " + aParam);
|
||||
xArgSize = Align(SizeOfType(xArgType), 4);
|
||||
new Comment("Arg type = " + xArgType.ToString());
|
||||
new Comment("Arg size = " + xArgSize);
|
||||
for (int i = 0; i < (xArgSize / 4); i++) {
|
||||
new Push {
|
||||
DestinationReg = Registers.EBP,
|
||||
DestinationIsIndirect = true,
|
||||
DestinationDisplacement = (int)(xDisplacement - (i * 4))
|
||||
};
|
||||
}
|
||||
uint xArgRealSize = SizeOfType(xArgType);
|
||||
uint xArgSize = Align(xArgRealSize, 4);
|
||||
new Comment("Arg type = " + xArgType.ToString());
|
||||
new Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize);
|
||||
if (xArgRealSize < 4)
|
||||
{
|
||||
new CPUx86.MoveSignExtend { DestinationReg = CPUx86.Registers.EAX, Size = (byte)(xArgRealSize * 8), SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = xDisplacement };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < (xArgSize / 4); i++) {
|
||||
new Push {
|
||||
DestinationReg = Registers.EBP,
|
||||
DestinationIsIndirect = true,
|
||||
DestinationDisplacement = xDisplacement - (i * 4)
|
||||
};
|
||||
}
|
||||
}
|
||||
Assembler.Stack.Push(xArgSize, xArgType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,16 +34,9 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
switch (xSize)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
new CPUx86.Xor { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.AL, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
new CPUx86.Xor { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.AX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset };
|
||||
new CPUx86.MoveSignExtend { DestinationReg = CPUx86.Registers.EAX, Size = (byte)(xSize * 8), SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 0 - xEBPOffset };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
break;
|
||||
}
|
||||
|
|
@ -53,13 +46,8 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#if DOTNETCOMPATIBLE
|
||||
Assembler.Stack.Push(ILOp.Align(xSize, 4), xVar.LocalType);
|
||||
#else
|
||||
Assembler.Stack.Push(xSize, xVar.LocalType);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using CPUx86 = Cosmos.Compiler.Assembler.X86;
|
||||
using Cosmos.Compiler.Assembler.X86;
|
||||
using Label = Cosmos.Compiler.Assembler.Label;
|
||||
namespace Cosmos.IL2CPU.X86.IL
|
||||
{
|
||||
|
|
@ -19,10 +18,10 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
{
|
||||
if (xStackContent.IsFloat)
|
||||
{
|
||||
new CPUx86.x87.FloatLoad { DestinationReg = Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||
new CPUx86.Add { SourceValue = 8, DestinationReg = Registers.ESP };
|
||||
new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||
new CPUx86.Add { SourceValue = 8, DestinationReg = CPUx86.Registers.ESP };
|
||||
new CPUx86.x87.FloatMul { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, Size = 64 };
|
||||
new CPUx86.x87.FloatStoreAndPop { DestinationReg = Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||
new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true };
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -47,7 +46,7 @@ namespace Cosmos.IL2CPU.X86.IL
|
|||
//mov RIGHT_HIGH to eax, is useable on Full 64 multiply
|
||||
new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = 4 };
|
||||
new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = 12 };
|
||||
new CPUx86.ConditionalJump { Condition = ConditionalTestEnum.Zero, DestinationLabel = Simple32Multiply };
|
||||
new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Zero, DestinationLabel = Simple32Multiply };
|
||||
// Full 64 Multiply
|
||||
|
||||
// eax contains already RIGHT_HIGH
|
||||
|
|
|
|||
|
|
@ -3,20 +3,51 @@ 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 )
|
||||
{
|
||||
}
|
||||
[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 )
|
||||
{
|
||||
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Neg { DestinationReg = CPUx86.Registers.EAX };
|
||||
new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX };
|
||||
}
|
||||
|
||||
}
|
||||
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 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace Cosmos.System.Plugs.System
|
|||
public const double PI = 3.14159265358979;
|
||||
public const double E = 2.71828182845905;
|
||||
|
||||
// TODO Abs decimal
|
||||
#region Abs
|
||||
public static double Abs(double value)
|
||||
{
|
||||
|
|
@ -37,6 +38,7 @@ namespace Cosmos.System.Plugs.System
|
|||
}
|
||||
}
|
||||
|
||||
/* should work from ms .net
|
||||
public static long Abs(long value)
|
||||
{
|
||||
if (value < 0)
|
||||
|
|
@ -59,23 +61,13 @@ namespace Cosmos.System.Plugs.System
|
|||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
#endregion
|
||||
|
||||
// TODO Max decimal
|
||||
#region Max
|
||||
public static byte Max(byte val1, byte val2)
|
||||
{
|
||||
if (val1 > val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
//public static decimal Max(decimal val1, decimal val2)
|
||||
|
||||
//public static decimal Max(decimal val1, decimal val2)
|
||||
//{
|
||||
// if (val1 > val2)
|
||||
// {
|
||||
|
|
@ -87,79 +79,10 @@ namespace Cosmos.System.Plugs.System
|
|||
// }
|
||||
//}
|
||||
|
||||
public static double Max(double val1, double val2)
|
||||
{
|
||||
if (val1 > val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static short Max(short val1, short val2)
|
||||
{
|
||||
if (val1 > val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static int Max(int val1, int val2)
|
||||
{
|
||||
if (val1 > val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static long Max(long val1, long val2)
|
||||
{
|
||||
if (val1 > val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static float Max(float val1, float val2)
|
||||
{
|
||||
if (val1 > val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
//TODO Min decimal
|
||||
#region Min
|
||||
public static byte Min(byte val1, byte val2)
|
||||
{
|
||||
if (val1 < val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
//public static decimal Min(decimal val1, decimal val2)
|
||||
//{
|
||||
|
|
@ -173,65 +96,6 @@ namespace Cosmos.System.Plugs.System
|
|||
// }
|
||||
//}
|
||||
|
||||
public static double Min(double val1, double val2)
|
||||
{
|
||||
if (val1 < val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static short Min(short val1, short val2)
|
||||
{
|
||||
if (val1 < val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static int Min(int val1, int val2)
|
||||
{
|
||||
if (val1 < val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static long Min(long val1, long val2)
|
||||
{
|
||||
if (val1 < val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
|
||||
public static float Min(float val1, float val2)
|
||||
{
|
||||
if (val1 < val2)
|
||||
{
|
||||
return val1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return val2;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Pow
|
||||
|
|
@ -261,7 +125,7 @@ namespace Cosmos.System.Plugs.System
|
|||
|
||||
#region Sin
|
||||
public static double Sin(double a)
|
||||
{
|
||||
{ // should be using assembler instruction
|
||||
bool signSwitch = false;
|
||||
double result = 0;
|
||||
|
||||
|
|
@ -283,8 +147,6 @@ namespace Cosmos.System.Plugs.System
|
|||
result = (radians) - (Math.Pow(radians, 3) / Factorial(3));
|
||||
result += (Math.Pow(radians, 5) / Factorial(5)) - (Math.Pow(radians, 7) / Factorial(7)) + (Math.Pow(radians, 9) / Factorial(9));
|
||||
|
||||
//result *= -1;
|
||||
|
||||
/* USE WHEN Modulus Works
|
||||
* int sign = 0;
|
||||
for (int i = 3; i < 19; i += 2)
|
||||
|
|
@ -318,7 +180,7 @@ namespace Cosmos.System.Plugs.System
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region Factorial
|
||||
#region Factorial (only used in Sin(), not plug )
|
||||
public static int Factorial(int n)
|
||||
{
|
||||
if (n == 0)
|
||||
|
|
@ -329,26 +191,23 @@ namespace Cosmos.System.Plugs.System
|
|||
#endregion
|
||||
|
||||
#region Ceiling
|
||||
public static double Ceiling(double a)
|
||||
{
|
||||
int returnval = (int)Floor(a);
|
||||
returnval += 1;
|
||||
return returnval;
|
||||
}
|
||||
public static double Ceiling(double a)
|
||||
{ // should be using assembler for bigger values than int or long max
|
||||
if (a == Double.NaN || a == Double.NegativeInfinity || a == Double.PositiveInfinity)
|
||||
return a;
|
||||
int i = (a - (int)a > 0) ? (int)(a + 1) : (int)a;
|
||||
return i;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Floor
|
||||
public static double Floor(double a)
|
||||
{
|
||||
int returnval = (int)a;
|
||||
|
||||
if (a < 0)
|
||||
{
|
||||
returnval -= 1;
|
||||
}
|
||||
|
||||
return returnval;
|
||||
}
|
||||
public static double Floor(double a)
|
||||
{ // should be using assembler for bigger values than int or long max
|
||||
if (a == Double.NaN || a == Double.NegativeInfinity || a == Double.PositiveInfinity)
|
||||
return a;
|
||||
int i = (a - (int)a < 0) ? (int)(a - 1) : (int)a;
|
||||
return i;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue