From 6f1da4335b60b2482d5668db6e12351949719a4f Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 18 May 2025 14:04:14 +0200 Subject: [PATCH] Fix continue/break for unrolled loops --- oscar64/Declaration.cpp | 13 +++++++++++++ oscar64/Declaration.h | 2 ++ oscar64/GlobalAnalyzer.cpp | 5 +++++ oscar64/GlobalOptimizer.cpp | 5 +++++ oscar64/InterCodeGenerator.cpp | 31 +++++++++++++++++++++++++++++++ oscar64/Parser.cpp | 17 +++++++++++------ 6 files changed, 67 insertions(+), 6 deletions(-) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 971e7bb..2616007 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -274,6 +274,9 @@ void Expression::Dump(int ident) const case EX_FOR: printf("FOR"); break; + case EX_FORBODY: + printf("FORBODY"); + break; case EX_DO: printf("DO"); break; @@ -3106,6 +3109,7 @@ Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration; Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration; Expression* TheVoidExpression; Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration; +Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration; void InitDeclarations(void) { @@ -3207,4 +3211,13 @@ void InitDeclarations(void) TheZeroFloatConstDeclaration->mBase = TheFloatTypeDeclaration; TheZeroFloatConstDeclaration->mSize = 4; + TheTrueConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER); + TheTrueConstDeclaration->mBase = TheBoolTypeDeclaration; + TheTrueConstDeclaration->mSize = 1; + TheTrueConstDeclaration->mInteger = 1; + + TheFalseConstDeclaration = new Declaration(noloc, DT_CONST_INTEGER); + TheFalseConstDeclaration->mBase = TheBoolTypeDeclaration; + TheFalseConstDeclaration->mSize = 1; + TheFalseConstDeclaration->mInteger = 0; } diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 954d593..599a2d3 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -218,6 +218,7 @@ enum ExpressionType EX_IF, EX_ELSE, EX_FOR, + EX_FORBODY, EX_DO, EX_SCOPE, EX_BREAK, @@ -385,5 +386,6 @@ extern Declaration* TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoid extern Declaration* TheVoidFunctionTypeDeclaration, * TheConstVoidValueDeclaration; extern Declaration* TheCharPointerTypeDeclaration, * TheConstCharPointerTypeDeclaration; extern Declaration* TheNullptrConstDeclaration, * TheZeroIntegerConstDeclaration, * TheZeroFloatConstDeclaration, * TheNullPointerTypeDeclaration; +extern Declaration* TheTrueConstDeclaration, * TheFalseConstDeclaration; extern Expression* TheVoidExpression; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 62607c1..d91abc5 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -1141,6 +1141,11 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo if (exp->mLeft->mLeft->mRight) ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false, false); break; + case EX_FORBODY: + ldec = Analyze(exp->mLeft, procDec, false, false); + if (exp->mRight) + Analyze(exp->mRight, procDec, false, false); + break; case EX_DO: procDec->mComplexity += 20; diff --git a/oscar64/GlobalOptimizer.cpp b/oscar64/GlobalOptimizer.cpp index 3df1ce0..ef46333 100644 --- a/oscar64/GlobalOptimizer.cpp +++ b/oscar64/GlobalOptimizer.cpp @@ -974,6 +974,11 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin if (exp->mLeft->mLeft->mRight) ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, 0); break; + case EX_FORBODY: + ldec = Analyze(exp->mLeft, procDec, 0); + if (exp->mRight) + rdec = Analyze(exp->mRight, procDec, 0); + break; case EX_DO: ldec = Analyze(exp->mRight, procDec, 0); rdec = Analyze(exp->mLeft, procDec, ANAFL_RHS); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 88298c3..c387831 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -5455,6 +5455,37 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* return ExValue(TheVoidTypeDeclaration); } + case EX_FORBODY: + { + DestructStack* odestack = destack; + + InterInstruction* jins0 = new InterInstruction(MapLocation(exp, inlineMapper), IC_JUMP); + InterInstruction* jins1 = new InterInstruction(MapLocation(exp, inlineMapper), IC_JUMP); + + InterCodeBasicBlock* lblock = new InterCodeBasicBlock(proc); + InterCodeBasicBlock* cblock = new InterCodeBasicBlock(proc); + + block->Append(jins0); + block->Close(lblock, nullptr); + + DestructStack* idestack = destack; + + vr = TranslateExpression(procType, proc, lblock, exp->mLeft, destack, gotos, breakBlock, BranchTarget(cblock, idestack), inlineMapper); + + lblock->Append(jins1); + lblock->Close(cblock, nullptr); + + UnwindDestructStack(procType, proc, cblock, destack, idestack, inlineMapper); + destack = idestack; + + block = cblock; + + exp = exp->mRight; + if (!exp) + return ExValue(TheVoidTypeDeclaration); + + } break; + case EX_FOR: { DestructStack* odestack = destack; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 3df4c5d..45a6420 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -10712,7 +10712,7 @@ Expression* Parser::ParseStatement(void) } conditionExp->mRight->mDecValue->mInteger = endValue; - Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE); + Expression* unrollBody = new Expression(mScanner->mLocation, EX_FORBODY); unrollBody->mLeft = bodyExp; Expression* bexp = unrollBody; if ((endValue - startValue) * stepValue > 0) @@ -10722,7 +10722,7 @@ Expression* Parser::ParseStatement(void) bexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE); bexp = bexp->mRight; bexp->mLeft = iterateExp; - bexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE); + bexp->mRight = new Expression(mScanner->mLocation, EX_FORBODY); bexp = bexp->mRight; bexp->mLeft = bodyExp; } @@ -10732,16 +10732,21 @@ Expression* Parser::ParseStatement(void) if (remain) { - finalExp = new Expression(mScanner->mLocation, EX_SEQUENCE); - finalExp->mLeft = bodyExp; - Expression* bexp = finalExp; + finalExp = new Expression(mScanner->mLocation, EX_DO); + finalExp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT); + finalExp->mLeft->mDecType = TheBoolTypeDeclaration; + finalExp->mLeft->mDecValue = TheFalseConstDeclaration; + + finalExp->mRight = new Expression(mScanner->mLocation, EX_FORBODY); + finalExp->mRight->mLeft = bodyExp; + Expression* bexp = finalExp->mRight; for (int i = 1; i < remain; i++) { bexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE); bexp = bexp->mRight; bexp->mLeft = iterateExp; - bexp->mRight = new Expression(mScanner->mLocation, EX_SEQUENCE); + bexp->mRight = new Expression(mScanner->mLocation, EX_FORBODY); bexp = bexp->mRight; bexp->mLeft = bodyExp; }