#!/usr/bin/env python3 import fileinput import re literalMove = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$(\d*)s%(\d*)\$hn$") regMove = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$\*(\d*)\$s%(\d*)\$hn$") regAdd = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$\*(\d*)\$s%1\$\*(\d*)\$s%(\d*)\$hn$") regLiteralAdd = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$\*(\d*)\$s%1\$(\d*)s%(\d*)\$hn$") literalRegAdd = re.compile(r"^%1\$(\d*)s%3\$hn%1\$(\d*)s%1\$(\d*)s%1\$\*(\d*)\$s%(\d*)\$hn$") jump = re.compile(r"^%1\$(\d*)s%3\$hn$") condJump = re.compile(r"^%(\d*)\$c%1\$(\d*)s%2\$c%4\$s%1\$(\d*)s%3\$hn$") # The address of the instruction being read addr = 0 def showRegisterDest(regRef): if regRef == 6: regStr = "(%r1)" elif regRef >= 7 and regRef <= 23 and regRef % 2 == 1: regStr = "%r{}".format(regRef // 2 - 2) else: print("bad destination: {}".format(regRef)) exit() return regStr def showRegisterSource(regRef): if regRef == 5: regStr = "(%r1)" elif regRef >= 6 and regRef <= 22 and regRef % 2 == 0: regStr = "%r{}".format(regRef // 2 - 2) else: print("bad source") exit() return regStr for line in fileinput.input(): oldAddr = addr addr += len(line) m = literalMove.match(line) if m: nextAddr = int(m.group(1)) filler = int(m.group(2)) literal = int(m.group(3)) regRef = int(m.group(4)) if addr != nextAddr: print("address is not the next instruction") exit() if nextAddr + filler != 0x10000: print("first two numbers do not add to 0x10000") exit() dest = showRegisterDest(regRef) print("{:04x}: mov 0x{:x}, {}".format(oldAddr, literal, dest)) continue m = regMove.match(line) if m: nextAddr = int(m.group(1)) filler = int(m.group(2)) sourceRef = int(m.group(3)) destRef = int(m.group(4)) if addr != nextAddr: print("address is not the next instruction") exit() if nextAddr + filler != 0x10000: print("first two numbers do not add to 0x10000") exit() source = showRegisterSource(sourceRef) dest = showRegisterDest(destRef) print("{:04x}: mov {}, {}".format(oldAddr, source, dest)) continue m = regAdd.match(line) if m: nextAddr = int(m.group(1)) filler = int(m.group(2)) source1Ref = int(m.group(3)) source2Ref = int(m.group(4)) destRef = int(m.group(5)) if addr != nextAddr: print("address is not the next instruction") exit() if nextAddr + filler != 0x10000: print("first two numbers do not add to 0x10000") exit() source1 = showRegisterSource(source1Ref) source2 = showRegisterSource(source2Ref) dest = showRegisterDest(destRef) print("{:04x}: add {}, {}, {}".format(oldAddr, source1, source2, dest)) continue m = regLiteralAdd.match(line) if m: nextAddr = int(m.group(1)) filler = int(m.group(2)) sourceRef = int(m.group(3)) literal = int(m.group(4)) destRef = int(m.group(5)) if addr != nextAddr: print("address is not the next instruction") exit() if nextAddr + filler != 0x10000: print("first two numbers do not add to 0x10000") exit() source = showRegisterSource(sourceRef) dest = showRegisterDest(destRef) print("{:04x}: add {}, 0x{:x}, {}".format(oldAddr, source, literal, dest)) continue m = literalRegAdd.match(line) if m: nextAddr = int(m.group(1)) filler = int(m.group(2)) sourceRef = int(m.group(4)) literal = int(m.group(3)) destRef = int(m.group(5)) if addr != nextAddr: print("address is not the next instruction") exit() if nextAddr + filler != 0x10000: print("first two numbers do not add to 0x10000") exit() source = showRegisterSource(sourceRef) dest = showRegisterDest(destRef) print("{:04x}: add {}, 0x{:x}, {}".format(oldAddr, source, literal, dest)) continue m = jump.match(line) if m: target = int(m.group(1)) if target == 0xfffe: print("{:04x}: halt".format(oldAddr)) else: print("{:04x}: jmp {:04x}".format(oldAddr, target)) continue m = condJump.match(line) if m: sourceRef = int(m.group(1)) fill1 = int(m.group(2)) fill2 = int(m.group(3)) source = showRegisterSource(sourceRef) zeroTarget = (fill1 + fill2 + 2) % 0x10000 nonzeroTarget = (fill1 * 2 + fill2 + 3) % 0x10000 if zeroTarget == addr: print("{:04x}: jnz {}, {:04x}".format(oldAddr, source, nonzeroTarget)) elif nonzeroTarget == addr: print("{:04x}: jz {}, {:04x}".format(oldAddr, source, zeroTarget)) else: print("neither jump target is the next instruction") exit() continue print(line[:-1])