From 5f5a34d736f9a8928dfd2dafb175b789c5069511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Quei=C3=9Fner?= Date: Sat, 21 May 2016 21:51:44 +0200 Subject: [PATCH] Adds support for get/set with negative index. --- prototypes/supervm-asm/assembler.cs | 100 +++++++++++++++++----------- prototypes/supervm-asm/testcode.asm | 73 ++++++++++++++------ prototypes/supervm/vm.c | 20 +++++- 3 files changed, 129 insertions(+), 64 deletions(-) diff --git a/prototypes/supervm-asm/assembler.cs b/prototypes/supervm-asm/assembler.cs index 1e25559..6852172 100644 --- a/prototypes/supervm-asm/assembler.cs +++ b/prototypes/supervm-asm/assembler.cs @@ -14,7 +14,12 @@ namespace supervm_asm static void Main(string[] args) { - // MnemonicParser.GenerateFromDocumentation(@"../supervm/supervm.md"); + if(args.Contains("-gen-code")) + { + MnemonicParser.GenerateFromDocumentation( + @"../supervm/supervm.md"); + return; + } foreach(var file in args.Where(a => !a.StartsWith("-") && Path.GetExtension(a) == ".asm")) { @@ -74,7 +79,7 @@ namespace supervm_asm { 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); + static Regex instructionMatcher = new Regex(@"(\w+)(?:\s+([@-]?\w+|'.'))?", RegexOptions.Compiled); public static ulong[] Assemble(string src) { @@ -147,10 +152,23 @@ namespace supervm_asm } else { - argument = Convert.ToUInt32(argstring, 10); + if(argstring.StartsWith("-")) + { + unchecked + { + argument = (uint)Convert.ToInt32(argstring, 10);; + } + } + else + argument = Convert.ToUInt32(argstring, 10); } } + if(mnemonics.ContainsKey(mnemonic) == false) + { + throw new InvalidOperationException("Unknown mnemonic: " + mnemonic); + } + var instruction = mnemonics[mnemonic]; foreach(var annotation in annotations) @@ -258,41 +276,45 @@ namespace supervm_asm static Dictionary mnemonics = new Dictionary() { - { "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, } }, - { "cmp", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 1, ModifyFlags = true, Output = OutputType.Discard, 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, } }, - { "syscall", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.SysCall, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } }, - { "hwio", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.HwIO, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } }, +{ "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, } }, +{ "spget", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.SpGet, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Push, Argument = 0, } }, +{ "spset", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Zero, Command = Command.SpSet, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } }, +{ "cpget", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.CpGet, CommandInfo = 1, ModifyFlags = false, Output = OutputType.Push, 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, } }, +{ "cmp", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Pop, Input1 = InputType.Pop, Command = Command.Math, CommandInfo = 1, ModifyFlags = true, Output = OutputType.Discard, 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, } }, +{ "syscall", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.SysCall, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } }, +{ "hwio", new Instruction() { ExecutionZ = ExecutionMode.Always, ExecutionN = ExecutionMode.Always, Input0 = InputType.Zero, Input1 = InputType.Zero, Command = Command.HwIO, CommandInfo = 0, ModifyFlags = false, Output = OutputType.Discard, Argument = 0, } }, + }; } @@ -420,7 +442,7 @@ namespace supervm_asm Set = 4, BpGet = 5, BpSet = 6, - RstStack = 7, + CpGet = 7, Math = 8, SpGet = 9, SpSet = 10, diff --git a/prototypes/supervm-asm/testcode.asm b/prototypes/supervm-asm/testcode.asm index d778648..ffa2a7c 100644 --- a/prototypes/supervm-asm/testcode.asm +++ b/prototypes/supervm-asm/testcode.asm @@ -1,30 +1,59 @@  - [i0:arg] syscall [ci:1] 'H' - [i0:arg] syscall [ci:1] 'a' - [i0:arg] syscall [ci:1] 'l' - [i0:arg] syscall [ci:1] 'l' - [i0:arg] syscall [ci:1] 'o' + [i0:arg] syscall [ci:1] 'S' - load 0 - load 1 - load 2 - load 3 + push 1 + push 2 + push 3 + push 4 + + cpget + jmp @print_str - store 67 - store 66 - store 65 - store 64 + [i0:arg] syscall [ci:1] 'Q' + + syscall [ci:0] ; Exit + +print_str: + spget + bpset + + push 200 + get -1 + get -2 + get -3 + get -4 + push 400 + + get 1 + + push 600 + + + + bpget + spset + jmpi + +; load 0 +; load 1 +; load 2 +; load 3 + +; store 67 +; store 66 +; store 65 +; store 64 - push 0 ; Some comment -_loop: - dup - [i0:arg] sub 10 [f:yes] [r:discard] - [ex(z)=1] jmp @_end - [i0:arg] add 1 - jmp @_loop -_end: - syscall [ci:0]; Exit \ No newline at end of file +; push 0 ; Some comment +;_loop: +; dup +; [i0:arg] sub 10 [f:yes] [r:discard] +; [ex(z)=1] jmp @_end +; [i0:arg] add 1 +; jmp @_loop +;_end: +; syscall [ci:0]; Exit \ No newline at end of file diff --git a/prototypes/supervm/vm.c b/prototypes/supervm/vm.c index 1026846..92f8c30 100644 --- a/prototypes/supervm/vm.c +++ b/prototypes/supervm/vm.c @@ -7,9 +7,6 @@ static void cmd_copy(CommandInfo *info) info->output = info->input0; } -// | 1 | STORE | output = MEMORY[input0] = input1 | -// | 2 | LOAD | output = MEMORY[input0] | - static void cmd_load(Process *p, CommandInfo *info) { info->output = vm_read_byte(p, info->input0); @@ -46,6 +43,21 @@ static void cmd_cpget(Process *p, CommandInfo *info) info->output = p->codePointer + info->additional; } +static inline int16_t makeSigned(uint16_t val) +{ + return *((int16_t*)&val); +} + +static void cmd_get(Process *p, CommandInfo *info) +{ + info->output = p->stack[p->basePointer + makeSigned(info->input0)]; +} + +static void cmd_set(Process *p, CommandInfo *info) +{ + info->output = p->stack[p->basePointer + makeSigned(info->input0)] = info->input1; +} + static void cmd_math(CommandInfo *info) { switch(info->additional) @@ -146,6 +158,8 @@ int vm_step_process(Process *process) case VM_CMD_BPGET: cmd_bpget(process, &info); break; case VM_CMD_BPSET: cmd_bpset(process, &info); break; case VM_CMD_CPGET: cmd_cpget(process, &info); break; + case VM_CMD_GET: cmd_get(process, &info); break; + case VM_CMD_SET: cmd_set(process, &info); break; default: vm_assert(0, "Invalid instruction: command undefined."); }