diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index c61a80c..404db81 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1208,6 +1208,11 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) { bool changed = false; + mFlags &= ~NCIF_YZERO; + + if ((data.mRegs[CPU_REG_Y].mMode & NRDM_IMMEDIATE) && (data.mRegs[CPU_REG_Y].mValue == 0)) + mFlags |= NCIF_YZERO; + if (mType == ASMIT_JSR) { data.mRegs[CPU_REG_C].Reset(); @@ -1226,8 +1231,32 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) return false; } + if (data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mValue == 0) + { + switch (mType) + { + case ASMIT_ROL: + mType = ASMIT_ASL; + changed = true; + break; + case ASMIT_ROR: + mType = ASMIT_LSR; + changed = true; + break; + } + } + switch (mType) { + case ASMIT_CLC: + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; + data.mRegs[CPU_REG_C].mValue = 0; + break; + case ASMIT_SEC: + data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE; + data.mRegs[CPU_REG_C].mValue = 1; + break; + case ASMIT_ROL: case ASMIT_ROR: case ASMIT_ASL: @@ -6819,6 +6848,53 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) progress = true; } #endif +#if 1 + if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO)) + { + const NativeCodeInstruction* ains; + + int apos, breg, ireg; + if (FindAddressSumY(i, mIns[i + 0].mAddress, apos, breg, ireg)) + { + if (breg != mIns[i + 0].mAddress || !(mIns[i + 0].mLive & LIVE_MEM)) + { + if (breg == mIns[i + 0].mAddress) + { + mIns[apos + 3].mType = ASMIT_NOP; + mIns[apos + 3].mMode = ASMIM_IMPLIED; + mIns[apos + 6].mType = ASMIT_NOP; + mIns[apos + 6].mMode = ASMIM_IMPLIED; + } + if (mIns[i + 0].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 1].mLive |= LIVE_CPU_REG_Y; + } + mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); + mIns[i + 1].mAddress = breg; + mIns[i + 1].mFlags &= ~NCIF_YZERO; + progress = true; + } + } + else if (FindGlobalAddressSumY(i, mIns[i + 0].mAddress, ains, ireg)) + { + if (mIns[i + 0].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 1].mLive |= LIVE_CPU_REG_Y; + } + + mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); + mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; + mIns[i + 1].mLinkerObject = ains->mLinkerObject; + mIns[i + 1].mAddress = ains->mAddress; + mIns[i + 1].mFlags &= ~NCIF_YZERO; + + progress = true; + } + } +#endif + #if 1 if (i + 1 < mIns.Size()) { @@ -6886,6 +6962,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) mIns[i + 1].mType = ASMIT_NOP; progress = true; } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].SameEffectiveAddress(mIns[i + 0])) + { + mIns[i + 1].mType = ASMIT_ROL; + mIns[i + 1].mMode = ASMIM_IMPLIED; + progress = true; + } else if ( mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress && (mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR)) @@ -6906,54 +6988,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) progress = true; } -#if 1 - if ( - mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && - mIns[i + 1].mMode == ASMIM_INDIRECT_Y) - { - const NativeCodeInstruction* ains; - - int apos, breg, ireg; - if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg)) - { - if (breg != mIns[i + 1].mAddress || !(mIns[i + 1].mLive & LIVE_MEM)) - { - if (breg == mIns[i + 1].mAddress) - { - mIns[apos + 3].mType = ASMIT_NOP; - mIns[apos + 3].mMode = ASMIM_IMPLIED; - mIns[apos + 6].mType = ASMIT_NOP; - mIns[apos + 6].mMode = ASMIM_IMPLIED; - } - if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 2].mLive |= LIVE_CPU_REG_Y; - } - mIns[i + 0].mMode = ASMIM_ZERO_PAGE; - mIns[i + 0].mAddress = ireg; - mIns[i + 1].mAddress = breg; - progress = true; - } - } - else if (FindGlobalAddressSumY(i, mIns[i + 1].mAddress, ains, ireg)) - { - if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 2].mLive |= LIVE_CPU_REG_Y; - } - - mIns[i + 0].mMode = ASMIM_ZERO_PAGE; - mIns[i + 0].mAddress = ireg; - - mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; - mIns[i + 1].mLinkerObject = ains->mLinkerObject; - mIns[i + 1].mAddress = ains->mAddress; - progress = true; - } - } -#endif } #endif @@ -7035,7 +7069,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) progress = true; } else if ( - mIns[i + 0].mType == ASMIT_LDA && + mIns[i + 0].ChangesAccuAndFlag() && mIns[i + 1].mType == ASMIT_STA && mIns[i + 2].mType == ASMIT_ORA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0) { @@ -7043,6 +7077,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) mIns[i + 1].mLive |= mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z); progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + (mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR) && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & LIVE_CPU_REG_A)) + { + mIns[i + 2].mType = mIns[i + 1].mType; + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + progress = true; + } #if 1 else if ( mIns[i + 0].mMode != ASMIM_RELATIVE && @@ -7129,6 +7173,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) mIns[i + 3].mType = ASMIT_DEC; progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_LDA && + mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress && + mIns[i + 3].mType == ASMIT_CMP && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress && !(mIns[i + 3].mLive & LIVE_MEM)) + { + mIns[i + 3].mMode = mIns[i + 0].mMode; + mIns[i + 3].mAddress = mIns[i + 0].mAddress; + mIns[i + 3].mLinkerObject = mIns[i + 0].mLinkerObject; + + progress = true; + } #if 0 if ( mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && @@ -7523,10 +7579,10 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mIndex = proc->mID; int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0; - int stackExpand = tempSave + proc->mLocalSize + 2; + int stackExpand = tempSave + proc->mLocalSize; mFrameOffset = 0; - mNoFrame = proc->mLocalSize == 0 && tempSave == 0 && !proc->mHasDynamicStack && !(proc->mHasInlineAssembler && !proc->mLeafProcedure); + mNoFrame = (stackExpand + proc->mCommonFrameSize) < 64 && !proc->mHasDynamicStack && !(proc->mHasInlineAssembler && !proc->mLeafProcedure); if (mNoFrame) proc->mLinkerObject->mFlags |= LOBJF_NO_FRAME; @@ -7540,8 +7596,37 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea)); - if (!mNoFrame) + if (mNoFrame) { + if (stackExpand > 0) + { + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + + if (tempSave) + { + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + if (tempSave > 1) + { + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8)); + } + } + + mFrameOffset = tempSave; + } + } + else + { + stackExpand += 2; + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff)); @@ -7560,12 +7645,14 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) if (tempSave) { entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED - 1)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); if (tempSave > 1) { entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -8)); + entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8)); } } @@ -7589,7 +7676,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); if (mNoFrame) - mFrameOffset = proc->mCommonFrameSize + 2; + mFrameOffset = proc->mCommonFrameSize + tempSave + 2; } entryBlock->mFrameOffset = mFrameOffset; @@ -7610,7 +7697,33 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); } - if (!mNoFrame) + if (mNoFrame) + { + if (stackExpand > 0) + { + if (tempSave) + { + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1)); + + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); + if (tempSave > 1) + { + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8)); + } + } + + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + } + } + else { exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); @@ -7624,15 +7737,13 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - if (tempSave > 1) - { - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -8)); - } exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); + if (tempSave > 1) + { + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8)); + } } exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index b328fdb..ec41f1f 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -40,6 +40,7 @@ struct NativeRegisterDataSet static const uint32 NCIF_LOWER = 0x00000001; static const uint32 NCIF_UPPER = 0x00000002; static const uint32 NCIF_RUNTIME = 0x00000004; +static const uint32 NCIF_YZERO = 0x00000008; class NativeCodeInstruction { diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 02fdf6a..06612bd 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,10 @@ int main(int argc, const char** argv) } DWORD length = ::GetModuleFileNameA(NULL, basePath, sizeof(basePath)); + #else + printf("Starting oscar64 1.0.37\n"); + #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 1b47837..b158978 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,36,0 - PRODUCTVERSION 1,0,36,0 + FILEVERSION 1,0,37,0 + PRODUCTVERSION 1,0,37,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.0.36.0" + VALUE "FileVersion", "1.0.37.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.0.36.0" + VALUE "ProductVersion", "1.0.37.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 0eef1d4..5f215b8 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -601,15 +601,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{0A2208F0-C8DE-46D7-B569-E7B22E61F4AB}" - "PackageCode" = "8:{0D2D2467-B741-440E-A623-A31ACCECE74B}" + "ProductCode" = "8:{DD6A1D1D-E6A7-4EB4-912E-725CBB8EB76F}" + "PackageCode" = "8:{5524804F-A9C3-411D-92CD-F805012EBDAE}" "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.0.36" + "ProductVersion" = "8:1.0.37" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"