diff options
Diffstat (limited to 'atk16_asm')
| -rw-r--r-- | atk16_asm/asm_ops.py | 226 |
1 files changed, 133 insertions, 93 deletions
diff --git a/atk16_asm/asm_ops.py b/atk16_asm/asm_ops.py index d5da1c1..a7ef88f 100644 --- a/atk16_asm/asm_ops.py +++ b/atk16_asm/asm_ops.py @@ -4,6 +4,7 @@ from .asm_eval import * ExpandResult = list[list[str]] ExpandFn = Callable[..., ExpandResult] +OpWordDict = dict[str, Callable[..., int]] OpExpansionDict = dict[str, ExpandFn] @dataclass @@ -17,6 +18,20 @@ def generate_unique_label(prefix: str) -> str: generate_unique_label_counter += 1 return label +operations: OpWordDict = {} +expansions: OpExpansionDict = {} + +def register_primitive(func): + ident: str = func.__name__.replace("make_", "") + operations[ident] = func + return func + +def register_macro(func): + ident: str = func.__name__.replace("expand_", "") + expansions[ident] = func + return func + +@register_primitive def make_alr(meta: Meta, symbols: Symbols, alu_op: str, left: str, right: str, target: str) -> int: """ALR 0000 TTTL LLRR RSSS""" target_e = eval_expr(symbols, target, bits=3) @@ -30,11 +45,16 @@ def make_alr(meta: Meta, symbols: Symbols, alu_op: str, left: str, right: str, t alu_op_e return word -def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: str, target: str) -> int: +@register_macro +def expand_alr(alu_op: str, left: str, right: str, target: str) -> ExpandResult: + return [["alr", alu_op, left, right, target]] + +@register_primitive +def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: int | str, target: str) -> int: """ALI 0001 TTTL LLII ISSS""" target_e = eval_expr(symbols, target, bits=3) left_e = eval_expr(symbols, left, bits=3) - imm_e = eval_expr(symbols, imm, bits=3) + imm_e = eval_expr(symbols, str(imm), bits=3) alu_op_e = eval_expr(symbols, alu_op, bits=3) word = (0b0001 << 12) + \ (target_e << 9) + \ @@ -43,6 +63,11 @@ def make_ali(meta: Meta, symbols: Symbols, alu_op: str, left: str, imm: str, tar alu_op_e return word +@register_macro +def expand_ali(alu_op: str, left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", alu_op, left, str(imm), target]] + +@register_primitive def make_ldr(meta: Meta, symbols: Symbols, addr_reg: str, to_reg: str) -> int: """LDR 0010 TTTR RRXX XXXX""" to_reg_e = eval_expr(symbols, to_reg, bits=3) @@ -52,6 +77,11 @@ def make_ldr(meta: Meta, symbols: Symbols, addr_reg: str, to_reg: str) -> int: (addr_reg_e << 6) return word +@register_macro +def expand_ldr(addr_reg: str, to_reg: str) -> ExpandResult: + return [["ldr", addr_reg, to_reg]] + +@register_primitive def make_str(meta: Meta, symbols: Symbols, from_reg: str, addr_reg: str) -> int: """STR 0011 XXXL LLRR RXXX""" addr_reg_e = eval_expr(symbols, from_reg, bits=3) @@ -61,15 +91,25 @@ def make_str(meta: Meta, symbols: Symbols, from_reg: str, addr_reg: str) -> int: (addr_reg_e << 3) return word -def make_ldi(meta: Meta, symbols: Symbols, imm: str, to_reg: str) -> int: +@register_macro +def expand_str(from_reg: str, addr_reg: str) -> ExpandResult: + return [["str", from_reg, addr_reg]] + +@register_primitive +def make_ldi(meta: Meta, symbols: Symbols, imm: int | str, to_reg: str) -> int: """LDI 0100 TTTI IIII IIII""" to_reg_e = eval_expr(symbols, to_reg, bits=3) - imm_e = eval_expr(symbols, imm, bits=9) + imm_e = eval_expr(symbols, str(imm), bits=9) word = (0b0100 << 12) + \ (to_reg_e << 9) + \ imm_e return word +@register_macro +def expand_ldi(imm: int | str, to_reg: str) -> ExpandResult: + return [["ldi", str(imm), to_reg]] + +@register_primitive def make_jpr(meta: Meta, symbols: Symbols, addr_reg: str) -> int: """JPR 0101 XXXR RRXX XXXX""" addr_reg_e = eval_expr(symbols, addr_reg, bits=3) @@ -77,17 +117,25 @@ def make_jpr(meta: Meta, symbols: Symbols, addr_reg: str) -> int: (addr_reg_e << 6) return word -def make_jpi(meta: Meta, symbols: Symbols, imm: str) -> int: +@register_macro +def expand_jpr(addr_reg: str) -> ExpandResult: + return [["jpr", addr_reg]] + +@register_primitive +def make_jpi(meta: Meta, symbols: Symbols, imm: int | str) -> int: """JPI 0110 XXXI IIII IIII""" - imm_e = eval_expr(symbols, imm, bits=9) + imm_e = eval_expr(symbols, str(imm), bits=9) imm_e = imm_e - meta.address - 1 imm_e = imm_e & (0b111111111) - #print("symbols:", symbols) - #print(meta, imm, f"0x{imm_e:>0x}") word = (0b0110 << 12) + \ imm_e return word +@register_macro +def expand_jpi(imm: int | str) -> ExpandResult: + return [["jpi", str(imm)]] + +@register_primitive def make_brr(meta: Meta, symbols: Symbols, flag_s: str, addr_reg: str) -> int: """brr 0111 XFFR RRXX XXXX""" flag_s_e = eval_expr(symbols, flag_s, bits=2) @@ -97,10 +145,15 @@ def make_brr(meta: Meta, symbols: Symbols, flag_s: str, addr_reg: str) -> int: (addr_reg_e << 6) return word -def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: str) -> int: +@register_macro +def expand_brr(flag_s: str, addr_reg: str) -> ExpandResult: + return [["brr", flag_s, addr_reg]] + +@register_primitive +def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: int | str) -> int: """BRI 1000 XFFI IIII IIII""" flag_s_e = eval_expr(symbols, flag_s, bits=2) - imm_e = eval_expr(symbols, imm, bits=9) + imm_e = eval_expr(symbols, str(imm), bits=9) imm_e = imm_e - meta.address - 1 imm_e = imm_e & (0b111111111) word = (0b1000 << 12) + \ @@ -108,6 +161,11 @@ def make_bri(meta: Meta, symbols: Symbols, flag_s: str, imm: str) -> int: imm_e return word +@register_macro +def expand_bri(flag_s: str, imm: int | str) -> ExpandResult: + return [["bri", flag_s, str(imm)]] + +@register_primitive def make_lpc(meta: Meta, symbols: Symbols, target: str) -> int: """LPC 1001 TTTX XXXX XXXX""" target_e = eval_expr(symbols, target, bits=3) @@ -115,72 +173,81 @@ def make_lpc(meta: Meta, symbols: Symbols, target: str) -> int: (target_e << 9) return word +@register_macro +def expand_lpc(target: str) -> ExpandResult: + return [["lpc", target]] + +@register_primitive def make_rti(meta: Meta, symbols: Symbols) -> int: """RTI 1110 XXXX XXXX XXXX""" word = (0b1110 << 12) return word +@register_macro +def expand_rti() -> ExpandResult: + return [["rti"]] + +@register_primitive def make_hlt(meta: Meta, symbols: Symbols) -> int: """HLT 1111 XXXX XXXX XXXX""" word = (0b1111 << 12) return word -OpWordDict = dict[str, Callable[..., int]] -operations: OpWordDict = { - "alr": make_alr, - "ali": make_ali, - "ldr": make_ldr, - "str": make_str, - "ldi": make_ldi, - "jpr": make_jpr, - "jpi": make_jpi, - "brr": make_brr, - "bri": make_bri, - "lpc": make_lpc, - "rti": make_rti, - "hlt": make_hlt, -} +@register_macro +def expand_hlt() -> ExpandResult: + return [["hlt"]] def expand_id(*parts: str) -> ExpandResult: return [list(parts)] +@register_macro def expand_add(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_plus", left, right, target]] +@register_macro def expand_sub(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_minus", left, right, target]] -def expand_addi(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_plus", left, imm, target]] +@register_macro +def expand_addi(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_plus", left, str(imm), target]] -def expand_subi(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_minus", left, imm, target]] +@register_macro +def expand_subi(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_minus", left, str(imm), target]] # FIXME: 0xFFFF does not fit in 3 bits # def expand_not(reg: str, target: str) -> ExpandResult: # return [["alr", "al_xor", reg, "0xFFFF", target]] -# def expand_noti(imm: str, target: str) -> ExpandResult: +# def expand_noti(imm: int | str, target: str) -> ExpandResult: # return [["ali", "al_xor", imm, "0xFFFF", target]] +@register_macro def expand_and(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_and", left, right, target]] -def expand_andi(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_and", left, imm, target]] +@register_macro +def expand_andi(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_and", left, str(imm), target]] +@register_macro def expand_or(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_or", left, right, target]] -def expand_ori(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_or", left, imm, target]] +@register_macro +def expand_ori(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_or", left, str(imm), target]] -def expand_xor(left: str, imm: str, target: str) -> ExpandResult: - return [["alr", "al_xor", left, imm, target]] +@register_macro +def expand_xor(left: str, imm: int | str, target: str) -> ExpandResult: + return [["alr", "al_xor", left, str(imm), target]] +@register_macro def expand_xori(left: str, right: str, target: str) -> ExpandResult: return [["ali", "al_xor", left, right, target]] +@register_macro def expand_not(reg: str) -> ExpandResult: tmp = "RA" return [ @@ -191,48 +258,63 @@ def expand_not(reg: str) -> ExpandResult: *expand_spo(tmp), ] +@register_macro def expand_sll(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_sll", left, right, target]] +@register_macro def expand_slr(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_slr", left, right, target]] +@register_macro def expand_sar(left: str, right: str, target: str) -> ExpandResult: return [["alr", "al_sar", left, right, target]] -def expand_slli(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_sll", left, imm, target]] +@register_macro +def expand_slli(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_sll", left, str(imm), target]] -def expand_slri(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_slr", left, imm, target]] +@register_macro +def expand_slri(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_slr", left, str(imm), target]] -def expand_sari(left: str, imm: str, target: str) -> ExpandResult: - return [["ali", "al_sar", left, imm, target]] +@register_macro +def expand_sari(left: str, imm: int | str, target: str) -> ExpandResult: + return [["ali", "al_sar", left, str(imm), target]] +@register_macro def expand_inc(reg: str) -> ExpandResult: return [["ali", "al_plus", reg, "1", reg]] +@register_macro def expand_dec(reg: str) -> ExpandResult: return [["ali", "al_minus", reg, "1", reg]] +@register_macro def expand_mov(from_reg: str, to_reg: str) -> ExpandResult: return [["ali", "al_plus", from_reg, "0", to_reg]] +@register_macro def expand_nop() -> ExpandResult: return [["ali", "al_plus", "RA", "0", "RA"]] +@register_macro def expand_spu(reg: str) -> ExpandResult: return [["str", reg, "SP"]] + expand_inc("SP") +@register_macro def expand_spo(reg: str) -> ExpandResult: return expand_dec("SP") + [["ldr", "SP", reg]] -def expand_sinc(imm: str) -> ExpandResult: +@register_macro +def expand_sinc(imm: int | str) -> ExpandResult: return expand_addi("SP", imm, "SP") -def expand_sdec(imm: str) -> ExpandResult: +@register_macro +def expand_sdec(imm: int | str) -> ExpandResult: return expand_subi("SP", imm, "SP") +@register_macro def expand_callr(addr_reg: str) -> ExpandResult: return [ ["lpc", "RG"], @@ -243,17 +325,19 @@ def expand_callr(addr_reg: str) -> ExpandResult: *expand_dec("SP"), ] -def expand_calli(addr_imm: str) -> ExpandResult: +@register_macro +def expand_calli(addr_imm: int | str) -> ExpandResult: ret_label = generate_unique_label(prefix="calli_return") return [ ["ldi", ret_label, "RG"], *expand_spu("RG"), - ["jpi", addr_imm], + ["jpi", str(addr_imm)], ["@label", ret_label], ["ldr", "SP", "RG"], # return leaves SP pointing at return value, read to reg *expand_dec("SP"), # decrement SP to fix stack ] +@register_macro def expand_return() -> ExpandResult: return [ ["str", "RG", "SP"], # store returned value on stack but don't increment SP @@ -263,6 +347,7 @@ def expand_return() -> ExpandResult: ["jpr", "RG"] # jump back to call site ] +@register_macro def stack_stash(*rs: str) -> ExpandResult: result: ExpandResult = [] for r in rs: @@ -270,6 +355,7 @@ def stack_stash(*rs: str) -> ExpandResult: return result +@register_macro def stack_restore(*rs: str) -> ExpandResult: result: ExpandResult = [] for r in rs: @@ -278,6 +364,7 @@ def stack_restore(*rs: str) -> ExpandResult: return result +@register_macro def set_graphics_mode(mode: str) -> ExpandResult: return [ ["ldi", "vt_gr_mode_addr", "RF"], @@ -285,50 +372,3 @@ def set_graphics_mode(mode: str) -> ExpandResult: ["ldi", mode, "RG"], ["str", "RG", "RF"], ] - -expansions: OpExpansionDict = { - "alr": lambda *args: expand_id("alr", *args), - "ali": lambda *args: expand_id("ali", *args), - "ldr": lambda *args: expand_id("ldr", *args), - "str": lambda *args: expand_id("str", *args), - "ldi": lambda *args: expand_id("ldi", *args), - "jpr": lambda *args: expand_id("jpr", *args), - "jpi": lambda *args: expand_id("jpi", *args), - "brr": lambda *args: expand_id("brr", *args), - "bri": lambda *args: expand_id("bri", *args), - "lpc": lambda *args: expand_id("lpc", *args), - "rti": lambda *args: expand_id("rti", *args), - "hlt": lambda *args: expand_id("hlt", *args), - - "add": expand_add, - "sub": expand_sub, - "addi": expand_addi, - "subi": expand_subi, - "not": expand_not, - "and": expand_and, - "andi": expand_andi, - "or": expand_or, - "ori": expand_ori, - "xor": expand_xor, - "xori": expand_xori, - "sll": expand_sll, - "slr": expand_slr, - "sar": expand_sar, - "slli": expand_slli, - "slri": expand_slri, - "sari": expand_sari, - "inc": expand_inc, - "dec": expand_dec, - "mov": expand_mov, - "nop": expand_nop, - "spu": expand_spu, - "spo": expand_spo, - "sinc": expand_sinc, - "sdec": expand_sdec, - "callr": expand_callr, - "calli": expand_calli, - "return": expand_return, - "stack_stash": stack_stash, - "stack_restore": stack_restore, - "set_graphics_mode": set_graphics_mode, -} |
