diff --git a/src/SVM.Assembler.Core/Linker.cs b/src/SVM.Assembler.Core/Linker.cs index d9a149e..1c0bf99 100644 --- a/src/SVM.Assembler.Core/Linker.cs +++ b/src/SVM.Assembler.Core/Linker.cs @@ -238,6 +238,7 @@ namespace SVM.Assembler.Core { if (Enum.TryParse(input, out var enumV)) { + //Console.WriteLine($"{input}=>{enumV}"); WriteData(inst, parameter.ExpectdValue.Type, parameter.ExpectdValue.Pos, (byte*)&enumV); return true; } diff --git a/src/SVM.Core/Data/CompactByte.cs b/src/SVM.Core/Data/CompactByte.cs index c24b26f..45d5a40 100644 --- a/src/SVM.Core/Data/CompactByte.cs +++ b/src/SVM.Core/Data/CompactByte.cs @@ -211,6 +211,10 @@ namespace SVM.Core.Data { return new CompactByte(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactDouble.cs b/src/SVM.Core/Data/CompactDouble.cs index afd00af..5904577 100644 --- a/src/SVM.Core/Data/CompactDouble.cs +++ b/src/SVM.Core/Data/CompactDouble.cs @@ -209,6 +209,10 @@ namespace SVM.Core.Data { return new CompactDouble(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactInt.cs b/src/SVM.Core/Data/CompactInt.cs index f5abd51..252209d 100644 --- a/src/SVM.Core/Data/CompactInt.cs +++ b/src/SVM.Core/Data/CompactInt.cs @@ -211,6 +211,10 @@ namespace SVM.Core.Data { return new CompactInt(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactLong.cs b/src/SVM.Core/Data/CompactLong.cs index 6f68ded..1860fa2 100644 --- a/src/SVM.Core/Data/CompactLong.cs +++ b/src/SVM.Core/Data/CompactLong.cs @@ -208,6 +208,10 @@ namespace SVM.Core.Data { return new CompactLong(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactSByte.cs b/src/SVM.Core/Data/CompactSByte.cs index 25d067e..651f1b5 100644 --- a/src/SVM.Core/Data/CompactSByte.cs +++ b/src/SVM.Core/Data/CompactSByte.cs @@ -209,6 +209,10 @@ namespace SVM.Core.Data { return new CompactSByte(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactShort.cs b/src/SVM.Core/Data/CompactShort.cs index 347ae09..55916c5 100644 --- a/src/SVM.Core/Data/CompactShort.cs +++ b/src/SVM.Core/Data/CompactShort.cs @@ -209,5 +209,9 @@ namespace SVM.Core.Data { return new CompactShort(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactSingle.cs b/src/SVM.Core/Data/CompactSingle.cs index 0a92611..72ea6e1 100644 --- a/src/SVM.Core/Data/CompactSingle.cs +++ b/src/SVM.Core/Data/CompactSingle.cs @@ -208,6 +208,10 @@ namespace SVM.Core.Data { return new CompactSingle(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactUInt.cs b/src/SVM.Core/Data/CompactUInt.cs index 9cb24cb..33e50f9 100644 --- a/src/SVM.Core/Data/CompactUInt.cs +++ b/src/SVM.Core/Data/CompactUInt.cs @@ -208,6 +208,10 @@ namespace SVM.Core.Data { return new CompactUInt(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactULong.cs b/src/SVM.Core/Data/CompactULong.cs index c6e1beb..c9c80a8 100644 --- a/src/SVM.Core/Data/CompactULong.cs +++ b/src/SVM.Core/Data/CompactULong.cs @@ -208,6 +208,10 @@ namespace SVM.Core.Data { return new CompactULong(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/Data/CompactUShort.cs b/src/SVM.Core/Data/CompactUShort.cs index 88e5730..27f2962 100644 --- a/src/SVM.Core/Data/CompactUShort.cs +++ b/src/SVM.Core/Data/CompactUShort.cs @@ -211,6 +211,10 @@ namespace SVM.Core.Data { return new CompactUShort(Value % R.Value); } + public override string ToString() + { + return this.Value.ToString(); + } } } diff --git a/src/SVM.Core/FuncImpl/MathImpl.cs b/src/SVM.Core/FuncImpl/MathImpl.cs index bead0f7..fc72d35 100644 --- a/src/SVM.Core/FuncImpl/MathImpl.cs +++ b/src/SVM.Core/FuncImpl/MathImpl.cs @@ -1,4 +1,5 @@ using SVM.Core.Data; +using System; using System.Runtime.CompilerServices; namespace SVM.Core.FuncImpl @@ -216,6 +217,7 @@ namespace SVM.Core.FuncImpl { TN = LN.Add(RN); } + Console.WriteLine($"SVM:Add:{typeof(N)}{LN}+{RN}={TN.ToString()}"); Register.SetData(T, TN); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/SVM.Core/Registers.cs b/src/SVM.Core/Registers.cs index 7b9625b..d5c565b 100644 --- a/src/SVM.Core/Registers.cs +++ b/src/SVM.Core/Registers.cs @@ -15,7 +15,8 @@ namespace SVM.Core public void Init(uint size) { Size = size; - Data = malloc(size); + Console.WriteLine($"Allocating:{size}"); + Data = calloc(size); } public T ReadData(int RegisterID) where T : unmanaged { @@ -36,7 +37,19 @@ namespace SVM.Core { if (offset == 0) return; if (offset + sizeof(T) > Size) return; - ((T*)(Data + offset))[0] = d; + ((T*)Data + offset)[0] = d; + } + public unsafe void SetDataInRegister(int offset, T d) where T : unmanaged + { + if (offset == 0) return; + if (offset * sizeof(ulong) + sizeof(T) > Size) return; + ((T*)((byte*)Data + offset * sizeof(ulong)))[0] = d; + } + public unsafe void SetDataOffsetInBytes(int offset, T d) where T : unmanaged + { + if (offset == 0) return; + if (offset + sizeof(T) > Size) return; + ((T*)((byte*)Data + offset))[0] = d; } public void Dispose() { diff --git a/src/SVM.Core/SVMProgram.cs b/src/SVM.Core/SVMProgram.cs index e7c6b2e..76add88 100644 --- a/src/SVM.Core/SVMProgram.cs +++ b/src/SVM.Core/SVMProgram.cs @@ -37,12 +37,18 @@ namespace SVM.Core { return null; } - var dataPtr = malloc(dataSectionLength); - Span dataBuffer = new Span((byte*)dataPtr, (int)dataSectionLength); - if (stream.Read(dataBuffer) != dataSectionLength) + Console.WriteLine(dataSectionLength); + Console.WriteLine(codeCount); + IntPtr dataPtr = malloc(dataSectionLength); + if (dataSectionLength != 0) { - free(dataPtr); - return null; + + Span dataBuffer = new Span((byte*)dataPtr, (int)dataSectionLength); + if (stream.Read(dataBuffer) != dataSectionLength) + { + free(dataPtr); + return null; + } } var codeLen = codeCount * sizeof(SVMInstruction); var codePtr = malloc((uint)codeLen); @@ -54,7 +60,7 @@ namespace SVM.Core return null; } var program = (SVMProgram*)malloc(sizeof(SVMProgram)); - program->data = (byte*)dataPtr; + program->data = dataSectionLength == 0 ? null : (byte*)dataPtr; program->DataSize = dataSectionLength; program->instructions = (SVMInstruction*)codePtr; program->InstructionCount = codeCount; diff --git a/src/SVM.Core/SimpleVirtualMachine.cs b/src/SVM.Core/SimpleVirtualMachine.cs index e0fc0d5..3dece13 100644 --- a/src/SVM.Core/SimpleVirtualMachine.cs +++ b/src/SVM.Core/SimpleVirtualMachine.cs @@ -50,6 +50,22 @@ namespace SVM.Core registers.SetData((int)SPOffset, new SVMPointer() { index = 1, offset = 0 }); } } + public bool isReachBinaryEnd() + { + uint SPOffset = 2; + uint PCOffset = 1; + uint ErrorIDOffset = 3; + if (Config != null) + { + SPOffset = Config.SPRegisterID; + PCOffset = Config.PCRegisterID; + ErrorIDOffset = Config.EIDRegisterID; + } + var PC = registers.GetData((int)PCOffset); + Console.WriteLine($"{PC},{Program->InstructionCount}"); + return PC >= Program->InstructionCount; + } + public void Step() { uint SPOffset = 2; @@ -67,6 +83,7 @@ namespace SVM.Core var currentInstPtr = GetPointer(PC); var Instruction = currentInstPtr.GetData(); var def = Instruction.GetDef(); + Console.WriteLine(def); fixed (MState* statePtr = &MachineState) { @@ -144,8 +161,9 @@ namespace SVM.Core var Reg = Instruction.GetData(1); PC++; var dataPtr = GetPointer(PC); - var data = currentInstPtr.GetData(); - registers.SetData(Reg, data); + var data = dataPtr.GetData(); + registers.SetDataInRegister(Reg, data); + Console.WriteLine($"SVM:SD:{data} form PC={PC}"); } break; case PrimaryInstruction.JAL: @@ -178,6 +196,7 @@ namespace SVM.Core } PC++; registers.SetData((int)PCOffset, PC); + PC = registers.GetData((int)PCOffset); } private void Convert(SVMInstruction Instruction) @@ -261,7 +280,7 @@ namespace SVM.Core public IntPtr GetPointer(ulong PC) { - return GetPointer(new SVMPointer() { offset = (uint)PC, index = 0 }); + return GetPointer(new SVMPointer() { offset = (uint)(PC * (uint)sizeof(SVMInstruction)), index = 0 }); } public IntPtr GetPointer(SVMPointer absoluteAddress) { @@ -277,7 +296,7 @@ namespace SVM.Core if (absoluteAddress.offset < offset0) { - return IntPtr.Add((IntPtr)Program->instructions, (int)absoluteAddress.offset); + return (IntPtr)(Program->instructions + absoluteAddress.offset / sizeof(SVMInstruction)); } else if (absoluteAddress.offset < offset1) { diff --git a/src/SVM.Core/Utils/PointerUtils.cs b/src/SVM.Core/Utils/PointerUtils.cs index f2ce592..d9e274f 100644 --- a/src/SVM.Core/Utils/PointerUtils.cs +++ b/src/SVM.Core/Utils/PointerUtils.cs @@ -9,9 +9,9 @@ namespace SVM.Core.Utils { return Marshal.PtrToStructure(ptr); } - public static T GetDataWithOffsetInBytes(this IntPtr ptr, int Offset) where T : unmanaged + public unsafe static T GetDataWithOffsetInBytes(this IntPtr ptr, int Offset) where T : unmanaged { - return Marshal.PtrToStructure(IntPtr.Add(ptr, Offset)); + return ((T*)((byte*)(ptr + Offset)))[0]; } public static T GetDataWithOffsetInStructCount(this IntPtr ptr, int Count) where T : unmanaged { diff --git a/src/SVM.Core/stdc/stdlib.cs b/src/SVM.Core/stdc/stdlib.cs index 771c39a..2f1cb1e 100644 --- a/src/SVM.Core/stdc/stdlib.cs +++ b/src/SVM.Core/stdc/stdlib.cs @@ -1,4 +1,5 @@ -using System; +using SVM.Core.Utils; +using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; @@ -18,6 +19,24 @@ namespace SVM.Core.stdc { return Marshal.AllocHGlobal(size); } + public static IntPtr calloc(int size) + { + var ptr = Marshal.AllocHGlobal(size); + for (int i = 0; i < size; i++) + { + System.Runtime.InteropServices.Marshal.WriteByte(ptr, i, 0); + } + return ptr; + } + public static IntPtr calloc(uint size) + { + var ptr = Marshal.AllocHGlobal((int)size); + for (int i = 0; i < size; i++) + { + System.Runtime.InteropServices.Marshal.WriteByte(ptr, i, 0); + } + return ptr; + } public static IntPtr realloc(IntPtr ptr, uint size) { return Marshal.ReAllocHGlobal(ptr, (IntPtr)size); diff --git a/src/SVM.Standalone/Program.cs b/src/SVM.Standalone/Program.cs index 9c834a2..b121b47 100644 --- a/src/SVM.Standalone/Program.cs +++ b/src/SVM.Standalone/Program.cs @@ -1,9 +1,35 @@ -namespace SVM.Standalone; +using SVM.Core; + +namespace SVM.Standalone; class Program { - static void Main(string[] args) - { - Console.WriteLine("Hello, World!"); - } + unsafe static void Main(string[] args) + { + string inputFile = "a.out"; + foreach (string arg in args) + { + if (File.Exists(arg)) + { + inputFile = arg; + } + } + if (!File.Exists(inputFile)) + { + Console.WriteLine("Not input file found!"); + return; + } + using var fs = File.OpenRead(inputFile); + var program = SVMProgram.LoadFromStream(fs); + SimpleVirtualMachine svm = new() + { + Program = program + }; + svm.Init(); + while (!svm.isReachBinaryEnd()) + { + Console.WriteLine("Step"); + svm.Step(); + } + } } diff --git a/src/SVM.Standalone/SVM.Standalone.csproj b/src/SVM.Standalone/SVM.Standalone.csproj index aa23c6f..f1af48c 100644 --- a/src/SVM.Standalone/SVM.Standalone.csproj +++ b/src/SVM.Standalone/SVM.Standalone.csproj @@ -9,6 +9,7 @@ net9.0 enable enable + true