From 16b4fbd209d71bdb1a066bacd03a9ccd1cf3d16c Mon Sep 17 00:00:00 2001 From: Jan Tuomi Date: Mon, 10 Apr 2023 15:02:50 +0300 Subject: Add stack ops, subroutines --- src/assembler.py | 3 +- src/assembler_eval.py | 6 ++-- src/assembler_ops.py | 49 ++++++++++++++++++++-------- src/ext_std.py | 90 +++++++++++++++++++++++++++++++++++++++++++++------ src/ucode.py | 4 +-- 5 files changed, 122 insertions(+), 30 deletions(-) diff --git a/src/assembler.py b/src/assembler.py index 3a1d39f..8a53a5c 100755 --- a/src/assembler.py +++ b/src/assembler.py @@ -50,7 +50,8 @@ def parse(line: str) -> list[str]: # 1st pass, gather labels, set options, eval operations options: dict[str, str] = { - "stack_pointer": "6" # RG + "stack_pointer": "6", # RG + "csr_scratch": "5", # RF } address: int = 0 diff --git a/src/assembler_eval.py b/src/assembler_eval.py index 3473ab8..7255572 100644 --- a/src/assembler_eval.py +++ b/src/assembler_eval.py @@ -13,9 +13,9 @@ constants: dict[str, str] = { "al_and": "2", "al_or": "3", "al_xor": "4", - "al_shift_lr": "5", - "al_shift_ar": "6", - "al_shift_ll": "7", + "al_slr": "5", + "al_sar": "6", + "al_sll": "7", # ALU flags "f_carry": "0", "f_overflow": "1", diff --git a/src/assembler_ops.py b/src/assembler_ops.py index 538dd78..0177140 100644 --- a/src/assembler_ops.py +++ b/src/assembler_ops.py @@ -1,7 +1,13 @@ from typing import Callable from assembler_eval import * +from dataclasses import dataclass -def make_alr(address: int, alu_op: str, left: str, right: str, target: str) -> list[int]: +@dataclass +class Meta: + address: int + options: dict[str, str] + +def make_alr(meta: Meta, alu_op: str, left: str, right: str, target: str) -> list[int]: """ALR 0000 TTTL LLRR RSSS""" target_e = eval_expr(target) left_e = eval_expr(left) @@ -14,11 +20,13 @@ def make_alr(address: int, alu_op: str, left: str, right: str, target: str) -> l alu_op_e return [word] -def make_ali(address: int, alu_op: str, left: str, imm: str, target: str) -> list[int]: +def make_ali(meta: Meta, alu_op: str, left: str, imm: str, target: str) -> list[int]: """ALI 0001 TTTL LLII ISSS""" target_e = eval_expr(target) left_e = eval_expr(left) imm_e = eval_expr(imm) + if imm_e >= 2**3: + raise Exception("ALI immediate value does not fit in 3 bits: " + str(imm_e)) alu_op_e = eval_expr(alu_op) word = (0b0001 << 12) + \ (target_e << 9) + \ @@ -27,7 +35,7 @@ def make_ali(address: int, alu_op: str, left: str, imm: str, target: str) -> lis alu_op_e return [word] -def make_ldr(address: int, to_reg: str, addr_reg: str) -> list[int]: +def make_ldr(meta: Meta, to_reg: str, addr_reg: str) -> list[int]: """LDR 0010 TTTR RRXX XXXX""" to_reg_e = eval_expr(to_reg) addr_reg_e = eval_expr(addr_reg) @@ -36,7 +44,7 @@ def make_ldr(address: int, to_reg: str, addr_reg: str) -> list[int]: (addr_reg_e << 6) return [word] -def make_str(address: int, from_reg: str, addr_reg: str) -> list[int]: +def make_str(meta: Meta, from_reg: str, addr_reg: str) -> list[int]: """STR 0011 TTTR RRXX XXXX""" from_reg_e = eval_expr(from_reg) addr_reg_e = eval_expr(addr_reg) @@ -45,7 +53,7 @@ def make_str(address: int, from_reg: str, addr_reg: str) -> list[int]: (addr_reg_e << 6) return [word] -def make_ldi(address: int, to_reg: str, imm: str) -> list[int]: +def make_ldi(meta: Meta, to_reg: str, imm: str) -> list[int]: """LDI 0100 TTTI IIII IIII""" to_reg_e = eval_expr(to_reg) imm_e = eval_expr(imm) @@ -54,22 +62,25 @@ def make_ldi(address: int, to_reg: str, imm: str) -> list[int]: imm_e return [word] -def make_jpr(address: int, addr_reg: str) -> list[int]: +def make_jpr(meta: Meta, addr_reg: str) -> list[int]: """JPR 0101 XXXR RRXX XXXX""" addr_reg_e = eval_expr(addr_reg) word = (0b0101 << 12) + \ (addr_reg_e << 6) return [word] -def make_jpi(address: int, imm: str) -> list[int]: +def make_jpi(meta: Meta, imm: str) -> list[int]: """JPI 0110 XXXI IIII IIII""" imm_e = eval_expr(imm) - imm_e = imm_e - address - 1 + imm_e = imm_e - meta.address - 1 + if imm_e >= 2**9: + raise Exception("JPI relative value does not fit in 9 bits: " + str(imm_e)) + word = (0b0110 << 12) + \ imm_e return [word] -def make_br(address: int, flag_s: str, addr_reg: str) -> list[int]: +def make_brr(meta: Meta, flag_s: str, addr_reg: str) -> list[int]: """brr 0111 XFFR RRXX XXXX""" flag_s_e = eval_expr(flag_s) addr_reg_e = eval_expr(addr_reg) @@ -78,17 +89,26 @@ def make_br(address: int, flag_s: str, addr_reg: str) -> list[int]: (addr_reg_e << 6) return [word] -def make_bri(address: int, flag_s: str, imm: str) -> list[int]: +def make_bri(meta: Meta, flag_s: str, imm: str) -> list[int]: """BRI 1000 XFFI IIII IIII""" flag_s_e = eval_expr(flag_s) imm_e = eval_expr(imm) - imm_e = imm_e - address - 1 + imm_e = imm_e - meta.address - 1 + if imm_e >= 2**9: + raise Exception("BRI relative value does not fit in 9 bits: " + str(imm_e)) word = (0b1000 << 12) + \ (flag_s_e << 9) + \ imm_e return [word] -def make_hlt(address: int, ) -> list[int]: +def make_lpc(meta: Meta, target: str) -> list[int]: + """LPC 1001 TTTX XXXX XXXX""" + target_e = eval_expr(target) + word = (0b1001 << 12) + \ + (target_e << 9) + return [word] + +def make_hlt(meta: Meta, ) -> list[int]: """HLT 1111 XXXX XXXX XXXX""" word = (0b1111 << 12) return [word] @@ -102,7 +122,8 @@ operations: dict[str, Callable[..., list[int]]] = { "ldi": make_ldi, "jpr": make_jpr, "jpi": make_jpi, - "brr": make_br, + "brr": make_brr, "bri": make_bri, + "lpc": make_lpc, "hlt": make_hlt, -} \ No newline at end of file +} diff --git a/src/ext_std.py b/src/ext_std.py index 017f40a..c0a53c1 100644 --- a/src/ext_std.py +++ b/src/ext_std.py @@ -1,24 +1,94 @@ from assembler_ops import * -def make_add(address:int, left: str, right: str, target: str) -> list[int]: - return make_alr(address, "al_plus", left, right, target) +def make_add(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_plus", left, right, target) -def make_sub(address: int, left: str, right: str, target: str) -> list[int]: - return make_alr(address, "al_minus", left, right, target) +def make_sub(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_minus", left, right, target) -def make_inc(address: int, reg: str) -> list[int]: - return make_ali(address, "al_plus", reg, "1", reg) +def make_and(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_and", left, right, target) -def make_dec(address: int, reg: str) -> list[int]: - return make_ali(address, "al_minus", reg, "1", reg) +def make_or(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_or", left, right, target) -def make_mov(address: int, from_reg: str, to_reg: str) -> list[int]: - return make_ali(address, "al_plus", from_reg, "0", to_reg) +def make_xor(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_xor", left, right, target) + +def make_sll(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_sll", left, right, target) + +def make_slr(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_slr", left, right, target) + +def make_sar(meta: Meta, left: str, right: str, target: str) -> list[int]: + return make_alr(meta, "al_sar", left, right, target) + +def make_slli(meta: Meta, left: str, imm: str, target: str) -> list[int]: + return make_ali(meta, "al_sll", left, imm, target) + +def make_slri(meta: Meta, left: str, imm: str, target: str) -> list[int]: + return make_ali(meta, "al_slr", left, imm, target) + +def make_sari(meta: Meta, left: str, imm: str, target: str) -> list[int]: + return make_ali(meta, "al_sar", left, imm, target) + +def make_inc(meta: Meta, reg: str) -> list[int]: + return make_ali(meta, "al_plus", reg, "1", reg) + +def make_dec(meta: Meta, reg: str) -> list[int]: + return make_ali(meta, "al_minus", reg, "1", reg) + +def make_mov(meta: Meta, from_reg: str, to_reg: str) -> list[int]: + return make_ali(meta, "al_plus", from_reg, "0", to_reg) + +def make_spu(meta: Meta, reg: str) -> list[int]: + sp_reg = meta.options["stack_pointer"] + str_word = make_str(meta, reg, sp_reg) + inc_word = make_inc(meta, sp_reg) + return str_word + inc_word + +def make_spo(meta: Meta, reg: str) -> list[int]: + sp_reg = meta.options["stack_pointer"] + dec_word = make_dec(meta, sp_reg) + ldr_word = make_ldr(meta, reg, sp_reg) + return dec_word + ldr_word + +def make_csr(meta: Meta, addr_reg: str) -> list[int]: + lpc_word = make_lpc(meta, meta.options["csr_scratch"]) + spu_word = make_spu(meta, meta.options["csr_scratch"]) + jpr_word = make_jpr(meta, addr_reg) + return lpc_word + spu_word + jpr_word + +def make_csi(meta: Meta, addr_imm: str) -> list[int]: + lpc_word = make_lpc(meta, meta.options["csr_scratch"]) + spu_word = make_spu(meta, meta.options["csr_scratch"]) + jpi_word = make_jpi(meta, addr_imm) + return lpc_word + spu_word + jpi_word + +def make_rsr(meta: Meta) -> list[int]: + spo_word = make_spo(meta, meta.options["csr_scratch"]) + jpr_word = make_jpr(meta, meta.options["csr_scratch"]) + return spo_word + jpr_word operations = { "add": make_add, "sub": make_sub, + "and": make_and, + "or": make_or, + "xor": make_xor, + "sll": make_sll, + "slr": make_slr, + "sar": make_sar, + "slli": make_slli, + "slri": make_slri, + "sari": make_sari, "inc": make_inc, "dec": make_dec, "mov": make_mov, + "spu": make_spu, + "spo": make_spo, + "csr": make_csr, + "csi": make_csi, + "rsr": make_rsr, } diff --git a/src/ucode.py b/src/ucode.py index 10dd853..9745a7e 100755 --- a/src/ucode.py +++ b/src/ucode.py @@ -65,8 +65,8 @@ ucode = [ # BRI 1000 XFFI IIII IIII branch([*fetch, US_RS, 0, 0, 0, 0, 0], [*fetch, IM_M|LI_OE|PC_IE, US_RS, 0, 0, 0, 0]), - # NOP 1001 XXXX XXXX XXXX - nop(), + # LPC 1001 TTTX XXXX XXXX + not_branch([*fetch, PC_OE|RW_IE, US_RS, 0, 0, 0, 0]), # NOP 1010 XXXX XXXX XXXX nop(), # NOP 1011 XXXX XXXX XXXX -- cgit v1.3