Adds assembler for SuperVM instructions.
This commit is contained in:
parent
9a7e2e8ceb
commit
cbc817bd36
6 changed files with 538 additions and 22 deletions
6
prototypes/supervm-asm/App.config
Normal file
6
prototypes/supervm-asm/App.config
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
</configuration>
|
400
prototypes/supervm-asm/Program.cs
Normal file
400
prototypes/supervm-asm/Program.cs
Normal file
|
@ -0,0 +1,400 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace supervm_asm
|
||||
{
|
||||
class Program
|
||||
{
|
||||
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// MnemonicParser.GenerateFromDocumentation(@"D:\felix\projects\DasOS\prototypes\supervm\instructions.md");
|
||||
|
||||
var code = Assembler.Assemble(File.ReadAllText("testcode.asm"));
|
||||
|
||||
for (int i = 0; i < code.Length; i++)
|
||||
{
|
||||
Console.Write("; {0:X3} ", i);
|
||||
Console.Write(Convert.ToString((long)code[i], 2).PadLeft(64, '0'));
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Assembler
|
||||
{
|
||||
static Regex annotationMatcher = new Regex(@"\[\s*(.*?)\s*\]", RegexOptions.Compiled);
|
||||
static Regex labelMatcher = new Regex(@"^(\w+):\s*(.*)\s*$", RegexOptions.Compiled);
|
||||
static Regex instructionMatcher = new Regex(@"(\w+)(?:\s+(@?\w+))?", RegexOptions.Compiled);
|
||||
|
||||
public static ulong[] Assemble(string src)
|
||||
{
|
||||
var lines = src.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var patches = new Dictionary<int, string>();
|
||||
var labels = new Dictionary<string, int>();
|
||||
|
||||
var code = new List<ulong>();
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
var line = lines[i].Trim();
|
||||
{ // Process comments
|
||||
var idx = line.IndexOf(';');
|
||||
if (idx >= 0)
|
||||
line = line.Substring(0, idx);
|
||||
}
|
||||
|
||||
{ // Process labels
|
||||
var match = labelMatcher.Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var label = match.Groups[1].Value;
|
||||
labels.Add(label, code.Count);
|
||||
line = match.Groups[2].Value;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
var annotations = new HashSet<string>();
|
||||
line = annotationMatcher.Replace(line, (m) =>
|
||||
{
|
||||
annotations.Add(m.Groups[1].Value.ToLower());
|
||||
return "";
|
||||
});
|
||||
line = line.Trim();
|
||||
|
||||
{
|
||||
var match = instructionMatcher.Match(line);
|
||||
if (match.Success == false)
|
||||
throw new InvalidOperationException("Invalid instruction: " + line);
|
||||
|
||||
var mnemonic = match.Groups[1].Value;
|
||||
|
||||
uint argument = 0;
|
||||
if (match.Groups[2].Length > 0)
|
||||
{
|
||||
var argstring = match.Groups[2].Value;
|
||||
if (argstring.StartsWith("@"))
|
||||
{
|
||||
// Add patch note for labels.
|
||||
patches.Add(code.Count, argstring.Substring(1));
|
||||
}
|
||||
else if (argstring.StartsWith("0x"))
|
||||
{
|
||||
argument = Convert.ToUInt32(argstring.Substring(2), 16);
|
||||
}
|
||||
else if (argstring.StartsWith("0b"))
|
||||
{
|
||||
argument = Convert.ToUInt32(argstring.Substring(2), 10);
|
||||
}
|
||||
else if (argstring.StartsWith("0d"))
|
||||
{
|
||||
argument = Convert.ToUInt32(argstring.Substring(2), 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
argument = Convert.ToUInt32(argstring, 10);
|
||||
}
|
||||
}
|
||||
|
||||
var instruction = mnemonics[mnemonic];
|
||||
|
||||
foreach(var annotation in annotations)
|
||||
{
|
||||
if(annotation.StartsWith("ci:"))
|
||||
{
|
||||
instruction.CommandInfo = UInt16.Parse(annotation.Substring(3));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (annotation.StartsWith("cmd:"))
|
||||
{
|
||||
instruction.Command = (Command)Enum.Parse(typeof(Command), annotation.Substring(4));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (annotation)
|
||||
{
|
||||
case "f:yes":
|
||||
instruction.ModifyFlags = false;
|
||||
break;
|
||||
case "f:no":
|
||||
instruction.ModifyFlags = true;
|
||||
break;
|
||||
case "r:discard":
|
||||
instruction.Output = OutputType.Discard;
|
||||
break;
|
||||
case "r:push":
|
||||
instruction.Output = OutputType.Push;
|
||||
break;
|
||||
case "r:jump":
|
||||
instruction.Output = OutputType.Jump;
|
||||
break;
|
||||
case "i0:zero":
|
||||
instruction.Input0 = InputType.Zero;
|
||||
break;
|
||||
case "i0:pop":
|
||||
instruction.Input0 = InputType.Pop;
|
||||
break;
|
||||
case "i0:peek":
|
||||
instruction.Input0 = InputType.Peek;
|
||||
break;
|
||||
case "i0:arg":
|
||||
instruction.Input0 = InputType.Argument;
|
||||
break;
|
||||
case "i1:zero":
|
||||
instruction.Input1 = InputType.Zero;
|
||||
break;
|
||||
case "i1:pop":
|
||||
instruction.Input1 = InputType.Pop;
|
||||
break;
|
||||
case "ex(z)=x":
|
||||
instruction.ExecutionZ = ExecutionMode.Always;
|
||||
break;
|
||||
case "ex(z)=0":
|
||||
instruction.ExecutionZ = ExecutionMode.Zero;
|
||||
break;
|
||||
case "ex(z)=1":
|
||||
instruction.ExecutionZ = ExecutionMode.One;
|
||||
break;
|
||||
case "ex(n)=x":
|
||||
instruction.ExecutionN = ExecutionMode.Always;
|
||||
break;
|
||||
case "ex(n)=0":
|
||||
instruction.ExecutionN = ExecutionMode.Zero;
|
||||
break;
|
||||
case "ex(n)=1":
|
||||
instruction.ExecutionN = ExecutionMode.One;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Unrecognized annotation: " + annotation);
|
||||
}
|
||||
}
|
||||
|
||||
ulong encoded = 0;
|
||||
|
||||
encoded |= ((uint)(instruction.ExecutionZ) << 0);
|
||||
encoded |= ((uint)(instruction.ExecutionN) << 2);
|
||||
encoded |= ((uint)(instruction.Input0) << 4);
|
||||
encoded |= ((uint)(instruction.Input1) << 6);
|
||||
encoded |= ((uint)(instruction.Command) << 7);
|
||||
encoded |= ((uint)(instruction.CommandInfo) << 13);
|
||||
encoded |= ((uint)(instruction.ModifyFlags ? 1 : 0) << 29);
|
||||
encoded |= ((uint)(instruction.Output) << 30);
|
||||
encoded |= ((ulong)argument << 32);
|
||||
|
||||
code.Add(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
{ // Install patches
|
||||
foreach (var patch in patches)
|
||||
{
|
||||
var target = patch.Value;
|
||||
var position = labels[target];
|
||||
code[patch.Key] =
|
||||
(code[patch.Key] & 0xFFFFFFFF) |
|
||||
((ulong)position << 32);
|
||||
}
|
||||
}
|
||||
|
||||
return code.ToArray();
|
||||
}
|
||||
|
||||
|
||||
static Dictionary<string, Instruction> mnemonics = new Dictionary<string, Instruction>()
|
||||
{
|
||||
{ "nop", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "push", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Argument, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "drop", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "dup", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Peek, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "jmp", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Argument, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Jump, Argument = 0, } },
|
||||
{ "jmpi", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Jump, Argument = 0, } },
|
||||
{ "ret", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.Copy, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Jump, Argument = 0, } },
|
||||
{ "load", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Argument, Input1 = InputType.Zero, Command = Command.Load, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "loadi", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.Load, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "store", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Argument, Input1 = InputType.Pop, Command = Command.Store, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "storei", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Store, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "get", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Argument, Input1 = InputType.Zero, Command = Command.Get, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "geti", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.Get, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "set", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Argument, Input1 = InputType.Pop, Command = Command.Set, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "seti", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Set, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "bpget", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.BpGet, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "bpset", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.BpSet, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } },
|
||||
{ "add", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "sub", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 1, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "mul", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 2, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "div", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 3, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "mod", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 4, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "and", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 5, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "or", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 6, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "xor", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 7, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "not", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.Math, CommandInfo = 8, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "rol", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 9, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "ror", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 10, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "asl", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 11, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "asr", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 12, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "shl", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 13, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
{ "shr", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 14, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } },
|
||||
};
|
||||
}
|
||||
|
||||
class MnemonicParser
|
||||
{
|
||||
public static void GenerateFromDocumentation(string file)
|
||||
{
|
||||
var relevantLines = File
|
||||
.ReadAllLines(file)
|
||||
.SkipWhile(l => l != "## Assembler Mnemonics")
|
||||
.Skip(1)
|
||||
.SkipWhile(l => string.IsNullOrWhiteSpace(l))
|
||||
.TakeWhile(l => l.StartsWith("|"))
|
||||
.Skip(2)
|
||||
.ToArray();
|
||||
|
||||
|
||||
|
||||
var instructions = relevantLines
|
||||
.Select(l => l
|
||||
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(s => s.Trim())
|
||||
.ToArray())
|
||||
.ToDictionary(a => a[0], a => new Instruction()
|
||||
{
|
||||
ExecutionN = ExecutionMode.Always,
|
||||
ExecutionZ = ExecutionMode.Always,
|
||||
Input0 = ToInputMode(a[2]),
|
||||
Input1 = ToInputMode(a[3]),
|
||||
Command = ToCommand(a[4]),
|
||||
CommandInfo = ushort.Parse(a[5]),
|
||||
ModifyFlags = false,
|
||||
Output = ToOutput(a[6]),
|
||||
Argument = 0,
|
||||
});
|
||||
|
||||
var fields = typeof(Instruction).GetFields();
|
||||
foreach (var item in instructions)
|
||||
{
|
||||
// { "a", new Instruction() { } },
|
||||
Console.Write("{{ \"{0}\", new Instruction() {{ ", item.Key);
|
||||
|
||||
foreach (var field in fields)
|
||||
{
|
||||
var value = field.GetValue(item.Value);
|
||||
if (field.FieldType.IsEnum)
|
||||
Console.Write("{0} = {1}.{2}, ", field.Name, field.FieldType.Name, value);
|
||||
else
|
||||
Console.Write("{0} = {1}, ", field.Name, value.ToString().ToLower());
|
||||
}
|
||||
|
||||
Console.WriteLine(" } },");
|
||||
}
|
||||
}
|
||||
|
||||
private static OutputType ToOutput(string v)
|
||||
{
|
||||
switch (v.ToLower())
|
||||
{
|
||||
case "discard": return OutputType.Discard;
|
||||
case "push": return OutputType.Push;
|
||||
case "jump": return OutputType.Jump;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private static Command ToCommand(string v)
|
||||
{
|
||||
return (Command)Enum.Parse(typeof(Command), v, true);
|
||||
}
|
||||
|
||||
private static InputType ToInputMode(string v)
|
||||
{
|
||||
switch (v.ToLower())
|
||||
{
|
||||
case "zero": return InputType.Zero;
|
||||
case "peek": return InputType.Peek;
|
||||
case "pop": return InputType.Pop;
|
||||
case "arg": return InputType.Argument;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct Instruction
|
||||
{
|
||||
public ExecutionMode ExecutionZ;
|
||||
public ExecutionMode ExecutionN;
|
||||
public InputType Input0;
|
||||
public InputType Input1;
|
||||
public Command Command;
|
||||
public ushort CommandInfo;
|
||||
public bool ModifyFlags;
|
||||
public OutputType Output;
|
||||
public uint Argument;
|
||||
}
|
||||
|
||||
public enum MathCommand
|
||||
{
|
||||
Add = 0,
|
||||
Subtract = 1,
|
||||
Multiplicate = 2,
|
||||
Divide = 3,
|
||||
Modulo = 4,
|
||||
And = 5,
|
||||
Or = 6,
|
||||
Xor = 7,
|
||||
Not = 8,
|
||||
RotShiftLeft = 9,
|
||||
RotShiftRight = 10,
|
||||
ArithmeticShiftLeft = 11,
|
||||
ArithmeticShiftRight = 12,
|
||||
LogicShiftLeft = 13,
|
||||
LogicShiftRight = 14,
|
||||
}
|
||||
|
||||
public enum Command
|
||||
{
|
||||
Copy = 0,
|
||||
Store = 1,
|
||||
Load = 2,
|
||||
Get = 3,
|
||||
Set = 4,
|
||||
BpGet = 5,
|
||||
BpSet = 6,
|
||||
RstStack = 7,
|
||||
Math = 8,
|
||||
SpGet = 9,
|
||||
SpSet = 10,
|
||||
}
|
||||
|
||||
public enum OutputType
|
||||
{
|
||||
Discard = 0,
|
||||
Push = 1,
|
||||
Jump = 2,
|
||||
}
|
||||
|
||||
public enum ExecutionMode
|
||||
{
|
||||
Always = 0,
|
||||
Zero = 2,
|
||||
One = 3,
|
||||
}
|
||||
|
||||
public enum InputType
|
||||
{
|
||||
Zero = 0,
|
||||
Pop = 1,
|
||||
Peek = 2,
|
||||
Argument = 3,
|
||||
}
|
||||
}
|
36
prototypes/supervm-asm/Properties/AssemblyInfo.cs
Normal file
36
prototypes/supervm-asm/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("supervm-asm")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("supervm-asm")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("7b2cb53a-d2ef-4aef-b354-fcf28c581280")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
65
prototypes/supervm-asm/supervm-asm.csproj
Normal file
65
prototypes/supervm-asm/supervm-asm.csproj
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{7B2CB53A-D2EF-4AEF-B354-FCF28C581280}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>supervm_asm</RootNamespace>
|
||||
<AssemblyName>supervm-asm</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="testcode.asm">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
8
prototypes/supervm-asm/testcode.asm
Normal file
8
prototypes/supervm-asm/testcode.asm
Normal file
|
@ -0,0 +1,8 @@
|
|||
push 0 ; Some comment
|
||||
loop:
|
||||
dup
|
||||
[f:yes] sub 10 [r:discard]
|
||||
[ex(z)=1] jmp @end
|
||||
add 1
|
||||
jmp @loop
|
||||
end:
|
|
@ -44,16 +44,17 @@ base pointer, then popping the previous base pointer from the stack.
|
|||
|
||||
An SuperVM instruction is composed of multiple components:
|
||||
|
||||
| Component | Range | Size | Function |
|
||||
|-----------|-------------------|------|-------------------------------------------|
|
||||
| execution | See below. | 4 | When is the instruction executed. |
|
||||
| input0 | Zero/Pop/Peek/Arg | 2 | Where does input0 come from? |
|
||||
| input1 | Zero/Pop | 1 | Where does input1 come from? |
|
||||
| command | [6bit] | 6 | Which command is executed? |
|
||||
| cmdinfo | [16bit] | 16 | Parameter value for the command. |
|
||||
| flagmod | yes/no | 1 | Does this command modifies flags? |
|
||||
| output | Discard/Push/Jump | 2 | What is done with the output? |
|
||||
| argument | [32bit] | 32 | Some commands can take extra information |
|
||||
| Component | Range | Size | Function |
|
||||
|-------------|-------------------|------|------------------------------------------|
|
||||
| execution Z | See below. | 2 | Excution dependend on Zero? |
|
||||
| execution N | See below. | 2 | Excution dependend on Negative? |
|
||||
| input0 | Zero/Pop/Peek/Arg | 2 | Where does input0 come from? |
|
||||
| input1 | Zero/Pop | 1 | Where does input1 come from? |
|
||||
| command | [6bit] | 6 | Which command is executed? |
|
||||
| cmdinfo | [16bit] | 16 | Parameter value for the command. |
|
||||
| flagmod | yes/no | 1 | Does this command modifies flags? |
|
||||
| output | Discard/Push/Jump | 2 | What is done with the output? |
|
||||
| argument | [32bit] | 32 | Some commands can take extra information |
|
||||
|
||||
### Execution Modes
|
||||
|
||||
|
@ -81,8 +82,8 @@ An instruction is only executed when all conditions are met.
|
|||
| 6 | BPSET | output = BP = input0 |
|
||||
| 7 | RSTSTACK | output = SP = BP |
|
||||
| 8 | MATH | output = input0 OP[info] input1 |
|
||||
| 9 | spget | output = SP + input0 |
|
||||
| 10 | spset | output = SP + input0 = input1 |
|
||||
| 9 | SPGET | output = SP + input0 |
|
||||
| 10 | SPSET | output = SP + input0 = input1 |
|
||||
| 11 | | |
|
||||
| 12 | | |
|
||||
| 13 | | |
|
||||
|
@ -123,16 +124,16 @@ by the `cmdinfo`.
|
|||
| jmp | yes | arg | zero | copy | 0 | jump |
|
||||
| jmpi | no | pop | zero | copy | 0 | jump |
|
||||
| ret | no | pop | zero | copy | 0 | jump |
|
||||
| load | yes | arg | zero | load | 0 | push |
|
||||
| loadi | no | pop | zero | load | 0 | push |
|
||||
| store | yes | arg | pop | store | 0 | discard |
|
||||
| storei | no | pop | pop | store | 0 | discard |
|
||||
| get | yes | arg | zero | get | 0 | push |
|
||||
| geti | no | pop | zero | get | 0 | push |
|
||||
| set | yes | arg | pop | set | 0 | discard |
|
||||
| seti | no | pop | pop | set | 0 | discard |
|
||||
| bpget | no | zero | zero | bpget | 0 | push |
|
||||
| bpset | no | pop | zero | bpset | 0 | discard |
|
||||
| load | yes | arg | zero | load | 0 | push |
|
||||
| loadi | no | pop | zero | load | 0 | push |
|
||||
| store | yes | arg | pop | store | 0 | discard |
|
||||
| storei | no | pop | pop | store | 0 | discard |
|
||||
| get | yes | arg | zero | get | 0 | push |
|
||||
| geti | no | pop | zero | get | 0 | push |
|
||||
| set | yes | arg | pop | set | 0 | discard |
|
||||
| seti | no | pop | pop | set | 0 | discard |
|
||||
| bpget | no | zero | zero | bpget | 0 | push |
|
||||
| bpset | no | pop | zero | bpset | 0 | discard |
|
||||
| add | no | pop | pop | math | 0 | push |
|
||||
| sub | no | pop | pop | math | 1 | push |
|
||||
| mul | no | pop | pop | math | 2 | push |
|
||||
|
|
Loading…
Reference in a new issue