diff --git a/autotest/asmtest.c b/autotest/asmtest.c index 28731ac1..8dc3f3b1 100644 --- a/autotest/asmtest.c +++ b/autotest/asmtest.c @@ -1,4 +1,5 @@ #include +#include int asum(int a, int b) { @@ -30,11 +31,46 @@ int bsum(int a, int b) } } +int b, t[10]; + +int bsome(int x) +{ + return x; +} + + +int qsum(int a, int (* c)(int)) +{ + char n = 0; + b = 0; + for(int i=0; iDumpCallGraph(); mInterCodeGenerator->mCompilerOptions = mCompilerOptions; + mNativeCodeGenerator->mCompilerOptions = mCompilerOptions; mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 9ff87ec4..7920c8c5 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2334,6 +2334,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vins->mConst.mOperandSize = vdec->mSize; vins->mConst.mIntConst = vdec->mOffset; } + else if (vdec->mType == DT_VARIABLE) + { + vins->mConst.mMemory = IM_LOCAL; + vins->mConst.mVarIndex = vdec->mVarIndex; + vins->mConst.mOperandSize = vdec->mSize; + vins->mConst.mIntConst = vdec->mOffset; + } block->Append(vins); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 382a055f..7dac1737 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1,4 +1,5 @@ #include "NativeCodeGenerator.h" +#include "CompilerTypes.h" static const int CPU_REG_A = 256; static const int CPU_REG_X = 257; @@ -6791,14 +6792,17 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void) { mVisited = true; - while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this) + if (!mLocked) { - for (int i = 0; i < mTrueJump->mIns.Size(); i++) - mIns.Push(mTrueJump->mIns[i]); - mBranch = mTrueJump->mBranch; - mFalseJump = mTrueJump->mFalseJump; - mTrueJump = mTrueJump->mTrueJump; - changed = true; + while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this && !mTrueJump->mLocked) + { + for (int i = 0; i < mTrueJump->mIns.Size(); i++) + mIns.Push(mTrueJump->mIns[i]); + mBranch = mTrueJump->mBranch; + mFalseJump = mTrueJump->mFalseJump; + mTrueJump = mTrueJump->mTrueJump; + changed = true; + } } if (mTrueJump) @@ -6909,6 +6913,80 @@ bool NativeCodeBasicBlock::ApplyEntryDataSet(void) return changed; } +void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mIns.Size(); i++) + { + switch (mIns[i].mMode) + { + case ASMIM_ZERO_PAGE: + used += mIns[i].mAddress; + break; + case ASMIM_INDIRECT_Y: + used += mIns[i].mAddress + 0; + used += mIns[i].mAddress + 1; + break; + case ASMIM_ABSOLUTE: + if (mIns[i].mType == ASMIT_JSR && mIns[i].mLinkerObject) + { + LinkerObject* lo = mIns[i].mLinkerObject; + + for (int i = 0; i < lo->mNumTemporaries; i++) + { + for (int j = 0; j < lo->mTempSizes[i]; j++) + used += lo->mTemporaries[i] + j; + } + } + break; + } + } + + if (mTrueJump) + mTrueJump->CollectZeroPageUsage(used); + if (mFalseJump) + mFalseJump->CollectZeroPageUsage(used); + } +} + +void NativeCodeBasicBlock::RemapZeroPage(const uint8* remap) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mIns.Size(); i++) + { + switch (mIns[i].mMode) + { + case ASMIM_ZERO_PAGE: + case ASMIM_INDIRECT_Y: + mIns[i].mAddress = remap[mIns[i].mAddress]; + break; + case ASMIM_ABSOLUTE: + if (mIns[i].mType == ASMIT_JSR && mIns[i].mLinkerObject) + { + LinkerObject* lo = mIns[i].mLinkerObject; + + for (int j = 0; j < lo->mNumTemporaries; j++) + { + lo->mTemporaries[j] = remap[lo->mTemporaries[j]]; + } + } + break; + } + } + + if (mTrueJump) + mTrueJump->RemapZeroPage(remap); + if (mFalseJump) + mFalseJump->RemapZeroPage(remap); + } +} + bool NativeCodeBasicBlock::SameTail(const NativeCodeInstruction& ins) const { if (mIns.Size() > 0) @@ -8765,6 +8843,7 @@ NativeCodeBasicBlock::NativeCodeBasicBlock(void) mKnownShortBranch = false; mBypassed = false; mAssembled = false; + mLocked = false; } NativeCodeBasicBlock::~NativeCodeBasicBlock(void) @@ -8783,8 +8862,62 @@ NativeCodeProcedure::~NativeCodeProcedure(void) } +void NativeCodeProcedure::CompressTemporaries(void) +{ + if (mInterProc->mTempSize > 16) + { + ResetVisited(); + + NumberSet used(256); + + mEntryBlock->CollectZeroPageUsage(used); + + uint8 remap[256]; + for (int i = 0; i < 256; i++) + remap[i] = i; + + int tpos = BC_REG_TMP_SAVED; + for (int i = 0; i < mInterProc->mTempOffset.Size(); i++) + { + bool tused = false; + + int reg = BC_REG_TMP + mInterProc->mTempOffset[i]; + if (reg >= BC_REG_TMP_SAVED) + { + int size = mInterProc->mTempSizes[i]; + + for (int j = 0; j < size; j++) + if (used[reg + j]) + tused = true; + + if (tused) + { + for (int j = 0; j < size; j++) + remap[reg + j] = tpos + j; + + mInterProc->mTempOffset[i] = tpos - BC_REG_TMP; + tpos += size; + + } + else + { + mInterProc->mTempOffset[i] = 0; + mInterProc->mTempSizes[i] = 0; + } + } + } + + ResetVisited(); + mEntryBlock->RemapZeroPage(remap); + + mInterProc->mTempSize = tpos - BC_REG_TMP; + } +} + void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { + mInterProc = proc; + int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; for (int i = 0; i < nblocks; i++) @@ -8800,122 +8933,145 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) commonFrameSize += 2; mFrameOffset = 0; - mNoFrame = (stackExpand + proc->mCommonFrameSize) < 64 && !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; - entryBlock = new NativeCodeBasicBlock(); - mBlocks.Push(entryBlock); - entryBlock->mNoFrame = mNoFrame; - entryBlock->mIndex = 0; + if (mNoFrame) + { + if (stackExpand > 0) + mFrameOffset = tempSave; + } + else + { + stackExpand += 2; + } + + if (!proc->mLeafProcedure) + { + if (mNoFrame) + mFrameOffset = commonFrameSize + tempSave; + } + + mEntryBlock = AllocateBlock(); + mEntryBlock->mLocked = true; + mBlocks.Push(mEntryBlock); + + mExitBlock = AllocateBlock(); + mExitBlock->mLocked = true; + mBlocks.Push(mExitBlock); -// generator->mByteCodeUsed[BC_NATIVE] = true; + mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]); + mEntryBlock->mBranch = ASMIT_JMP; - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea)); + // Place a temporary RTS + + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED)); + + Optimize(); + + assert(mEntryBlock->mIns.Size() == 0); + + // Remove temporary RTS + + mExitBlock->mIns.Pop(); + + CompressTemporaries(); + + tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0; + + if (!(mGenerator->mCompilerOptions & COPT_NATIVE)) + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea)); 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)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff)); + mEntryBlock->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)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); + mEntryBlock->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)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mEntryBlock->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)); - 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)); - - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, stackExpand & 0xff)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK)); if (tempSave) { - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mEntryBlock->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)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); + mEntryBlock->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)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8)); } } - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, tempSave + 2)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, tempSave + 2)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); } if (!proc->mLeafProcedure) { if (commonFrameSize > 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, commonFrameSize & 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, (commonFrameSize >> 8) & 0xff)); - entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, commonFrameSize & 0xff)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff)); + mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); } - - if (mNoFrame) - mFrameOffset = commonFrameSize + tempSave; } - entryBlock->mFrameOffset = mFrameOffset; - - tblocks[0] = entryBlock; - - exitBlock = AllocateBlock(); - mBlocks.Push(exitBlock); - if (!proc->mLeafProcedure && commonFrameSize > 0) { - 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, commonFrameSize & 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, (commonFrameSize >> 8) & 0xff)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); } if (mNoFrame) @@ -8924,63 +9080,85 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { if (tempSave) { - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave - 1)); + mExitBlock->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)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + mExitBlock->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)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mExitBlock->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)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff)); + mExitBlock->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)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); if (tempSave) { - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); - 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)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK)); + mExitBlock->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)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); + mExitBlock->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)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, stackExpand & 0xff)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (stackExpand >> 8) & 0xff)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); } - exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED)); + mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED)); + + mEntryBlock->Assemble(); - CompileInterBlock(proc, proc->mBlocks[0], entryBlock); + int total, base; + + NativeCodeBasicBlock* lentryBlock = mEntryBlock->BypassEmptyBlocks(); + + total = 0; + lentryBlock->CalculateOffset(total); + proc->mLinkerObject->mType = LOT_NATIVE_CODE; + lentryBlock->CopyCode(this, proc->mLinkerObject->AddSpace(total)); + + for (int i = 0; i < mRelocations.Size(); i++) + { + LinkerReference& rl(mRelocations[i]); + rl.mObject = proc->mLinkerObject; + if (!rl.mRefObject) + rl.mRefObject = proc->mLinkerObject; + proc->mLinkerObject->AddReference(rl); + } +} + +void NativeCodeProcedure::Optimize(void) +{ #if 1 int step = 0; @@ -8997,52 +9175,52 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mBlocks[i]->mLoopHead = false; mBlocks[i]->mFromJump = nullptr; } - entryBlock->CountEntries(nullptr); + mEntryBlock->CountEntries(nullptr); #if 1 do { BuildDataFlowSets(); ResetVisited(); - changed = entryBlock->RemoveUnusedResultInstructions(); + changed = mEntryBlock->RemoveUnusedResultInstructions(); ResetVisited(); NativeRegisterDataSet data; - if (entryBlock->ValueForwarding(data)) + if (mEntryBlock->ValueForwarding(data)) changed = true; } while (changed); #endif ResetVisited(); - if (entryBlock->PeepHoleOptimizer()) + if (mEntryBlock->PeepHoleOptimizer()) changed = true; ResetVisited(); - if (entryBlock->OptimizeSimpleLoop(this)) + if (mEntryBlock->OptimizeSimpleLoop(this)) changed = true; ResetVisited(); - if (entryBlock->MergeBasicBlocks()) + if (mEntryBlock->MergeBasicBlocks()) changed = true; ResetVisited(); for (int i = 0; i < mBlocks.Size(); i++) mBlocks[i]->mEntryBlocks.SetSize(0); - entryBlock->CollectEntryBlocks(nullptr); + mEntryBlock->CollectEntryBlocks(nullptr); if (step > 2) { ResetVisited(); - if (entryBlock->JoinTailCodeSequences()) + if (mEntryBlock->JoinTailCodeSequences()) changed = true; } #if 1 ResetVisited(); NativeRegisterDataSet data; - entryBlock->BuildEntryDataSet(data); + mEntryBlock->BuildEntryDataSet(data); ResetVisited(); - if (entryBlock->ApplyEntryDataSet()) + if (mEntryBlock->ApplyEntryDataSet()) changed = true; #endif if (!changed && step < 4) @@ -9053,27 +9231,6 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) } while (changed); #endif - - entryBlock->Assemble(); - - int total, base; - - NativeCodeBasicBlock* lentryBlock = entryBlock->BypassEmptyBlocks(); - - total = 0; - lentryBlock->CalculateOffset(total); - - proc->mLinkerObject->mType = LOT_NATIVE_CODE; - lentryBlock->CopyCode(this, proc->mLinkerObject->AddSpace(total)); - - for (int i = 0; i < mRelocations.Size(); i++) - { - LinkerReference& rl(mRelocations[i]); - rl.mObject = proc->mLinkerObject; - if (!rl.mRefObject) - rl.mRefObject = proc->mLinkerObject; - proc->mLinkerObject->AddReference(rl); - } } void NativeCodeProcedure::BuildDataFlowSets(void) @@ -9397,12 +9554,12 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode } } - block->Close(exitBlock, nullptr, ASMIT_JMP); + block->Close(mExitBlock, nullptr, ASMIT_JMP); return; } case IC_RETURN: - block->Close(exitBlock, nullptr, ASMIT_JMP); + block->Close(mExitBlock, nullptr, ASMIT_JMP); return; case IC_TYPECAST: @@ -9443,7 +9600,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode NativeCodeGenerator::NativeCodeGenerator(Errors* errors, Linker* linker) - : mErrors(errors), mLinker(linker), mRuntime({ 0 }) + : mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT), mRuntime({ 0 }) { } diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index d8e8901f..6adcd34f 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -105,7 +105,7 @@ class NativeCodeBasicBlock GrowingArray mEntryBlocks; int mOffset, mSize, mNumEntries, mNumEntered, mFrameOffset; - bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting; + bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked; NativeRegisterDataSet mDataSet, mNDataSet; @@ -183,6 +183,9 @@ class NativeCodeBasicBlock void BuildEntryDataSet(const NativeRegisterDataSet& set); bool ApplyEntryDataSet(void); + + void CollectZeroPageUsage(NumberSet& used); + void RemapZeroPage(const uint8* remap); }; class NativeCodeProcedure @@ -191,11 +194,13 @@ class NativeCodeProcedure NativeCodeProcedure(NativeCodeGenerator* generator); ~NativeCodeProcedure(void); - NativeCodeBasicBlock* entryBlock, * exitBlock; + NativeCodeBasicBlock* mEntryBlock, * mExitBlock; NativeCodeBasicBlock** tblocks; NativeCodeGenerator* mGenerator; + InterCodeProcedure* mInterProc; + int mProgStart, mProgSize, mIndex, mFrameOffset; bool mNoFrame; int mTempBlocks; @@ -204,12 +209,15 @@ class NativeCodeProcedure GrowingArray < NativeCodeBasicBlock*> mBlocks; void Compile(InterCodeProcedure* proc); + void Optimize(void); + NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block); NativeCodeBasicBlock* AllocateBlock(void); - NativeCodeBasicBlock* TransientBlock(void); void CompileInterBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* iblock, NativeCodeBasicBlock*block); + void CompressTemporaries(void); + void BuildDataFlowSets(void); void ResetVisited(void); @@ -223,6 +231,8 @@ class NativeCodeGenerator void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset); + uint64 mCompilerOptions; + struct Runtime { const Ident * mIdent; diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 8d422291..e11a3dad 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -75,7 +75,7 @@ int main(int argc, const char** argv) DWORD length = ::GetModuleFileNameA(NULL, basePath, sizeof(basePath)); #else - printf("Starting oscar64 1.1.42\n"); + printf("Starting oscar64 1.1.43\n"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 9e7806ff..cb6a1ca2 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,1,42,0 - PRODUCTVERSION 1,1,42,0 + FILEVERSION 1,1,43,0 + PRODUCTVERSION 1,1,43,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.1.42.0" + VALUE "FileVersion", "1.1.43.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.1.42.0" + VALUE "ProductVersion", "1.1.43.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 679fda89..e6e8cb1d 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -28,6 +28,12 @@ } "Entry" { + "MsmKey" = "8:_1F88FA4F35F043B3ABFCB552FCEA5CDD" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_216D2A5FECF74C96A4964A74DFEB8552" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -106,6 +112,12 @@ } "Entry" { + "MsmKey" = "8:_A566398810C1458E8E063A81FA88D46F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_B4265CBF352343D2867DBCCE67D9F493" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -118,6 +130,12 @@ } "Entry" { + "MsmKey" = "8:_C72E9CB8EC154F9BA499FAC968B83A93" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_D0E45B48D76B4407B0BDE4378C1DB2C7" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -303,6 +321,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1F88FA4F35F043B3ABFCB552FCEA5CDD" + { + "SourcePath" = "8:..\\include\\c64\\rasterirq.c" + "TargetName" = "8:rasterirq.c" + "Tag" = "8:" + "Folder" = "8:_247D4CAD3CB843B3A8A4DC2D90F47C28" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_216D2A5FECF74C96A4964A74DFEB8552" { "SourcePath" = "8:..\\include\\stdbool.h" @@ -563,6 +601,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_A566398810C1458E8E063A81FA88D46F" + { + "SourcePath" = "8:..\\include\\stddef.h" + "TargetName" = "8:stddef.h" + "Tag" = "8:" + "Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_B4265CBF352343D2867DBCCE67D9F493" { "SourcePath" = "8:..\\include\\c64\\joystick.c" @@ -603,6 +661,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C72E9CB8EC154F9BA499FAC968B83A93" + { + "SourcePath" = "8:..\\include\\c64\\rasterirq.h" + "TargetName" = "8:rasterirq.h" + "Tag" = "8:" + "Folder" = "8:_247D4CAD3CB843B3A8A4DC2D90F47C28" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D0E45B48D76B4407B0BDE4378C1DB2C7" { "SourcePath" = "8:..\\include\\stdlib.h" @@ -872,15 +950,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{BE34D2A8-161C-4DA2-972D-BBF520134E2C}" - "PackageCode" = "8:{B497440C-3E40-4996-868C-98739B7F7C7B}" + "ProductCode" = "8:{9CDBFF70-1B69-46D4-AF9A-421A9A0A39A3}" + "PackageCode" = "8:{5E5D8444-E4D7-49D3-B597-D5F498EC44BE}" "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.1.42" + "ProductVersion" = "8:1.1.43" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:"