diff --git a/include/gfx/mcbitmap.c b/include/gfx/mcbitmap.c index 90f3092..4e90a2e 100644 --- a/include/gfx/mcbitmap.c +++ b/include/gfx/mcbitmap.c @@ -456,7 +456,7 @@ static void mbuildline(char ly, char lx, int dx, int dy, int stride, bool left, ip += asm_np(BLIT_CODE + ip, ASM_RTS); } -#pragma native(buildline) +#pragma native(mbuildline) static inline void mcallline(byte * dst, byte bit, int m, char lh) { diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 8f89749..400648d 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2845,7 +2845,7 @@ void InterInstruction::Disassemble(FILE* file) InterCodeBasicBlock::InterCodeBasicBlock(void) : mInstructions(nullptr), mEntryRenameTable(-1), mExitRenameTable(-1), mMergeTValues(nullptr), mTrueJump(nullptr), mFalseJump(nullptr), mLoopPrefix(nullptr), - mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr) + mEntryValueRange(IntegerValueRange()), mTrueValueRange(IntegerValueRange()), mFalseValueRange(IntegerValueRange()), mLocalValueRange(IntegerValueRange()), mEntryBlocks(nullptr), mLoadStoreInstructions(nullptr) { mInPath = false; mLoopHead = false; @@ -4575,8 +4575,6 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void) void InterCodeBasicBlock::RestartLocalIntegerRangeSets(void) { - int i; - if (!mVisited) { mVisited = true; @@ -4599,8 +4597,6 @@ void InterCodeBasicBlock::RestartLocalIntegerRangeSets(void) void InterCodeBasicBlock::BuildLocalIntegerRangeSets(int num) { - int i; - if (!mVisited) { mVisited = true; @@ -4708,9 +4704,6 @@ static bool SameSingleAssignment(const GrowingInstructionPtrArray& tunified, con bool InterCodeBasicBlock::SingleAssignmentTempForwarding(const GrowingInstructionPtrArray& tunified, const GrowingInstructionPtrArray& tvalues) { -#if 0 - return false; -#else bool changed = false; if (!mVisited) @@ -4758,7 +4751,6 @@ bool InterCodeBasicBlock::SingleAssignmentTempForwarding(const GrowingInstructio } return changed; -#endif } bool InterCodeBasicBlock::CalculateSingleAssignmentTemps(FastNumberSet& tassigned, GrowingInstructionPtrArray& tvalue, NumberSet& modifiedParams, InterMemory paramMemory) @@ -5039,7 +5031,6 @@ void InterCodeBasicBlock::BuildGlobalProvidedStaticVariableSet(const GrowingVari bool InterCodeBasicBlock::BuildGlobalRequiredStaticVariableSet(const GrowingVariableArray& staticVars, NumberSet& fromRequiredVars) { bool revisit = false; - int i; if (!mVisited) { @@ -5616,6 +5607,187 @@ static int Find(GrowingIntArray& table, int i) return j; } +static bool MatchingMem(const InterOperand& op1, const InterOperand& op2) +{ + if (op1.mMemory != op2.mMemory) + return false; + + switch (op1.mMemory) + { + case IM_LOCAL: + case IM_FPARAM: + case IM_PARAM: + return op1.mVarIndex == op2.mVarIndex; + case IM_ABSOLUTE: + return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize; + case IM_GLOBAL: + if (op1.mLinkerObject == op2.mLinkerObject) + return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize; + else + return false; + default: + return false; + } +} + +static bool MatchingMem(const InterOperand& op, const InterInstruction * ins) +{ + if (ins->mCode == IC_LOAD) + return MatchingMem(op, ins->mSrc[0]); + else if (ins->mCode == IC_STORE) + return MatchingMem(op, ins->mSrc[1]); + else + return false; +} + +static bool SameMem(const InterOperand& op1, const InterOperand& op2) +{ + if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst) + return false; + + switch (op1.mMemory) + { + case IM_LOCAL: + case IM_FPARAM: + case IM_PARAM: + return op1.mVarIndex == op2.mVarIndex; + case IM_ABSOLUTE: + return true; + case IM_GLOBAL: + return op1.mLinkerObject == op2.mLinkerObject; + default: + return false; + } +} + +static bool SameMem(const InterOperand& op, const InterInstruction* ins) +{ + if (ins->mCode == IC_LOAD) + return SameMem(op, ins->mSrc[0]); + else if (ins->mCode == IC_STORE) + return SameMem(op, ins->mSrc[1]); + else + return false; +} + +void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue) +{ + if (!mVisited) + { + if (!mLoopHead) + { + if (mNumEntries > 0) + { + if (mNumEntered == 0) + mLoadStoreInstructions = tvalue; + else + { + int i = 0; + while (i < mLoadStoreInstructions.Size()) + { + if (tvalue.IndexOf(mLoadStoreInstructions[i]) == -1) + mLoadStoreInstructions.Remove(i); + else + i++; + } + } + + mNumEntered++; + + if (mNumEntered < mNumEntries) + { + return; + } + } + } + + mVisited = true; + + for (int i = 0; i < mInstructions.Size(); i++) + { + InterInstruction* ins(mInstructions[i]); + + if (ins->mDst.mTemp >= 0) + { + int j = 0, k = 0, t = ins->mDst.mTemp; + + while (j < mLoadStoreInstructions.Size()) + { + if (t != mLoadStoreInstructions[j]->mDst.mTemp && t != mLoadStoreInstructions[j]->mSrc[0].mTemp) + mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; + j++; + } + mLoadStoreInstructions.SetSize(k); + } + + if (ins->mCode == IC_LOAD) + { + if (ins->mSrc[0].mTemp < 0) + { + if (!ins->mVolatile) + { + int j = 0; + while (j < mLoadStoreInstructions.Size() && !SameMem(ins->mSrc[0], mLoadStoreInstructions[j])) + j++; + if (j < mLoadStoreInstructions.Size()) + { + InterInstruction* lins = mLoadStoreInstructions[j]; + if (lins->mCode == IC_LOAD) + { + ins->mCode = IC_LOAD_TEMPORARY; + ins->mSrc[0] = lins->mDst; + ins->mNumOperands = 1; + } + else if (lins->mCode == IC_STORE) + { + if (lins->mSrc[0].mTemp < 0) + { + ins->mCode = IC_CONSTANT; + ins->mConst = lins->mSrc[0]; + } + else + { + ins->mCode = IC_LOAD_TEMPORARY; + ins->mSrc[0] = lins->mSrc[0]; + ins->mNumOperands = 1; + } + } + } + else + mLoadStoreInstructions.Push(ins); + } + } + } + else if (ins->mCode == IC_STORE) + { + if (ins->mSrc[1].mTemp < 0) + { + if (!ins->mVolatile) + { + int j = 0; + while (j < mLoadStoreInstructions.Size() && !MatchingMem(ins->mSrc[1], mLoadStoreInstructions[j])) + j++; + if (j < mLoadStoreInstructions.Size()) + mLoadStoreInstructions[j] = ins; + else + mLoadStoreInstructions.Push(ins); + } + } + else + mLoadStoreInstructions.SetSize(0); + } + else if (ins->mCode == IC_COPY) + mLoadStoreInstructions.SetSize(0); + else if (HasSideEffect(ins->mCode)) + mLoadStoreInstructions.SetSize(0); + + } + + if (mTrueJump) mTrueJump->LoadStoreForwarding(mLoadStoreInstructions); + if (mFalseJump) mFalseJump->LoadStoreForwarding(mLoadStoreInstructions); + } +} + void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable, int& num) { @@ -8393,6 +8565,18 @@ void InterCodeProcedure::Close(void) mEntryBlock->CompactInstructions(); #endif + + GrowingInstructionPtrArray gipa(nullptr); + ResetVisited(); + mEntryBlock->LoadStoreForwarding(gipa); + + DisassembleDebug("Load/Store forwardingX"); + + TempForwarding(); + RemoveUnusedInstructions(); + + DisassembleDebug("Load/Store forwarding"); + FastNumberSet activeSet(numTemps); // diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 037c947..42bc19d 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -341,6 +341,8 @@ public: NumberSet mEntryRequiredParams, mEntryProvidedParams; NumberSet mExitRequiredParams, mExitProvidedParams; + GrowingInstructionArray mLoadStoreInstructions; + GrowingIntegerValueRangeArray mEntryValueRange, mTrueValueRange, mFalseValueRange, mLocalValueRange; GrowingArray mEntryBlocks; @@ -393,6 +395,8 @@ public: GrowingIntArray mEntryRenameTable; GrowingIntArray mExitRenameTable; + void LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue); + void LocalRenameRegister(const GrowingIntArray& renameTable, int& num); void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index a7d4570..2df76b7 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -2025,8 +2025,17 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT } else if (data.mRegs[mAddress].SameData(data.mRegs[CPU_REG_A])) { - mType = ASMIT_NOP; - mMode = ASMIM_IMPLIED; + if (mLive & LIVE_CPU_REG_Z) + { + mType = ASMIT_ORA; + mMode = ASMIM_IMMEDIATE; + mAddress = 0; + } + else + { + mType = ASMIT_NOP; + mMode = ASMIM_IMPLIED; + } changed = true; } else if (data.mRegs[mAddress].mMode == NRDM_ZERO_PAGE) diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 05dfdb2..541745e 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -959,9 +959,10 @@ Declaration* Parser::ParseDeclaration(bool variable) { Declaration* pdec; - if (mGlobals == mScope) + if (mGlobals == mScope && !(storageFlags & DTF_STATIC)) { pdec = mCompilationUnits->mScope->Insert(ndec->mIdent, ndec); + Declaration * ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec); if (ldec && ldec != pdec) mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition"); @@ -2845,6 +2846,8 @@ void Parser::ParsePragma(void) if (mScanner->mToken == TK_IDENT) { Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent); + if (!dec) + dec = mScope->Lookup(mScanner->mTokenIdent); if (dec && dec->mType == DT_CONST_FUNCTION) dec->mFlags |= DTF_NATIVE; else diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 895ea72..941339b 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.2.65"); + strcpy(strProductVersion, "1.2.66"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 2a5b1bc..0256d34 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,65,0 - PRODUCTVERSION 1,2,65,0 + FILEVERSION 1,2,66,0 + PRODUCTVERSION 1,2,66,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.2.65.0" + VALUE "FileVersion", "1.2.66.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.2.65.0" + VALUE "ProductVersion", "1.2.66.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 9ed813b..9b85ef2 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -3169,15 +3169,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{0FB2DB6E-9367-4974-9A50-08F7ACC08077}" - "PackageCode" = "8:{5D22AE55-B504-4AAB-9129-C8AAB71ECD3C}" + "ProductCode" = "8:{71F1F5C2-A7B5-46C1-8354-C7B870ADCD34}" + "PackageCode" = "8:{7F48C21E-E13E-479D-824A-5AB731A09EB1}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.2.65" + "ProductVersion" = "8:1.2.66" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/memmap/easyflash.crt b/samples/memmap/easyflash.crt index f5a11be..7e421e4 100644 Binary files a/samples/memmap/easyflash.crt and b/samples/memmap/easyflash.crt differ