fixed up (again, maybe right this time) pcrel stuff in getlabel
This commit is contained in:
parent
111347faa2
commit
2f17117c02
1 changed files with 17 additions and 12 deletions
|
@ -300,14 +300,14 @@ class PDP11InstructionAssembler:
|
||||||
class FwdRef:
|
class FwdRef:
|
||||||
"""Values determined by a not-yet-seen label() definition."""
|
"""Values determined by a not-yet-seen label() definition."""
|
||||||
|
|
||||||
def __init__(self, name, block, *, pcrel=False):
|
def __init__(self, name, block, *, idxrel=False, idxadj=0):
|
||||||
self.loc = len(block)
|
self.loc = len(block)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.block = block
|
self.block = block
|
||||||
if pcrel:
|
if idxrel:
|
||||||
self.pcadj = (2 * self.loc) + 4
|
self.adjust = (2 * self.loc) + idxadj
|
||||||
else:
|
else:
|
||||||
self.pcadj = 0
|
self.adjust = 0
|
||||||
block._fwdrefs[name].append(self)
|
block._fwdrefs[name].append(self)
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
|
@ -330,7 +330,7 @@ class FwdRef:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def transform(self):
|
def transform(self):
|
||||||
return self.block._neg16(self.block.getlabel(self.name) - self.pcadj)
|
return self.block._neg16(self.block.getlabel(self.name) - self.adjust)
|
||||||
|
|
||||||
|
|
||||||
class BranchTarget(FwdRef):
|
class BranchTarget(FwdRef):
|
||||||
|
@ -429,7 +429,7 @@ class InstructionBlock(PDP11InstructionAssembler):
|
||||||
# IF it starts with '+' it means use PC-relative addr mode
|
# IF it starts with '+' it means use PC-relative addr mode
|
||||||
# which will require some fussing around...
|
# which will require some fussing around...
|
||||||
if operand_token[0] == '+':
|
if operand_token[0] == '+':
|
||||||
return [0o67, self.getlabel(operand_token[1:], pcrel=True)]
|
return [0o67, self.getlabel(operand_token[1:], idxrel=True, idxadj=4)]
|
||||||
else:
|
else:
|
||||||
return [0o27, self.getlabel(operand_token)]
|
return [0o27, self.getlabel(operand_token)]
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ class InstructionBlock(PDP11InstructionAssembler):
|
||||||
|
|
||||||
return self._labels[name]
|
return self._labels[name]
|
||||||
|
|
||||||
def getlabel(self, name, *, fwdfactory=FwdRef, pcrel=False):
|
def getlabel(self, name, *, fwdfactory=FwdRef, idxrel=False, idxadj=0):
|
||||||
"""Return value (loc) of name, which may be a FwdRef object.
|
"""Return value (loc) of name, which may be a FwdRef object.
|
||||||
|
|
||||||
Label values are offsets relative to the start of the block.
|
Label values are offsets relative to the start of the block.
|
||||||
|
@ -514,10 +514,11 @@ class InstructionBlock(PDP11InstructionAssembler):
|
||||||
try:
|
try:
|
||||||
x = self._labels[name]
|
x = self._labels[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return fwdfactory(name=name, block=self, pcrel=pcrel)
|
return fwdfactory(name=name, block=self,
|
||||||
|
idxrel=idxrel, idxadj=idxadj)
|
||||||
else:
|
else:
|
||||||
if pcrel:
|
if idxrel:
|
||||||
x = self._neg16(x - (2 * (len(self) + 2)))
|
x = self._neg16(x - ((2 * len(self)) + idxadj))
|
||||||
return x
|
return x
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -584,7 +585,7 @@ class InstructionBlock(PDP11InstructionAssembler):
|
||||||
|
|
||||||
# labels become operand mode 0o67 ... PC-relative w/offset
|
# labels become operand mode 0o67 ... PC-relative w/offset
|
||||||
inst = 0o004067 | (self.register_parser(reg) << 6)
|
inst = 0o004067 | (self.register_parser(reg) << 6)
|
||||||
offs = self.getlabel(dst, pcrel=True)
|
offs = self.getlabel(dst, idxrel=True, idxadj=4)
|
||||||
return self._seqwords([inst, offs])
|
return self._seqwords([inst, offs])
|
||||||
|
|
||||||
def jmp(self, dst):
|
def jmp(self, dst):
|
||||||
|
@ -594,7 +595,7 @@ class InstructionBlock(PDP11InstructionAssembler):
|
||||||
|
|
||||||
# labels become operand mode 0o67 ... PC-relative w/offset
|
# labels become operand mode 0o67 ... PC-relative w/offset
|
||||||
inst = 0o000167
|
inst = 0o000167
|
||||||
return self._seqwords([inst, self.getlabel(dst, pcrel=True)])
|
return self._seqwords([inst, self.getlabel(dst, idxrel=True, idxadj=4)])
|
||||||
|
|
||||||
def sob(self, reg, target):
|
def sob(self, reg, target):
|
||||||
# the register can be a naked integer 0 .. 5 or an 'r' string
|
# the register can be a naked integer 0 .. 5 or an 'r' string
|
||||||
|
@ -642,6 +643,9 @@ class InstructionBlock(PDP11InstructionAssembler):
|
||||||
f.write(f"D PC {oct(startaddr)[2:]}\n")
|
f.write(f"D PC {oct(startaddr)[2:]}\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -677,6 +681,7 @@ if __name__ == "__main__":
|
||||||
insts = list(a)
|
insts = list(a)
|
||||||
self.assertEqual(list(a), [0o012700, 6, 0o005001, 0o012701, 6])
|
self.assertEqual(list(a), [0o012700, 6, 0o005001, 0o012701, 6])
|
||||||
|
|
||||||
|
|
||||||
def test_labelmath_dot(self):
|
def test_labelmath_dot(self):
|
||||||
a = InstructionBlock()
|
a = InstructionBlock()
|
||||||
a.mov('bozo', 'r0')
|
a.mov('bozo', 'r0')
|
||||||
|
|
Loading…
Add table
Reference in a new issue