more fwdref improvements, some more instrs
This commit is contained in:
parent
1f196e1923
commit
7354007fe4
1 changed files with 36 additions and 30 deletions
|
@ -267,6 +267,16 @@ class PDP11InstructionAssembler:
|
|||
def rti(self):
|
||||
return self.literal(2)
|
||||
|
||||
def nop(self):
|
||||
return self.literal(0o000240)
|
||||
|
||||
def clc(self):
|
||||
"""Clear Carry"""
|
||||
return self.literal(0o000241)
|
||||
|
||||
def wait(self):
|
||||
return self.literal(1)
|
||||
|
||||
def mtpi(self, dst):
|
||||
return self._1op(0o006600, dst)
|
||||
|
||||
|
@ -290,10 +300,14 @@ class PDP11InstructionAssembler:
|
|||
class FwdRef:
|
||||
"""Values determined by a not-yet-seen label() definition."""
|
||||
|
||||
def __init__(self, name, block):
|
||||
def __init__(self, name, block, *, pcrel=False):
|
||||
self.loc = len(block)
|
||||
self.name = name
|
||||
self.block = block
|
||||
if pcrel:
|
||||
self.pcadj = (2 * self.loc) + 4
|
||||
else:
|
||||
self.pcadj = 0
|
||||
block._fwdrefs[name].append(self)
|
||||
|
||||
def __call__(self):
|
||||
|
@ -309,17 +323,14 @@ class FwdRef:
|
|||
def __iter__(self):
|
||||
return iter([0o27, self])
|
||||
|
||||
def transform(self):
|
||||
return self.block.getlabel(self.name) - (2 * self.loc)
|
||||
def __repr__(self):
|
||||
s = f"{self.__class__.__name__}<"
|
||||
s += f"{str(self.name)}, block<len={len(self.block)}>"
|
||||
s += f", loc={self.loc}>"
|
||||
return s
|
||||
|
||||
|
||||
class JumpTarget(FwdRef):
|
||||
# when a label is used as a PC-relative offset in a Jump (or JSR)
|
||||
# target, the PC is already advanced according to where the literal of
|
||||
# forward reference occurs in the stream. This has to be adjusted for.
|
||||
def transform(self):
|
||||
return self.block._neg16(
|
||||
self.block.getlabel(self.name) - (2 * (self.loc + 2)))
|
||||
return self.block._neg16(self.block.getlabel(self.name) - self.pcadj)
|
||||
|
||||
|
||||
class BranchTarget(FwdRef):
|
||||
|
@ -415,7 +426,12 @@ class InstructionBlock(PDP11InstructionAssembler):
|
|||
raise
|
||||
|
||||
# falling through to here means it is a label or forward reference
|
||||
return [0o27, self.getlabel(operand_token)]
|
||||
# IF it starts with '+' it means use PC-relative addr mode
|
||||
# which will require some fussing around...
|
||||
if operand_token[0] == '+':
|
||||
return [0o67, self.getlabel(operand_token[1:], pcrel=True)]
|
||||
else:
|
||||
return [0o27, self.getlabel(operand_token)]
|
||||
|
||||
def __len__(self):
|
||||
"""Returns the length of the sequence in WORDS"""
|
||||
|
@ -480,7 +496,7 @@ class InstructionBlock(PDP11InstructionAssembler):
|
|||
|
||||
return self._labels[name]
|
||||
|
||||
def getlabel(self, name, *, fwdfactory=FwdRef):
|
||||
def getlabel(self, name, *, fwdfactory=FwdRef, pcrel=False):
|
||||
"""Return value (loc) of name, which may be a FwdRef object.
|
||||
|
||||
Label values are offsets relative to the start of the block.
|
||||
|
@ -496,9 +512,13 @@ class InstructionBlock(PDP11InstructionAssembler):
|
|||
forward references raise a TypeError
|
||||
"""
|
||||
try:
|
||||
return self._labels[name]
|
||||
x = self._labels[name]
|
||||
except KeyError:
|
||||
return fwdfactory(name=name, block=self)
|
||||
return fwdfactory(name=name, block=self, pcrel=pcrel)
|
||||
else:
|
||||
if pcrel:
|
||||
x = self._neg16(x - (2 * (len(self) + 2)))
|
||||
return x
|
||||
|
||||
@staticmethod
|
||||
def _neg16(x):
|
||||
|
@ -564,16 +584,9 @@ class InstructionBlock(PDP11InstructionAssembler):
|
|||
|
||||
# labels become operand mode 0o67 ... PC-relative w/offset
|
||||
inst = 0o004067 | (self.register_parser(reg) << 6)
|
||||
x = self.getlabel(dst, fwdfactory=JumpTarget)
|
||||
try:
|
||||
offs = self._neg16(x - (2 * (len(self) + 2)))
|
||||
except TypeError:
|
||||
# forward reference will be patched later
|
||||
offs = x
|
||||
|
||||
offs = self.getlabel(dst, pcrel=True)
|
||||
return self._seqwords([inst, offs])
|
||||
|
||||
# override JMP to provide reference/label support (like branches)
|
||||
def jmp(self, dst):
|
||||
# anything not a label handled by the regular jmp method:
|
||||
if not self._allowable_label(dst):
|
||||
|
@ -581,14 +594,7 @@ class InstructionBlock(PDP11InstructionAssembler):
|
|||
|
||||
# labels become operand mode 0o67 ... PC-relative w/offset
|
||||
inst = 0o000167
|
||||
x = self.getlabel(dst, fwdfactory=JumpTarget)
|
||||
try:
|
||||
offs = self._neg16(x - (2 * (len(self) + 2)))
|
||||
except TypeError:
|
||||
# forward reference will be patched later
|
||||
offs = x
|
||||
|
||||
return self._seqwords([inst, offs])
|
||||
return self._seqwords([inst, self.getlabel(dst, pcrel=True)])
|
||||
|
||||
def sob(self, reg, target):
|
||||
# the register can be a naked integer 0 .. 5 or an 'r' string
|
||||
|
|
Loading…
Add table
Reference in a new issue