mirror of
https://github.com/creeperlv/SVM.git
synced 2026-01-10 20:39:54 +00:00
Implemented CMP.
This commit is contained in:
309
src/SVM.Core/FuncImpl/CompareFunctions.cs
Normal file
309
src/SVM.Core/FuncImpl/CompareFunctions.cs
Normal file
@@ -0,0 +1,309 @@
|
||||
using SVM.Core.Data;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace SVM.Core.FuncImpl
|
||||
{
|
||||
public unsafe static class CompareFunctions
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LT(Registers context, SVMInstruction_InSeparateBytes inst)
|
||||
{
|
||||
var type = (NativeType)inst.D2;
|
||||
var L = inst.D3;
|
||||
var R = inst.D4;
|
||||
var T = inst.D4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NativeType.BU:
|
||||
GenericLT<CompactByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.BS:
|
||||
GenericLT<CompactSByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.S:
|
||||
GenericLT<CompactShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.SU:
|
||||
GenericLT<CompactUShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.I:
|
||||
GenericLT<CompactInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.IU:
|
||||
GenericLT<CompactUInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.L:
|
||||
GenericLT<CompactLong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.LU:
|
||||
GenericLT<CompactULong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.F:
|
||||
GenericLT<CompactSingle>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.D:
|
||||
GenericLT<CompactDouble>(context, L, R, T);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GT(Registers context, SVMInstruction_InSeparateBytes inst)
|
||||
{
|
||||
var type = (NativeType)inst.D2;
|
||||
var L = inst.D3;
|
||||
var R = inst.D4;
|
||||
var T = inst.D4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NativeType.BU:
|
||||
GenericGT<CompactByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.BS:
|
||||
GenericGT<CompactSByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.S:
|
||||
GenericGT<CompactShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.SU:
|
||||
GenericGT<CompactUShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.I:
|
||||
GenericGT<CompactInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.IU:
|
||||
GenericGT<CompactUInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.L:
|
||||
GenericGT<CompactLong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.LU:
|
||||
GenericGT<CompactULong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.F:
|
||||
GenericGT<CompactSingle>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.D:
|
||||
GenericGT<CompactDouble>(context, L, R, T);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void LE(Registers context, SVMInstruction_InSeparateBytes inst)
|
||||
{
|
||||
var type = (NativeType)inst.D2;
|
||||
var L = inst.D3;
|
||||
var R = inst.D4;
|
||||
var T = inst.D4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NativeType.BU:
|
||||
GenericLT<CompactByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.BS:
|
||||
GenericLT<CompactSByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.S:
|
||||
GenericLT<CompactShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.SU:
|
||||
GenericLT<CompactUShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.I:
|
||||
GenericLT<CompactInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.IU:
|
||||
GenericLT<CompactUInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.L:
|
||||
GenericLT<CompactLong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.LU:
|
||||
GenericLT<CompactULong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.F:
|
||||
GenericLT<CompactSingle>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.D:
|
||||
GenericLT<CompactDouble>(context, L, R, T);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GE(Registers context, SVMInstruction_InSeparateBytes inst)
|
||||
{
|
||||
var type = (NativeType)inst.D2;
|
||||
var L = inst.D3;
|
||||
var R = inst.D4;
|
||||
var T = inst.D4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NativeType.BU:
|
||||
GenericGE<CompactByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.BS:
|
||||
GenericGE<CompactSByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.S:
|
||||
GenericGE<CompactShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.SU:
|
||||
GenericGE<CompactUShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.I:
|
||||
GenericGE<CompactInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.IU:
|
||||
GenericGE<CompactUInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.L:
|
||||
GenericGE<CompactLong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.LU:
|
||||
GenericGE<CompactULong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.F:
|
||||
GenericGE<CompactSingle>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.D:
|
||||
GenericGE<CompactDouble>(context, L, R, T);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void EQ(Registers context, SVMInstruction_InSeparateBytes inst)
|
||||
{
|
||||
var type = (NativeType)inst.D2;
|
||||
var L = inst.D3;
|
||||
var R = inst.D4;
|
||||
var T = inst.D4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NativeType.BU:
|
||||
GenericEQ<CompactByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.BS:
|
||||
GenericEQ<CompactSByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.S:
|
||||
GenericEQ<CompactShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.SU:
|
||||
GenericEQ<CompactUShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.I:
|
||||
GenericEQ<CompactInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.IU:
|
||||
GenericEQ<CompactUInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.L:
|
||||
GenericEQ<CompactLong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.LU:
|
||||
GenericEQ<CompactULong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.F:
|
||||
GenericEQ<CompactSingle>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.D:
|
||||
GenericEQ<CompactDouble>(context, L, R, T);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void NE(Registers context, SVMInstruction_InSeparateBytes inst)
|
||||
{
|
||||
var type = (NativeType)inst.D2;
|
||||
var L = inst.D3;
|
||||
var R = inst.D4;
|
||||
var T = inst.D4;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case NativeType.BU:
|
||||
GenericNE<CompactByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.BS:
|
||||
GenericNE<CompactSByte>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.S:
|
||||
GenericNE<CompactShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.SU:
|
||||
GenericNE<CompactUShort>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.I:
|
||||
GenericNE<CompactInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.IU:
|
||||
GenericNE<CompactUInt>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.L:
|
||||
GenericNE<CompactLong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.LU:
|
||||
GenericNE<CompactULong>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.F:
|
||||
GenericNE<CompactSingle>(context, L, R, T);
|
||||
break;
|
||||
case NativeType.D:
|
||||
GenericNE<CompactDouble>(context, L, R, T);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GenericLT<N>(Registers Register, int L, int R, int T) where N : unmanaged, INumbericData<N>
|
||||
{
|
||||
var LN = Register.GetData<N>(L);
|
||||
var RN = Register.GetData<N>(R);
|
||||
bool TN = LN.LT(RN);
|
||||
Register.SetData(T, TN ? 1 : 0);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GenericGT<N>(Registers Register, int L, int R, int T) where N : unmanaged, INumbericData<N>
|
||||
{
|
||||
var LN = Register.GetData<N>(L);
|
||||
var RN = Register.GetData<N>(R);
|
||||
bool TN = LN.GT(RN);
|
||||
Register.SetData(T, TN ? 1 : 0);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GenericLE<N>(Registers Register, int L, int R, int T) where N : unmanaged, INumbericData<N>
|
||||
{
|
||||
var LN = Register.GetData<N>(L);
|
||||
var RN = Register.GetData<N>(R);
|
||||
bool TN = LN.LE(RN);
|
||||
Register.SetData(T, TN ? 1 : 0);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GenericGE<N>(Registers Register, int L, int R, int T) where N : unmanaged, INumbericData<N>
|
||||
{
|
||||
var LN = Register.GetData<N>(L);
|
||||
var RN = Register.GetData<N>(R);
|
||||
bool TN = LN.GE(RN);
|
||||
Register.SetData(T, TN ? 1 : 0);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GenericEQ<N>(Registers Register, int L, int R, int T) where N : unmanaged, INumbericData<N>
|
||||
{
|
||||
var LN = Register.GetData<N>(L);
|
||||
var RN = Register.GetData<N>(R);
|
||||
bool TN = LN.EQ(RN);
|
||||
Register.SetData(T, TN ? 1 : 0);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void GenericNE<N>(Registers Register, int L, int R, int T) where N : unmanaged, INumbericData<N>
|
||||
{
|
||||
var LN = Register.GetData<N>(L);
|
||||
var RN = Register.GetData<N>(R);
|
||||
bool TN = LN.NE(RN);
|
||||
Register.SetData(T, TN ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@
|
||||
//Cvt [I]SType [I]TType [I]S [I]T
|
||||
Cvt,
|
||||
// Set Conditional Register to 1 if condition met.
|
||||
// 0 1 2 3 4
|
||||
// Cmp [R]Op [R]L [R]R [R]T
|
||||
// 0 1 2 3 4 5
|
||||
// Cmp [R]Op [I]Type [R]L [R]R [R]T
|
||||
Cmp,
|
||||
//Set Data to Register
|
||||
//SD T
|
||||
@@ -75,6 +75,21 @@
|
||||
Float,
|
||||
Double,
|
||||
}
|
||||
|
||||
public enum NativeType : byte
|
||||
{
|
||||
BS = SVMNativeTypes.Int8,
|
||||
BU = SVMNativeTypes.UInt8,
|
||||
S = SVMNativeTypes.Int16,
|
||||
SU = SVMNativeTypes.UInt16,
|
||||
I = SVMNativeTypes.Int32,
|
||||
IU = SVMNativeTypes.UInt32,
|
||||
L = SVMNativeTypes.Int64,
|
||||
LU = SVMNativeTypes.UInt64,
|
||||
F = SVMNativeTypes.Float,
|
||||
D = SVMNativeTypes.Double,
|
||||
R
|
||||
}
|
||||
public enum ConditionFlag : byte
|
||||
{
|
||||
/// <summary>
|
||||
@@ -109,4 +124,8 @@
|
||||
Log,
|
||||
Sqrt
|
||||
}
|
||||
public enum CompareOperator : byte
|
||||
{
|
||||
LT = 0, GT = 1, GE = 2, EQ = 3, LE = 4, NE = 5,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +215,34 @@ namespace SVM.Core
|
||||
}
|
||||
break;
|
||||
case PrimaryInstruction.Cmp:
|
||||
{
|
||||
var InstAlt = Instruction.CastAs<SVMInstruction, SVMInstruction_InSeparateBytes>(0);
|
||||
var OP = (CompareOperator)InstAlt.D0;
|
||||
switch (OP)
|
||||
{
|
||||
case CompareOperator.LT:
|
||||
CompareFunctions.LT(this.registers, InstAlt);
|
||||
break;
|
||||
case CompareOperator.GT:
|
||||
CompareFunctions.GT(this.registers, InstAlt);
|
||||
break;
|
||||
case CompareOperator.GE:
|
||||
CompareFunctions.GE(this.registers, InstAlt);
|
||||
break;
|
||||
case CompareOperator.EQ:
|
||||
CompareFunctions.EQ(this.registers, InstAlt);
|
||||
break;
|
||||
case CompareOperator.LE:
|
||||
CompareFunctions.LE(this.registers, InstAlt);
|
||||
break;
|
||||
case CompareOperator.NE:
|
||||
CompareFunctions.NE(this.registers, InstAlt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case PrimaryInstruction.SD:
|
||||
{
|
||||
@@ -550,4 +578,16 @@ namespace SVM.Core
|
||||
}
|
||||
}
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct SVMInstruction_InSeparateBytes
|
||||
{
|
||||
public byte D0;
|
||||
public byte D1;
|
||||
public byte D2;
|
||||
public byte D3;
|
||||
public byte D4;
|
||||
public byte D5;
|
||||
public byte D6;
|
||||
public byte D7;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ namespace SVM.Core.Utils
|
||||
{
|
||||
GetDataWithOffsetInStructCount<T>(ptr, (IntPtr)dest, offset);
|
||||
}
|
||||
public static V CastAs<T, V>(this T t, ushort offset = 0) where T : unmanaged where V : unmanaged
|
||||
{
|
||||
return ((V*)&t)[offset];
|
||||
}
|
||||
public static void SetData<T>(this IntPtr ptr, T data) where T : unmanaged
|
||||
{
|
||||
var srcPtr = (byte*)&data;
|
||||
|
||||
Reference in New Issue
Block a user