summaryrefslogtreecommitdiffstats
path: root/lab1ucode.py
diff options
context:
space:
mode:
Diffstat (limited to 'lab1ucode.py')
-rw-r--r--lab1ucode.py159
1 files changed, 159 insertions, 0 deletions
diff --git a/lab1ucode.py b/lab1ucode.py
new file mode 100644
index 0000000..6c74130
--- /dev/null
+++ b/lab1ucode.py
@@ -0,0 +1,159 @@
+import sys
+
+TWOWAY = {
+ "ir": "001",
+ "pm": "010",
+ "pc": "011",
+ "hr": "101",
+ "grx": "110",
+}
+
+# to bus: source
+TB = TWOWAY | {
+ "ar": "100",
+ # "styrord": "111",
+}
+
+# from bus: destination
+FB = TWOWAY | {
+ "asr": "111"
+}
+
+def compile(lines):
+ addr = 0
+ labels = {}
+ compiled = []
+ todo = []
+ for line in lines:
+ if not line:
+ # empty line, ignore
+ continue
+ if line.startswith(";"):
+ # comment
+ continue
+ if line.endswith(":"):
+ # label
+ labels[line.split(":")[0]] = addr
+ continue
+ if line.startswith("!"):
+ # inline
+ compiled.append(line[1:])
+ addr += 1
+ continue
+
+ for inst in line.split(", "):
+ alu = "0000"
+ tb = "000"
+ fb = "000"
+ s = "0"
+ p = "0"
+ lc = "00"
+ seq = "0000"
+ myadr = "0000000"
+
+ if "->" in inst:
+ # move a value
+ fr, to = inst.split("->")
+ # via bus
+ if fr in TB:
+ tb = TB[fr]
+ if to in FB:
+ fb = FB[to]
+
+ if "gr" in fr and len(fr) == 3:
+ tb = TB["grx"]
+ if "gr" in to and len(to) == 3:
+ fb = FB["grx"]
+
+ if to == "lc":
+ lc = "10"
+
+ # load alu
+ if to == "ar":
+ alu = "0001"
+
+ # alu addition
+ if "+" in fr:
+ if "+'" in fr:
+ # ignore flags
+ other = fr.split("+'")[0]
+ alu = "1000"
+ else:
+ other = fr.split("+")[0]
+ alu = "0100"
+ tb = TB[other]
+
+ # alu subtraction
+ if "-" in fr:
+ other = fr.split("-")[0]
+ tb = TB[other]
+ alu = "0101"
+
+ if inst == "pc++":
+ p = "1"
+
+ if inst == "k1->upc":
+ seq = "0001"
+ if inst == "k2->upc":
+ seq = "0010"
+ if inst == "0->upc":
+ seq = "0011"
+ if inst == "halt":
+ seq = "1111"
+ if inst == "lc--":
+ lc = "01"
+ if inst == "lsr":
+ alu = "1101"
+
+ if "?" in inst:
+ cond, to = inst.split("? ")
+ if cond == "l=1":
+ seq = "1100"
+ else:
+ assert False
+ myadr = f"<{to}>"
+
+ if inst.startswith("b "):
+ seq = "0110" #TODO 0101?
+ myadr = "<{}>".format(inst.split("b ")[1])
+
+ compiled.append((inst, (alu, tb, fb, s, p, lc, seq, myadr)))
+
+ addr += 1
+
+ linked = []
+ for addr, line in enumerate(compiled):
+ if type(line) is str:
+ linked.append((addr, line))
+ continue
+ inst, (alu, tb, fb, s, p, lc, seq, myadr) = line
+ if myadr != "0000000":
+ for label, label_line in labels.items():
+ myadr = myadr.replace(f"<{label}>", str(bin(label_line)[2:]).zfill(7))
+ first = alu[0]
+ rest = alu[1:] + tb + fb + s + p + lc + seq + myadr
+ hs = "".join([f"{int(first):01x}"] + [f"{int(rest[i:i+4], 2):01x}" for i in range(0, len(rest), 4)])
+ linked.append((addr, hs))
+ if hs == "0000000":
+ todo.append(inst)
+
+ return ["{:02x}: {}".format(addr, line) for addr, line in linked], labels
+ """
+ todo
+ l=1? lsr_exit
+ b lsr_loop
+ end->upc
+ """
+
+ print("todo")
+ print("\n".join(todo))
+
+
+if __name__ == "__main__":
+ prog, labels = compile([line.strip() for line in sys.stdin])
+ print("prog:")
+ print("\n".join(prog))
+ print()
+ print("labels:")
+ for label, label_nr in labels.items():
+ print(label, hex(label_nr))