From e2e6f4ea01088b88a84baf43eeda751644c2e458 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 14 Oct 2021 16:51:59 +0200 Subject: [PATCH] Add command line options for optimization --- README.md | 5 + autotest/autotest.bat | 201 ++++++++++++-------------------- oscar64/Compiler.cpp | 12 +- oscar64/Compiler.h | 4 +- oscar64/CompilerTypes.h | 23 ++++ oscar64/Declaration.cpp | 2 +- oscar64/Declaration.h | 2 +- oscar64/Emulator.cpp | 3 + oscar64/GlobalAnalyzer.cpp | 24 +++- oscar64/GlobalAnalyzer.h | 3 + oscar64/InterCode.cpp | 33 ++++-- oscar64/InterCodeGenerator.cpp | 4 +- oscar64/InterCodeGenerator.h | 3 +- oscar64/NativeCodeGenerator.cpp | 2 + oscar64/Scanner.cpp | 2 - oscar64/oscar64.cpp | 15 ++- oscar64/oscar64.vcxproj | 1 + oscar64/oscar64.vcxproj.filters | 3 + 18 files changed, 183 insertions(+), 159 deletions(-) create mode 100644 oscar64/CompilerTypes.h diff --git a/README.md b/README.md index ca7221b..b90762c 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,11 @@ The compiler is command line driven, and creates an executable .prg file. * -e : execute the result in the integrated emulator * -n : create pure native code for all functions * -d : define a symbol (e.g. NOFLOAT or NOLONG to avoid float/long code in printf) +* -O1 or -O : default optimizations +* -O0: disable optimizations +* -O2: more aggressive speed optimizations including auto inline of small functions +* -O3: aggressive optimization for speed +* -Os: optimize for size A list of source files can be provided. diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 920d91f..5dd8235 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -1,195 +1,142 @@ @echo off -..\release\oscar64 -e stdlibtest.c +call :test stdlibtest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n stdlibtest.c +call :test testint16.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e testint16.c +call :test testint32.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n testint16.c +call :test testint16mul.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e testint32.c +call :test recursiontest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n testint32.c +call :test strcmptest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e testint16mul.c +call :test strcmptest2.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n testint16mul.c +call :test arraytest.c if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e recursiontest.c +call :test arraytestfloat.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n recursiontest.c +call :test optiontest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e strcmptest.c +call :test floatcmptest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n strcmptest.c +call :test floatmultest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e strcmptest2.c +call :test staticconsttest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n strcmptest2.c +call :test arrayinittest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e arraytest.c +call :test array2stringinittest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n arraytest.c +call :test testint16cmp.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e arraytestfloat.c +call :test testint32cmp.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n arraytestfloat.c +call :test floatstringtest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e optiontest.c +call :test qsorttest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n optiontest.c +call :test loopdomtest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e floatcmptest.c +call :test byteindextest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n floatcmptest.c +call :test asmtest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e floatmultest.c +call :testb bitshifttest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n floatmultest.c +call :test arrparam.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e staticconsttest.c +call :test bsstest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n staticconsttest.c +call :test copyintvec.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e arrayinittest.c +call :test divmodtest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n arrayinittest.c +call :test enumswitch.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e array2stringinittest.c +call :test incvector.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n array2stringinittest.c +call :test structoffsettest2.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e testint16cmp.c +call :test funcvartest.c if %errorlevel% neq 0 goto :error -..\release\oscar64 -e -n testint16cmp.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e testint32cmp.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n testint32cmp.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e floatstringtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n floatstringtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e qsorttest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n qsorttest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e loopdomtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n loopdomtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e byteindextest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n byteindextest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e asmtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n asmtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e bitshifttest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n bitshifttest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e arrparam.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n arrparam.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e bsstest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n bsstest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e copyintvec.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n copyintvec.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e divmodtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n divmodtest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e enumswitch.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n enumswitch.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e incvector.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n incvector.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e structoffsettest2.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n structoffsettest2.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e funcvartest.c -if %errorlevel% neq 0 goto :error - -..\release\oscar64 -e -n funcvartest.c -if %errorlevel% neq 0 goto :error - - - exit /b 0 + :error echo Failed with error #%errorlevel%. exit /b %errorlevel% + +:test +..\release\oscar64 -e %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O2 %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O2 -n %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O0 %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O0 -n %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O3 %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O3 -n %~1 +if %errorlevel% neq 0 goto :error + +exit /b 0 + +:testb +..\release\oscar64 -e %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O2 %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O0 %~1 +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O3 %~1 +if %errorlevel% neq 0 goto :error + +exit /b 0 diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index edf7226..5bd9547 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -9,7 +9,7 @@ #include Compiler::Compiler(void) - : mByteCodeFunctions(nullptr), mNativeCode(false), mDefines({nullptr, nullptr}) + : mByteCodeFunctions(nullptr), mCompilerOptions(COPT_DEFAULT), mDefines({nullptr, nullptr}) { mErrors = new Errors(); mLinker = new Linker(mErrors); @@ -36,11 +36,6 @@ Compiler::~Compiler(void) } -void Compiler::ForceNativeCode(bool native) -{ - mNativeCode = native; -} - void Compiler::AddDefine(const Ident* ident, const char* value) { Define define; @@ -157,12 +152,15 @@ bool Compiler::GenerateCode(void) dcrtstart->mSection = sectionStartup; + mGlobalAnalyzer->mCompilerOptions = mCompilerOptions; + mGlobalAnalyzer->AnalyzeAssembler(dcrtstart->mValue, nullptr); mGlobalAnalyzer->DumpCallGraph(); mGlobalAnalyzer->AutoInline(); mGlobalAnalyzer->DumpCallGraph(); - mInterCodeGenerator->mForceNativeCode = mNativeCode; + mInterCodeGenerator->mCompilerOptions = mCompilerOptions; + mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr); if (mErrors->mErrorCount != 0) diff --git a/oscar64/Compiler.h b/oscar64/Compiler.h index 38fc89b..cb337ee 100644 --- a/oscar64/Compiler.h +++ b/oscar64/Compiler.h @@ -8,6 +8,7 @@ #include "InterCodeGenerator.h" #include "GlobalAnalyzer.h" #include "Linker.h" +#include "CompilerTypes.h" class Compiler { @@ -27,7 +28,7 @@ public: GrowingArray mByteCodeFunctions; - bool mNativeCode; + uint64 mCompilerOptions; struct Define { @@ -42,7 +43,6 @@ public: bool WriteOutputFile(const char* targetPath); int ExecuteCode(void); - void ForceNativeCode(bool native); void AddDefine(const Ident* ident, const char* value); void RegisterRuntime(const Location& loc, const Ident* ident); diff --git a/oscar64/CompilerTypes.h b/oscar64/CompilerTypes.h new file mode 100644 index 0000000..9fffd9e --- /dev/null +++ b/oscar64/CompilerTypes.h @@ -0,0 +1,23 @@ +#pragma once + +#include "MachineTypes.h" + +static const uint64 COPT_OPTIMIZE_BASIC = 0x00000001; +static const uint64 COPT_OPTIMIZE_INLINE = 0x00000002; + +static const uint64 COPT_OPTIMIZE_AUTO_INLINE = 0x00000010; +static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 0x00000020; + +static const uint64 COPT_NATIVE = 0x01000000; + +static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE; + +static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE; + +static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE; + +static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE; + +static const uint64 COPT_OPTIMIZE_ALL = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL; + + diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index cfcff96..3c4c185 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -337,7 +337,7 @@ Expression* Expression::ConstantFold(void) } Declaration::Declaration(const Location& loc, DecType type) - : mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr) + : mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr) {} Declaration::~Declaration(void) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 2acef33..b850709 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -165,7 +165,7 @@ public: Declaration* mBase, *mParams, * mNext; Expression* mValue; DeclarationScope* mScope; - int mOffset, mSize, mVarIndex, mNumVars, mComplexity; + int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize; int64 mInteger; double mNumber; uint32 mFlags; diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index d5996dd..36a7c5f 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -671,6 +671,9 @@ int Emulator::Emulate(int startIP) if (mRegS == 0) { + for (int i = 0; i < 256; i++) + if (mMemory[i] != 0) + printf("ZP %02x : %02x\n", i, mMemory[i]); DumpCycles(); return int16(mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1]); } diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 3623720..534d5b5 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -1,7 +1,7 @@ #include "GlobalAnalyzer.h" GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker) - : mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr) + : mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr), mCompilerOptions(COPT_DEFAULT) { } @@ -59,7 +59,7 @@ void GlobalAnalyzer::AutoInline(void) for (int i = 0; i < mFunctions.Size(); i++) { Declaration* f = mFunctions[i]; - if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE)) + if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100) { int nparams = 0; Declaration* dec = f->mParams; @@ -70,8 +70,16 @@ void GlobalAnalyzer::AutoInline(void) } int cost = (f->mComplexity - 20 * nparams); - if (cost * (f->mCallers.Size() - 1) <= 0 || (f->mFlags & DTF_REQUEST_INLINE)) - //if (cost * (f->mCallers.Size() - 1) <= 1000 || (f->mFlags & DTF_REQUEST_INLINE)) + + bool doinline = false; + if ((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_INLINE)) + doinline = true; + if ((mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && (cost * (f->mCallers.Size() - 1) <= 0)) + doinline = true; + if ((mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (f->mCallers.Size() - 1) <= 10000)) + doinline = true; + + if (doinline) { printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size()); f->mFlags |= DTF_INLINE; @@ -245,6 +253,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) return exp->mDecValue; case EX_VARIABLE: + if (!(exp->mDecValue->mFlags & DTF_STATIC) && !(exp->mDecValue->mFlags & DTF_GLOBAL)) + { + if (!(exp->mDecValue->mFlags & DTF_ANALYZED)) + { + procDec->mLocalSize += exp->mDecValue->mSize; + exp->mDecValue->mFlags |= DTF_ANALYZED; + } + } return exp->mDecValue; case EX_ASSIGNMENT: ldec = Analyze(exp->mLeft, procDec); diff --git a/oscar64/GlobalAnalyzer.h b/oscar64/GlobalAnalyzer.h index 8b533ff..2252b09 100644 --- a/oscar64/GlobalAnalyzer.h +++ b/oscar64/GlobalAnalyzer.h @@ -2,6 +2,7 @@ #include "Declaration.h" #include "Linker.h" +#include "CompilerTypes.h" class GlobalAnalyzer { @@ -16,6 +17,8 @@ public: void AnalyzeAssembler(Expression* exp, Declaration* procDec); void AnalyzeGlobalVariable(Declaration* dec); + uint64 mCompilerOptions; + protected: Errors* mErrors; Linker* mLinker; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 6d0a1d5..b557b10 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -86,7 +86,7 @@ void ValueSet::FlushCallAliases(void) } } -static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2 = 0) +static int64 ConstantFolding(InterOperator oper, InterType type, int64 val1, int64 val2 = 0) { switch (oper) { @@ -133,7 +133,18 @@ static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2 = 0) return (uint64)val1 >> (uint64)val2; break; case IA_SAR: - return val1 >> val2; + + switch (type) + { + case IT_INT8: + return int8(val1) >> val2; + case IT_INT16: + return int16(val1) >> val2; + case IT_INT32: + return int32(val1) >> val2; + default: + return val1 >> val2; + } break; case IA_CMPEQ: return val1 == val2 ? 1 : 0; @@ -679,7 +690,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) { ins->mCode = IC_CONSTANT; - ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); + ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; @@ -926,7 +937,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) { ins->mCode = IC_CONSTANT; - ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); + ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); ins->mSrc[0].mTemp = -1; i = 0; @@ -999,7 +1010,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) { ins->mCode = IC_CONSTANT; - ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); + ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; @@ -2138,7 +2149,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) { ins->mCode = IC_CONSTANT; - ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); + ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; } @@ -2234,12 +2245,12 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI { if (pins->mSrc[1].mTemp < 0) { - ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[1].mIntConst, pins->mSrc[1].mIntConst); + ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[1].mIntConst, pins->mSrc[1].mIntConst); ins->mSrc[0].mTemp = pins->mSrc[0].mTemp; } else if (pins->mSrc[0].mTemp < 0) { - ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[1].mIntConst, pins->mSrc[0].mIntConst); + ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[1].mIntConst, pins->mSrc[0].mIntConst); ins->mSrc[0].mTemp = pins->mSrc[1].mTemp; } } @@ -2251,12 +2262,12 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI { if (pins->mSrc[1].mTemp < 0) { - ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[0].mIntConst, pins->mSrc[1].mIntConst); + ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[1].mIntConst); ins->mSrc[1].mTemp = pins->mSrc[0].mTemp; } else if (pins->mSrc[0].mTemp < 0) { - ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst); + ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst); ins->mSrc[1].mTemp = pins->mSrc[1].mTemp; } } @@ -2337,7 +2348,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) { ins->mCode = IC_CONSTANT; - ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); + ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst); ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index e5ac650..dda2e17 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1,7 +1,7 @@ #include "InterCodeGenerator.h" InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker) - : mErrors(errors), mLinker(linker), mForceNativeCode(false) + : mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT) { } @@ -2787,7 +2787,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod dec->mLinkerObject = proc->mLinkerObject; proc->mNumLocals = dec->mNumVars; - if (mForceNativeCode) + if (mCompilerOptions & COPT_NATIVE) dec->mFlags |= DTF_NATIVE; if (dec->mFlags & DTF_NATIVE) diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 29e4c12..c0ecaa7 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -3,6 +3,7 @@ #include "Parser.h" #include "InterCode.h" #include "Linker.h" +#include "CompilerTypes.h" class InterCodeGenerator { @@ -20,7 +21,7 @@ public: {} }; - bool mForceNativeCode; + uint64 mCompilerOptions; InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec); void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray * refvars); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index f7713a1..939526b 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -6913,6 +6913,8 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at) j--; if ((mIns[j].mMode == ASMIM_ZERO_PAGE || mIns[j].mMode == ASMIM_INDIRECT_Y) && mIns[j].mAddress == mIns[at + 1].mAddress) return false; + if (mIns[j].mMode == ASMIM_INDIRECT_Y && mIns[j].mAddress + 1 == mIns[at + 1].mAddress) + return false; if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress && mIns[j].ChangesAddress()) return false; if (mIns[j].mMode == ASMIM_ABSOLUTE_Y && mIns[j].mAddress <= mIns[at + 1].mAddress && mIns[j].mType == ASMIT_LDA && !mIns[j].mLinkerObject) diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index b08b117..b0df82b 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -1299,8 +1299,6 @@ void Scanner::CharToken(void) } } - mTokenChar = mTokenChar; - mTokenInteger = mTokenChar; if (mLine[mOffset] && mLine[mOffset] == '\'') diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index ab32495..01b5b6f 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -135,7 +135,20 @@ int main(int argc, const char** argv) } else if (arg[1] == 'n') { - compiler->ForceNativeCode(true); + compiler->mCompilerOptions |= COPT_NATIVE; + } + else if (arg[1] == 'O') + { + if (arg[2] == '0') + compiler->mCompilerOptions &= ~(COPT_OPTIMIZE_ALL); + else if (arg[1] == '1' || arg[1] == 0) + compiler->mCompilerOptions |= COPT_OPTIMIZE_DEFAULT; + else if (arg[2] == '2') + compiler->mCompilerOptions |= COPT_OPTIMIZE_SPEED; + else if (arg[2] == '3') + compiler->mCompilerOptions |= COPT_OPTIMIZE_ALL; + else if (arg[2] == 's') + compiler->mCompilerOptions |= COPT_OPTIMIZE_SIZE; } else if (arg[1] == 'e') { diff --git a/oscar64/oscar64.vcxproj b/oscar64/oscar64.vcxproj index 57b2040..7cfcc21 100644 --- a/oscar64/oscar64.vcxproj +++ b/oscar64/oscar64.vcxproj @@ -168,6 +168,7 @@ + diff --git a/oscar64/oscar64.vcxproj.filters b/oscar64/oscar64.vcxproj.filters index 35735e8..1c0730c 100644 --- a/oscar64/oscar64.vcxproj.filters +++ b/oscar64/oscar64.vcxproj.filters @@ -143,6 +143,9 @@ Header Files + + Header Files +