feat: процедура выполнения опкода

This commit is contained in:
ElectronixTM
2025-03-29 00:17:02 +03:00
parent 0f5ac310e8
commit b73f92ef88
2 changed files with 44 additions and 7 deletions

View File

@ -29,7 +29,7 @@ class OpcodeActions(Enum):
LOAD = auto() LOAD = auto()
STORE = auto() STORE = auto()
BRANCH = auto() BRANCH = auto()
MEM_BRANCH = auto() IND_BRANCH = auto()
OpA = OpcodeActions OpA = OpcodeActions

View File

@ -1,6 +1,6 @@
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import ClassVar, Callable, Any from typing import ClassVar, Callable
from ctypes import c_uint32, c_int32, c_uint8 from ctypes import c_uint32, c_int32, c_uint8
import struct import struct
from optable import OPCODES, OpcodeDescription, OpL, OpA, OpF, OpD from optable import OPCODES, OpcodeDescription, OpL, OpA, OpF, OpD
@ -86,7 +86,7 @@ class VM:
self._branch_callback, self._branch_callback,
OpD(OpF.QUICK, OpL.BRANCH, OpA.BRANCH): OpD(OpF.QUICK, OpL.BRANCH, OpA.BRANCH):
self._branch_callback, self._branch_callback,
OpD(OpF(0), OpL.BRANCH, OpA.MEM_BRANCH): OpD(OpF(0), OpL.BRANCH, OpA.IND_BRANCH):
self._branch_indexed_callback self._branch_indexed_callback
} }
@ -94,12 +94,16 @@ class VM:
""" """
Make one step (only step into) Make one step (only step into)
""" """
# По какой-то причине адрессация работает
# так, будто мы на 1 слово впереди опкода
if not VMFlags.AFTER_BRANCH:
self.pc = c_uint32(self.cc.value + 1)
# сбрасываем флаг AFTER_BRANCH
self._vm_flags &= ~(VMFlags.AFTER_BRANCH)
opcode = self.mem[self.pc.value] opcode = self.mem[self.pc.value]
opdesc = self._fetch_opcode_desc(opcode) opdesc = self._fetch_opcode_desc(opcode)
args = self._parse_arguments(opdesc) args = self._parse_arguments(opdesc)
if not VMFlags.AFTER_BRANCH: self._run_callback(opdesc, args)
self.pc = c_uint32(self.cc.value + 1)
self._vm_flags &= ~(VMFlags.AFTER_BRANCH)
def continue_(self) -> None: def continue_(self) -> None:
""" """
@ -142,7 +146,39 @@ class VM:
self.instr_callbacks[opdesc]( self.instr_callbacks[opdesc](
r3, r1, r2_or_i8 r3, r1, r2_or_i8
) )
if opdesc.layout == OpL.MEM if opdesc.layout == OpL.MEM:
if OpF.QUICK in opdesc.flags:
assert len(args) == 4
_, r3, r1, i8 = args
self.instr_callbacks[opdesc](
r3, r1, i8
)
else:
assert len(args) == 5
_, r3, r1, _, disp = args
self.instr_callbacks[opdesc](
r3, r1, disp
)
if opdesc.layout == OpL.BRANCH:
if OpF.QUICK in opdesc.flags:
assert len(args) == 4
_, cond, _, i8 = args
self.instr_callbacks[opdesc](
cond, i8
)
elif opdesc.action == OpA.IND_BRANCH:
assert len(args) == 5
_, cond, r1, _, disp = args
self.instr_callbacks[opdesc](
cond, r1, disp
)
else:
assert len(args) == 5
_, cond, _, _, disp = args
self.instr_callbacks[opdesc](
cond, disp
)
def _math_callback_gen( def _math_callback_gen(
self, self,
@ -200,3 +236,4 @@ class VM:
self._vm_flags |= VMFlags.AFTER_BRANCH self._vm_flags |= VMFlags.AFTER_BRANCH
addr = self.registers[r1].value + disp addr = self.registers[r1].value + disp
self.pc = c_uint32(addr) self.pc = c_uint32(addr)