Add intermediat code select operator
This commit is contained in:
parent
ba661759fb
commit
bcc59a9afb
15
README.md
15
README.md
|
@ -192,6 +192,21 @@ The character map for string and char constants can be changed with a pragma to
|
||||||
|
|
||||||
The compiler can be provided with additional information using the built in function __assume(cond). This can be useful to mark unreachable code using __assume(false) for e.g. the default of a switch statement. Another good option is to limit the value range of arguments to allow the compiler using byte operations without the need for integer promotion.
|
The compiler can be provided with additional information using the built in function __assume(cond). This can be useful to mark unreachable code using __assume(false) for e.g. the default of a switch statement. Another good option is to limit the value range of arguments to allow the compiler using byte operations without the need for integer promotion.
|
||||||
|
|
||||||
|
### Loop unrolling
|
||||||
|
|
||||||
|
Loop unrolling on 6502 is hard to decide for the compiler. Memory is usually scarce, so it only does it in realy obvious cases (and in less obbious cases for O3). On the other hand unrolling is required to get good performance in e.g. scrolling code. Therefore the compiler offers an unrolling pragma, that can be used to specifiy the amount of unrolling either as a number or "full" for complete.
|
||||||
|
|
||||||
|
The following code scrolls the screen to the left, and completely unrolls the inner vertical loop.
|
||||||
|
|
||||||
|
|
||||||
|
for(char x=0; x<39; x++)
|
||||||
|
{
|
||||||
|
#pragma unroll(full)
|
||||||
|
for(char y=0; y<25; y++)
|
||||||
|
screen[y][x] = screen[y][x + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
### Marking functions as native
|
### Marking functions as native
|
||||||
|
|
||||||
Routines can be marked to be compiled to 6502 machine code with the native pragma:
|
Routines can be marked to be compiled to 6502 machine code with the native pragma:
|
||||||
|
|
|
@ -23,6 +23,7 @@ enum ErrorID
|
||||||
EWARN_NOT_INTERRUPT_SAFE,
|
EWARN_NOT_INTERRUPT_SAFE,
|
||||||
EWARN_BOOL_SHORTCUT,
|
EWARN_BOOL_SHORTCUT,
|
||||||
EWARN_OPTIMIZER_LOCKED,
|
EWARN_OPTIMIZER_LOCKED,
|
||||||
|
EWARN_LOOP_UNROLL_IGNORED,
|
||||||
|
|
||||||
EERR_GENERIC = 3000,
|
EERR_GENERIC = 3000,
|
||||||
EERR_FILE_NOT_FOUND,
|
EERR_FILE_NOT_FOUND,
|
||||||
|
|
|
@ -2787,6 +2787,7 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
|
||||||
{
|
{
|
||||||
// previous instruction produced result, but it is not needed here
|
// previous instruction produced result, but it is not needed here
|
||||||
pre->mDst.mTemp = mDst.mTemp;
|
pre->mDst.mTemp = mDst.mTemp;
|
||||||
|
pre->mSingleAssignment = mSingleAssignment;
|
||||||
|
|
||||||
mCode = IC_NONE;
|
mCode = IC_NONE;
|
||||||
mDst.mTemp = -1;
|
mDst.mTemp = -1;
|
||||||
|
@ -3513,6 +3514,9 @@ void InterInstruction::Disassemble(FILE* file)
|
||||||
case IC_TYPECAST:
|
case IC_TYPECAST:
|
||||||
fprintf(file, "CAST");
|
fprintf(file, "CAST");
|
||||||
break;
|
break;
|
||||||
|
case IC_SELECT:
|
||||||
|
fprintf(file, "SELECT");
|
||||||
|
break;
|
||||||
case IC_CONSTANT:
|
case IC_CONSTANT:
|
||||||
fprintf(file, "CONST");
|
fprintf(file, "CONST");
|
||||||
break;
|
break;
|
||||||
|
@ -4100,6 +4104,16 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IC_SELECT:
|
||||||
|
for(int i=0; i<3; i++)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[i].mTemp >= 0 && tvalue[ins->mSrc[i].mTemp] && tvalue[ins->mSrc[i].mTemp]->mCode == IC_CONSTANT)
|
||||||
|
{
|
||||||
|
ins->mSrc[i] = tvalue[ins->mSrc[i].mTemp]->mConst;
|
||||||
|
ins->mSrc[i].mTemp = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case IC_RETURN_VALUE:
|
case IC_RETURN_VALUE:
|
||||||
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
|
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
|
||||||
{
|
{
|
||||||
|
@ -5238,6 +5252,10 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
case IC_LOAD_TEMPORARY:
|
case IC_LOAD_TEMPORARY:
|
||||||
vr = ins->mSrc[0].mRange;
|
vr = ins->mSrc[0].mRange;
|
||||||
break;
|
break;
|
||||||
|
case IC_SELECT:
|
||||||
|
vr = ins->mSrc[1].mRange;
|
||||||
|
vr.Merge(ins->mSrc[0].mRange, false, false);
|
||||||
|
break;
|
||||||
case IC_UNARY_OPERATOR:
|
case IC_UNARY_OPERATOR:
|
||||||
{
|
{
|
||||||
switch (ins->mOperator)
|
switch (ins->mOperator)
|
||||||
|
@ -6911,7 +6929,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra
|
||||||
mInstructions[j] = ins;
|
mInstructions[j] = ins;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
{
|
{
|
||||||
InterInstruction* ins = mInstructions[i];
|
InterInstruction* ins = mInstructions[i];
|
||||||
|
@ -6943,7 +6961,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bins != lins && ins->mSrc[pi].mIntConst + lins->mSrc[1].mIntConst - bins->mSrc[1].mIntConst < 252)
|
if (bins != lins && ins->mSrc[pi].mIntConst + lins->mSrc[1].mIntConst - bins->mSrc[1].mIntConst < 252 && ins->mSrc[pi].mIntConst + lins->mSrc[1].mIntConst - bins->mSrc[1].mIntConst >= 0)
|
||||||
{
|
{
|
||||||
ins->mSrc[pi].mTemp = bins->mDst.mTemp;
|
ins->mSrc[pi].mTemp = bins->mDst.mTemp;
|
||||||
ins->mSrc[pi].mIntConst += lins->mSrc[1].mIntConst - bins->mSrc[1].mIntConst;
|
ins->mSrc[pi].mIntConst += lins->mSrc[1].mIntConst - bins->mSrc[1].mIntConst;
|
||||||
|
@ -6969,6 +6987,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra
|
||||||
ltvalue[dtemp] = ins;
|
ltvalue[dtemp] = ins;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mTrueJump && mTrueJump->MergeIndexedLoadStore(ltvalue))
|
if (mTrueJump && mTrueJump->MergeIndexedLoadStore(ltvalue))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -7238,7 +7257,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
{
|
{
|
||||||
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
|
InterInstruction* pins = ltvalue[ins->mSrc[1].mTemp];
|
||||||
|
|
||||||
if (pins->mCode == IC_LEA && pins->mSrc[0].mTemp < 0)
|
if (pins->mCode == IC_LEA && pins->mSrc[0].mTemp < 0 && ins->mSrc[1].mIntConst + pins->mSrc[0].mIntConst >= 0)
|
||||||
{
|
{
|
||||||
ins->mSrc[1].Forward(pins->mSrc[1]);
|
ins->mSrc[1].Forward(pins->mSrc[1]);
|
||||||
pins->mSrc[1].mFinal = false;
|
pins->mSrc[1].mFinal = false;
|
||||||
|
@ -7254,7 +7273,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
{
|
{
|
||||||
InterInstruction* pins = ltvalue[ins->mSrc[0].mTemp];
|
InterInstruction* pins = ltvalue[ins->mSrc[0].mTemp];
|
||||||
|
|
||||||
if (pins->mCode == IC_LEA && pins->mSrc[0].mTemp < 0)
|
if (pins->mCode == IC_LEA && pins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst + pins->mSrc[0].mIntConst >= 0)
|
||||||
{
|
{
|
||||||
ins->mSrc[0].Forward(pins->mSrc[1]);
|
ins->mSrc[0].Forward(pins->mSrc[1]);
|
||||||
pins->mSrc[1].mFinal = false;
|
pins->mSrc[1].mFinal = false;
|
||||||
|
@ -8426,6 +8445,51 @@ bool InterCodeBasicBlock::ForwardDiamondMovedTemp(void)
|
||||||
{
|
{
|
||||||
if (tblock->mNumEntries == 1 && fblock->mNumEntries == 2)
|
if (tblock->mNumEntries == 1 && fblock->mNumEntries == 2)
|
||||||
{
|
{
|
||||||
|
if (tblock->mInstructions.Size() == 2 && tblock->mInstructions[0]->mCode == IC_LEA && tblock->mInstructions[0]->mSrc[0].mTemp < 0 && tblock->mInstructions[0]->mSrc[1].mTemp >= 0)
|
||||||
|
{
|
||||||
|
InterInstruction* lins = tblock->mInstructions[0];
|
||||||
|
|
||||||
|
// Single "lea temp, imm" in diamond
|
||||||
|
int i = mInstructions.Size();
|
||||||
|
while (i > 0 && mInstructions[i - 1]->mDst.mTemp != lins->mSrc[1].mTemp)
|
||||||
|
i--;
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
InterInstruction* tins = mInstructions[i];
|
||||||
|
|
||||||
|
if (mInstructions[i]->mCode == IC_LOAD_TEMPORARY)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
bool fail = false;
|
||||||
|
for (int j = i + 1; j < mInstructions.Size(); j++)
|
||||||
|
{
|
||||||
|
if (mInstructions[j]->mDst.mTemp == tins->mSrc[0].mTemp)
|
||||||
|
{
|
||||||
|
if (mInstructions[j]->mCode == IC_LEA && mInstructions[j]->mSrc[1].mTemp == tins->mSrc[0].mTemp && mInstructions[j]->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
offset += mInstructions[j]->mSrc[0].mIntConst;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fail)
|
||||||
|
{
|
||||||
|
mExitRequiredTemps += tins->mSrc[0].mTemp;
|
||||||
|
tblock->mEntryRequiredTemps += tins->mSrc[0].mTemp;
|
||||||
|
|
||||||
|
lins->mSrc[1].mTemp = tins->mSrc[0].mTemp;
|
||||||
|
lins->mSrc[0].mIntConst -= offset;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = mInstructions.Size() - 1; i >= 0; i--)
|
for (int i = mInstructions.Size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
InterInstruction* mins = mInstructions[i];
|
InterInstruction* mins = mInstructions[i];
|
||||||
|
@ -8792,6 +8856,91 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::ExpandSelect(InterCodeProcedure* proc)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < mInstructions.Size() && mInstructions[i]->mCode != IC_SELECT)
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i < mInstructions.Size())
|
||||||
|
{
|
||||||
|
InterInstruction* sins = mInstructions[i];
|
||||||
|
|
||||||
|
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
|
||||||
|
proc->Append(tblock);
|
||||||
|
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
|
||||||
|
proc->Append(fblock);
|
||||||
|
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
|
||||||
|
proc->Append(eblock);
|
||||||
|
|
||||||
|
for (int j = i + 1; j < mInstructions.Size(); j++)
|
||||||
|
eblock->mInstructions.Push(mInstructions[j]);
|
||||||
|
eblock->Close(mTrueJump, mFalseJump);
|
||||||
|
|
||||||
|
mInstructions.SetSize(i);
|
||||||
|
|
||||||
|
InterInstruction* bins = new InterInstruction();
|
||||||
|
bins->mCode = IC_BRANCH;
|
||||||
|
bins->mSrc[0] = sins->mSrc[2];
|
||||||
|
mInstructions.Push(bins);
|
||||||
|
|
||||||
|
InterInstruction* tins = new InterInstruction();
|
||||||
|
if (sins->mSrc[1].mTemp < 0)
|
||||||
|
{
|
||||||
|
tins->mCode = IC_CONSTANT;
|
||||||
|
tins->mConst = sins->mSrc[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tins->mCode = IC_LOAD_TEMPORARY;
|
||||||
|
tins->mSrc[0] = sins->mSrc[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
tins->mDst = sins->mDst;
|
||||||
|
|
||||||
|
InterInstruction* fins = new InterInstruction();
|
||||||
|
if (sins->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
fins->mCode = IC_CONSTANT;
|
||||||
|
fins->mConst = sins->mSrc[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fins->mCode = IC_LOAD_TEMPORARY;
|
||||||
|
fins->mSrc[0] = sins->mSrc[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
fins->mDst = sins->mDst;
|
||||||
|
|
||||||
|
tblock->mInstructions.Push(tins);
|
||||||
|
InterInstruction* jins = new InterInstruction();
|
||||||
|
jins->mCode = IC_JUMP;
|
||||||
|
tblock->mInstructions.Push(jins);
|
||||||
|
|
||||||
|
tblock->Close(eblock, nullptr);
|
||||||
|
|
||||||
|
fblock->mInstructions.Push(fins);
|
||||||
|
jins = new InterInstruction();
|
||||||
|
jins->mCode = IC_JUMP;
|
||||||
|
fblock->mInstructions.Push(jins);
|
||||||
|
|
||||||
|
fblock->Close(eblock, nullptr);
|
||||||
|
|
||||||
|
mTrueJump = tblock;
|
||||||
|
mFalseJump = fblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->ExpandSelect(proc);
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->ExpandSelect(proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
|
void InterCodeBasicBlock::SplitBranches(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -9893,6 +10042,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
GrowingArray<InterInstructionPtr> indexins(nullptr);
|
GrowingArray<InterInstructionPtr> indexins(nullptr);
|
||||||
|
GrowingArray<InterInstructionPtr> pindexins(nullptr);
|
||||||
|
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < mInstructions.Size(); i++)
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
@ -10028,35 +10178,60 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
}
|
}
|
||||||
else if (ins->mCode == IC_LEA && (ins->mSrc[1].mTemp < 0 || dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED) && dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED)
|
else if (ins->mCode == IC_LEA && (ins->mSrc[1].mTemp < 0 || dep[ins->mSrc[1].mTemp] == DEP_UNKNOWN || dep[ins->mSrc[1].mTemp] == DEP_DEFINED) && dep[ins->mSrc[0].mTemp] == DEP_INDEX_DERIVED)
|
||||||
{
|
{
|
||||||
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp];
|
#if 1
|
||||||
indexBase[ins->mDst.mTemp] = 0;
|
int k = 0;
|
||||||
|
while (k < pindexins.Size() && !(
|
||||||
|
ins->mSrc[0].mTemp == pindexins[k]->mSrc[0].mTemp &&
|
||||||
|
ins->mSrc[1].mTemp == pindexins[k]->mSrc[1].mTemp &&
|
||||||
|
ins->mSrc[1].mMemory == pindexins[k]->mSrc[1].mMemory &&
|
||||||
|
ins->mSrc[1].mVarIndex == pindexins[k]->mSrc[1].mVarIndex))
|
||||||
|
k++;
|
||||||
|
|
||||||
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
|
if (k < pindexins.Size() && ins->mSrc[1].mIntConst >= pindexins[k]->mSrc[1].mIntConst)
|
||||||
|
|
||||||
InterInstruction* ains = new InterInstruction();
|
|
||||||
ains->mCode = IC_LEA;
|
|
||||||
ains->mDst = ins->mDst;
|
|
||||||
ains->mSrc[1] = ins->mDst;
|
|
||||||
ains->mSrc[1].mMemory = IM_INDIRECT;
|
|
||||||
ains->mSrc[1].mIntConst = 0;
|
|
||||||
ains->mSrc[0].mType = IT_INT16;
|
|
||||||
ains->mSrc[0].mTemp = -1;
|
|
||||||
ains->mSrc[0].mIntConst = indexStep[ins->mSrc[0].mTemp];
|
|
||||||
|
|
||||||
if (tailBlock->mEntryRequiredTemps[ains->mDst.mTemp])
|
|
||||||
{
|
{
|
||||||
InterInstruction* dins = new InterInstruction();
|
ins->mSrc[0].mTemp = -1;
|
||||||
dins->mCode = IC_LEA;
|
ins->mSrc[0].mIntConst = ins->mSrc[1].mIntConst - pindexins[k]->mSrc[1].mIntConst;
|
||||||
dins->mDst = ins->mDst;
|
ins->mSrc[1].mTemp = pindexins[k]->mDst.mTemp;
|
||||||
dins->mSrc[1] = ins->mDst;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
dins->mSrc[1].mMemory = IM_INDIRECT;
|
ins->mSrc[1].mIntConst = 0;
|
||||||
dins->mSrc[1].mIntConst = 0;
|
mInstructions[j++] = ins;
|
||||||
dins->mSrc[0].mType = IT_INT16;
|
}
|
||||||
dins->mSrc[0].mTemp = -1;
|
else
|
||||||
dins->mSrc[0].mIntConst = - indexStep[ins->mSrc[0].mTemp];
|
#endif
|
||||||
tailBlock->mInstructions.Insert(0, dins);
|
{
|
||||||
|
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp];
|
||||||
|
indexBase[ins->mDst.mTemp] = 0;
|
||||||
|
|
||||||
|
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, ins);
|
||||||
|
|
||||||
|
InterInstruction* ains = new InterInstruction();
|
||||||
|
ains->mCode = IC_LEA;
|
||||||
|
ains->mDst = ins->mDst;
|
||||||
|
ains->mSrc[1] = ins->mDst;
|
||||||
|
ains->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
ains->mSrc[1].mIntConst = 0;
|
||||||
|
ains->mSrc[0].mType = IT_INT16;
|
||||||
|
ains->mSrc[0].mTemp = -1;
|
||||||
|
ains->mSrc[0].mIntConst = indexStep[ins->mSrc[0].mTemp];
|
||||||
|
|
||||||
|
if (tailBlock->mEntryRequiredTemps[ains->mDst.mTemp])
|
||||||
|
{
|
||||||
|
InterInstruction* dins = new InterInstruction();
|
||||||
|
dins->mCode = IC_LEA;
|
||||||
|
dins->mDst = ins->mDst;
|
||||||
|
dins->mSrc[1] = ins->mDst;
|
||||||
|
dins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
dins->mSrc[1].mIntConst = 0;
|
||||||
|
dins->mSrc[0].mType = IT_INT16;
|
||||||
|
dins->mSrc[0].mTemp = -1;
|
||||||
|
dins->mSrc[0].mIntConst = -indexStep[ins->mSrc[0].mTemp];
|
||||||
|
tailBlock->mInstructions.Insert(0, dins);
|
||||||
|
}
|
||||||
|
indexins.Push(ains);
|
||||||
|
|
||||||
|
if (indexStep[ins->mSrc[0].mTemp] > 1)
|
||||||
|
pindexins.Push(ins);
|
||||||
}
|
}
|
||||||
indexins.Push(ains);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ins->mDst.mTemp >= 0 && dep[ins->mDst.mTemp] == DEP_INDEX_EXTENDED)
|
else if (ins->mDst.mTemp >= 0 && dep[ins->mDst.mTemp] == DEP_INDEX_EXTENDED)
|
||||||
|
@ -10130,6 +10305,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
{
|
{
|
||||||
int dt = ins->mDst.mTemp, st = ins->mSrc[0].mTemp;
|
int dt = ins->mDst.mTemp, st = ins->mSrc[0].mTemp;
|
||||||
|
|
||||||
|
int toffset = 0;
|
||||||
int j = i + 1;
|
int j = i + 1;
|
||||||
while (j < mInstructions.Size())
|
while (j < mInstructions.Size())
|
||||||
{
|
{
|
||||||
|
@ -10140,7 +10316,12 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
else if (cins->mCode == IC_LOAD_TEMPORARY && cins->mSrc[0].mTemp == st && cins->mSrc[0].mFinal)
|
else if (cins->mCode == IC_LOAD_TEMPORARY && cins->mSrc[0].mTemp == st && cins->mSrc[0].mFinal)
|
||||||
st = cins->mDst.mTemp;
|
st = cins->mDst.mTemp;
|
||||||
else if (cins->mDst.mTemp == st)
|
else if (cins->mDst.mTemp == st)
|
||||||
break;
|
{
|
||||||
|
if (cins->mCode == IC_LEA && cins->mSrc[1].mTemp == st && cins->mSrc[0].mTemp < 0)
|
||||||
|
toffset += cins->mSrc[0].mIntConst;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -10148,6 +10329,18 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
if (j == mInstructions.Size())
|
if (j == mInstructions.Size())
|
||||||
{
|
{
|
||||||
ins->mSrc[0].mTemp = st;
|
ins->mSrc[0].mTemp = st;
|
||||||
|
if (toffset != 0)
|
||||||
|
{
|
||||||
|
if (ins->mDst.mType == IT_POINTER)
|
||||||
|
{
|
||||||
|
ins->mCode = IC_LEA;
|
||||||
|
ins->mNumOperands = 2;
|
||||||
|
ins->mSrc[1] = ins->mSrc[0];
|
||||||
|
ins->mSrc[0].mTemp = -1;
|
||||||
|
ins->mSrc[0].mType = IT_INT16;
|
||||||
|
ins->mSrc[0].mIntConst = -toffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
tailBlock->mInstructions.Insert(0, ins);
|
tailBlock->mInstructions.Insert(0, ins);
|
||||||
mInstructions.Remove(i);
|
mInstructions.Remove(i);
|
||||||
}
|
}
|
||||||
|
@ -10700,6 +10893,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
||||||
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
|
||||||
mInstructions[i + 1]->mDst.mTemp = mInstructions[i + 1]->mSrc[0].mTemp;
|
mInstructions[i + 1]->mDst.mTemp = mInstructions[i + 1]->mSrc[0].mTemp;
|
||||||
mInstructions[i + 1]->mSrc[0].mTemp = mInstructions[i + 0]->mDst.mTemp;
|
mInstructions[i + 1]->mSrc[0].mTemp = mInstructions[i + 0]->mDst.mTemp;
|
||||||
|
mInstructions[i + 0]->mSingleAssignment = mInstructions[i + 1]->mSingleAssignment;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -11293,7 +11487,7 @@ void InterCodeProcedure::DisassembleDebug(const char* name)
|
||||||
void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
|
void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
|
||||||
{
|
{
|
||||||
// Count number of entries
|
// Count number of entries
|
||||||
//
|
//
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
for (int i = 0; i < mBlocks.Size(); i++)
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -11702,6 +11896,11 @@ void InterCodeProcedure::MergeIndexedLoadStore(void)
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
} while (mEntryBlock->MergeIndexedLoadStore(silvalues));
|
} while (mEntryBlock->MergeIndexedLoadStore(silvalues));
|
||||||
|
|
||||||
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
TempForwarding();
|
||||||
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
DisassembleDebug("MergeIndexedLoadStore");
|
DisassembleDebug("MergeIndexedLoadStore");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11743,6 +11942,25 @@ void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet)
|
||||||
DisassembleDebug("SimplifyIntegerNumeric");
|
DisassembleDebug("SimplifyIntegerNumeric");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::ExpandSelect(void)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->ExpandSelect(this);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
|
mBlocks[i]->mNumEntries = 0;
|
||||||
|
mEntryBlock->CollectEntries();
|
||||||
|
|
||||||
|
ResetEntryBlocks();
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
|
||||||
|
DisassembleDebug("ExpandSelect");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::EliminateAliasValues()
|
void InterCodeProcedure::EliminateAliasValues()
|
||||||
{
|
{
|
||||||
GrowingInstructionPtrArray eivalues(nullptr);
|
GrowingInstructionPtrArray eivalues(nullptr);
|
||||||
|
@ -11970,6 +12188,12 @@ void InterCodeProcedure::Close(void)
|
||||||
#endif
|
#endif
|
||||||
CheckUsedDefinedTemps();
|
CheckUsedDefinedTemps();
|
||||||
|
|
||||||
|
ExpandSelect();
|
||||||
|
|
||||||
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
CheckUsedDefinedTemps();
|
||||||
|
|
||||||
SingleAssignmentForwarding();
|
SingleAssignmentForwarding();
|
||||||
|
|
||||||
CheckUsedDefinedTemps();
|
CheckUsedDefinedTemps();
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum InterCode
|
||||||
IC_RETURN,
|
IC_RETURN,
|
||||||
IC_ASSEMBLER,
|
IC_ASSEMBLER,
|
||||||
IC_JUMPF,
|
IC_JUMPF,
|
||||||
|
IC_SELECT,
|
||||||
IC_UNREACHABLE
|
IC_UNREACHABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -478,6 +479,8 @@ public:
|
||||||
InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc);
|
InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc);
|
||||||
void BuildLoopSuffix(InterCodeProcedure* proc);
|
void BuildLoopSuffix(InterCodeProcedure* proc);
|
||||||
|
|
||||||
|
void ExpandSelect(InterCodeProcedure* proc);
|
||||||
|
|
||||||
void SplitBranches(InterCodeProcedure* proc);
|
void SplitBranches(InterCodeProcedure* proc);
|
||||||
void FollowJumps(void);
|
void FollowJumps(void);
|
||||||
|
|
||||||
|
@ -567,6 +570,7 @@ protected:
|
||||||
void MergeIndexedLoadStore(void);
|
void MergeIndexedLoadStore(void);
|
||||||
void EliminateAliasValues();
|
void EliminateAliasValues();
|
||||||
void LoadStoreForwarding(InterMemory paramMemory);
|
void LoadStoreForwarding(InterMemory paramMemory);
|
||||||
|
void ExpandSelect(void);
|
||||||
|
|
||||||
void MergeBasicBlocks(void);
|
void MergeBasicBlocks(void);
|
||||||
void CheckUsedDefinedTemps(void);
|
void CheckUsedDefinedTemps(void);
|
||||||
|
|
|
@ -2849,112 +2849,206 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
case EX_CONDITIONAL:
|
case EX_CONDITIONAL:
|
||||||
{
|
{
|
||||||
InterInstruction * jins0 = new InterInstruction();
|
#if 1
|
||||||
jins0->mCode = IC_JUMP;
|
if ((exp->mRight->mLeft->mType == EX_CONSTANT || exp->mRight->mLeft->mType == EX_VARIABLE) &&
|
||||||
InterInstruction* jins1 = new InterInstruction();
|
(exp->mRight->mRight->mType == EX_CONSTANT || exp->mRight->mRight->mType == EX_VARIABLE))
|
||||||
jins1->mCode = IC_JUMP;
|
|
||||||
|
|
||||||
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
|
|
||||||
proc->Append(tblock);
|
|
||||||
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
|
|
||||||
proc->Append(fblock);
|
|
||||||
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
|
|
||||||
proc->Append(eblock);
|
|
||||||
|
|
||||||
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
|
|
||||||
|
|
||||||
vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper);
|
|
||||||
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper);
|
|
||||||
|
|
||||||
int ttemp;
|
|
||||||
InterType ttype, stypel, styper;
|
|
||||||
|
|
||||||
stypel = InterTypeOf(vl.mType);
|
|
||||||
styper = InterTypeOf(vr.mType);
|
|
||||||
|
|
||||||
Declaration* dtype;
|
|
||||||
if (stypel == IT_POINTER || styper == IT_POINTER)
|
|
||||||
{
|
{
|
||||||
if (vl.mType->mType == DT_TYPE_ARRAY)
|
ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
|
||||||
vl = Dereference(proc, tblock, vl, 1);
|
|
||||||
else
|
|
||||||
vl = Dereference(proc, tblock, vl);
|
|
||||||
|
|
||||||
if (vr.mType->mType == DT_TYPE_ARRAY)
|
vl = TranslateExpression(procType, proc, block, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper);
|
||||||
vr = Dereference(proc, fblock, vr, 1);
|
vr = TranslateExpression(procType, proc, block, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper);
|
||||||
else
|
|
||||||
vr = Dereference(proc, fblock, vr);
|
|
||||||
|
|
||||||
if (vl.mType->mBase->IsSubType(vr.mType->mBase))
|
vc = Dereference(proc, block, vc);
|
||||||
dtype = vr.mType;
|
vl = Dereference(proc, block, vl);
|
||||||
else if (vr.mType->mBase->IsSubType(vl.mType->mBase))
|
vr = Dereference(proc, block, vr);
|
||||||
dtype = vl.mType;
|
|
||||||
|
int ttemp;
|
||||||
|
InterType ttype, stypel, styper;
|
||||||
|
|
||||||
|
stypel = InterTypeOf(vl.mType);
|
||||||
|
styper = InterTypeOf(vr.mType);
|
||||||
|
|
||||||
|
Declaration* dtype;
|
||||||
|
if (stypel == IT_POINTER || styper == IT_POINTER)
|
||||||
|
{
|
||||||
|
if (vl.mType->mType == DT_TYPE_ARRAY)
|
||||||
|
vl = Dereference(proc, block, vl, 1);
|
||||||
|
else
|
||||||
|
vl = Dereference(proc, block, vl);
|
||||||
|
|
||||||
|
if (vr.mType->mType == DT_TYPE_ARRAY)
|
||||||
|
vr = Dereference(proc, block, vr, 1);
|
||||||
|
else
|
||||||
|
vr = Dereference(proc, block, vr);
|
||||||
|
|
||||||
|
if (vl.mType->mBase->IsSubType(vr.mType->mBase))
|
||||||
|
dtype = vr.mType;
|
||||||
|
else if (vr.mType->mBase->IsSubType(vl.mType->mBase))
|
||||||
|
dtype = vl.mType;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
|
||||||
|
dtype = vl.mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
|
||||||
|
ntype->mBase = dtype->mBase;
|
||||||
|
dtype = ntype;
|
||||||
|
|
||||||
|
ttype = IT_POINTER;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
|
|
||||||
dtype = vl.mType;
|
if (stypel == styper)
|
||||||
|
{
|
||||||
|
ttype = stypel;
|
||||||
|
dtype = vl.mType;
|
||||||
|
}
|
||||||
|
else if (stypel > styper)
|
||||||
|
{
|
||||||
|
ttype = stypel;
|
||||||
|
dtype = vl.mType;
|
||||||
|
|
||||||
|
vr = CoerceType(proc, block, vr, dtype);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ttype = styper;
|
||||||
|
dtype = vr.mType;
|
||||||
|
|
||||||
|
vl = CoerceType(proc, block, vl, dtype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
|
vc = CoerceType(proc, block, vc, TheBoolTypeDeclaration);
|
||||||
ntype->mBase = dtype->mBase;
|
|
||||||
dtype = ntype;
|
|
||||||
|
|
||||||
ttype = IT_POINTER;
|
ttemp = proc->AddTemporary(ttype);
|
||||||
|
|
||||||
|
InterInstruction* sins = new InterInstruction();
|
||||||
|
sins->mCode = IC_SELECT;
|
||||||
|
sins->mSrc[2].mType = InterTypeOf(vc.mType);
|
||||||
|
sins->mSrc[2].mTemp = vc.mTemp;
|
||||||
|
sins->mSrc[1].mType = ttype;
|
||||||
|
sins->mSrc[1].mTemp = vl.mTemp;
|
||||||
|
sins->mSrc[0].mType = ttype;
|
||||||
|
sins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
sins->mDst.mType = ttype;
|
||||||
|
sins->mDst.mTemp = ttemp;
|
||||||
|
block->Append(sins);
|
||||||
|
|
||||||
|
return ExValue(dtype, ttemp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
vl = Dereference(proc, tblock, vl);
|
InterInstruction* jins0 = new InterInstruction();
|
||||||
vr = Dereference(proc, fblock, vr);
|
jins0->mCode = IC_JUMP;
|
||||||
|
InterInstruction* jins1 = new InterInstruction();
|
||||||
|
jins1->mCode = IC_JUMP;
|
||||||
|
|
||||||
if (stypel == styper)
|
InterCodeBasicBlock* tblock = new InterCodeBasicBlock();
|
||||||
{
|
proc->Append(tblock);
|
||||||
ttype = stypel;
|
InterCodeBasicBlock* fblock = new InterCodeBasicBlock();
|
||||||
dtype = vl.mType;
|
proc->Append(fblock);
|
||||||
}
|
InterCodeBasicBlock* eblock = new InterCodeBasicBlock();
|
||||||
else if (stypel > styper)
|
proc->Append(eblock);
|
||||||
{
|
|
||||||
ttype = stypel;
|
|
||||||
dtype = vl.mType;
|
|
||||||
|
|
||||||
vr = CoerceType(proc, fblock, vr, dtype);
|
TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper);
|
||||||
|
|
||||||
|
vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper);
|
||||||
|
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
|
int ttemp;
|
||||||
|
InterType ttype, stypel, styper;
|
||||||
|
|
||||||
|
stypel = InterTypeOf(vl.mType);
|
||||||
|
styper = InterTypeOf(vr.mType);
|
||||||
|
|
||||||
|
Declaration* dtype;
|
||||||
|
if (stypel == IT_POINTER || styper == IT_POINTER)
|
||||||
|
{
|
||||||
|
if (vl.mType->mType == DT_TYPE_ARRAY)
|
||||||
|
vl = Dereference(proc, tblock, vl, 1);
|
||||||
|
else
|
||||||
|
vl = Dereference(proc, tblock, vl);
|
||||||
|
|
||||||
|
if (vr.mType->mType == DT_TYPE_ARRAY)
|
||||||
|
vr = Dereference(proc, fblock, vr, 1);
|
||||||
|
else
|
||||||
|
vr = Dereference(proc, fblock, vr);
|
||||||
|
|
||||||
|
if (vl.mType->mBase->IsSubType(vr.mType->mBase))
|
||||||
|
dtype = vr.mType;
|
||||||
|
else if (vr.mType->mBase->IsSubType(vl.mType->mBase))
|
||||||
|
dtype = vl.mType;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types");
|
||||||
|
dtype = vl.mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER);
|
||||||
|
ntype->mBase = dtype->mBase;
|
||||||
|
dtype = ntype;
|
||||||
|
|
||||||
|
ttype = IT_POINTER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ttype = styper;
|
vl = Dereference(proc, tblock, vl);
|
||||||
dtype = vr.mType;
|
vr = Dereference(proc, fblock, vr);
|
||||||
|
|
||||||
vl = CoerceType(proc, tblock, vl, dtype);
|
if (stypel == styper)
|
||||||
|
{
|
||||||
|
ttype = stypel;
|
||||||
|
dtype = vl.mType;
|
||||||
|
}
|
||||||
|
else if (stypel > styper)
|
||||||
|
{
|
||||||
|
ttype = stypel;
|
||||||
|
dtype = vl.mType;
|
||||||
|
|
||||||
|
vr = CoerceType(proc, fblock, vr, dtype);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ttype = styper;
|
||||||
|
dtype = vr.mType;
|
||||||
|
|
||||||
|
vl = CoerceType(proc, tblock, vl, dtype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ttemp = proc->AddTemporary(ttype);
|
||||||
|
|
||||||
|
InterInstruction* rins = new InterInstruction();
|
||||||
|
rins->mCode = IC_LOAD_TEMPORARY;
|
||||||
|
rins->mSrc[0].mType = ttype;
|
||||||
|
rins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
rins->mDst.mType = ttype;
|
||||||
|
rins->mDst.mTemp = ttemp;
|
||||||
|
fblock->Append(rins);
|
||||||
|
|
||||||
|
InterInstruction* lins = new InterInstruction();
|
||||||
|
lins->mCode = IC_LOAD_TEMPORARY;
|
||||||
|
lins->mSrc[0].mType = ttype;
|
||||||
|
lins->mSrc[0].mTemp = vl.mTemp;
|
||||||
|
lins->mDst.mType = ttype;
|
||||||
|
lins->mDst.mTemp = ttemp;
|
||||||
|
tblock->Append(lins);
|
||||||
|
|
||||||
|
tblock->Append(jins0);
|
||||||
|
tblock->Close(eblock, nullptr);
|
||||||
|
|
||||||
|
fblock->Append(jins1);
|
||||||
|
fblock->Close(eblock, nullptr);
|
||||||
|
|
||||||
|
block = eblock;
|
||||||
|
|
||||||
|
return ExValue(dtype, ttemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ttemp = proc->AddTemporary(ttype);
|
|
||||||
|
|
||||||
InterInstruction * rins = new InterInstruction();
|
|
||||||
rins->mCode = IC_LOAD_TEMPORARY;
|
|
||||||
rins->mSrc[0].mType = ttype;
|
|
||||||
rins->mSrc[0].mTemp = vr.mTemp;
|
|
||||||
rins->mDst.mType = ttype;
|
|
||||||
rins->mDst.mTemp = ttemp;
|
|
||||||
fblock->Append(rins);
|
|
||||||
|
|
||||||
InterInstruction * lins = new InterInstruction();
|
|
||||||
lins->mCode = IC_LOAD_TEMPORARY;
|
|
||||||
lins->mSrc[0].mType = ttype;
|
|
||||||
lins->mSrc[0].mTemp = vl.mTemp;
|
|
||||||
lins->mDst.mType = ttype;
|
|
||||||
lins->mDst.mTemp = ttemp;
|
|
||||||
tblock->Append(lins);
|
|
||||||
|
|
||||||
tblock->Append(jins0);
|
|
||||||
tblock->Close(eblock, nullptr);
|
|
||||||
|
|
||||||
fblock->Append(jins1);
|
|
||||||
fblock->Close(eblock, nullptr);
|
|
||||||
|
|
||||||
block = eblock;
|
|
||||||
|
|
||||||
return ExValue(dtype, ttemp);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11503,8 +11503,24 @@ bool NativeCodeBasicBlock::OptimizeXYPairUsage(void)
|
||||||
j++;
|
j++;
|
||||||
if (j + 1 == mIns.Size() || !(mIns[j].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Y)))
|
if (j + 1 == mIns.Size() || !(mIns[j].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Y)))
|
||||||
{
|
{
|
||||||
|
bool tox = ins.mType == ASMIT_LDY, toy = ins.mType == ASMIT_LDX;
|
||||||
for (int k = i; k <= j; k++)
|
for (int k = i; k <= j; k++)
|
||||||
mIns[k].SwapXYReg();
|
{
|
||||||
|
if (mIns[k].ChangesXReg())
|
||||||
|
tox = false;
|
||||||
|
if (mIns[k].ChangesYReg())
|
||||||
|
toy = false;
|
||||||
|
|
||||||
|
if (tox)
|
||||||
|
mIns[k].ReplaceYRegWithXReg();
|
||||||
|
else if (toy)
|
||||||
|
mIns[k].ReplaceXRegWithYReg();
|
||||||
|
else
|
||||||
|
mIns[k].SwapXYReg();
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckLive();
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11915,6 +11931,49 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
|
if (i + 4 < mIns.Size() &&
|
||||||
|
(mIns[i + 0].mType == ASMIT_CPX || mIns[i + 0].mType == ASMIT_CPY) && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0x01 &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0x00 &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0xff &&
|
||||||
|
mIns[i + 3].mType == ASMIT_AND && mIns[i + 3].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 4].mType == ASMIT_EOR && mIns[i + 4].mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
char veq = mIns[i + 3].mAddress ^ mIns[i + 4].mAddress, vne = mIns[i + 4].mAddress;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
|
||||||
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* neblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* rblock = proc->AllocateBlock();
|
||||||
|
|
||||||
|
rblock->mTrueJump = mTrueJump;
|
||||||
|
rblock->mFalseJump = mFalseJump;
|
||||||
|
rblock->mBranch = mBranch;
|
||||||
|
|
||||||
|
for (int j = i + 5; j < mIns.Size(); j++)
|
||||||
|
rblock->mIns.Push(mIns[j]);
|
||||||
|
mIns.SetSize(i + 1);
|
||||||
|
if (mIns[i + 0].mType == ASMIT_CPX)
|
||||||
|
mIns[i + 0].mType = ASMIT_TXA;
|
||||||
|
else if (mIns[i + 0].mType == ASMIT_CPY)
|
||||||
|
mIns[i + 0].mType = ASMIT_TYA;
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_Z;
|
||||||
|
|
||||||
|
mTrueJump = neblock;
|
||||||
|
mFalseJump = eblock;
|
||||||
|
mBranch = ASMIT_BNE;
|
||||||
|
|
||||||
|
if (veq != 0)
|
||||||
|
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, veq));
|
||||||
|
neblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, vne));
|
||||||
|
|
||||||
|
eblock->Close(rblock, nullptr, ASMIT_JMP);
|
||||||
|
neblock->Close(rblock, nullptr, ASMIT_JMP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (i + 4 < mIns.Size() &&
|
if (i + 4 < mIns.Size() &&
|
||||||
mIns[i + 0].ChangesAccuAndFlag() &&
|
mIns[i + 0].ChangesAccuAndFlag() &&
|
||||||
|
@ -20950,7 +21009,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
#if 1
|
#if 1
|
||||||
// replace zero page down
|
// replace zero page down
|
||||||
|
|
||||||
for (int i = 1; i + 1 < mIns.Size(); i++)
|
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && (mIns[i + 0].mLive & LIVE_MEM))
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && (mIns[i + 0].mLive & LIVE_MEM))
|
||||||
{
|
{
|
||||||
|
@ -24463,7 +24522,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
if (i + 1 < mIns.Size() && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & (LIVE_MEM | LIVE_CPU_REG_Y)))
|
if (i + 1 < mIns.Size() && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & (LIVE_MEM | LIVE_CPU_REG_Y)))
|
||||||
{
|
{
|
||||||
int apos, breg;
|
int apos, breg;
|
||||||
|
@ -24473,7 +24532,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO))
|
if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO))
|
||||||
{
|
{
|
||||||
int apos, breg;
|
int apos, breg;
|
||||||
|
@ -24483,6 +24543,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2171,7 +2171,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
|
|
||||||
conditionExp->mRight->mDecValue->mInteger = endValue;
|
conditionExp->mRight->mDecValue->mInteger = endValue;
|
||||||
|
|
||||||
Expression * unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
unrollBody->mLeft = bodyExp;
|
unrollBody->mLeft = bodyExp;
|
||||||
Expression* bexp = unrollBody;
|
Expression* bexp = unrollBody;
|
||||||
if (endValue > startValue)
|
if (endValue > startValue)
|
||||||
|
@ -2206,7 +2206,11 @@ Expression* Parser::ParseStatement(void)
|
||||||
|
|
||||||
bodyExp = unrollBody;
|
bodyExp = unrollBody;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(exp->mLocation, EWARN_LOOP_UNROLL_IGNORED, "Loop unroll ignored, bounds and step not integer");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(exp->mLocation, EWARN_LOOP_UNROLL_IGNORED, "Loop unroll ignored, bounds and step not const");
|
||||||
}
|
}
|
||||||
|
|
||||||
exp->mLeft->mRight = initExp;
|
exp->mLeft->mRight = initExp;
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.7.140");
|
strcpy(strProductVersion, "1.7.141");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,7,140,0
|
FILEVERSION 1,7,141,0
|
||||||
PRODUCTVERSION 1,7,140,0
|
PRODUCTVERSION 1,7,141,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.7.140.0"
|
VALUE "FileVersion", "1.7.141.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.7.140.0"
|
VALUE "ProductVersion", "1.7.141.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -4153,15 +4153,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{4AC1A78B-6BCA-4D2F-A54D-DEA5F627B017}"
|
"ProductCode" = "8:{AAAF5F55-0261-47DA-B051-EF84642395A5}"
|
||||||
"PackageCode" = "8:{ED70C89A-F338-434F-9FB2-90C1BD8EB020}"
|
"PackageCode" = "8:{A7501921-EE58-422B-AEE2-4491A2249AC0}"
|
||||||
"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.7.140"
|
"ProductVersion" = "8:1.7.141"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
|
@ -46,7 +46,7 @@ void expand(char c, byte f)
|
||||||
byte * fp = font + 8 * c;
|
byte * fp = font + 8 * c;
|
||||||
|
|
||||||
// Unroll eight times for each byte in glyph data
|
// Unroll eight times for each byte in glyph data
|
||||||
// #pragma unroll(full)
|
//#pragma unroll(full)
|
||||||
for(char y=0; y<8; y++)
|
for(char y=0; y<8; y++)
|
||||||
{
|
{
|
||||||
char t = (fp[y] & f) ? 160 : 32;
|
char t = (fp[y] & f) ? 160 : 32;
|
||||||
|
|
Loading…
Reference in New Issue