Add TP04a

This commit is contained in:
augustin64 2024-10-20 15:01:32 +02:00
parent b7601abd73
commit 4c7a2c85a2
2 changed files with 163 additions and 16 deletions

View File

@ -14,11 +14,23 @@ class AllInMemAllocator(Allocator):
before: List[Instruction] = []
after: List[Instruction] = []
new_args: List[Operand] = []
# TODO: compute before,after,args.
# TODO: iterate over old_args, check which argument
# TODO: is a temporary (e.g. isinstance(..., Temporary)),
# TODO: and if so, generate ld/sd accordingly. Replace the
# TODO: temporary with S[1], S[2] or S[3] physical registers.
s_index = 0
for arg in old_instr.args():
if isinstance(arg, Temporary):
# TODO: don't ld/sd when nothing changed (eg don't ld a destination only,
# TODO: don't sd a source only)
s_index += 1
before.append(RiscV.ld(
S[s_index], arg.get_alloced_loc()
))
after.append(RiscV.sd(
S[s_index], arg.get_alloced_loc()
))
new_args.append(S[s_index])
else:
new_args.append(arg)
new_instr = old_instr.with_args(new_args)
return before + [new_instr] + after

View File

@ -74,8 +74,13 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
raise MiniCUnsupportedError("float literal")
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
# true is 1 false is 0
raise NotImplementedError() # TODO
dest = self._current_function.fdata.fresh_tmp()
self._current_function.add_instruction(
RiscV.li(
dest, Operands.Immediate(1 if ctx.getText() == "true" else 0)
)
)
return dest # true is 1 false is 0
def visitIdAtom(self, ctx) -> Operands.Temporary:
try:
@ -99,13 +104,37 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
assert ctx.myop is not None
tmpl: Operands.Temporary = self.visit(ctx.expr(0))
tmpr: Operands.Temporary = self.visit(ctx.expr(1))
raise NotImplementedError() # TODO
tmp = self._current_function.fdata.fresh_tmp()
if ctx.myop.type == MiniCParser.PLUS:
self._current_function.add_instruction(
RiscV.add(tmp, tmpl, tmpr)
)
elif ctx.myop.type == MiniCParser.MINUS:
self._current_function.add_instruction(
RiscV.sub(tmp, tmpl, tmpr)
)
else:
raise MiniCInternalError(
f"Unknown additive operator '{ctx.myop}'")
return tmp
def visitOrExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError() # TODO
tmp = self._current_function.fdata.fresh_tmp()
t1, t2 = self.visit(ctx.expr(0)), self.visit(ctx.expr(1))
self._current_function.add_instruction(
RiscV.lor(tmp, t1, t2)
)
return tmp
def visitAndExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError() # TODO
tmp = self._current_function.fdata.fresh_tmp()
t1, t2 = self.visit(ctx.expr(0)), self.visit(ctx.expr(1))
self._current_function.add_instruction(
RiscV.land(tmp, t1, t2)
)
return tmp
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
return self.visitRelationalExpr(ctx)
@ -117,18 +146,83 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print("relational expression:")
print(Trees.toStringTree(ctx, [], self._parser))
print("Condition:", c)
raise NotImplementedError() # TODO
dest = self._current_function.fdata.fresh_tmp()
t1 = self.visit(ctx.expr(0))
t2 = self.visit(ctx.expr(1))
endrel = self._current_function.fdata.fresh_label("end_rel")
# dest <- 1
# t1 cond t2 ? jmp end
# dest <- 0
# end:
self._current_function.add_instruction(
RiscV.li(dest, Operands.Immediate(1)))
self._current_function.add_instruction(
RiscV.conditional_jump(endrel, t1, Condition(ctx.myop.type), t2))
self._current_function.add_instruction(
RiscV.li(dest, Operands.Immediate(0)))
self._current_function.add_label(endrel)
return dest
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
assert ctx.myop is not None
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
raise NotImplementedError() # TODO
t1 = self.visit(ctx.expr(0))
t2 = self.visit(ctx.expr(1))
dest = self._current_function.fdata.fresh_tmp()
if ctx.myop.type == MiniCParser.DIV or ctx.myop.type == MiniCParser.MOD:
self._current_function.add_instruction(
RiscV.conditional_jump(div_by_zero_lbl, t2, Condition("beq"), Operands.ZERO))
if ctx.myop.type == MiniCParser.MULT:
self._current_function.add_instruction(
RiscV.mul(dest, t1, t2))
elif ctx.myop.type == MiniCParser.DIV:
self._current_function.add_instruction(
RiscV.div(dest, t1, t2))
elif ctx.myop.type == MiniCParser.MOD:
self._current_function.add_instruction(
RiscV.rem(dest, t1, t2))
else:
raise MiniCInternalError(
f"Unknown additive operator '{ctx.myop}'")
return dest
def visitNotExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError() # TODO
dest = self._current_function.fdata.fresh_tmp()
label_neq_zero = self._current_function.fdata.fresh_label("neq_zero")
t1 = self.visit(ctx.expr())
# dest <- 0
# t1 != dest ? jmp neq_zero
# dest <- 1
# neq_zero:
self._current_function.add_instruction(
RiscV.li(dest, Operands.Immediate(0))
)
self._current_function.add_instruction(
RiscV.conditional_jump(label_neq_zero, t1, Condition("bne"), Operands.ZERO)
)
self._current_function.add_instruction(
RiscV.li(dest, Operands.Immediate(1))
)
self._current_function.add_label(label_neq_zero)
return dest
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
raise NotImplementedError("unaryminusexpr") # TODO
dest = self._current_function.fdata.fresh_tmp()
self._current_function.add_instruction(
RiscV.sub(dest, Operands.ZERO, self.visit(ctx.expr()))
)
return dest
def visitProgRule(self, ctx) -> None:
self.visitChildren(ctx)
@ -160,8 +254,25 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
def visitIfStat(self, ctx) -> None:
if self._debug:
print("if statement")
else_label = self._current_function.fdata.fresh_label("else_if")
end_if_label = self._current_function.fdata.fresh_label("end_if")
raise NotImplementedError() # TODO
self._current_function.add_instruction(
RiscV.conditional_jump(
else_label, self.visit(ctx.expr()),
Condition('beq'), Operands.ZERO
)
)
self.visit(ctx.stat_block()[0])
self._current_function.add_instruction(
RiscV.jump(end_if_label)
)
self._current_function.add_label(else_label)
if len(ctx.stat_block()) > 1:
self.visit(ctx.stat_block()[1])
self._current_function.add_label(end_if_label)
def visitWhileStat(self, ctx) -> None:
@ -170,7 +281,31 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
print(Trees.toStringTree(ctx.expr(), [], self._parser))
print("and block is:")
print(Trees.toStringTree(ctx.stat_block(), [], self._parser))
raise NotImplementedError() # TODO
# ltest <- fresh_label()
loop_test = self._current_function.fdata.fresh_label("loop_test")
# lendwhile <- fresh_label()
end_while = self._current_function.fdata.fresh_label("end_while")
# code.addLabel(ltest)
self._current_function.add_label(loop_test)
# t1 <- GenCodeExpr(b)
# code.add("beq lendwhile, t1, 0")
self._current_function.add_instruction(
RiscV.conditional_jump(
end_while, self.visit(ctx.expr()),
Condition('beq'), Operands.ZERO
)
)
# GenCodeSmt(S) # execute S
self.visit(ctx.stat_block())
# code.add("j ltest") # and jump to the test
self._current_function.add_instruction(
RiscV.jump(loop_test)
)
# code.addLabel(lendwhile) # else it is done.
self._current_function.add_label(end_while)
# visit statements
def visitPrintlnintStat(self, ctx) -> None: