Add TP04a
This commit is contained in:
parent
b7601abd73
commit
4c7a2c85a2
@ -14,11 +14,23 @@ class AllInMemAllocator(Allocator):
|
|||||||
before: List[Instruction] = []
|
before: List[Instruction] = []
|
||||||
after: List[Instruction] = []
|
after: List[Instruction] = []
|
||||||
new_args: List[Operand] = []
|
new_args: List[Operand] = []
|
||||||
# TODO: compute before,after,args.
|
|
||||||
# TODO: iterate over old_args, check which argument
|
s_index = 0
|
||||||
# TODO: is a temporary (e.g. isinstance(..., Temporary)),
|
for arg in old_instr.args():
|
||||||
# TODO: and if so, generate ld/sd accordingly. Replace the
|
if isinstance(arg, Temporary):
|
||||||
# TODO: temporary with S[1], S[2] or S[3] physical registers.
|
# 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)
|
new_instr = old_instr.with_args(new_args)
|
||||||
return before + [new_instr] + after
|
return before + [new_instr] + after
|
||||||
|
|
||||||
|
@ -74,8 +74,13 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
raise MiniCUnsupportedError("float literal")
|
raise MiniCUnsupportedError("float literal")
|
||||||
|
|
||||||
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
||||||
# true is 1 false is 0
|
dest = self._current_function.fdata.fresh_tmp()
|
||||||
raise NotImplementedError() # TODO
|
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:
|
def visitIdAtom(self, ctx) -> Operands.Temporary:
|
||||||
try:
|
try:
|
||||||
@ -99,13 +104,37 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
tmpl: Operands.Temporary = self.visit(ctx.expr(0))
|
tmpl: Operands.Temporary = self.visit(ctx.expr(0))
|
||||||
tmpr: Operands.Temporary = self.visit(ctx.expr(1))
|
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:
|
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:
|
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:
|
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
|
||||||
return self.visitRelationalExpr(ctx)
|
return self.visitRelationalExpr(ctx)
|
||||||
@ -117,18 +146,83 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
print("relational expression:")
|
print("relational expression:")
|
||||||
print(Trees.toStringTree(ctx, [], self._parser))
|
print(Trees.toStringTree(ctx, [], self._parser))
|
||||||
print("Condition:", c)
|
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:
|
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
|
||||||
assert ctx.myop is not None
|
assert ctx.myop is not None
|
||||||
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
|
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:
|
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:
|
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:
|
def visitProgRule(self, ctx) -> None:
|
||||||
self.visitChildren(ctx)
|
self.visitChildren(ctx)
|
||||||
@ -160,8 +254,25 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
def visitIfStat(self, ctx) -> None:
|
def visitIfStat(self, ctx) -> None:
|
||||||
if self._debug:
|
if self._debug:
|
||||||
print("if statement")
|
print("if statement")
|
||||||
|
else_label = self._current_function.fdata.fresh_label("else_if")
|
||||||
end_if_label = self._current_function.fdata.fresh_label("end_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)
|
self._current_function.add_label(end_if_label)
|
||||||
|
|
||||||
def visitWhileStat(self, ctx) -> None:
|
def visitWhileStat(self, ctx) -> None:
|
||||||
@ -170,7 +281,31 @@ class MiniCCodeGen3AVisitor(MiniCVisitor):
|
|||||||
print(Trees.toStringTree(ctx.expr(), [], self._parser))
|
print(Trees.toStringTree(ctx.expr(), [], self._parser))
|
||||||
print("and block is:")
|
print("and block is:")
|
||||||
print(Trees.toStringTree(ctx.stat_block(), [], self._parser))
|
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
|
# visit statements
|
||||||
|
|
||||||
def visitPrintlnintStat(self, ctx) -> None:
|
def visitPrintlnintStat(self, ctx) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user