From ae79862c077f3a8464926283d3448478b2a25154 Mon Sep 17 00:00:00 2001 From: Creeper Lv Date: Fri, 18 Jul 2025 03:13:41 +0800 Subject: [PATCH] Made some basic staff. --- src/SVM.Core/Data/CompactByte.cs | 216 ++++++++++++++++ src/SVM.Core/Data/CompactDouble.cs | 214 ++++++++++++++++ src/SVM.Core/Data/CompactInt.cs | 216 ++++++++++++++++ src/SVM.Core/Data/CompactLong.cs | 213 ++++++++++++++++ src/SVM.Core/Data/CompactSByte.cs | 214 ++++++++++++++++ src/SVM.Core/Data/CompactShort.cs | 213 ++++++++++++++++ src/SVM.Core/Data/CompactSingle.cs | 213 ++++++++++++++++ src/SVM.Core/Data/CompactUInt.cs | 213 ++++++++++++++++ src/SVM.Core/Data/CompactULong.cs | 213 ++++++++++++++++ src/SVM.Core/Data/CompactUShort.cs | 216 ++++++++++++++++ src/SVM.Core/Data/INumberData.cs | 68 +++++ src/SVM.Core/FuncImpl/MathImpl.cs | 284 +++++++++++++++++++++ src/SVM.Core/Registers.cs | 41 +++ src/SVM.Core/{SVMInst.cs => SVMInstDef.cs} | 65 +++-- src/SVM.Core/SimpleVirtualMachine.cs | 282 +++++++++++++++++--- src/SVM.Core/stdc/stdlib.cs | 4 + 16 files changed, 2831 insertions(+), 54 deletions(-) create mode 100644 src/SVM.Core/Data/CompactByte.cs create mode 100644 src/SVM.Core/Data/CompactDouble.cs create mode 100644 src/SVM.Core/Data/CompactInt.cs create mode 100644 src/SVM.Core/Data/CompactLong.cs create mode 100644 src/SVM.Core/Data/CompactSByte.cs create mode 100644 src/SVM.Core/Data/CompactShort.cs create mode 100644 src/SVM.Core/Data/CompactSingle.cs create mode 100644 src/SVM.Core/Data/CompactUInt.cs create mode 100644 src/SVM.Core/Data/CompactULong.cs create mode 100644 src/SVM.Core/Data/CompactUShort.cs create mode 100644 src/SVM.Core/Data/INumberData.cs create mode 100644 src/SVM.Core/FuncImpl/MathImpl.cs create mode 100644 src/SVM.Core/Registers.cs rename src/SVM.Core/{SVMInst.cs => SVMInstDef.cs} (54%) diff --git a/src/SVM.Core/Data/CompactByte.cs b/src/SVM.Core/Data/CompactByte.cs new file mode 100644 index 0000000..260d5d9 --- /dev/null +++ b/src/SVM.Core/Data/CompactByte.cs @@ -0,0 +1,216 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactByte : INumbericData + { + public byte Value; + public CompactByte(byte value) { Value = value; } + public CompactByte(int value) { Value = (byte)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactByte Add(CompactByte R) + { + return new CompactByte(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactByte Sub(CompactByte R) + { + return new CompactByte(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactByte Mul(CompactByte R) + { + return new CompactByte(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactByte Div(CompactByte R) + { + return new CompactByte(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactByte R) + { + CompactByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactByte(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactByte(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactByte R) + { + CompactByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactByte(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactByte(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactByte R) + { + CompactByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactByte(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactByte(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactByte R) + { + CompactByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactByte(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactByte(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactByte R) + { + return Value < R.Value; + } + + public bool GT(CompactByte R) + { + return Value > R.Value; + } + + public bool LE(CompactByte R) + { + return Value <= R.Value; + } + + public bool GE(CompactByte R) + { + return Value >= R.Value; + } + + public bool EQ(CompactByte R) + { + return Value == R.Value; + } + + public bool NE(CompactByte R) + { + return Value != R.Value; + } + + public INumbericData Cast_Byte() + { + return new CompactByte(Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort(Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort(Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt(Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt(Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong(Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + targetPtr[0] = Value; + } + public int SizeOf() + { + return sizeof(byte); + } + + public CompactByte Mod(CompactByte R) + { + return new CompactByte(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactDouble.cs b/src/SVM.Core/Data/CompactDouble.cs new file mode 100644 index 0000000..65aaf5b --- /dev/null +++ b/src/SVM.Core/Data/CompactDouble.cs @@ -0,0 +1,214 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactDouble : INumbericData + { + public double Value; + public CompactDouble(double value) { Value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactDouble Add(CompactDouble R) + { + return new CompactDouble(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactDouble Sub(CompactDouble R) + { + return new CompactDouble(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactDouble Mul(CompactDouble R) + { + return new CompactDouble(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactDouble Div(CompactDouble R) + { + return new CompactDouble(Value / R.Value); + } + + public SCVMSimpleResult AddOF(CompactDouble R) + { + CompactDouble result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactDouble(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactDouble(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactDouble R) + { + CompactDouble result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactDouble(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactDouble(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactDouble R) + { + CompactDouble result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactDouble(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactDouble(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactDouble R) + { + CompactDouble result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactDouble(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactDouble(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactDouble R) + { + return Value < R.Value; + } + + public bool GT(CompactDouble R) + { + return Value > R.Value; + } + + public bool LE(CompactDouble R) + { + return Value <= R.Value; + } + + public bool GE(CompactDouble R) + { + return Value >= R.Value; + } + + public bool EQ(CompactDouble R) + { + return Value == R.Value; + } + + public bool NE(CompactDouble R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt((int)Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong((long)Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong((ulong)Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle((float)Value); + } + public unsafe void Write(byte* targetPtr) + { + ((double*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(double); + } + + public CompactDouble Mod(CompactDouble R) + { + return new CompactDouble(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactInt.cs b/src/SVM.Core/Data/CompactInt.cs new file mode 100644 index 0000000..d24b2f7 --- /dev/null +++ b/src/SVM.Core/Data/CompactInt.cs @@ -0,0 +1,216 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactInt : INumbericData + { + public int Value; + public CompactInt(int value) { Value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactInt Add(CompactInt R) + { + return new CompactInt(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactInt Sub(CompactInt R) + { + return new CompactInt(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactInt Mul(CompactInt R) + { + return new CompactInt(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactInt Div(CompactInt R) + { + return new CompactInt(Value / R.Value); + } + + public SCVMSimpleResult AddOF(CompactInt R) + { + CompactInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactInt(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactInt(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactInt R) + { + CompactInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactInt(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactInt(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactInt R) + { + CompactInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactInt(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactInt(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactInt R) + { + CompactInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactInt(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactInt(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactInt R) + { + return Value < R.Value; + } + + public bool GT(CompactInt R) + { + return Value > R.Value; + } + + public bool LE(CompactInt R) + { + return Value <= R.Value; + } + + public bool GE(CompactInt R) + { + return Value >= R.Value; + } + + public bool EQ(CompactInt R) + { + return Value == R.Value; + } + + public bool NE(CompactInt R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt(Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong((ulong)Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + + public unsafe void Write(byte* targetPtr) + { + ((int*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(int); + } + + public CompactInt Mod(CompactInt R) + { + return new CompactInt(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactLong.cs b/src/SVM.Core/Data/CompactLong.cs new file mode 100644 index 0000000..8d29c47 --- /dev/null +++ b/src/SVM.Core/Data/CompactLong.cs @@ -0,0 +1,213 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactLong : INumbericData + { + public long Value; + public CompactLong(long value) { Value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactLong Add(CompactLong R) + { + return new CompactLong(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactLong Sub(CompactLong R) + { + return new CompactLong(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactLong Mul(CompactLong R) + { + return new CompactLong(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactLong Div(CompactLong R) + { + return new CompactLong(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactLong R) + { + CompactLong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactLong(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactLong(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactLong R) + { + CompactLong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactLong(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactLong(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactLong R) + { + CompactLong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactLong(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactLong(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactLong R) + { + CompactLong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactLong(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactLong(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactLong R) + { + return Value < R.Value; + } + + public bool GT(CompactLong R) + { + return Value > R.Value; + } + + public bool LE(CompactLong R) + { + return Value <= R.Value; + } + + public bool GE(CompactLong R) + { + return Value >= R.Value; + } + + public bool EQ(CompactLong R) + { + return Value == R.Value; + } + + public bool NE(CompactLong R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt((int)Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong((ulong)Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + ((long*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(long); + } + + public CompactLong Mod(CompactLong R) + { + return new CompactLong(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactSByte.cs b/src/SVM.Core/Data/CompactSByte.cs new file mode 100644 index 0000000..5f75380 --- /dev/null +++ b/src/SVM.Core/Data/CompactSByte.cs @@ -0,0 +1,214 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactSByte : INumbericData + { + public sbyte Value; + public CompactSByte(sbyte value) { Value = value; } + public CompactSByte(int value) { Value = (sbyte)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSByte Add(CompactSByte R) + { + return new CompactSByte(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSByte Sub(CompactSByte R) + { + return new CompactSByte(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSByte Mul(CompactSByte R) + { + return new CompactSByte(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSByte Div(CompactSByte R) + { + return new CompactSByte(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactSByte R) + { + CompactSByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSByte(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSByte(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactSByte R) + { + CompactSByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSByte(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSByte(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactSByte R) + { + CompactSByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSByte(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSByte(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactSByte R) + { + CompactSByte result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSByte(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSByte(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactSByte R) + { + return Value < R.Value; + } + + public bool GT(CompactSByte R) + { + return Value > R.Value; + } + + public bool LE(CompactSByte R) + { + return Value <= R.Value; + } + + public bool GE(CompactSByte R) + { + return Value >= R.Value; + } + + public bool EQ(CompactSByte R) + { + return Value == R.Value; + } + + public bool NE(CompactSByte R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte(Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort(Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt(Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong((ulong)Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + ((sbyte*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(sbyte); + } + + public CompactSByte Mod(CompactSByte R) + { + return new CompactSByte(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactShort.cs b/src/SVM.Core/Data/CompactShort.cs new file mode 100644 index 0000000..333b9de --- /dev/null +++ b/src/SVM.Core/Data/CompactShort.cs @@ -0,0 +1,213 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactShort : INumbericData + { + public short Value; + public CompactShort(short value) { Value = value; } + public CompactShort(int value) { Value = (short)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactShort Add(CompactShort R) + { + return new CompactShort(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactShort Sub(CompactShort R) + { + return new CompactShort(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactShort Mul(CompactShort R) + { + return new CompactShort(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactShort Div(CompactShort R) + { + return new CompactShort(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactShort R) + { + CompactShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactShort(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactShort(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactShort R) + { + CompactShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactShort(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactShort(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactShort R) + { + CompactShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactShort(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactShort(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactShort R) + { + CompactShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactShort(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactShort(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactShort R) + { + return Value < R.Value; + } + + public bool GT(CompactShort R) + { + return Value > R.Value; + } + + public bool LE(CompactShort R) + { + return Value <= R.Value; + } + + public bool GE(CompactShort R) + { + return Value >= R.Value; + } + + public bool EQ(CompactShort R) + { + return Value == R.Value; + } + + public bool NE(CompactShort R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort(Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt(Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong((ulong)Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + ((short*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(short); + } + + public CompactShort Mod(CompactShort R) + { + return new CompactShort(Value % R.Value); + } + } +} diff --git a/src/SVM.Core/Data/CompactSingle.cs b/src/SVM.Core/Data/CompactSingle.cs new file mode 100644 index 0000000..6766145 --- /dev/null +++ b/src/SVM.Core/Data/CompactSingle.cs @@ -0,0 +1,213 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactSingle : INumbericData + { + public float Value; + public CompactSingle(float value) { Value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSingle Add(CompactSingle R) + { + return new CompactSingle(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSingle Sub(CompactSingle R) + { + return new CompactSingle(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSingle Mul(CompactSingle R) + { + return new CompactSingle(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactSingle Div(CompactSingle R) + { + return new CompactSingle(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactSingle R) + { + CompactSingle result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSingle(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSingle(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactSingle R) + { + CompactSingle result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSingle(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSingle(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactSingle R) + { + CompactSingle result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSingle(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSingle(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactSingle R) + { + CompactSingle result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactSingle(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactSingle(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactSingle R) + { + return Value < R.Value; + } + + public bool GT(CompactSingle R) + { + return Value > R.Value; + } + + public bool LE(CompactSingle R) + { + return Value <= R.Value; + } + + public bool GE(CompactSingle R) + { + return Value >= R.Value; + } + + public bool EQ(CompactSingle R) + { + return Value == R.Value; + } + + public bool NE(CompactSingle R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt((int)Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong((long)Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong((ulong)Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + ((float*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(float); + } + + public CompactSingle Mod(CompactSingle R) + { + return new CompactSingle(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactUInt.cs b/src/SVM.Core/Data/CompactUInt.cs new file mode 100644 index 0000000..f0520fd --- /dev/null +++ b/src/SVM.Core/Data/CompactUInt.cs @@ -0,0 +1,213 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactUInt : INumbericData + { + public uint Value; + public CompactUInt(uint value) { Value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUInt Add(CompactUInt R) + { + return new CompactUInt(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUInt Sub(CompactUInt R) + { + return new CompactUInt(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUInt Mul(CompactUInt R) + { + return new CompactUInt(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUInt Div(CompactUInt R) + { + return new CompactUInt(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactUInt R) + { + CompactUInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUInt(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUInt(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactUInt R) + { + CompactUInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUInt(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUInt(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactUInt R) + { + CompactUInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUInt(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUInt(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactUInt R) + { + CompactUInt result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUInt(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUInt(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactUInt R) + { + return Value < R.Value; + } + + public bool GT(CompactUInt R) + { + return Value > R.Value; + } + + public bool LE(CompactUInt R) + { + return Value <= R.Value; + } + + public bool GE(CompactUInt R) + { + return Value >= R.Value; + } + + public bool EQ(CompactUInt R) + { + return Value == R.Value; + } + + public bool NE(CompactUInt R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt((int)Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt(Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong(Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + ((uint*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(uint); + } + + public CompactUInt Mod(CompactUInt R) + { + return new CompactUInt(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactULong.cs b/src/SVM.Core/Data/CompactULong.cs new file mode 100644 index 0000000..f069f32 --- /dev/null +++ b/src/SVM.Core/Data/CompactULong.cs @@ -0,0 +1,213 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactULong : INumbericData + { + public ulong Value; + public CompactULong(ulong value) { Value = value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactULong Add(CompactULong R) + { + return new CompactULong(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactULong Sub(CompactULong R) + { + return new CompactULong(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactULong Mul(CompactULong R) + { + return new CompactULong(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactULong Div(CompactULong R) + { + return new CompactULong(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactULong R) + { + CompactULong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactULong(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactULong(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactULong R) + { + CompactULong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactULong(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactULong(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactULong R) + { + CompactULong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactULong(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactULong(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactULong R) + { + CompactULong result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactULong(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactULong(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactULong R) + { + return Value < R.Value; + } + + public bool GT(CompactULong R) + { + return Value > R.Value; + } + + public bool LE(CompactULong R) + { + return Value <= R.Value; + } + + public bool GE(CompactULong R) + { + return Value >= R.Value; + } + + public bool EQ(CompactULong R) + { + return Value == R.Value; + } + + public bool NE(CompactULong R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort((ushort)Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt((int)Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt((uint)Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong((long)Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong(Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + public unsafe void Write(byte* targetPtr) + { + ((ulong*)targetPtr)[0] = Value; + } + public int SizeOf() + { + return sizeof(ulong); + } + + public CompactULong Mod(CompactULong R) + { + return new CompactULong(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/CompactUShort.cs b/src/SVM.Core/Data/CompactUShort.cs new file mode 100644 index 0000000..a37a885 --- /dev/null +++ b/src/SVM.Core/Data/CompactUShort.cs @@ -0,0 +1,216 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace SVM.Core.Data +{ + [StructLayout(LayoutKind.Sequential)] + public struct CompactUShort : INumbericData + { + public ushort Value; + public CompactUShort(ushort value) { Value = value; } + public CompactUShort(int value) { Value = (ushort)value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUShort Add(CompactUShort R) + { + return new CompactUShort(Value + R.Value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUShort Sub(CompactUShort R) + { + return new CompactUShort(Value - R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUShort Mul(CompactUShort R) + { + return new CompactUShort(Value * R.Value); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public CompactUShort Div(CompactUShort R) + { + return new CompactUShort(Value / R.Value); + } + public SCVMSimpleResult AddOF(CompactUShort R) + { + CompactUShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUShort(Value + R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUShort(Value + R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult SubOF(CompactUShort R) + { + CompactUShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUShort(Value - R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUShort(Value - R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult DivOF(CompactUShort R) + { + CompactUShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUShort(Value / R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUShort(Value / R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public SCVMSimpleResult MulOF(CompactUShort R) + { + CompactUShort result = default; + bool IsOF = false; + checked + { + try + { + result = new CompactUShort(Value * R.Value); + } + catch (System.Exception) + { + unchecked + { + IsOF = true; + result = new CompactUShort(Value * R.Value); + } + } + } + return new SCVMSimpleResult(IsOF, result); + } + + public bool LT(CompactUShort R) + { + return Value < R.Value; + } + + public bool GT(CompactUShort R) + { + return Value > R.Value; + } + + public bool LE(CompactUShort R) + { + return Value <= R.Value; + } + + public bool GE(CompactUShort R) + { + return Value >= R.Value; + } + + public bool EQ(CompactUShort R) + { + return Value == R.Value; + } + + public bool NE(CompactUShort R) + { + return Value != R.Value; + } + public INumbericData Cast_Byte() + { + return new CompactByte((byte)Value); + } + + public INumbericData Cast_SByte() + { + return new CompactSByte((sbyte)Value); + } + + public INumbericData Cast_Short() + { + return new CompactShort((short)Value); + } + + public INumbericData Cast_UShort() + { + return new CompactUShort(Value); + } + + public INumbericData Cast_Int() + { + return new CompactInt(Value); + } + + public INumbericData Cast_UInt() + { + return new CompactUInt(Value); + } + + public INumbericData Cast_Long() + { + return new CompactLong(Value); + } + + public INumbericData Cast_ULong() + { + return new CompactULong(Value); + } + + public INumbericData Cast_Double() + { + return new CompactDouble(Value); + } + + public INumbericData Cast_Float() + { + return new CompactSingle(Value); + } + + public unsafe void Write(byte* targetPtr) + { + ((ushort*)targetPtr)[0] = Value; + } + + public int SizeOf() + { + return sizeof(ushort); + } + + public CompactUShort Mod(CompactUShort R) + { + return new CompactUShort(Value % R.Value); + } + } + +} diff --git a/src/SVM.Core/Data/INumberData.cs b/src/SVM.Core/Data/INumberData.cs new file mode 100644 index 0000000..330d6b2 --- /dev/null +++ b/src/SVM.Core/Data/INumberData.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace SVM.Core.Data +{ + public interface INumbericData : IPointerWritable where T : unmanaged + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + T Add(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + T Sub(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + T Mul(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + T Div(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + T Mod(T R); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + SCVMSimpleResult AddOF(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + SCVMSimpleResult SubOF(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + SCVMSimpleResult DivOF(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + SCVMSimpleResult MulOF(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + bool LT(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + bool GT(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + bool LE(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + bool GE(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + bool EQ(T R); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + bool NE(T R); + INumbericData Cast_Byte(); + INumbericData Cast_SByte(); + INumbericData Cast_Short(); + INumbericData Cast_UShort(); + INumbericData Cast_Int(); + INumbericData Cast_UInt(); + INumbericData Cast_Long(); + INumbericData Cast_ULong(); + INumbericData Cast_Double(); + INumbericData Cast_Float(); + } + public unsafe interface IPointerWritable + { + public void Write(byte* targetPtr); + public int SizeOf(); + } + public struct SCVMSimpleResult where T : unmanaged + { + public bool IsSuccess; + public T Value; + + public SCVMSimpleResult(bool isSuccess, T value) + { + IsSuccess = isSuccess; + Value = value; + } + } +} diff --git a/src/SVM.Core/FuncImpl/MathImpl.cs b/src/SVM.Core/FuncImpl/MathImpl.cs new file mode 100644 index 0000000..bead0f7 --- /dev/null +++ b/src/SVM.Core/FuncImpl/MathImpl.cs @@ -0,0 +1,284 @@ +using SVM.Core.Data; +using System.Runtime.CompilerServices; + +namespace SVM.Core.FuncImpl +{ + public static unsafe class MathImpl + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MathAdd(Registers register, MState* state, SVMNativeTypes Type, int L, int R, int T, bool CheckOF) + { + switch (Type) + { + case SVMNativeTypes.Int8: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int16: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int32: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int64: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt8: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt16: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt32: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt64: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Float: + GenericAdd(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Double: + GenericAdd(register, state, L, R, T, CheckOF); + break; + default: + break; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MathSub(Registers register, MState* state, SVMNativeTypes Type, int L, int R, int T, bool CheckOF) + { + switch (Type) + { + case SVMNativeTypes.Int8: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int16: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int32: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int64: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt8: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt16: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt32: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt64: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Float: + GenericSub(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Double: + GenericSub(register, state, L, R, T, CheckOF); + break; + default: + break; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MathMod(Registers register, MState* state, SVMNativeTypes Type, int L, int R, int T) + { + switch (Type) + { + case SVMNativeTypes.Int8: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.Int16: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.Int32: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.Int64: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.UInt8: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.UInt16: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.UInt32: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.UInt64: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.Float: + GenericMod(register, state, L, R, T); + break; + case SVMNativeTypes.Double: + GenericMod(register, state, L, R, T); + break; + default: + break; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MathMul(Registers register, MState* state, SVMNativeTypes Type, int L, int R, int T, bool CheckOF) + { + switch (Type) + { + case SVMNativeTypes.Int8: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int16: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int32: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int64: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt8: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt16: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt32: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt64: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Float: + GenericMul(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Double: + GenericMul(register, state, L, R, T, CheckOF); + break; + default: + break; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void MathDiv(Registers register, MState* state, SVMNativeTypes Type, int L, int R, int T, bool CheckOF) + { + switch (Type) + { + case SVMNativeTypes.Int8: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int16: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int32: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Int64: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt8: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt16: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt32: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.UInt64: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Float: + GenericDiv(register, state, L, R, T, CheckOF); + break; + case SVMNativeTypes.Double: + GenericDiv(register, state, L, R, T, CheckOF); + break; + default: + break; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void GenericAdd(Registers Register, MState* state, int L, int R, int T, bool CheckOF) where N : unmanaged, INumbericData + { + var LN = Register.GetData(L); + var RN = Register.GetData(R); + N TN = default; + if (CheckOF) + { + var result = LN.AddOF(RN); + TN = result.Value; + state->OF = (byte)(result.IsSuccess ? 0 : 1); + } + else + { + TN = LN.Add(RN); + } + Register.SetData(T, TN); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void GenericSub(Registers Register, MState* state, int L, int R, int T, bool CheckOF) where N : unmanaged, INumbericData + { + var LN = Register.GetData(L); + var RN = Register.GetData(R); + N TN = default; + if (CheckOF) + { + var result = LN.SubOF(RN); + TN = result.Value; + state->OF = (byte)(result.IsSuccess ? 0 : 1); + } + else + { + TN = LN.Sub(RN); + } + Register.SetData(T, TN); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void GenericMul(Registers Register, MState* state, int L, int R, int T, bool CheckOF) where N : unmanaged, INumbericData + { + var LN = Register.GetData(L); + var RN = Register.GetData(R); + N TN = default; + if (CheckOF) + { + var result = LN.MulOF(RN); + TN = result.Value; + state->OF = (byte)(result.IsSuccess ? 0 : 1); + } + else + { + TN = LN.Mul(RN); + } + Register.SetData(T, TN); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void GenericDiv(Registers Register, MState* state, int L, int R, int T, bool CheckOF) where N : unmanaged, INumbericData + { + var LN = Register.GetData(L); + var RN = Register.GetData(R); + N TN = default; + if (CheckOF) + { + var result = LN.DivOF(RN); + TN = result.Value; + state->OF = (byte)(result.IsSuccess ? 0 : 1); + } + else + { + TN = LN.Div(RN); + } + Register.SetData(T, TN); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void GenericMod(Registers Register, MState* state, int L, int R, int T) where N : unmanaged, INumbericData + { + var LN = Register.GetData(L); + var RN = Register.GetData(R); + Register.SetData(T, LN.Mod(RN)); + } + + } +} diff --git a/src/SVM.Core/Registers.cs b/src/SVM.Core/Registers.cs new file mode 100644 index 0000000..3f68c18 --- /dev/null +++ b/src/SVM.Core/Registers.cs @@ -0,0 +1,41 @@ +using SVM.Core.Utils; +using System; +using System.Runtime.InteropServices; +using static SVM.Core.stdc.stdlib; +namespace SVM.Core +{ + /// + /// Offset 0 is always 0. + /// + [StructLayout(LayoutKind.Sequential)] + public struct Registers : IDisposable + { + IntPtr Data; + uint Size; + public void Init(uint size) + { + Size = size; + Data = malloc(size); + } + public T ReadData(int RegisterID) where T : unmanaged + { + if (RegisterID == 0) return default; + return Data.GetDataWithOffsetInBytes(RegisterID * sizeof(Int64)); + } + public T GetData(int RegisterID) where T : unmanaged + { + if (RegisterID == 0) return default; + return Data.GetDataWithOffsetInBytes(RegisterID * sizeof(Int64)); + } + public unsafe void SetData(int offset, T d) where T : unmanaged + { + if (offset == 0) return; + if (offset + sizeof(T) > Size) return; + ((T*)(Data + offset))[0] = d; + } + public void Dispose() + { + free(Data); + } + } +} diff --git a/src/SVM.Core/SVMInst.cs b/src/SVM.Core/SVMInstDef.cs similarity index 54% rename from src/SVM.Core/SVMInst.cs rename to src/SVM.Core/SVMInstDef.cs index 9b47f07..550d507 100644 --- a/src/SVM.Core/SVMInst.cs +++ b/src/SVM.Core/SVMInstDef.cs @@ -1,24 +1,31 @@ namespace SVM.Core { - public enum SVMInst : byte + public enum SVMInstDef : byte { + // 0 1 2 3 4 5 6 + // Math [I]Op [I]Type [R]L [R]R [R]T [I]CheckOF + BMath, // 0 1 2 3 4 - // Add [I]Type [R]L [R]R [R]T - Add, - Sub, - Mul, - Div, - Mod, + // Math [I]Op [I]Type [R]L [R]T + UMath, + //0 1 2 3 4 + //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 Cmp, + //Set Data to Register + //SD T + //Data (64-bit) + SD, + // 0 1 // JAL RD // [I]Address (int32) JAL, // Jump And Link If Conditional Register is set. - // JALF RD + // JALF RD FlagID // [I]Address (int32) JALF, // 0 1 2 3 @@ -31,15 +38,20 @@ Call, // Return Return, - // System - // [I]CallID (uint64) + // System [I]CallID (uint32) System, // 0 1 2 3 4 5 // SIMD Op [R]LAddr [R]RAddr [R]TAddr [R]Len SIMD, - // 0 1 2 3 4 - // AdvMath Op [R]L [R]R [R]T - AdvMath, + //0 1 2 + //Alloc [R]Size [R]Pointer + Alloc, + //0 1 2 3 + //Alloc [R]Size [R]SPointer [R]TPointer + Realloc, + //0 1 + //Alloc [R]Pointer + Free, } public enum CmpOperator : byte { @@ -58,11 +70,32 @@ Float, Double, } + public enum ConditionFlag + { + Cmp, + Of, + } public enum SIMDOperator : byte { - Add, - Sub, - Mul, + Add, + Sub, + Mul, Div, } + public enum BMathOp : byte + { + Add, + Sub, + Mul, + Div, + Mod, + } + public enum UMathOp : byte + { + Sin, + Cos, + Tan, + Log, + Sqrt + } } diff --git a/src/SVM.Core/SimpleVirtualMachine.cs b/src/SVM.Core/SimpleVirtualMachine.cs index f59b116..faf561e 100644 --- a/src/SVM.Core/SimpleVirtualMachine.cs +++ b/src/SVM.Core/SimpleVirtualMachine.cs @@ -1,85 +1,291 @@ -using System; -using static SVM.Core.stdc.stdlib; -using System.Runtime.InteropServices; -using System.Collections.Generic; +using SVM.Core.FuncImpl; using SVM.Core.Utils; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using static SVM.Core.stdc.stdlib; namespace SVM.Core { + /// + /// Memory Layout: + ///
+ /// Index 0 - Program.
+ /// Index 1 - GPMemory:
+ /// Offset |Length |Usage
+ /// 0 |StackLength | Stack + ///
public unsafe class SimpleVirtualMachine : IDisposable { public Registers registers; public MemoryBlock Stack; - public MemoryBlock* GPMemory; + public List Memories = new List(); public SVMConfig? Config = null; - public void Init(uint StackSize = 1024 * 1024, uint RegisterSize = 512) + public MState MachineState; + public SVMProgram* Program = null; + public static uint InitGPMemorySize = 696320; + public void Init(uint StackSize = 1024 * 1024, uint RegisterSize = 512, uint GPMemory = uint.MaxValue) { - GPMemory = null; + registers.Init(RegisterSize); + + uint SPOffset = 2; + if (Config != null) + { + SPOffset = Config.SPRegisterID; + } + if (GPMemory == 0) + { + + } + else + { + if (GPMemory == uint.MaxValue) + { + GPMemory = InitGPMemorySize; + } + MemoryBlock block = new MemoryBlock(); + block.Init(GPMemory); + SetMemory(1, block); + registers.SetData((int)SPOffset, new SVMPointer() { index = 1, offset = 0 }); + } } public void Step() { - uint SPOffset = 4; - uint PCOffset = 0; + uint SPOffset = 2; + uint PCOffset = 1; + uint ErrorIDOffset = 3; if (Config != null) { - SPOffset = Config.SPRegisterOffset; - PCOffset = Config.PCRegisterOffset; + SPOffset = Config.SPRegisterID; + PCOffset = Config.PCRegisterID; + ErrorIDOffset = Config.EIDRegisterID; } + if (Program == null) return; + var PC = registers.GetData((int)PCOffset); + if (PC >= Program->InstructionCount) return; + var currentInstPtr = GetPointer(PC); + var Instruction = currentInstPtr.GetData(); + var def = Instruction.GetDef(); + fixed (MState* statePtr = &MachineState) + { + + switch (def) + { + case SVMInstDef.BMath: + { + var Op = Instruction.GetData(1); + var NativeType = Instruction.GetData(2); + var L = Instruction.GetData(3); + var R = Instruction.GetData(4); + var T = Instruction.GetData(5); + var Of = Instruction.GetData(6); + switch (Op) + { + case BMathOp.Add: + MathImpl.MathAdd(registers, statePtr, NativeType, L, R, T, Of == 1); + break; + case BMathOp.Sub: + MathImpl.MathSub(registers, statePtr, NativeType, L, R, T, Of == 1); + break; + case BMathOp.Mul: + MathImpl.MathMul(registers, statePtr, NativeType, L, R, T, Of == 1); + break; + case BMathOp.Div: + MathImpl.MathDiv(registers, statePtr, NativeType, L, R, T, Of == 1); + break; + case BMathOp.Mod: + MathImpl.MathMod(registers, statePtr, NativeType, L, R, T); + break; + default: + break; + } + } + break; + case SVMInstDef.UMath: + break; + case SVMInstDef.Cvt: + break; + case SVMInstDef.Cmp: + break; + case SVMInstDef.SD: + { + var Reg = Instruction.GetData(1); + PC++; + var dataPtr = GetPointer(PC); + var data = currentInstPtr.GetData(); + registers.SetData(Reg, data); + } + break; + case SVMInstDef.JAL: + break; + case SVMInstDef.JALF: + break; + case SVMInstDef.Load: + break; + case SVMInstDef.Save: + break; + case SVMInstDef.Call: + break; + case SVMInstDef.Return: + break; + case SVMInstDef.System: + if (Config != null) + { + var target = Instruction.GetData(1); + if (Config.FuncCalls.TryGetValue(target, out var func)) + { + func(this); + } + } + break; + case SVMInstDef.SIMD: + break; + default: + break; + } + } + PC++; + registers.SetData((int)PCOffset, PC); } - public void SetGPMemory(MemoryBlock* ptr) + public IntPtr GetPointer(ulong PC) { - GPMemory = ptr; + return GetPointer(new SVMPointer() { offset = (uint)PC, index = 0 }); + } + public IntPtr GetPointer(SVMPointer absoluteAddress) + { + if (absoluteAddress.index == 0) + { + ulong offset0 = 0; + ulong offset1 = 0; + + if (Program != null) + { + offset0 = Program->InstructionCount * (ulong)sizeof(SVMInstruction); + offset1 = Program->DataSize; + if (absoluteAddress.offset < offset0) + { + + return IntPtr.Add((IntPtr)Program->instructions, (int)absoluteAddress.offset); + } + else if (absoluteAddress.offset < offset1) + { + return IntPtr.Add((IntPtr)Program->instructions, (int)(absoluteAddress.offset - offset0)); + + } + } + } + var realIndex = absoluteAddress.index - 1; + if (realIndex < Memories.Count) + { + return IntPtr.Add(Memories[(int)realIndex].StartAddress, (int)absoluteAddress.offset); + + } + return IntPtr.Zero; + } + public MemoryBlock SetMemory(int id, MemoryBlock block) + { + var realID = id - 1; + if (id < Memories.Count) + { + var old = Memories[(int)realID]; + Memories[(int)realID] = block; + return old; + } + else + { + var count = realID - Memories.Count; + for (int i = 0; i <= count; i++) + { + Memories.Add(default); + } + Memories[(int)realID] = block; + return default; + } } public void Dispose() { registers.Dispose(); Stack.Dispose(); + foreach (var item in Memories) + { + item.Dispose(); + } } } + [StructLayout(LayoutKind.Sequential)] + public struct SVMPointer + { + public uint offset; + public uint index; + } public class SVMConfig { public Dictionary FuncCalls = new Dictionary(); - public uint SPRegisterOffset; - public uint PCRegisterOffset; + public uint SPRegisterID; + public uint PCRegisterID; + /// + /// Error ID Register. + /// + public uint EIDRegisterID; + } + public unsafe struct SVMProgram + { + public UInt64 InstructionCount; + public UInt64 DataSize; + public SVMInstruction* instructions; + public byte* data; + public static SVMProgram* LoadFromStream(Stream stream) + { + var program = (SVMProgram*)malloc(sizeof(SVMProgram)); + + return program; + } } public delegate void FuncCall(SimpleVirtualMachine machine); [StructLayout(LayoutKind.Sequential)] public struct MState { - public uint PC; + public byte OF; } [StructLayout(LayoutKind.Sequential)] public struct MemoryBlock : IDisposable { public IntPtr StartAddress; - public int Size; - + public uint Size; + public void Init(uint Size) + { + this.Size = Size; + StartAddress = malloc(Size); + } public void Dispose() { free(StartAddress); } } [StructLayout(LayoutKind.Sequential)] - public struct Registers : IDisposable - { - IntPtr Data; - public void Init(int size) - { - Data = malloc((uint)size); - } - public T ReadData(int RegisterID) where T : unmanaged - { - return Data.GetDataWithOffsetInBytes(RegisterID * sizeof(Int64)); - } - public void Dispose() - { - free(Data); - } - } - [StructLayout(LayoutKind.Sequential)] public struct Callframe { - public int PC; - public uint SP; + public ulong PC; + public ulong SP; + } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct SVMInstruction + { + public ulong data; + public T GetData(int offset) where T : unmanaged + { + fixed (ulong* dataPtr = &data) + { + return ((T*)(((byte*)dataPtr) + offset))[0]; + } + } + public SVMInstDef GetDef() + { + fixed (ulong* dataPtr = &data) + { + return ((SVMInstDef*)dataPtr)[0]; + } + } } - } diff --git a/src/SVM.Core/stdc/stdlib.cs b/src/SVM.Core/stdc/stdlib.cs index 89ed7ee..771c39a 100644 --- a/src/SVM.Core/stdc/stdlib.cs +++ b/src/SVM.Core/stdc/stdlib.cs @@ -14,6 +14,10 @@ namespace SVM.Core.stdc { return Marshal.AllocHGlobal((int)size); } + public static IntPtr malloc(int size) + { + return Marshal.AllocHGlobal(size); + } public static IntPtr realloc(IntPtr ptr, uint size) { return Marshal.ReAllocHGlobal(ptr, (IntPtr)size);