diff options
-rw-r--r-- | asm.py | 154 | ||||
-rw-r--r-- | r1b.txt | 70 | ||||
-rw-r--r-- | test.r1 | 67 |
3 files changed, 291 insertions, 0 deletions
@@ -0,0 +1,154 @@ +mnems = """ +nop +rot +nrt +dup +swp +ovr +drp +tck +nip +equ +neq +add +sub +mul +div +neg +slt +ult +sle +ule +lod +sto +psh +pop +""".split() +mnems.extend(['???']*(64-len(mnems))) +def opws(kw): + for k in range(16): + mnems.append(kw + str(k)) +opws("mark") # who is mark +opws("loc") +opws("ret") +opws("lit") + +# print(mnems) +import sys + +import collections + +pc = 0 +labels = {} +local_labels = {} +# map of labelname -> (dest, ifn) +label_wants = collections.defaultdict(set) +local_label_wants = collections.defaultdict(set) +output = bytearray() + +class Wrong(Exception): + def __init__(self, lineno, msg): + self.lineno = lineno + self.msg = msg + def __str__(self): + return f"{self.lineno}: {self.msg}" + +def assemble_line(args, lineno): + + match args: + case ["c", label] if label in labels: + emit_call(labels[label]) + case ["c", label]: + label_wants[label].add((pc,call_instr)) + emit(0) + case ['b', label] if label in local_labels: + emit_obranch(local_labels[label]) + case ['b', label]: + local_label_wants[label].add((pc, obranch_instr)) + case ['j', label] if label in local_labels: + emit_jump(local_labels[label]) + case ['j', label]: + local_label_wants[label].add((pc, jump_instr)) + + case ["i", i1]: + assemble_line(["i", i1, "nop"], lineno) + case ["i", i1, i2]: + opc1 = mnems.index(i1) + opc2 = mnems.index(i2) + emit_instrs(opc1, opc2) + case ["l", val]: + emit_lit(int(val)) + case [':', label]: + if label in labels: + raise Wrong(lineno, "label defined twice "+label) + labels[label] = pc + for (dest, ifn) in label_wants[label]: + put_at(dest, ifn(pc, dest)) + del label_wants[label] + + local_labels.clear() + for u,v in local_label_wants.items(): + raise Wrong(lineno, "unfulfilled local label "+u) + local_label_wants.clear() + + case ['%', label]: + if label in local_labels: + raise Wrong(lineno, "local label defined twice "+label) + local_labels[label] = pc + for (dest, ifn) in local_label_wants[label]: + put_at(dest, ifn(pc, dest)) + del local_label_wants[label] + + case []: pass + + + case _: + raise Wrong(lineno, "unknown wordtype") + +def emit_call(addr): + emit(call_instr(addr)) +def emit_instrs(opc1, opc2): + emit(instrs_instr(opc1, opc2)) +def emit_lit(val): + emit(lit_instr(val)) +def emit_obranch(addr): + emit(obranch_instr(addr, origin=pc)) +def emit_jump(addr): + emit(jump_instr(addr, origin=pc)) + +def emit(word): + output.extend(word.to_bytes(2)) + global pc + pc += 2 + +def put_at(addr, word): + output[addr:addr+1] = word.to_bytes(2) + +def lit_instr(val): + return (val&0b1111111111111) | 0b0110000000000000 +def instrs_instr(opc1, opc2): + return (opc1 << 7) | opc2 +def call_instr(addr,*_): + return (addr>>1)|0b1000000000000000 +def obranch_instr(target, origin): + rel = target - origin + 2048 + return (rel&0b111111111111)|0b0101000000000000 +def jump_instr(target, origin): + rel = target - origin + 2048 + return (rel&0b111111111111)|0b0100000000000000 + + + + +import sys +def main(): + for ix, line in enumerate(sys.stdin): + line = line.strip() + args = line.split() + assemble_line(args, ix+1) + + for u,v in label_wants.items(): + print("unfulfilled global label",u, file=sys.stderr) + sys.stdout.buffer.write(output) + +if __name__ == "__main__": main() @@ -0,0 +1,70 @@ +nop +rot (abc-bca) +-rot (abc-cab) +dup (x-xx) +swap (xy-yx) +over (xy-xyx) +drop (xy-x) +tuck (xy-yxy) +nip (xy-y) +lit (-l) +equal (xy-f) +nequal (xy-f) +add (xy-z) +sub (xy-z) +mul +div +neg +slt +ult +sle +ule +lod (a-d) +sto (da-) +push +pop + + + +what abotu either + +1[addr:15] : call +0 +01 literal + + +want: +calls (15 bits) +j, cj, relative addr, 8 bits +lit, 4 or 8 or 16 bits +mark,loc,ret, + 4bit arg +regular op, no arg (between 16 and 32 of these) + +CALL (addr:15) +or +JMP (cond?:1) (rdst:rest) +or +(mark/loc/ret/lit4) (arg:4) +or + +regular op (7 bits) + + + +OPW:7: 1 T:2 arg:4 +OPR:7: 0 opcode:6 + 00 - 3f regular opcodes (64 of them) + 4x mark x + 5x loc x + 6x ret x + 7x lit4 x + +I: 0 0 (OPW|OPR) (OPW|OPR) +J: 0 1 0 cond? raddr:12 +L: 0 1 1 value:13 +C: 1 addr:15 + + + + + @@ -0,0 +1,67 @@ +: sqrt +i mark2 dup +i loc0 sto +c /2 +i loc1 sto +% loop +i loc0 lod +i loc1 lod +c newton +i dup loc1 +c replace! +c thresh +c close? +b loop +i loc1 lod +i ret2 + +: newton +c tuck +c square +i add div +c /2 +i ret0 + +: square +i dup mul +i ret0 +: tuck +i dup nrt +i ret0 + +: replace! +i dup lod +i nrt sto +i ret0 + +: close? +i nrt +c absdiff +i swp sle +i ret0 + +: /2 +i lit2 div +i ret0 + +: thresh +i lit4 ret0 + +: absdiff +i sub + +: abs +i lit0 slt +b f1 +i neg +% f1 +i ret0 + + +: hypot +c square +i swp +c square +i add +c sqrt +i ret0 |