From 07c67dbef6cde2cadcdeaf2a27a70acefb34f288 Mon Sep 17 00:00:00 2001 From: Guy C Date: Wed, 26 Feb 2025 07:13:12 +0000 Subject: [PATCH] feat: add zero division error handling in asmGenerator --- src/main/wacc/backend/asmGenerator.scala | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/main/wacc/backend/asmGenerator.scala b/src/main/wacc/backend/asmGenerator.scala index a9b5fba..7212e56 100644 --- a/src/main/wacc/backend/asmGenerator.scala +++ b/src/main/wacc/backend/asmGenerator.scala @@ -12,6 +12,24 @@ object asmGenerator { import wacc.types._ import lexer.escapedChars + abstract case class Error() { + def strLabel: String + def errStr: String + def errLabel: String + + def stringDef: Chain[AsmLine] = Chain( + Directive.Int(errStr.size), + LabelDef(strLabel), + Directive.Asciz(errStr) + ) + } + object zeroDivError extends Error { + // TODO: is this bad? Can we make an error case class/some other structure? + def strLabel = ".L._errDivZero_str0" + def errStr = "fatal error: division or modulo by zero" + def errLabel = ".L._errDivZero" + } + val RAX = Register(RegSize.R64, RegName.AX) val EAX = Register(RegSize.E32, RegName.AX) val ESP = Register(RegSize.E32, RegName.SP) @@ -66,7 +84,7 @@ object asmGenerator { LabelDef(s".L.str$i"), Directive.Asciz(str.escaped) ) - } + } ++ zeroDivError.stringDef Chain( Directive.IntelSyntax, @@ -135,6 +153,17 @@ object asmGenerator { ) ) + chain ++= Chain( + // TODO can this be done with a call to generateStmt? + // Consider other error cases -> look to generalise + LabelDef(zeroDivError.errLabel), + stack.align(), + Load(RDI, IndexAddress(RIP, LabelArg(zeroDivError.strLabel))), + assemblyIR.Call(CLibFunc.PrintF), + Move(RDI, ImmediateVal(-1)), + assemblyIR.Call(CLibFunc.Exit) + ) + chain } @@ -254,6 +283,8 @@ object asmGenerator { chain += stack.push(RAX) case BinaryOperator.Div => + chain += Compare(stack.head(SizeDir.Word), ImmediateVal(0)) + chain += Jump(LabelArg(zeroDivError.errLabel), Cond.Equal) chain += CDQ() chain += Divide(stack.head(SizeDir.Word)) chain += stack.drop()