From f061cf5db95ecf9288eee4b212d02db0fb23d0da Mon Sep 17 00:00:00 2001 From: Neil Webber Date: Sun, 24 Sep 2023 09:01:13 -0400 Subject: [PATCH] dynamically build all branch instruction methods --- pdpasmhelper.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/pdpasmhelper.py b/pdpasmhelper.py index dbd2b0d..4e9039d 100644 --- a/pdpasmhelper.py +++ b/pdpasmhelper.py @@ -28,6 +28,7 @@ # are focused around helping to create hand-constructed test code. # +import re from contextlib import AbstractContextManager from branches import BRANCH_CODES from collections import namedtuple @@ -422,6 +423,15 @@ class InstructionBlock(PDP11InstructionAssembler, AbstractContextManager): return self._neg16(x) + # branches can have forward references (of course), but the offset + # doesn't occupy a full 16-bit word. What this does is turn the + # branch location in the instruction stream into a 16-bit FwdRef + # but with a customized handler to validate and modify the branch + # offset once it becomes known, and to OR it with the branch code. + def _branchhandler(self, opcode, target): + # TBD / changes to come + pass + # can't use the standard fwdword patcher because the offset # needs to be divided by 2 and checked if fits within 8 bits def _branchpatch(self, fref): @@ -450,18 +460,14 @@ class InstructionBlock(PDP11InstructionAssembler, AbstractContextManager): offs >>= 1 return offs & 0o377 - def bne(self, target): - return self.literal(BRANCH_CODES['bne'] | self.bxx_offset(target)) - - def blt(self, target): - return self.literal(BRANCH_CODES['blt'] | self.bxx_offset(target)) - - def beq(self, target): - return self.literal(BRANCH_CODES['beq'] | self.bxx_offset(target)) - - # overrides the base br to implement label support - def br(self, target): - return self.literal(0o000400 | self.bxx_offset(target)) + # dynamically construct the methods for all the Bxx branches + # This makes methods: beq, bne, bgt, etc + for _bname, _code in BRANCH_CODES.items(): + def branchxx(self, target, code=_code): + return self.literal(code | self.bxx_offset(target)) + branchxx.__name__ = _bname + setattr(PDP11InstructionAssembler, _bname, branchxx) + del _bname, _code, branchxx def sob(self, reg, target): # the register can be a naked integer 0 .. 5 or an 'r' string