mirror of
https://github.com/creeperlv/SVM.git
synced 2026-01-10 20:39:54 +00:00
Jump and Call are working as intended.
This commit is contained in:
@@ -3,8 +3,10 @@ text0 "Hello, World!\n"
|
|||||||
file_name "example.txt"
|
file_name "example.txt"
|
||||||
.code:
|
.code:
|
||||||
sd.int32 $4 123
|
sd.int32 $4 123
|
||||||
write_file:
|
|
||||||
sd.int32 $20 -4
|
sd.int32 $20 -4
|
||||||
|
sd.int64 $20 label0
|
||||||
|
jmp 20
|
||||||
|
write_file:
|
||||||
sd.int32 $10 file_name
|
sd.int32 $10 file_name
|
||||||
sd.int32 $11 11
|
sd.int32 $11 11
|
||||||
sd.int32 $12 1
|
sd.int32 $12 1
|
||||||
@@ -13,6 +15,9 @@ sd.int32 $11 text0
|
|||||||
sd.int32 $12 14
|
sd.int32 $12 14
|
||||||
sys 4
|
sys 4
|
||||||
return
|
return
|
||||||
|
label0:
|
||||||
|
sd.int64 $20 write_file
|
||||||
|
call 20
|
||||||
sd.int32 $10 100
|
sd.int32 $10 100
|
||||||
sys 1
|
sys 1
|
||||||
bmath add Int32 $4 $5 $6
|
bmath add Int32 $4 $5 $6
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ namespace SVM.Advanced.BSDStyleVM
|
|||||||
public static void __exit(SimpleVirtualMachine machine)
|
public static void __exit(SimpleVirtualMachine machine)
|
||||||
{
|
{
|
||||||
var status = machine.registers.GetData<int>(10);
|
var status = machine.registers.GetData<int>(10);
|
||||||
|
Console.WriteLine($"Bye with {status}.");
|
||||||
Environment.Exit(status);
|
Environment.Exit(status);
|
||||||
}
|
}
|
||||||
public unsafe static void __open(SimpleVirtualMachine machine)
|
public unsafe static void __open(SimpleVirtualMachine machine)
|
||||||
@@ -81,7 +82,7 @@ namespace SVM.Advanced.BSDStyleVM
|
|||||||
var stream = File.Open(fn, fm, fa);
|
var stream = File.Open(fn, fm, fa);
|
||||||
FileDescripter fd = new FileDescripter(stream);
|
FileDescripter fd = new FileDescripter(stream);
|
||||||
w.FDs.Add(fdID, fd);
|
w.FDs.Add(fdID, fd);
|
||||||
machine.registers.SetDataInRegister<int>(10,fdID);
|
machine.registers.SetDataInRegister<int>(10, fdID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -97,7 +98,9 @@ namespace SVM.Advanced.BSDStyleVM
|
|||||||
var size = machine.registers.GetData<ulong>(12);
|
var size = machine.registers.GetData<ulong>(12);
|
||||||
if (w.FDs.TryGetValue(fd, out var descripter))
|
if (w.FDs.TryGetValue(fd, out var descripter))
|
||||||
{
|
{
|
||||||
|
Console.Write("\"");
|
||||||
Console.OpenStandardOutput().WriteData(machine.GetPointer(ptr), size);
|
Console.OpenStandardOutput().WriteData(machine.GetPointer(ptr), size);
|
||||||
|
Console.WriteLine($"\">>{fd}");
|
||||||
descripter.stream.WriteData(machine.GetPointer(ptr), size);
|
descripter.stream.WriteData(machine.GetPointer(ptr), size);
|
||||||
descripter.stream.Flush();
|
descripter.stream.Flush();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ Register \${D}+
|
|||||||
LabelCode \.code\:
|
LabelCode \.code\:
|
||||||
LabelData \.data\:
|
LabelData \.data\:
|
||||||
LabelConst \.const\:
|
LabelConst \.const\:
|
||||||
word [\w\d\.]+
|
|
||||||
GenericLabel {word}\:
|
GenericLabel {word}\:
|
||||||
|
word [\w\d\.]+
|
||||||
LineEnd \n
|
LineEnd \n
|
||||||
string ""\"".*\""""
|
string ""\"".*\""""
|
||||||
Number \d+
|
Number \d+
|
||||||
@@ -133,7 +133,7 @@ LabelConstant InternalLbl
|
|||||||
}
|
}
|
||||||
if (!item.AllowedTokenIds.Contains(next.Result.LexSegmentId))
|
if (!item.AllowedTokenIds.Contains(next.Result.LexSegmentId))
|
||||||
{
|
{
|
||||||
operationResult.AddError(new ErrorWMsg($"Token: {LexDef.Content ?? "<null>"} is not allowed here.", LexDef));
|
operationResult.AddError(new ErrorWMsg($"Token: {LexDef.Content ?? "<null>"} is not allowed here. Current context:{instructionDef.Id}", LexDef));
|
||||||
return operationResult;
|
return operationResult;
|
||||||
}
|
}
|
||||||
intermediateInstruction.Parameters.Add(next.Result);
|
intermediateInstruction.Parameters.Add(next.Result);
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ namespace SVM.Assembler.Core
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (TryParseUInt8(input, context, out registerID))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (context.IntermediateObject.TryGetConst(input, out var realStr))
|
if (context.IntermediateObject.TryGetConst(input, out var realStr))
|
||||||
{
|
{
|
||||||
return TryParseRegister(realStr, context, out registerID);
|
return TryParseRegister(realStr, context, out registerID);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace SVM.Assembler.Core
|
|||||||
if (DataOffsets.TryGetValue(label, out offset))
|
if (DataOffsets.TryGetValue(label, out offset))
|
||||||
{
|
{
|
||||||
//Don't directly give the length there.
|
//Don't directly give the length there.
|
||||||
offset += (uint)IntermediateObject.DetermineFinalInstructionCount(this) * (uint)sizeof(SVMInstruction)+sizeof(int);
|
offset += (uint)IntermediateObject.DetermineFinalInstructionCount(this) * (uint)sizeof(SVMInstruction) + sizeof(int);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -33,16 +33,18 @@ namespace SVM.Assembler.Core
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
int acc=0;
|
||||||
for (int i = 0; i < IntermediateObject.instructions.Count; i++)
|
for (int i = 0; i < IntermediateObject.instructions.Count; i++)
|
||||||
{
|
{
|
||||||
IntermediateInstruction? item = IntermediateObject.instructions[i];
|
IntermediateInstruction? item = IntermediateObject.instructions[i];
|
||||||
if (item.Label != null)
|
if (item.Label != null)
|
||||||
if (item.Label.Content == label)
|
if (item.Label.Content == label)
|
||||||
{
|
{
|
||||||
this.label.Add(label, i);
|
this.label.Add(label, acc);
|
||||||
offset = i;
|
offset = acc;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
acc += Definition.InstructionDefinitions[item.InstDefID].InstructionCount;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
</InstructionParameter>
|
</InstructionParameter>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</InstructionDefinition>
|
</InstructionDefinition>
|
||||||
<InstructionDefinition Id="std.int32" PrimaryInstruction="SD" InstructionCount="2">
|
<InstructionDefinition Id="sd.int32" PrimaryInstruction="SD" InstructionCount="2">
|
||||||
<Aliases>
|
<Aliases>
|
||||||
<Alias Name="sd.int"/>
|
<Alias Name="sd.int"/>
|
||||||
<Alias Name="sd.int32"/>
|
<Alias Name="sd.int32"/>
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
</InstructionParameter>
|
</InstructionParameter>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</InstructionDefinition>
|
</InstructionDefinition>
|
||||||
<InstructionDefinition Id="call" PrimaryInstruction="Call" InstructionCount="2">
|
<InstructionDefinition Id="call" PrimaryInstruction="Call" InstructionCount="1">
|
||||||
<Aliases>
|
<Aliases>
|
||||||
<Alias Name="call"/>
|
<Alias Name="call"/>
|
||||||
<Alias Name="c"/>
|
<Alias Name="c"/>
|
||||||
@@ -122,8 +122,49 @@
|
|||||||
<MatchingItems>
|
<MatchingItems>
|
||||||
<Item Id="Number"/>
|
<Item Id="Number"/>
|
||||||
<Item Id="Word"/>
|
<Item Id="Word"/>
|
||||||
|
<Item Id="Register"/>
|
||||||
</MatchingItems>
|
</MatchingItems>
|
||||||
<ExpectedValue Type="Int64" Pos="8" Converter="Integer64" />
|
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||||
|
</InstructionParameter>
|
||||||
|
</Parameters>
|
||||||
|
</InstructionDefinition>
|
||||||
|
<InstructionDefinition Id="jmp" PrimaryInstruction="JMP" InstructionCount="1">
|
||||||
|
<Aliases>
|
||||||
|
<Alias Name="j"/>
|
||||||
|
<Alias Name="jmp"/>
|
||||||
|
</Aliases>
|
||||||
|
<Parameters>
|
||||||
|
<InstructionParameter>
|
||||||
|
<MatchingItems>
|
||||||
|
<Item Id="Number"/>
|
||||||
|
<Item Id="Word"/>
|
||||||
|
<Item Id="Register"/>
|
||||||
|
</MatchingItems>
|
||||||
|
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||||
|
</InstructionParameter>
|
||||||
|
</Parameters>
|
||||||
|
</InstructionDefinition>
|
||||||
|
<InstructionDefinition Id="jif" PrimaryInstruction="JIF" InstructionCount="1">
|
||||||
|
<Aliases>
|
||||||
|
<Alias Name="jif"/>
|
||||||
|
<Alias Name="jf"/>
|
||||||
|
<Alias Name="jmpif"/>
|
||||||
|
</Aliases>
|
||||||
|
<Parameters>
|
||||||
|
<InstructionParameter>
|
||||||
|
<MatchingItems>
|
||||||
|
<Item Id="Number"/>
|
||||||
|
<Item Id="Word"/>
|
||||||
|
<Item Id="Register"/>
|
||||||
|
</MatchingItems>
|
||||||
|
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
||||||
|
</InstructionParameter>
|
||||||
|
<InstructionParameter>
|
||||||
|
<MatchingItems>
|
||||||
|
<Item Id="Number"/>
|
||||||
|
<Item Id="Word"/>
|
||||||
|
</MatchingItems>
|
||||||
|
<ExpectedValue Type="UInt8" Pos="2" Converter="UInt8" />
|
||||||
</InstructionParameter>
|
</InstructionParameter>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</InstructionDefinition>
|
</InstructionDefinition>
|
||||||
@@ -133,13 +174,6 @@
|
|||||||
<Alias Name="ret"/>
|
<Alias Name="ret"/>
|
||||||
</Aliases>
|
</Aliases>
|
||||||
<Parameters>
|
<Parameters>
|
||||||
<InstructionParameter>
|
|
||||||
<MatchingItems>
|
|
||||||
<Item Id="Number"/>
|
|
||||||
<Item Id="Word"/>
|
|
||||||
</MatchingItems>
|
|
||||||
<ExpectedValue Type="Int32" Pos="4" Converter="Integer32" />
|
|
||||||
</InstructionParameter>
|
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</InstructionDefinition>
|
</InstructionDefinition>
|
||||||
<InstructionDefinition Id="load" PrimaryInstruction="Load" InstructionCount="1">
|
<InstructionDefinition Id="load" PrimaryInstruction="Load" InstructionCount="1">
|
||||||
@@ -200,34 +234,5 @@
|
|||||||
</InstructionParameter>
|
</InstructionParameter>
|
||||||
</Parameters>
|
</Parameters>
|
||||||
</InstructionDefinition>
|
</InstructionDefinition>
|
||||||
<InstructionDefinition Id="load" PrimaryInstruction="Save" InstructionCount="1">
|
|
||||||
<Aliases>
|
|
||||||
<Alias Name="load"/>
|
|
||||||
<Alias Name="ld"/>
|
|
||||||
</Aliases>
|
|
||||||
<Parameters>
|
|
||||||
<InstructionParameter>
|
|
||||||
<MatchingItems>
|
|
||||||
<Item Id="Register"/>
|
|
||||||
<Item Id="Word"/>
|
|
||||||
</MatchingItems>
|
|
||||||
<ExpectedValue Type="UInt8" Pos="1" Converter="Register" />
|
|
||||||
</InstructionParameter>
|
|
||||||
<InstructionParameter>
|
|
||||||
<MatchingItems>
|
|
||||||
<Item Id="Number"/>
|
|
||||||
<Item Id="Word"/>
|
|
||||||
</MatchingItems>
|
|
||||||
<ExpectedValue Type="UInt8" Pos="2" Converter="UInt8" />
|
|
||||||
</InstructionParameter>
|
|
||||||
<InstructionParameter>
|
|
||||||
<MatchingItems>
|
|
||||||
<Item Id="Register"/>
|
|
||||||
<Item Id="Word"/>
|
|
||||||
</MatchingItems>
|
|
||||||
<ExpectedValue Type="UInt8" Pos="3" Converter="Register" />
|
|
||||||
</InstructionParameter>
|
|
||||||
</Parameters>
|
|
||||||
</InstructionDefinition>
|
|
||||||
</Definitions>
|
</Definitions>
|
||||||
</ISARoot>
|
</ISARoot>
|
||||||
@@ -75,6 +75,10 @@ namespace SVM.Assembler
|
|||||||
if (fResult.HasError())
|
if (fResult.HasError())
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Finalizer error!");
|
Console.Error.WriteLine("Finalizer error!");
|
||||||
|
foreach (var item in fResult.Errors)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(item.ToString());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fResult.Result == null)
|
if (fResult.Result == null)
|
||||||
|
|||||||
@@ -26,12 +26,11 @@
|
|||||||
SD,
|
SD,
|
||||||
|
|
||||||
// 0 1
|
// 0 1
|
||||||
// JMP RD
|
// JMP [R]TargetPC
|
||||||
// [I]Address (int32)
|
|
||||||
JMP,
|
JMP,
|
||||||
// Jump And Link If Conditional Register is set.
|
// Jump If Conditional Register is set.
|
||||||
// JIF RD FlagID
|
// 0 1 2
|
||||||
// [I]Address (int32)
|
// JIF [R]TargetPC [I]FlagID
|
||||||
JIF,
|
JIF,
|
||||||
// 0 1 2 3
|
// 0 1 2 3
|
||||||
// Load [R]Address [I]Len [R]T
|
// Load [R]Address [I]Len [R]T
|
||||||
@@ -39,9 +38,8 @@
|
|||||||
// 0 1 2 3
|
// 0 1 2 3
|
||||||
// Load [R]Src [I]Len [R]TAddr
|
// Load [R]Src [I]Len [R]TAddr
|
||||||
Save,
|
Save,
|
||||||
// 0
|
// 0 1
|
||||||
// Call
|
// Call [R]Address
|
||||||
// [I]Address (int64)
|
|
||||||
Call,
|
Call,
|
||||||
// Return
|
// Return
|
||||||
Return,
|
Return,
|
||||||
@@ -77,7 +75,7 @@
|
|||||||
Float,
|
Float,
|
||||||
Double,
|
Double,
|
||||||
}
|
}
|
||||||
public enum ConditionFlag
|
public enum ConditionFlag : byte
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Compare Flag
|
/// Compare Flag
|
||||||
|
|||||||
@@ -77,6 +77,15 @@ namespace SVM.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public ulong GetPC()
|
||||||
|
{
|
||||||
|
uint PCOffset = 1;
|
||||||
|
if (Config != null)
|
||||||
|
{
|
||||||
|
PCOffset = Config.PCRegisterID;
|
||||||
|
}
|
||||||
|
return registers.GetData<ulong>((int)PCOffset);
|
||||||
|
}
|
||||||
public bool isReachBinaryEnd()
|
public bool isReachBinaryEnd()
|
||||||
{
|
{
|
||||||
uint PCOffset = 1;
|
uint PCOffset = 1;
|
||||||
@@ -214,12 +223,44 @@ namespace SVM.Core
|
|||||||
var dataPtr = GetPointer(PC);
|
var dataPtr = GetPointer(PC);
|
||||||
var data = dataPtr.GetData<int>();
|
var data = dataPtr.GetData<int>();
|
||||||
registers.SetDataInRegister(Reg, data);
|
registers.SetDataInRegister(Reg, data);
|
||||||
//Console.WriteLine($"SVM:SD:{data} form PC={PC}");
|
Console.WriteLine($"SVM:SD:{data} to {Reg} form PC={PC}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PrimaryInstruction.JMP:
|
case PrimaryInstruction.JMP:
|
||||||
|
{
|
||||||
|
var RegisterID = Instruction.GetData<byte>(1);
|
||||||
|
PC = registers.ReadData<ulong>(RegisterID);
|
||||||
|
Console.WriteLine($"Jump to:{PC}");
|
||||||
|
PC--;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PrimaryInstruction.JIF:
|
case PrimaryInstruction.JIF:
|
||||||
|
{
|
||||||
|
var RegisterID = Instruction.GetData<byte>(1);
|
||||||
|
var FlagID = Instruction.GetData<ConditionFlag>(2);
|
||||||
|
bool isSet = false;
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (FlagID)
|
||||||
|
{
|
||||||
|
case ConditionFlag.CF:
|
||||||
|
isSet = statePtr->CF != 0;
|
||||||
|
break;
|
||||||
|
case ConditionFlag.Of:
|
||||||
|
isSet = statePtr->OF != 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSet)
|
||||||
|
{
|
||||||
|
|
||||||
|
PC = registers.ReadData<ulong>(RegisterID);
|
||||||
|
PC--;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PrimaryInstruction.Load:
|
case PrimaryInstruction.Load:
|
||||||
{
|
{
|
||||||
@@ -248,6 +289,10 @@ namespace SVM.Core
|
|||||||
{
|
{
|
||||||
var cfPtr = GetPointer(ReadCallFrameRegisterAsPtr());
|
var cfPtr = GetPointer(ReadCallFrameRegisterAsPtr());
|
||||||
cfPtr.SetData(PC + 1);
|
cfPtr.SetData(PC + 1);
|
||||||
|
var RegisterID = Instruction.GetData<byte>(1);
|
||||||
|
PC = registers.ReadData<ulong>(RegisterID);
|
||||||
|
Console.WriteLine($"Call to:{PC} ({RegisterID})");
|
||||||
|
PC--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PrimaryInstruction.Return:
|
case PrimaryInstruction.Return:
|
||||||
|
|||||||
@@ -30,7 +30,16 @@ class Program
|
|||||||
svm.Init();
|
svm.Init();
|
||||||
while (!svm.isReachBinaryEnd())
|
while (!svm.isReachBinaryEnd())
|
||||||
{
|
{
|
||||||
svm.Step();
|
try
|
||||||
|
{
|
||||||
|
svm.Step();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error at:{svm.GetPC()}");
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Assembler", "SVM.Assemb
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Advanced", "SVM.Advanced\SVM.Advanced.csproj", "{F9F2F699-49F7-4427-BA22-B444DD6259FD}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SVM.Advanced", "SVM.Advanced\SVM.Advanced.csproj", "{F9F2F699-49F7-4427-BA22-B444DD6259FD}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
..\examples\hello.s = ..\examples\hello.s
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|||||||
Reference in New Issue
Block a user