Skip to content

Commit

Permalink
#16 [asm] added coditional codegen draft
Browse files Browse the repository at this point in the history
  • Loading branch information
vityaman committed Feb 6, 2024
1 parent 11d4329 commit e2ce156
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 16 deletions.
4 changes: 4 additions & 0 deletions sleepy/asmik/argument.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def ze(cls) -> "PhysicalRegister":
def a1(cls) -> "PhysicalRegister":
return PhysicalRegister("a1")

@classmethod
def ra(cls) -> "PhysicalRegister":
return PhysicalRegister("ra")


@dataclass(repr=False)
class VirtualRegister(Register):
Expand Down
78 changes: 69 additions & 9 deletions sleepy/asmik/emit.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
from .instruction import (
Addi,
Addim,
Br,
Divi,
Hlt,
Instruction,
Load,
Muli,
Expand All @@ -18,6 +18,7 @@
Slti,
Xorb,
mov,
movi,
)
from .memory import Memory

Expand All @@ -29,7 +30,21 @@ def __init__(self) -> None:
self.memory = Memory()
self.regs: dict[str, VirtReg] = {}

self.resolved: dict[str, int] = {}

self.block: tafka.Block
self.block_until: list[tafka.Block] = []

def emit_block(self, block: tafka.Block) -> None:
if (
len(self.block_until) > 0
and self.block_until[-1].label == block.label
):
return

self.resolved[repr(block.label)] = len(self.memory.instr) * 4

self.block = block
for statement in block.statements:
self.emit_stmt(statement)

Expand All @@ -42,13 +57,47 @@ def emit_stmt(self, stmt: tafka.Statement) -> None:

def emit_jump(self, jump: tafka.Jump) -> None:
match jump:
case tafka.Return(value):
self.emit_i(mov(Reg.a1(), self.reg_var(value)))
self.emit_i(Hlt())
case tafka.Goto(block):
raise NotImplementedError
case tafka.Conditional(cond, then_br, else_br, next):
raise NotImplementedError
case tafka.Return() as ret:
self.emit_jump_return(ret)
case tafka.Goto() as goto:
self.emit_jump_goto(goto)
case tafka.Conditional() as cond:
self.emit_jump_cond(cond)

def emit_jump_return(self, stmt: tafka.Return) -> None:
self.emit_i(mov(Reg.a1(), self.reg_var(stmt.value)))
true = self.reg_tmp()
self.emit_i(movi(true, Integer(1)))
self.emit_i(Br(true, Reg.ra()))

def emit_jump_goto(self, stmt: tafka.Goto) -> None:
true = self.reg_tmp()
true_val = Integer(1)
self.emit_i(movi(true, true_val))

label = self.reg_tmp()
label_val = Unassigned(repr(stmt.block.label))
self.emit_i(movi(label, label_val))

self.emit_i(Br(true, label))

def emit_jump_cond(self, conditional: tafka.Conditional) -> None:
self.block_until.append(conditional.next_block)

cond = self.reg_var(conditional.condition)

els = self.reg_tmp()
els_val = Unassigned(repr(conditional.else_branch.label))
self.emit_i(movi(els, els_val))

self.emit_i(Br(cond, els))

self.emit_block(conditional.then_branch)
self.emit_block(conditional.else_branch)

self.block_until.pop()

self.emit_block(conditional.next_block)

def emit_set_stmt(self, stmt: tafka.Set) -> None:
match stmt.source:
Expand Down Expand Up @@ -129,13 +178,24 @@ def addr_of(self, cnst: tafka.Const) -> Immediate:
data = IntegerData(int(cnst.name))
addr = self.memory.data_put(data)
return Integer(addr)
return Unassigned(f"{cnst!r}")
raise NotImplementedError


AsmikUnit = AsmikEmiter


def asmik_resolve(asmik: AsmikUnit) -> None:
for instr in asmik.memory.instr:
if (
isinstance(instr, Addim) #
and isinstance(instr.rhs, Unassigned)
):
label = instr.rhs.label
instr.rhs = Integer(asmik.resolved[label])


def asmik_emit(tafka: TafkaUnit) -> AsmikUnit:
asmik = AsmikEmiter()
asmik.emit_block(tafka.main)
asmik_resolve(asmik)
return asmik
10 changes: 7 additions & 3 deletions sleepy/asmik/instruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,19 @@ def __repr__(self) -> str:


@dataclass(repr=False)
class Brn(Instruction):
class Br(Instruction):
cond: Register
label: Register

@override
@property
def name(self) -> str:
return "brn"
return "br"

@override
@property
def action(self) -> str:
return "ip <- (not cond) ? label : (ip + 4)"
return "ip <- (cond) ? label : (ip + 4)"

@override
def __repr__(self) -> str:
Expand All @@ -234,3 +234,7 @@ def __repr__(self) -> str:

def mov(dst: Register, src: Register) -> Instruction:
return Addim(dst, src, Integer(0))


def movi(dst: Register, src: Immediate) -> Instruction:
return Addim(dst, Register.ze(), src)
5 changes: 2 additions & 3 deletions test/golden/group/arithmetics/1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,5 @@ asmik-virt: |-
0056: addim v9, ze, 16
0060: load v9, v9
0064: addim a1, v9, 0
0068: hlt
asmik-virt-interp: "TODO"
0068: addim v10, ze, 1
0072: br v10, ra
33 changes: 32 additions & 1 deletion test/golden/group/conditional/1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,35 @@ tafka: |-
var(5): int = load(const(0): int): int
return var(5): int
asmik-virt: TODO
asmik-virt: |-
memory stack
0000: 1 # const(1): int
0008: 0 # const(0): int
memory instr
0000: addim v0, ze, 0
0004: load v0, v0
0008: addim v1, ze, 0
0012: load v1, v1
0016: slti v2, v0, v1
0020: slti v3, v1, v0
0024: orb v2, v2, v3
0028: addim v4, ze, -1
0032: xorb v2, v2, v4
0036: addim v5, ze, 64
0040: br v2, v5
0044: addim v6, ze, 0
0048: load v6, v6
0052: addim v7, ze, 1
0056: addim v8, ze, 88
0060: br v7, v8
0064: addim v9, ze, 0
0068: load v9, v9
0072: addim v6, v9, 0
0076: addim v10, ze, 1
0080: addim v11, ze, 88
0084: br v10, v11
0088: addim v12, ze, 8
0092: load v12, v12
0096: addim a1, v12, 0
0100: addim v13, ze, 1
0104: br v13, ra

0 comments on commit e2ce156

Please sign in to comment.