summaryrefslogtreecommitdiff
path: root/nandgame/assembler/disas.py
diff options
context:
space:
mode:
Diffstat (limited to 'nandgame/assembler/disas.py')
-rwxr-xr-xnandgame/assembler/disas.py61
1 files changed, 41 insertions, 20 deletions
diff --git a/nandgame/assembler/disas.py b/nandgame/assembler/disas.py
index 0256976..1a3ae33 100755
--- a/nandgame/assembler/disas.py
+++ b/nandgame/assembler/disas.py
@@ -12,7 +12,8 @@ import sys
ZERO = "#0"
DEST_NONE = "_"
JUMP_NONE = ""
-
+JUMPS_IF_NZERO = ["jgt", "jlt", "jne", "jmp"]
+JUMPS_IF_ZERO = ["jge", "jle", "jeq", "jmp"]
def decode_jump(ins: int) -> str:
if (ins & 0x7) == 0:
@@ -133,25 +134,45 @@ def decode_instruction(ins: int) -> list[str]:
def fixup_ins(ins: int) -> list[str]:
(mnemonic, dest, op1, op2, jumpdest) = decode_instruction(ins)
# fixups
- # subtract something from #0 - subtraction
- if op1 == ZERO and mnemonic == "sub":
- return ["neg", dest, op2, "", jumpdest]
-
- # 0 AND something = 0
- # if no dest, only jump matters
- if mnemonic == "and" and op1 == ZERO and dest == DEST_NONE:
- # jump always or jump-if-zero --> always jump
- if jumpdest in ["jgt", "jlt", "jne", JUMP_NONE]:
- return ["nop", "", "", "", ""]
- # all other jumps? <=, >=, =, <=>
- else:
- return ["jmp", "", "", "", ""]
- if mnemonic == "and" and op1 == ZERO:
- if jumpdest in ["jgt", "jlt", "jne", JUMP_NONE]:
- newjmp = ""
- else:
- newjmp = "jmp"
- return ["mov", dest, ZERO, "", newjmp]
+ if op1 == ZERO:
+ # subtract something from #0 - subtraction
+ if mnemonic == "sub":
+ return ["neg", dest, op2, "", jumpdest]
+
+ # 0 AND something = 0
+ if mnemonic == "and":
+ # if no dest, only jump matters
+ if dest == DEST_NONE:
+ # jump always or jump-if-zero --> always jump
+ if jumpdest in JUMPS_IF_ZERO:
+ return ["jmp", "", "", "", ""]
+ # all other jumps? <, >, <>, nojmp
+ else:
+ return ["nop", "", "", "", ""]
+ else:
+ if jumpdest in JUMPS_IF_ZERO:
+ newjmp = "jmp"
+ else:
+ newjmp = ""
+ return ["mov", dest, ZERO, "", newjmp]
+
+ # 0 +/|/^ something = something
+ if mnemonic in ["add", "or", "xor"]:
+ if dest == DEST_NONE and jumpdest == JUMP_NONE:
+ return ["nop", "", "", "", ""]
+ else:
+ return ["mov", dest, op2, "", jumpdest]
+
+ # basically, not 0 == 0xFFFF....
+ # opposite of what AND is doing?
+ if mnemonic == "not":
+ # if no dest, only jump matters
+ if dest == DEST_NONE:
+ # 0xFFFF is not jgt, since highest bit is always signed.
+ if jumpdest in ["jeq", "jgt", "jge", JUMP_NONE]:
+ return ["nop", "", "", "", ""]
+ else:
+ return ["jmp", "", "", "", ""]
return [mnemonic, dest, op1, op2, jumpdest]