mirror of
https://github.com/creeperlv/SVM.git
synced 2026-01-11 12:59: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 [I]SType [I]TType [I]S [I]T
|
||||||
Cvt,
|
Cvt,
|
||||||
// Set Conditional Register to 1 if condition met.
|
// Set Conditional Register to 1 if condition met.
|
||||||
// 0 1 2 3 4
|
// 0 1 2 3 4 5
|
||||||
// Cmp [R]Op [R]L [R]R [R]T
|
// Cmp [R]Op [I]Type [R]L [R]R [R]T
|
||||||
Cmp,
|
Cmp,
|
||||||
//Set Data to Register
|
//Set Data to Register
|
||||||
//SD T
|
//SD T
|
||||||
@@ -75,6 +75,21 @@
|
|||||||
Float,
|
Float,
|
||||||
Double,
|
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
|
public enum ConditionFlag : byte
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -109,4 +124,8 @@
|
|||||||
Log,
|
Log,
|
||||||
Sqrt
|
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;
|
break;
|
||||||
case PrimaryInstruction.Cmp:
|
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;
|
break;
|
||||||
case PrimaryInstruction.SD:
|
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);
|
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
|
public static void SetData<T>(this IntPtr ptr, T data) where T : unmanaged
|
||||||
{
|
{
|
||||||
var srcPtr = (byte*)&data;
|
var srcPtr = (byte*)&data;
|
||||||
|
|||||||
Reference in New Issue
Block a user