Optimizations for global variables

This commit is contained in:
drmortalwombat 2022-05-07 14:03:56 +02:00
parent fa223b90ad
commit 29bd0c8d2d
11 changed files with 719 additions and 61 deletions

View File

@ -24,6 +24,9 @@ rem @echo off
@call :test strcmptest2.c @call :test strcmptest2.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test memmovetest.c
@if %errorlevel% neq 0 goto :error
@call :test arraytest.c @call :test arraytest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error

49
autotest/memmovetest.c Normal file
View File

@ -0,0 +1,49 @@
#include <string.h>
#include <assert.h>
#include <stdio.h>
unsigned b[4096];
void testfwd(unsigned sz)
{
for(unsigned i=0; i<4096; i++)
b[i] = i;
memmove(b + 100, b + 101, 2 * sz);
for(unsigned i=0; i<100; i++)
assert(b[i] == i);
for(unsigned i=100; i<100 + sz; i++)
assert(b[i] == i + 1);
for(unsigned i=100 + sz; i<4096; i++)
assert(b[i] == i);
}
void testback(unsigned sz)
{
for(unsigned i=0; i<4096; i++)
b[i] = i;
memmove(b + 101, b + 100, 2 * sz);
for(unsigned i=0; i<101; i++)
assert(b[i] == i);
for(unsigned i=101; i<101 + sz; i++)
assert(b[i] == i - 1);
for(unsigned i=101 + sz; i<4096; i++)
assert(b[i] == i);
}
int main(void)
{
for(unsigned i=1; i<2048; i *= 2)
{
testfwd(i - 1);
testfwd(i);
testback(i);
testback(i - 1);
}
return 0;
}

View File

@ -218,20 +218,26 @@ void * memcpy(void * dst, const void * src, int size)
#pragma native(memcpy) #pragma native(memcpy)
void * memmove(void * dst, const void * src, int size) void * memmove(void * dst, const void * src, int size)
{ {
char * d = dst, * s = src; int sz = size;
if (d < s) if (sz > 0)
{ {
while (size--) char * d = dst, * s = src;
*d++ = *s++; if (d < s)
{
do {
*d++ = *s++;
} while (--sz);
}
else if (d > s)
{
d += sz;
s += sz;
do {
*--d = *--s;
} while (--sz);
}
} }
else if (d > s)
{
d += size;
s += size;
while (size--)
*--d = *--s;
}
return dst; return dst;
} }

View File

@ -2308,6 +2308,20 @@ bool InterOperand::IsUnsigned(void) const
} }
void InterOperand::ForwardMem(const InterOperand& op)
{
mIntConst = op.mIntConst;
mFloatConst = op.mFloatConst;
mVarIndex = op.mVarIndex;
mOperandSize = op.mOperandSize;
mLinkerObject = op.mLinkerObject;
mMemory = op.mMemory;
mTemp = op.mTemp;
mType = op.mType;
mRange = op.mRange;
mFinal = false;
}
void InterOperand::Forward(const InterOperand& op) void InterOperand::Forward(const InterOperand& op)
{ {
mTemp = op.mTemp; mTemp = op.mTemp;
@ -3066,7 +3080,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
case IC_LOAD: case IC_LOAD:
if (mSrc[0].mMemory == IM_LOCAL && mSrc[0].mTemp < 0) if (mSrc[0].mMemory == IM_LOCAL && mSrc[0].mTemp < 0)
{ {
if (localTypes[mSrc[0].mVarIndex] == IT_NONE || localTypes[mSrc[0].mVarIndex] == mDst.mType) if ((localTypes[mSrc[0].mVarIndex] == IT_NONE || localTypes[mSrc[0].mVarIndex] == mDst.mType) && mSrc[0].mIntConst == 0)
{ {
localTypes[mSrc[0].mVarIndex] = mDst.mType; localTypes[mSrc[0].mVarIndex] = mDst.mType;
simpleLocals += mSrc[0].mVarIndex; simpleLocals += mSrc[0].mVarIndex;
@ -3076,7 +3090,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
} }
else if ((mSrc[0].mMemory == IM_PARAM || mSrc[0].mMemory == IM_FPARAM) && mSrc[0].mTemp < 0) else if ((mSrc[0].mMemory == IM_PARAM || mSrc[0].mMemory == IM_FPARAM) && mSrc[0].mTemp < 0)
{ {
if (paramTypes[mSrc[0].mVarIndex] == IT_NONE || paramTypes[mSrc[0].mVarIndex] == mDst.mType) if ((paramTypes[mSrc[0].mVarIndex] == IT_NONE || paramTypes[mSrc[0].mVarIndex] == mDst.mType) && mSrc[0].mIntConst == 0)
{ {
paramTypes[mSrc[0].mVarIndex] = mDst.mType; paramTypes[mSrc[0].mVarIndex] = mDst.mType;
simpleParams += mSrc[0].mVarIndex; simpleParams += mSrc[0].mVarIndex;
@ -3088,7 +3102,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
case IC_STORE: case IC_STORE:
if (mSrc[1].mMemory == IM_LOCAL && mSrc[1].mTemp < 0) if (mSrc[1].mMemory == IM_LOCAL && mSrc[1].mTemp < 0)
{ {
if (localTypes[mSrc[1].mVarIndex] == IT_NONE || localTypes[mSrc[1].mVarIndex] == mSrc[0].mType) if ((localTypes[mSrc[1].mVarIndex] == IT_NONE || localTypes[mSrc[1].mVarIndex] == mSrc[0].mType) && mSrc[1].mIntConst == 0)
{ {
localTypes[mSrc[1].mVarIndex] = mSrc[0].mType; localTypes[mSrc[1].mVarIndex] = mSrc[0].mType;
simpleLocals += mSrc[1].mVarIndex; simpleLocals += mSrc[1].mVarIndex;
@ -3098,7 +3112,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum
} }
else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0) else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0)
{ {
if (paramTypes[mSrc[1].mVarIndex] == IT_NONE || paramTypes[mSrc[1].mVarIndex] == mSrc[0].mType) if ((paramTypes[mSrc[1].mVarIndex] == IT_NONE || paramTypes[mSrc[1].mVarIndex] == mSrc[0].mType) && mSrc[1].mIntConst == 0)
{ {
paramTypes[mSrc[1].mVarIndex] = mSrc[0].mType; paramTypes[mSrc[1].mVarIndex] = mSrc[0].mType;
simpleParams += mSrc[1].mVarIndex; simpleParams += mSrc[1].mVarIndex;
@ -4779,6 +4793,29 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
} }
#endif #endif
if (sz >= 1 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mTemp < 0)
{
InterInstruction* bins = mInstructions[sz - 1];
if (bins->mSrc[0].mIntConst)
{
mFalseJump->mNumEntries--;
mFalseJump = nullptr;
bins->mCode = IC_JUMP;
bins->mSrc[0].mTemp = -1;
bins->mNumOperands = 0;
}
else
{
mTrueJump->mNumEntries--;
mTrueJump = mFalseJump;
mFalseJump = nullptr;
bins->mCode = IC_JUMP;
bins->mSrc[0].mTemp = -1;
bins->mNumOperands = 0;
}
}
if (sz >= 2 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_CONSTANT && mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp) if (sz >= 2 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_CONSTANT && mInstructions[sz - 2]->mDst.mTemp == mInstructions[sz - 1]->mSrc[0].mTemp)
{ {
InterInstruction* bins = mInstructions[sz - 1]; InterInstruction* bins = mInstructions[sz - 1];
@ -4801,6 +4838,7 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
bins->mNumOperands = 0; bins->mNumOperands = 0;
} }
} }
#if 1 #if 1
for (int i = 0; i < sz; i++) for (int i = 0; i < sz; i++)
@ -5572,6 +5610,24 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
mTrueValueRange = mLocalValueRange; mTrueValueRange = mLocalValueRange;
mFalseValueRange = mLocalValueRange; mFalseValueRange = mLocalValueRange;
if (sz >= 1)
{
if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mTemp >= 0 && mInstructions[sz - 1]->mSrc[0].mType == IT_BOOL)
{
int s = mInstructions[sz - 1]->mSrc[0].mTemp;
mTrueValueRange[s].mMinState = IntegerValueRange::S_BOUND;
mTrueValueRange[s].mMinValue = 1;
mTrueValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
mTrueValueRange[s].mMaxValue = 1;
mFalseValueRange[s].mMinState = IntegerValueRange::S_BOUND;
mFalseValueRange[s].mMinValue = 0;
mFalseValueRange[s].mMaxState = IntegerValueRange::S_BOUND;
mFalseValueRange[s].mMaxValue = 0;
}
}
if (sz >= 2) if (sz >= 2)
{ {
if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR && if (mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 2]->mCode == IC_RELATIONAL_OPERATOR &&
@ -5699,11 +5755,15 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
} }
break; break;
case IA_CMPGU: case IA_CMPGU:
if (s0 < 0) if (s1 >= 0)
{ {
mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1); mTrueValueRange[s1].LimitMin(1);
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst); if (s0 < 0)
mFalseValueRange[s1].LimitMin(0); {
mTrueValueRange[s1].LimitMin(mInstructions[sz - 2]->mSrc[0].mIntConst + 1);
mFalseValueRange[s1].LimitMax(mInstructions[sz - 2]->mSrc[0].mIntConst);
mFalseValueRange[s1].LimitMin(0);
}
} }
break; break;
case IA_CMPGEU: case IA_CMPGEU:
@ -6595,6 +6655,18 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
} }
#endif #endif
} }
else if (ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].mTemp < 0 && ltvalue[ins->mSrc[1].mTemp])
{
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
if (pins->mCode == IC_LEA && pins->mSrc[1].mTemp < 0)
{
ins->mSrc[1].ForwardMem(pins->mSrc[1]);
ins->mSrc[1].mIntConst += ins->mSrc[0].mIntConst;
ins->mSrc[0].Forward(pins->mSrc[0]);
changed = true;
}
}
break; break;
} }
@ -7089,8 +7161,10 @@ static int Find(GrowingIntArray& table, int i)
return j; return j;
} }
void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue) bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue)
{ {
bool changed = false;
if (!mVisited) if (!mVisited)
{ {
if (!mLoopHead) if (!mLoopHead)
@ -7108,17 +7182,19 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
mLoadStoreInstructions.Remove(i); mLoadStoreInstructions.Remove(i);
else else
i++; i++;
} }
} }
mNumEntered++; mNumEntered++;
if (mNumEntered < mNumEntries) if (mNumEntered < mNumEntries)
{ {
return; return false;
} }
} }
} }
else
mLoadStoreInstructions.SetSize(0);
mVisited = true; mVisited = true;
@ -7144,6 +7220,7 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst; ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1; ins->mNumOperands = 1;
changed = true;
} }
else if (lins->mCode == IC_STORE) else if (lins->mCode == IC_STORE)
{ {
@ -7151,12 +7228,14 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
{ {
ins->mCode = IC_CONSTANT; ins->mCode = IC_CONSTANT;
ins->mConst = lins->mSrc[0]; ins->mConst = lins->mSrc[0];
changed = true;
} }
else else
{ {
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mSrc[0]; ins->mSrc[0] = lins->mSrc[0];
ins->mNumOperands = 1; ins->mNumOperands = 1;
changed = true;
} }
} }
} }
@ -7175,9 +7254,11 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
{ {
ins->mCode = IC_NONE; ins->mCode = IC_NONE;
ins->mNumOperands = 0; ins->mNumOperands = 0;
changed = true;
} }
else else
{ {
j = 0;
while (j < mLoadStoreInstructions.Size()) while (j < mLoadStoreInstructions.Size())
{ {
if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j])) if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j]))
@ -7203,6 +7284,7 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst; ins->mSrc[0] = lins->mDst;
ins->mNumOperands = 1; ins->mNumOperands = 1;
changed = true;
} }
else else
nins = ins; nins = ins;
@ -7236,9 +7318,13 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
mLoadStoreInstructions.Push(nins); mLoadStoreInstructions.Push(nins);
} }
if (mTrueJump) mTrueJump->LoadStoreForwarding(mLoadStoreInstructions); if (mTrueJump && mTrueJump->LoadStoreForwarding(mLoadStoreInstructions))
if (mFalseJump) mFalseJump->LoadStoreForwarding(mLoadStoreInstructions); changed = true;
if (mFalseJump && mFalseJump->LoadStoreForwarding(mLoadStoreInstructions))
changed = true;
} }
return changed;
} }
@ -10598,17 +10684,20 @@ void InterCodeProcedure::Close(void)
DisassembleDebug("Copy forwarding"); DisassembleDebug("Copy forwarding");
do {
GrowingInstructionPtrArray gipa(nullptr);
ResetVisited();
changed = mEntryBlock->LoadStoreForwarding(gipa);
GrowingInstructionPtrArray gipa(nullptr); DisassembleDebug("Load/Store forwardingX");
ResetVisited();
mEntryBlock->LoadStoreForwarding(gipa);
DisassembleDebug("Load/Store forwardingX"); RemoveUnusedStoreInstructions(paramMemory);
TempForwarding(); TempForwarding();
RemoveUnusedInstructions(); RemoveUnusedInstructions();
DisassembleDebug("Load/Store forwarding"); DisassembleDebug("Load/Store forwarding");
} while (changed);
FastNumberSet activeSet(numTemps); FastNumberSet activeSet(numTemps);

View File

@ -253,6 +253,7 @@ public:
IntegerValueRange mRange; IntegerValueRange mRange;
void Forward(const InterOperand& op); void Forward(const InterOperand& op);
void ForwardMem(const InterOperand& op);
InterOperand(void); InterOperand(void);
@ -408,7 +409,7 @@ public:
GrowingIntArray mEntryRenameTable; GrowingIntArray mEntryRenameTable;
GrowingIntArray mExitRenameTable; GrowingIntArray mExitRenameTable;
void LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue); bool LoadStoreForwarding(const GrowingInstructionPtrArray& tvalue);
void LocalRenameRegister(const GrowingIntArray& renameTable, int& num); void LocalRenameRegister(const GrowingIntArray& renameTable, int& num);
void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable);

View File

@ -1047,7 +1047,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else else
{ {
if (vl.mType->mType == DT_TYPE_POINTER && (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)) if (vl.mType->mType == DT_TYPE_POINTER && (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION))
{
vr = Dereference(proc, block, vr, 1); vr = Dereference(proc, block, vr, 1);
vr.mReference = 0;
vr.mType = vl.mType;
}
else else
vr = Dereference(proc, block, vr); vr = Dereference(proc, block, vr);

View File

@ -958,6 +958,11 @@ bool NativeCodeInstruction::ChangesAddress(void) const
return false; return false;
} }
bool NativeCodeInstruction::IsSimpleJSR(void) const
{
return mType == ASMIT_JSR && mMode == ASMIM_ABSOLUTE && !(mLinkerObject && (mLinkerObject->mFlags & LOBJF_INLINE));
}
bool NativeCodeInstruction::IsShift(void) const bool NativeCodeInstruction::IsShift(void) const
{ {
return mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR; return mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR;
@ -1087,6 +1092,28 @@ bool NativeCodeInstruction::MayBeChangedOnAddress(const NativeCodeInstruction& i
return false; return false;
} }
bool NativeCodeInstruction::UsesMemoryOf(const NativeCodeInstruction& ins) const
{
if (ins.mMode == ASMIM_ZERO_PAGE)
return UsesZeroPage(ins.mAddress);
else if (UsesAddress())
{
if (ins.mMode == ASMIM_ABSOLUTE && mMode == ASMIM_ABSOLUTE)
return mLinkerObject == ins.mLinkerObject && mAddress == ins.mAddress;
else if (
(ins.mMode == ASMIM_ABSOLUTE || ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) &&
(mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y))
return mLinkerObject == ins.mLinkerObject;
else if (ins.mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_INDIRECT_Y)
return true;
else
return false;
}
else
return false;
}
bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& ins) const bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& ins) const
{ {
@ -3548,8 +3575,16 @@ int NativeCodeBasicBlock::PutJump(NativeCodeProcedure* proc, NativeCodeBasicBloc
{ {
if (target->mIns.Size() == 1 && target->mIns[0].mType == ASMIT_RTS) if (target->mIns.Size() == 1 && target->mIns[0].mType == ASMIT_RTS)
{ {
PutByte(0x60); if (mIns.Size() > 0 && mIns.Last().IsSimpleJSR())
return 1; {
this->mCode[this->mCode.Size() - 3] = 0x4c;
return 0;
}
else
{
PutByte(0x60);
return 1;
}
} }
#if 1 #if 1
else if (offset >= -126 && offset <= 129) else if (offset >= -126 && offset <= 129)
@ -3601,7 +3636,12 @@ int NativeCodeBasicBlock::BranchByteSize(int from, int to)
int NativeCodeBasicBlock::JumpByteSize(NativeCodeBasicBlock* target, int offset) int NativeCodeBasicBlock::JumpByteSize(NativeCodeBasicBlock* target, int offset)
{ {
if (target->mIns.Size() == 1 && target->mIns[0].mType == ASMIT_RTS) if (target->mIns.Size() == 1 && target->mIns[0].mType == ASMIT_RTS)
return 1; {
if (mIns.Size() > 0 && mIns.Last().IsSimpleJSR())
return 0;
else
return 1;
}
#if 1 #if 1
else if (offset >= -126 && offset <= 129) else if (offset >= -126 && offset <= 129)
{ {
@ -11088,20 +11128,10 @@ bool NativeCodeBasicBlock::AlternateXYUsage(void)
} }
else if (ins.ChangesXReg()) else if (ins.ChangesXReg())
{ {
if (currXPos != -1)
{
predXEnd = start;
predXPos = currXPos;
}
currXPos = -1; currXPos = -1;
} }
else if (ins.ChangesYReg()) else if (ins.ChangesYReg())
{ {
if (currYPos != -1)
{
predYEnd = start;
predYPos = currYPos;
}
currYPos = -1; currYPos = -1;
} }
else else
@ -11129,6 +11159,77 @@ bool NativeCodeBasicBlock::AlternateXYUsage(void)
return changed; return changed;
} }
bool NativeCodeBasicBlock::Split16BitLoopCount(NativeCodeProcedure* proc)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
#if 1
int sz = mIns.Size();
if (sz >= 8 && mBranch == ASMIT_BNE)
{
if (mIns[sz - 8].mType == ASMIT_CLC &&
mIns[sz - 7].mType == ASMIT_LDA &&
mIns[sz - 6].mType == ASMIT_ADC && mIns[sz - 6].mMode == ASMIM_IMMEDIATE && mIns[sz - 6].mAddress == 0xff &&
mIns[sz - 5].mType == ASMIT_STA && mIns[sz - 5].SameEffectiveAddress(mIns[sz - 7]) &&
mIns[sz - 4].mType == ASMIT_LDA &&
mIns[sz - 3].mType == ASMIT_ADC && mIns[sz - 3].mMode == ASMIM_IMMEDIATE && mIns[sz - 3].mAddress == 0xff &&
mIns[sz - 2].mType == ASMIT_STA && mIns[sz - 2].SameEffectiveAddress(mIns[sz - 4]) &&
mIns[sz - 1].mType == ASMIT_ORA && mIns[sz - 1].SameEffectiveAddress(mIns[sz - 7]) &&
HasAsmInstructionMode(ASMIT_DEC, mIns[sz - 5].mMode) &&
HasAsmInstructionMode(ASMIT_DEC, mIns[sz - 2].mMode) &&
!(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
changed = true;
NativeCodeBasicBlock* hblock = proc->AllocateBlock();
NativeCodeBasicBlock* dblock = proc->AllocateBlock();
NativeCodeBasicBlock* zblock = proc->AllocateBlock();
zblock->mTrueJump = mTrueJump;
zblock->mFalseJump = mFalseJump;
zblock->mBranch = ASMIT_BNE;
dblock->mTrueJump = mTrueJump;
dblock->mFalseJump = zblock;
dblock->mBranch = ASMIT_BNE;
hblock->mTrueJump = dblock;
hblock->mBranch = ASMIT_JMP;
mTrueJump = dblock;
mFalseJump = hblock;
NativeCodeInstruction ilow(mIns[sz - 7]);
NativeCodeInstruction ihigh(mIns[sz - 4]);
mIns.SetSize(sz - 8);
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ilow.mMode, ilow.mAddress, ilow.mLinkerObject));
hblock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ihigh.mMode, ihigh.mAddress, ihigh.mLinkerObject));
dblock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ilow.mMode, ilow.mAddress, ilow.mLinkerObject));
zblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ihigh.mMode, ihigh.mAddress, ihigh.mLinkerObject));
}
}
#endif
if (mTrueJump && mTrueJump->Split16BitLoopCount(proc))
changed = true;
if (mFalseJump && mFalseJump->Split16BitLoopCount(proc))
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc) bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
{ {
bool changed = false; bool changed = false;
@ -11180,6 +11281,47 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
mBranch = ASMIT_BNE; mBranch = ASMIT_BNE;
break; break;
} }
if (mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0xff &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 1].SameEffectiveAddress(mIns[i + 3]) &&
mIns[i + 4].mType == ASMIT_LDA &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0xff &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 4].SameEffectiveAddress(mIns[i + 6]) &&
HasAsmInstructionMode(ASMIT_DEC, mIns[i + 3].mMode) &&
HasAsmInstructionMode(ASMIT_DEC, mIns[i + 6].mMode) &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
changed = true;
NativeCodeBasicBlock* iblock = proc->AllocateBlock();
NativeCodeBasicBlock* fblock = proc->AllocateBlock();
fblock->mTrueJump = mTrueJump;
fblock->mFalseJump = mFalseJump;
fblock->mBranch = mBranch;
fblock->mIns.Push(mIns[i + 1]);
fblock->mIns[0].mType = ASMIT_DEC;
mIns[i + 0].mType = ASMIT_NOP;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_Z;
for (int j = i + 7; j < mIns.Size(); j++)
fblock->mIns.Push(mIns[j]);
iblock->mIns.Push(mIns[i + 6]);
mIns.SetSize(i + 4);
iblock->mIns[0].mType = ASMIT_DEC;
iblock->mTrueJump = fblock;
iblock->mBranch = ASMIT_JMP;
mTrueJump = fblock;
mFalseJump = iblock;
mBranch = ASMIT_BNE;
break;
}
} }
#endif #endif
@ -11949,6 +12091,28 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::SplitMatchingTails(NativeCodeProced
return nullptr; return nullptr;
} }
NativeCodeBasicBlock* NativeCodeBasicBlock::AddDominatorBlock(NativeCodeProcedure* proc, NativeCodeBasicBlock* pblock)
{
if (pblock->mFalseJump)
{
NativeCodeBasicBlock* tblock = proc->AllocateBlock();
tblock->mBranch = ASMIT_JMP;
tblock->mTrueJump = this;
tblock->mEntryBlocks.Push(pblock);
mEntryBlocks[mEntryBlocks.IndexOf(pblock)] = tblock;
if (pblock->mTrueJump == this)
pblock->mTrueJump = tblock;
if (pblock->mFalseJump == this)
pblock->mFalseJump = tblock;
return tblock;
}
else
return pblock;
}
bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops) bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops)
{ {
bool changed = false; bool changed = false;
@ -12020,7 +12184,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
NativeCodeBasicBlock* pblock = mEntryBlocks[0], * lblock = mEntryBlocks[1]; NativeCodeBasicBlock* pblock = mEntryBlocks[0], * lblock = mEntryBlocks[1];
int ps = pblock->mIns.Size(), ls = lblock->mIns.Size(); int ps = pblock->mIns.Size(), ls = lblock->mIns.Size();
if (ps >= 2 && ls >= 2 && !pblock->mFalseJump) if (ls >= 2)
{ {
if (mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE && !(mIns[0].mLive & LIVE_CPU_REG_A)) if (mIns[0].mType == ASMIT_LDY && mIns[0].mMode == ASMIM_ZERO_PAGE && !(mIns[0].mLive & LIVE_CPU_REG_A))
{ {
@ -12030,6 +12194,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
lblock->mIns[ls - 2].mType = ASMIT_LDY; lblock->mIns[ls - 2].mLive |= LIVE_CPU_REG_Y; lblock->mIns[ls - 2].mType = ASMIT_LDY; lblock->mIns[ls - 2].mLive |= LIVE_CPU_REG_Y;
lblock->mIns[ls - 1].mType = ASMIT_CPY; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_Y; lblock->mIns[ls - 1].mType = ASMIT_CPY; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_Y;
pblock = AddDominatorBlock(proc, pblock);
pblock->mIns.Push(mIns[0]); pblock->mIns.Push(mIns[0]);
mIns.Remove(0); mIns.Remove(0);
@ -12040,6 +12206,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
{ {
lblock->mIns[ls - 1].mType = ASMIT_LDY; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_Y; lblock->mIns[ls - 1].mType = ASMIT_LDY; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_Y;
pblock = AddDominatorBlock(proc, pblock);
pblock->mIns.Push(mIns[0]); pblock->mIns.Push(mIns[0]);
mIns.Remove(0); mIns.Remove(0);
@ -12054,6 +12222,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
lblock->mIns[ls - 2].mType = ASMIT_LDX; lblock->mIns[ls - 2].mLive |= LIVE_CPU_REG_X; lblock->mIns[ls - 2].mType = ASMIT_LDX; lblock->mIns[ls - 2].mLive |= LIVE_CPU_REG_X;
lblock->mIns[ls - 1].mType = ASMIT_CPX; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_X; lblock->mIns[ls - 1].mType = ASMIT_CPX; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_X;
pblock = AddDominatorBlock(proc, pblock);
pblock->mIns.Push(mIns[0]); pblock->mIns.Push(mIns[0]);
mIns.Remove(0); mIns.Remove(0);
@ -12065,6 +12235,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
if (lblock->mIns[ls - 2].mType == ASMIT_LDA && lblock->mIns[ls - 2].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 2].mAddress == mIns[0].mAddress && if (lblock->mIns[ls - 2].mType == ASMIT_LDA && lblock->mIns[ls - 2].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 2].mAddress == mIns[0].mAddress &&
lblock->mIns[ls - 1].mType == ASMIT_CMP) lblock->mIns[ls - 1].mType == ASMIT_CMP)
{ {
pblock = AddDominatorBlock(proc, pblock);
pblock->mIns.Push(mIns[0]); pblock->mIns.Push(mIns[0]);
mIns.Remove(0); mIns.Remove(0);
@ -14611,7 +14783,7 @@ bool NativeCodeBasicBlock::MoveLoadAddImmStoreUp(int at)
if (mIns[j].ChangesZeroPage(mIns[at + 1].mAddress)) if (mIns[j].ChangesZeroPage(mIns[at + 1].mAddress))
return false; return false;
if (mIns[j].UsesZeroPage(mIns[at + 3].mAddress)) if (mIns[j].UsesMemoryOf(mIns[at + 3]))
return false; return false;
if (mIns[j].ChangesCarry()) if (mIns[j].ChangesCarry())
return false; return false;
@ -15781,6 +15953,9 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
if (!prevBlock) if (!prevBlock)
return OptimizeSimpleLoopInvariant(proc); return OptimizeSimpleLoopInvariant(proc);
for (int i = 0; i < mIns.Size(); i++)
mIns[i].mLive |= LIVE_CPU_REG_Y;
prevBlock->mIns.Push(mIns[ai]); prevBlock->mIns.Push(mIns[ai]);
mIns.Remove(ai); mIns.Remove(ai);
@ -18073,7 +18248,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 0].mType == ASMIT_CLC && mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && (mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) == 0) mIns[i + 3].mType == ASMIT_STA && (mIns[i + 3].mMode == ASMIM_ZERO_PAGE || mIns[i + 3].mMode == ASMIM_ABSOLUTE) &&
(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) == 0)
{ {
if (MoveLoadAddImmStoreUp(i)) if (MoveLoadAddImmStoreUp(i))
changed = true; changed = true;
@ -18413,31 +18589,46 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
if (mIns[i].mType == ASMIT_TXA && mIns[i + 1].mType == ASMIT_TAY) if (mIns[i].mType == ASMIT_TXA && mIns[i + 1].mType == ASMIT_TAY)
{ {
int j = i + 2; int j = i + 2, k = i, n = i;
while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg()) while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg())
{ {
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y) if (mIns[j].mMode == ASMIM_ABSOLUTE_Y)
{ {
assert(HasAsmInstructionMode(mIns[j].mType, ASMIM_ABSOLUTE_X)); assert(HasAsmInstructionMode(mIns[j].mType, ASMIM_ABSOLUTE_X));
mIns[j].mMode = ASMIM_ABSOLUTE_X; mIns[j].mMode = ASMIM_ABSOLUTE_X;
n = j;
changed = true; changed = true;
} }
j++; j++;
} }
while (k < n)
{
mIns[k].mLive |= LIVE_CPU_REG_X;
k++;
}
} }
else if (mIns[i].mType == ASMIT_TYA && mIns[i + 1].mType == ASMIT_TAX) else if (mIns[i].mType == ASMIT_TYA && mIns[i + 1].mType == ASMIT_TAX)
{ {
int j = i + 2; int j = i + 2, k = i, n = i;
while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg()) while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg())
{ {
if (mIns[j].mMode == ASMIM_ABSOLUTE_X) if (mIns[j].mMode == ASMIM_ABSOLUTE_X)
{ {
assert(HasAsmInstructionMode(mIns[j].mType, ASMIM_ABSOLUTE_Y)); assert(HasAsmInstructionMode(mIns[j].mType, ASMIM_ABSOLUTE_Y));
mIns[j].mMode = ASMIM_ABSOLUTE_Y; mIns[j].mMode = ASMIM_ABSOLUTE_Y;
n = j;
changed = true; changed = true;
} }
j++; j++;
} }
while (k < n)
{
mIns[k].mLive |= LIVE_CPU_REG_Y;
k++;
}
} }
} }
CheckLive(); CheckLive();
@ -20313,6 +20504,46 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mAddress += 2; mIns[i + 2].mAddress += 2;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 1 &&
mIns[i + 2].mType == ASMIT_TAY && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
mIns[i + 0].mType = ASMIT_TAY; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_SEC &&
mIns[i + 1].mType == ASMIT_SBC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 1 &&
mIns[i + 2].mType == ASMIT_TAY && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
mIns[i + 0].mType = ASMIT_TAY; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_DEY; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 1 &&
mIns[i + 2].mType == ASMIT_TAX && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
mIns[i + 0].mType = ASMIT_TAX; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_INX; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_SEC &&
mIns[i + 1].mType == ASMIT_SBC && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 1 &&
mIns[i + 2].mType == ASMIT_TAX && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
mIns[i + 0].mType = ASMIT_TAX; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_DEX; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
if ( if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
@ -21750,7 +21981,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
changed = true; changed = true;
} }
} }
else if (sz >= 2 &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 0 &&
mIns[sz - 1].mType == ASMIT_SBC && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0 && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
if (mBranch == ASMIT_BNE)
{
mBranch = ASMIT_BCC;
mIns.SetSize(sz - 2);
changed = true;
}
else if (mBranch == ASMIT_BEQ)
{
mBranch = ASMIT_BCS;
mIns.SetSize(sz - 2);
changed = true;
}
}
if (sz >= 1 && if (sz >= 1 &&
mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) && mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) &&
(mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE)) (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE))
@ -21997,6 +22246,16 @@ void NativeCodeBasicBlock::BuildPlacement(GrowingArray<NativeCodeBasicBlock*>& p
mFalseJump->BuildPlacement(placement); mFalseJump->BuildPlacement(placement);
mTrueJump->BuildPlacement(placement); mTrueJump->BuildPlacement(placement);
} }
else if (mTrueJump->mCode.Size() < 32 && (mTrueJump->mTrueJump && mTrueJump->mTrueJump->mPlaced) || (mTrueJump->mFalseJump && mTrueJump->mFalseJump->mPlaced))
{
mTrueJump->BuildPlacement(placement);
mFalseJump->BuildPlacement(placement);
}
else if (mFalseJump->mCode.Size() < 32 && (mFalseJump->mTrueJump && mFalseJump->mTrueJump->mPlaced) || (mFalseJump->mFalseJump && mFalseJump->mFalseJump->mPlaced))
{
mFalseJump->BuildPlacement(placement);
mTrueJump->BuildPlacement(placement);
}
else if ( else if (
!mTrueJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mTrueJump->mPlaced && mTrueJump->mCode.Size() < 120 || !mTrueJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mTrueJump->mPlaced && mTrueJump->mCode.Size() < 120 ||
mTrueJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mFalseJump->mPlaced && mTrueJump->mTrueJump->mPlaced && mTrueJump->mCode.Size() < 120) mTrueJump->mFalseJump && mTrueJump->mTrueJump && mTrueJump->mFalseJump->mPlaced && mTrueJump->mTrueJump->mPlaced && mTrueJump->mCode.Size() < 120)
@ -22116,6 +22375,8 @@ void NativeCodeBasicBlock::CopyCode(NativeCodeProcedure * proc, uint8* target)
{ {
if (mTrueJump->mPlace != mPlace + 1) if (mTrueJump->mPlace != mPlace + 1)
end += PutJump(proc, mTrueJump, mTrueJump->mOffset - end); end += PutJump(proc, mTrueJump, mTrueJump->mOffset - end);
else if (mTrueJump->mIns.Size() == 1 && mTrueJump->mIns[0].mType == ASMIT_RTS && mIns.Size() > 0 && mIns.Last().IsSimpleJSR())
this->mCode[this->mCode.Size() - 3] = 0x4c;
} }
assert(end == next); assert(end == next);
@ -22700,6 +22961,12 @@ void NativeCodeProcedure::Optimize(void)
} }
#endif #endif
if (step == 4)
{
ResetVisited();
mEntryBlock->Split16BitLoopCount(this);
}
ResetVisited(); ResetVisited();
ResetEntryBlocks(); ResetEntryBlocks();
mEntryBlock->CountEntries(nullptr); mEntryBlock->CountEntries(nullptr);
@ -23209,7 +23476,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 1]->mOperator == IA_SAR && iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 1]->mOperator == IA_SAR &&
iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal &&
iblock->mInstructions[i + 1]->mSrc[0].mTemp < 0 && iblock->mInstructions[i + 1]->mSrc[0].mIntConst <= 4 && iblock->mInstructions[i + 1]->mSrc[0].mTemp < 0 && iblock->mInstructions[i + 1]->mSrc[0].mIntConst <= 4 &&
ins->mSrc[0].mIntConst == (1 << (iblock->mInstructions[i + 1]->mSrc[0].mIntConst - 1))) ins->mSrc[0].mIntConst == (1LL << (iblock->mInstructions[i + 1]->mSrc[0].mIntConst - 1)))
{ {
block->AddAsrSignedByte(iproc, ins, iblock->mInstructions[i + 1]); block->AddAsrSignedByte(iproc, ins, iblock->mInstructions[i + 1]);
i ++; i ++;

View File

@ -111,13 +111,16 @@ public:
bool UsesZeroPage(int address) const; bool UsesZeroPage(int address) const;
bool ReferencesZeroPage(int address) const; bool ReferencesZeroPage(int address) const;
bool ChangesGlobalMemory(void) const; bool ChangesGlobalMemory(void) const;
bool UsesMemoryOf(const NativeCodeInstruction& ins) const;
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const; bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
bool MayBeChangedOnAddress(const NativeCodeInstruction& ins) const; bool MayBeChangedOnAddress(const NativeCodeInstruction& ins) const;
bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const; bool MayBeSameAddress(const NativeCodeInstruction& ins, bool sameXY = false) const;
bool IsSame(const NativeCodeInstruction& ins) const; bool IsSame(const NativeCodeInstruction& ins) const;
bool IsCommutative(void) const; bool IsCommutative(void) const;
bool IsShift(void) const; bool IsShift(void) const;
bool IsSimpleJSR(void) const;
bool ReplaceYRegWithXReg(void); bool ReplaceYRegWithXReg(void);
bool ReplaceXRegWithYReg(void); bool ReplaceXRegWithYReg(void);
@ -304,6 +307,7 @@ public:
NativeCodeBasicBlock * SplitMatchingTails(NativeCodeProcedure* proc); NativeCodeBasicBlock * SplitMatchingTails(NativeCodeProcedure* proc);
NativeCodeBasicBlock* AddDominatorBlock(NativeCodeProcedure* proc, NativeCodeBasicBlock* pblock);
bool JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops); bool JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops);
bool SameTail(const NativeCodeInstruction& ins) const; bool SameTail(const NativeCodeInstruction& ins) const;
@ -325,6 +329,7 @@ public:
bool ReduceLocalXPressure(void); bool ReduceLocalXPressure(void);
bool ExpandADCToBranch(NativeCodeProcedure* proc); bool ExpandADCToBranch(NativeCodeProcedure* proc);
bool Split16BitLoopCount(NativeCodeProcedure* proc);
bool AlternateXYUsage(void); bool AlternateXYUsage(void);
bool ForwardAbsoluteLoadStores(void); bool ForwardAbsoluteLoadStores(void);

View File

@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.6.123"); strcpy(strProductVersion, "1.6.124");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,6,123,0 FILEVERSION 1,6,124,0
PRODUCTVERSION 1,6,123,0 PRODUCTVERSION 1,6,124,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.6.123.0" VALUE "FileVersion", "1.6.124.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.6.123.0" VALUE "ProductVersion", "1.6.124.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -34,6 +34,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_03D7013B0D39A89CEA9D267005ADCE39"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_04ABABC55200450383686DD782DD1548" "MsmKey" = "8:_04ABABC55200450383686DD782DD1548"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -160,6 +166,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_326B44043E3720E0A341FB5627DA8873"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF" "MsmKey" = "8:_3277DE1463544F67B7E7390175F8A9CF"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -172,6 +184,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_36B4A1247BFCE001E1BAE7560E9CFEEA"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_379EE3C17FEC4C5EA79D07668CD05FC4" "MsmKey" = "8:_379EE3C17FEC4C5EA79D07668CD05FC4"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -244,6 +262,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_458189403F0009BC49371204B74F3BD3"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_47A877D439EE429BAB64C52FEF69EDA4" "MsmKey" = "8:_47A877D439EE429BAB64C52FEF69EDA4"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -370,6 +394,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_749A2BA18335F50EB53CCE7029861FBC"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_749F54DFBD4D404DA9C2E2D5BA7CDDBF" "MsmKey" = "8:_749F54DFBD4D404DA9C2E2D5BA7CDDBF"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -430,6 +460,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_8667075410229C38BF63AC1CC776055E"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_8827B6B07A1C4B32B08DF784E090381D" "MsmKey" = "8:_8827B6B07A1C4B32B08DF784E090381D"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -754,6 +790,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_DD5A4DD822437085CD584319732F2D4D"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_DEADBEA270134B77800770802B21859C" "MsmKey" = "8:_DEADBEA270134B77800770802B21859C"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -814,6 +856,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_EA3C0BCB01F2639DFA2E37EC8436E5F6"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_ED872D39D58443D590B7C80604BC0FF4" "MsmKey" = "8:_ED872D39D58443D590B7C80604BC0FF4"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -844,6 +892,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_F20F5618C7576D758C01D89C87469AF8"
"OwnerKey" = "8:_FB2E467BC172457785F4279BB0BFE8B6"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_F35970F9D8FA46B09F36D7E9DE5532CA" "MsmKey" = "8:_F35970F9D8FA46B09F36D7E9DE5532CA"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -1025,6 +1079,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_03D7013B0D39A89CEA9D267005ADCE39"
{
"SourcePath" = "8:VCRUNTIME140.dll"
"TargetName" = "8:VCRUNTIME140.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_04ABABC55200450383686DD782DD1548" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_04ABABC55200450383686DD782DD1548"
{ {
"SourcePath" = "8:..\\samples\\games\\lander.c" "SourcePath" = "8:..\\samples\\games\\lander.c"
@ -1445,6 +1519,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_326B44043E3720E0A341FB5627DA8873"
{
"SourcePath" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-stdio-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_3277DE1463544F67B7E7390175F8A9CF"
{ {
"SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c" "SourcePath" = "8:..\\samples\\rasterirq\\autocrawler.c"
@ -1485,6 +1579,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_36B4A1247BFCE001E1BAE7560E9CFEEA"
{
"SourcePath" = "8:api-ms-win-crt-math-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-math-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_379EE3C17FEC4C5EA79D07668CD05FC4" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_379EE3C17FEC4C5EA79D07668CD05FC4"
{ {
"SourcePath" = "8:..\\samples\\memmap\\easyflash.c" "SourcePath" = "8:..\\samples\\memmap\\easyflash.c"
@ -1725,6 +1839,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_458189403F0009BC49371204B74F3BD3"
{
"SourcePath" = "8:api-ms-win-crt-string-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-string-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_47A877D439EE429BAB64C52FEF69EDA4" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_47A877D439EE429BAB64C52FEF69EDA4"
{ {
"SourcePath" = "8:..\\samples\\memmap\\largemem.c" "SourcePath" = "8:..\\samples\\memmap\\largemem.c"
@ -2145,6 +2279,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749A2BA18335F50EB53CCE7029861FBC"
{
"SourcePath" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-runtime-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749F54DFBD4D404DA9C2E2D5BA7CDDBF" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_749F54DFBD4D404DA9C2E2D5BA7CDDBF"
{ {
"SourcePath" = "8:..\\samples\\resources\\breakoutchars.bin" "SourcePath" = "8:..\\samples\\resources\\breakoutchars.bin"
@ -2345,6 +2499,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8667075410229C38BF63AC1CC776055E"
{
"SourcePath" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-filesystem-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8827B6B07A1C4B32B08DF784E090381D" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8827B6B07A1C4B32B08DF784E090381D"
{ {
"SourcePath" = "8:..\\samples\\memmap\\tsr.c" "SourcePath" = "8:..\\samples\\memmap\\tsr.c"
@ -3425,6 +3599,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DD5A4DD822437085CD584319732F2D4D"
{
"SourcePath" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-heap-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DEADBEA270134B77800770802B21859C" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DEADBEA270134B77800770802B21859C"
{ {
"SourcePath" = "8:..\\samples\\games\\connectfour.c" "SourcePath" = "8:..\\samples\\games\\connectfour.c"
@ -3625,6 +3819,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EA3C0BCB01F2639DFA2E37EC8436E5F6"
{
"SourcePath" = "8:VERSION.dll"
"TargetName" = "8:VERSION.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ED872D39D58443D590B7C80604BC0FF4" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_ED872D39D58443D590B7C80604BC0FF4"
{ {
"SourcePath" = "8:..\\samples\\kernalio\\fileread.c" "SourcePath" = "8:..\\samples\\kernalio\\fileread.c"
@ -3725,6 +3939,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "IsolateTo" = "8:"
} }
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F20F5618C7576D758C01D89C87469AF8"
{
"SourcePath" = "8:api-ms-win-crt-locale-l1-1-0.dll"
"TargetName" = "8:api-ms-win-crt-locale-l1-1-0.dll"
"Tag" = "8:"
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
"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:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F35970F9D8FA46B09F36D7E9DE5532CA" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F35970F9D8FA46B09F36D7E9DE5532CA"
{ {
"SourcePath" = "8:..\\include\\c64\\charwin.h" "SourcePath" = "8:..\\include\\c64\\charwin.h"
@ -4101,15 +4335,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{F66E2274-2B16-49B2-950F-83A3DC2EEA9D}" "ProductCode" = "8:{F5C14785-E716-4D8A-8390-DBB8B4DEEA8D}"
"PackageCode" = "8:{4F43842C-6F90-403A-8CE1-352F775F975F}" "PackageCode" = "8:{86E78AF0-FBD2-4C41-8643-0068DA813076}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.6.123" "ProductVersion" = "8:1.6.124"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"