aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/assembler.py3
-rw-r--r--src/assembler_eval.py6
-rw-r--r--src/assembler_ops.py49
-rw-r--r--src/ext_std.py90
-rwxr-xr-xsrc/ucode.py4
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