summaryrefslogtreecommitdiff
path: root/src/vm/instruction.js
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2023-05-24 13:06:45 -0500
committersanine-a <sanine.not@pm.me>2023-05-24 13:06:45 -0500
commit9f478261bc8fd1502090c701c998e48a4018e7ee (patch)
treec1758c322450af1eead232cb42491e558b5aba12 /src/vm/instruction.js
parent15323007750e0f0f7c36a6a6fa01ad1d303a4a16 (diff)
fix operand resolution to match specmain
Diffstat (limited to 'src/vm/instruction.js')
-rw-r--r--src/vm/instruction.js146
1 files changed, 82 insertions, 64 deletions
diff --git a/src/vm/instruction.js b/src/vm/instruction.js
index dcf9a51..2b8ce84 100644
--- a/src/vm/instruction.js
+++ b/src/vm/instruction.js
@@ -3,68 +3,86 @@
const { AddrMode } = require('./enum.js');
-exports.DAT = function(core, pc, ins) {
+function getOp(core, pc, op) {
+ switch(op.mode) {
+ case AddrMode.Immediate:
+ return { mode: AddrMode.Immediate, value: op.value };
+ default:
+ return { mode: 'precomp', value: core.getLocation(pc, op) };
+ }
+}
+
+
+function Instruction(f) {
+ return function(core, pc, ins) {
+ const a = getOp(core, pc, ins.a);
+ const b = getOp(core, pc, ins.b);
+ return f(core, pc, a, b);
+ }
+}
+
+
+exports.DAT = Instruction((core, pc, a, b) => {
// do nothing and die
return [];
-}
+});
-exports.MOV = function(core, pc, ins) {
- if (ins.a.mode === AddrMode.Immediate) {
- const dst = core.getValue(pc, ins.b);
- dst.b.value = ins.a.value;
+exports.MOV = Instruction((core, pc, a, b) => {
+ if (a.mode === AddrMode.Immediate) {
+ const dst = core.data[b.value];
+ dst.b.value = a.value;
} else {
- const src = core.getValue(pc, ins.a);
- const dstLocation = core.getLocation(pc, ins.b);
+ const src = core.data[a.value];
// hacky deep copy
- core.data[dstLocation] = JSON.parse(JSON.stringify(src));
+ core.data[b.value] = JSON.parse(JSON.stringify(src));
}
return [core.normalize(pc, 1)];
-}
+});
-exports.ADD = function(core, pc, ins) {
- if (ins.a.mode === AddrMode.Immediate) {
- const dst = core.getValue(pc, ins.b);
- dst.b.value += ins.a.value;
+exports.ADD = Instruction((core, pc, a, b) => {
+ if (a.mode === AddrMode.Immediate) {
+ const dst = core.data[b.value];
+ dst.b.value += a.value;
} else {
- const src = core.getValue(pc, ins.a);
- const dst = core.getValue(pc, ins.b);
+ const src = core.data[a.value];
+ const dst = core.data[b.value];
dst.a.value += src.a.value;
dst.b.value += src.b.value;
}
return [core.normalize(pc, 1)];
-}
+});
-exports.SUB = function(core, pc, ins) {
- if (ins.a.mode === AddrMode.Immediate) {
- const dst = core.getValue(pc, ins.b);
- dst.b.value -= ins.a.value;
+exports.SUB = Instruction((core, pc, a, b) => {
+ if (a.mode === AddrMode.Immediate) {
+ const dst = core.data[b.value];
+ dst.b.value -= a.value;
} else {
- const src = core.getValue(pc, ins.a);
- const dst = core.getValue(pc, ins.b);
+ const src = core.data[a.value];
+ const dst = core.data[b.value];
dst.a.value -= src.a.value;
dst.b.value -= src.b.value;
}
return [core.normalize(pc, 1)];
-}
+});
-exports.CMP = function(core, pc, ins) {
- if (ins.a.mode === AddrMode.Immediate) {
- const test = core.getValue(pc, ins.b);
- if (test.b.value === ins.a.value) {
+exports.CMP = Instruction((core, pc, a, b) => {
+ if (a.mode === AddrMode.Immediate) {
+ const test = core.data[b.value];
+ if (test.b.value === a.value) {
return [core.normalize(pc, 2)];
} else {
return [core.normalize(pc, 1)];
}
} else {
- const left = core.getValue(pc, ins.a);
- const right = core.getValue(pc, ins.b);
+ const left = core.data[a.value];
+ const right = core.data[b.value];
if (
// compare opcode
left.opcode === right.opcode &&
@@ -80,93 +98,93 @@ exports.CMP = function(core, pc, ins) {
return [core.normalize(pc, 1)];
}
}
-}
+});
-exports.SLT = function(core, pc, ins) {
- if (ins.a.mode === AddrMode.Immediate) {
- const test = core.getValue(pc, ins.b);
- if (ins.a.value < test.b.value) {
+exports.SLT = Instruction((core, pc, a, b) => {
+ if (a.mode === AddrMode.Immediate) {
+ const test = core.data[b.value];
+ if (a.value < test.b.value) {
return [core.normalize(pc, 2)];
} else {
return [core.normalize(pc, 1)];
}
} else {
- const left = core.getValue(pc, ins.a);
- const right = core.getValue(pc, ins.b);
+ const left = core.data[a.value];
+ const right = core.data[b.value];
if (left.b.value < right.b.value) {
return [core.normalize(pc, 2)];
} else {
return [core.normalize(pc, 1)];
}
}
-}
+});
-exports.JMP = function(core, pc, ins) {
- const dstLoc = core.getLocation(pc, ins.a);
- return [dstLoc];
-}
+exports.JMP = Instruction((core, pc, a, b) => {
+ return [a.value];
+});
-exports.JMZ = function(core, pc, ins) {
+exports.JMZ = Instruction((core, pc, a, b) => {
let test
- if (ins.b.mode === AddrMode.Immediate) {
- test = (ins.b.value === 0);
+ if (b.mode === AddrMode.Immediate) {
+ test = (b.value === 0);
} else {
- const src = core.getValue(pc, ins.b);
+ const src = core.data[b.value];
test = (src.b.value === 0);
}
if (test) {
- return [core.getLocation(pc, ins.a)];
+ return [a.value];
} else {
return [core.normalize(pc, 1)];
}
-}
+});
-exports.JMN = function(core, pc, ins) {
+exports.JMN = Instruction((core, pc, a, b) => {
let test;
- if (ins.b.mode === AddrMode.Immediate) {
- test = (ins.b.value !== 0);
+ if (b.mode === AddrMode.Immediate) {
+ test = (b.value !== 0);
} else {
- const src = core.getValue(pc, ins.b);
+ const src = core.data[b.value];
test = (src.b.value !== 0);
}
if (test) {
- return [core.getLocation(pc, ins.a)];
+ return [a.value];
} else {
return [core.normalize(pc, 1)];
}
-}
+});
-exports.DJN = function(core, pc, ins) {
+exports.DJN = Instruction((core, pc, a, b) => {
let test;
- if (ins.b.mode === AddrMode.Immediate) {
- ins.b.value -= 1;
- test = (ins.b.value !== 0);
+ if (b.mode === AddrMode.Immediate) {
+ core.data[pc].b.value -= 1;
+ b.value -= 1;
+ test = (b.value !== 0);
} else {
- const src = core.getValue(pc, ins.b);
+ const src = core.data[b.value];
src.b.value -= 1;
test = (src.b.value !== 0);
}
if (test) {
- return [core.getLocation(pc, ins.a)];
+ return [a.value];
} else {
return [core.normalize(pc, 1)];
}
-}
+});
-exports.SPL = function(core, pc, ins) {
+exports.SPL = Instruction((core, pc, a, b) => {
return [
core.normalize(pc, 1),
- core.getLocation(pc, ins.a),
+ a.value,
];
-}
+});