diff --git a/include/math.c b/include/math.c index 2a2e50d..8ae35c2 100644 --- a/include/math.c +++ b/include/math.c @@ -216,35 +216,24 @@ float sqrt(float f) bool isinf(float f) { - __asm - { - lda #$00 - sta accu + 1 - asl f + 2 - lda f + 3 - rol - eor #$ff - beq W1 - lda #$01 - W1: - eor #$01 - sta accu - } + union { + float f; + int i[2]; + } x; + + x.f = f; + + return ((x.i[0] >> 7) & 0xff) == 0xff; } bool isfinite(float f) { - __asm - { - lda #$00 - sta accu + 1 - asl f + 2 - lda f + 3 - rol - eor #$ff - beq W1 - lda #$01 - W1: - sta accu - } + union { + float f; + int i[2]; + } x; + + x.f = f; + + return ((x.i[0] >> 7) & 0xff) != 0xff; } diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 16090a4..c7e408f 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -71,8 +71,9 @@ static const uint32 DTF_FUNC_VARIABLE = 0x00040000; static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000; static const uint32 DTF_FUNC_RECURSIVE = 0x00100000; static const uint32 DTF_FUNC_ANALYZING = 0x00200000; +static const uint32 DTF_FUNC_CONSTEXPR = 0x00400000; -static const uint32 DTF_VAR_ALIASING = 0x00400000; +static const uint32 DTF_VAR_ALIASING = 0x00800000; class Declaration; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 5009c49..cb5373e 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -39,12 +39,15 @@ void GlobalAnalyzer::DumpCallGraph(void) { for (int j = 0; j < decs.Size(); j++) { - printf("CALL %s[%d] -> %d -> %s[%d]\n", from->mIdent->mString, from->mComplexity, calls[j], decs[j]->mIdent->mString, decs[j]->mComplexity); + if (decs[j]->mType == DT_CONST_FUNCTION) + printf("CALL %s[%d, %08x] -> %d -> %s[%d, %08x]\n", from->mIdent->mString, from->mComplexity, from->mFlags, calls[j], decs[j]->mIdent->mString, decs[j]->mComplexity, decs[j]->mFlags); + else + printf("CALL %s[%d, %08x] -> %d\n", from->mIdent->mString, from->mComplexity, from->mFlags, calls[j]); } } else { - printf("LEAF %d -> %s[%d]\n", from->mCallers.Size(), from->mIdent->mString, from->mComplexity ); + printf("LEAF %d -> %s[%d, %08x]\n", from->mCallers.Size(), from->mIdent->mString, from->mComplexity, from->mFlags ); } } } @@ -144,7 +147,10 @@ void GlobalAnalyzer::AutoInline(void) void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec) { if (dec->mFlags & DTF_FUNC_ANALYZING) + { dec->mFlags |= DTF_FUNC_RECURSIVE; + dec->mFlags &= ~DTF_FUNC_CONSTEXPR; + } if (!(dec->mFlags & DTF_ANALYZED)) { @@ -154,9 +160,12 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec) dec->mFlags |= DTF_ANALYZED; if (dec->mFlags & DTF_INTRINSIC) - ; + dec->mFlags |= DTF_FUNC_CONSTEXPR; else if (dec->mFlags & DTF_DEFINED) + { + dec->mFlags |= DTF_FUNC_CONSTEXPR; Analyze(exp, dec); + } else mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent->mString); @@ -257,7 +266,11 @@ 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_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL)) + { + procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; + } + else { if (!(exp->mDecValue->mFlags & DTF_ANALYZED)) { @@ -326,6 +339,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) } while (exp); break; case EX_WHILE: + procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; + ldec = Analyze(exp->mLeft, procDec); rdec = Analyze(exp->mRight, procDec); break; @@ -338,6 +353,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) case EX_ELSE: break; case EX_FOR: + procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; + if (exp->mLeft->mRight) ldec = Analyze(exp->mLeft->mRight, procDec); if (exp->mLeft->mLeft->mLeft) @@ -372,6 +389,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) break; case EX_ASSEMBLER: procDec->mFlags |= DTF_FUNC_ASSEMBLER; + procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; AnalyzeAssembler(exp, procDec); break; case EX_UNDEFINED: @@ -406,6 +424,9 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to) { if (to->mType == DT_CONST_FUNCTION) { + if (!(to->mFlags & DTF_FUNC_CONSTEXPR)) + from->mFlags &= ~DTF_FUNC_CONSTEXPR; + if (to->mCallers.Size() == 0) mCalledFunctions.Push(to); to->mCallers.Push(from); @@ -415,12 +436,14 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to) } else if (to->mType == DT_TYPE_FUNCTION) { + from->mFlags &= ~DTF_FUNC_CONSTEXPR; if (from->mCalled.Size() == 0) mCallingFunctions.Push(from); from->mCalled.Push(to); } else if (to->mType == DT_TYPE_POINTER && to->mBase->mType == DT_TYPE_FUNCTION) { + from->mFlags &= ~DTF_FUNC_CONSTEXPR; if (from->mCalled.Size() == 0) mCallingFunctions.Push(from); from->mCalled.Push(to->mBase); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index adb7ea7..24f35d7 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1897,8 +1897,40 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* return ExValue(TheVoidTypeDeclaration); } } - - if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INLINE) && !(inlineMapper && inlineMapper->mDepth > 10)) + + bool canInline = exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && !(inlineMapper && inlineMapper->mDepth > 10); + bool doInline = false, inlineConstexpr = false; + + if (canInline) + { + if (inlineMapper && inlineMapper->mConstExpr) + inlineConstexpr = true; + else if (exp->mLeft->mDecValue->mFlags & DTF_FUNC_CONSTEXPR) + { + Expression* pex = exp->mRight; + inlineConstexpr = true; + while (inlineConstexpr && pex) + { + if (pex->mType == EX_LIST) + { + if (pex->mLeft->mType != EX_CONSTANT) + inlineConstexpr = false; + pex = pex->mRight; + } + else + { + if (pex->mType != EX_CONSTANT) + inlineConstexpr = false; + pex = nullptr; + } + } + } + + if (inlineConstexpr || (exp->mLeft->mDecValue->mFlags & DTF_INLINE)) + doInline = true; + } + + if (doInline) { Declaration* fdec = exp->mLeft->mDecValue; Expression* fexp = fdec->mValue; @@ -1907,6 +1939,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InlineMapper nmapper; nmapper.mReturn = new InterCodeBasicBlock(); nmapper.mVarIndex = proc->mNumLocals; + nmapper.mConstExpr = inlineConstexpr; proc->mNumLocals += fdec->mNumVars; if (inlineMapper) nmapper.mDepth = inlineMapper->mDepth + 1; diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 342ac8f..c8df044 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -36,6 +36,7 @@ protected: GrowingArray mParams; InterCodeBasicBlock * mReturn; int mResult, mDepth, mVarIndex; + bool mConstExpr; InlineMapper(void) : mParams(-1), mResult(-1), mDepth(0) diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index e4e0429..b36ed11 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -9646,6 +9646,43 @@ bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& bre return false; } +bool NativeCodeBasicBlock::MoveIndirectLoadStoreDown(int at) +{ + int j = at + 2; + + while (j < mIns.Size()) + { + if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at + 1].mAddress) + { + if (!(mIns[j].mLive & LIVE_MEM) && HasAsmInstructionMode(mIns[j].mType, ASMIM_INDIRECT_Y)) + { + mIns[j].mMode = ASMIM_INDIRECT_Y; + mIns[j].mAddress = mIns[at].mAddress; + mIns[at + 0].mType = ASMIT_NOP; mIns[at + 0].mMode = ASMIM_IMPLIED; + mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mMode = ASMIM_IMPLIED; + + for (int k = at; k < j; k++) + mIns[k].mLive |= LIVE_CPU_REG_Y; + + return true; + } + + return false; + } + + if (mIns[j].ChangesYReg()) + return false; + if (mIns[j].ChangesZeroPage(mIns[at].mAddress) || mIns[j].ChangesZeroPage(mIns[at].mAddress + 1)) + return false; + if (mIns[j].ChangesGlobalMemory()) + return false; + + j++; + } + + return false; +} + bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at) { int j = at - 1; @@ -11552,6 +11589,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif +#if 1 + // move load (),y store zp down to potential user + for (int i = 2; i + 2 < mIns.Size(); i++) + { + if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) + { + if (MoveIndirectLoadStoreDown(i)) + changed = true; + } + } + +#endif + #if 1 // move load - store abs up to initial store // diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index e31788f..1d09850 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -201,6 +201,8 @@ public: bool MoveLoadStoreXUp(int at); bool MoveLoadImmStoreAbsoluteUp(int at); + bool MoveIndirectLoadStoreDown(int at); + bool MoveIndirectLoadStoreUp(int at); bool MoveAbsoluteLoadStoreUp(int at); bool MoveLoadStoreOutOfXYRangeUp(int at);