Add intermediat code select operator

This commit is contained in:
drmortalwombat 2022-07-02 14:53:00 +02:00
parent ba661759fb
commit bcc59a9afb
11 changed files with 538 additions and 135 deletions

View File

@ -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.
### 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
Routines can be marked to be compiled to 6502 machine code with the native pragma:

View File

@ -23,6 +23,7 @@ enum ErrorID
EWARN_NOT_INTERRUPT_SAFE,
EWARN_BOOL_SHORTCUT,
EWARN_OPTIMIZER_LOCKED,
EWARN_LOOP_UNROLL_IGNORED,
EERR_GENERIC = 3000,
EERR_FILE_NOT_FOUND,

View File

@ -2787,6 +2787,7 @@ bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, Num
{
// previous instruction produced result, but it is not needed here
pre->mDst.mTemp = mDst.mTemp;
pre->mSingleAssignment = mSingleAssignment;
mCode = IC_NONE;
mDst.mTemp = -1;
@ -3513,6 +3514,9 @@ void InterInstruction::Disassemble(FILE* file)
case IC_TYPECAST:
fprintf(file, "CAST");
break;
case IC_SELECT:
fprintf(file, "SELECT");
break;
case IC_CONSTANT:
fprintf(file, "CONST");
break;
@ -4100,6 +4104,16 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
}
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:
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:
vr = ins->mSrc[0].mRange;
break;
case IC_SELECT:
vr = ins->mSrc[1].mRange;
vr.Merge(ins->mSrc[0].mRange, false, false);
break;
case IC_UNARY_OPERATOR:
{
switch (ins->mOperator)
@ -6911,7 +6929,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra
mInstructions[j] = ins;
}
}
#if 1
for (int i = 0; i < mInstructions.Size(); 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].mIntConst += lins->mSrc[1].mIntConst - bins->mSrc[1].mIntConst;
@ -6969,6 +6987,7 @@ bool InterCodeBasicBlock::MergeIndexedLoadStore(const GrowingInstructionPtrArra
ltvalue[dtemp] = ins;
}
}
#endif
if (mTrueJump && mTrueJump->MergeIndexedLoadStore(ltvalue))
changed = true;
@ -7238,7 +7257,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{
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]);
pins->mSrc[1].mFinal = false;
@ -7254,7 +7273,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
{
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]);
pins->mSrc[1].mFinal = false;
@ -8426,6 +8445,51 @@ bool InterCodeBasicBlock::ForwardDiamondMovedTemp(void)
{
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--)
{
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)
{
if (!mVisited)
@ -9893,6 +10042,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
} while (changed);
GrowingArray<InterInstructionPtr> indexins(nullptr);
GrowingArray<InterInstructionPtr> pindexins(nullptr);
int j = 0;
for (int i = 0; i < mInstructions.Size(); i++)
@ -10028,6 +10178,27 @@ 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)
{
#if 1
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++;
if (k < pindexins.Size() && ins->mSrc[1].mIntConst >= pindexins[k]->mSrc[1].mIntConst)
{
ins->mSrc[0].mTemp = -1;
ins->mSrc[0].mIntConst = ins->mSrc[1].mIntConst - pindexins[k]->mSrc[1].mIntConst;
ins->mSrc[1].mTemp = pindexins[k]->mDst.mTemp;
ins->mSrc[1].mMemory = IM_INDIRECT;
ins->mSrc[1].mIntConst = 0;
mInstructions[j++] = ins;
}
else
#endif
{
indexStep[ins->mDst.mTemp] = indexStep[ins->mSrc[0].mTemp];
indexBase[ins->mDst.mTemp] = 0;
@ -10053,10 +10224,14 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
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];
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);
}
}
}
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 toffset = 0;
int j = i + 1;
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)
st = cins->mDst.mTemp;
else if (cins->mDst.mTemp == st)
{
if (cins->mCode == IC_LEA && cins->mSrc[1].mTemp == st && cins->mSrc[0].mTemp < 0)
toffset += cins->mSrc[0].mIntConst;
else
break;
}
j++;
}
@ -10148,6 +10329,18 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
if (j == mInstructions.Size())
{
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);
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 + 1]->mDst.mTemp = mInstructions[i + 1]->mSrc[0].mTemp;
mInstructions[i + 1]->mSrc[0].mTemp = mInstructions[i + 0]->mDst.mTemp;
mInstructions[i + 0]->mSingleAssignment = mInstructions[i + 1]->mSingleAssignment;
changed = true;
}
#endif
@ -11293,7 +11487,7 @@ void InterCodeProcedure::DisassembleDebug(const char* name)
void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
{
// Count number of entries
//
//
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
{
@ -11702,6 +11896,11 @@ void InterCodeProcedure::MergeIndexedLoadStore(void)
ResetVisited();
} while (mEntryBlock->MergeIndexedLoadStore(silvalues));
BuildDataFlowSets();
TempForwarding();
RemoveUnusedInstructions();
DisassembleDebug("MergeIndexedLoadStore");
}
@ -11743,6 +11942,25 @@ void InterCodeProcedure::SimplifyIntegerNumeric(FastNumberSet& activeSet)
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()
{
GrowingInstructionPtrArray eivalues(nullptr);
@ -11970,6 +12188,12 @@ void InterCodeProcedure::Close(void)
#endif
CheckUsedDefinedTemps();
ExpandSelect();
BuildDataFlowSets();
CheckUsedDefinedTemps();
SingleAssignmentForwarding();
CheckUsedDefinedTemps();

View File

@ -36,6 +36,7 @@ enum InterCode
IC_RETURN,
IC_ASSEMBLER,
IC_JUMPF,
IC_SELECT,
IC_UNREACHABLE
};
@ -478,6 +479,8 @@ public:
InterCodeBasicBlock* BuildLoopPrefix(InterCodeProcedure * proc);
void BuildLoopSuffix(InterCodeProcedure* proc);
void ExpandSelect(InterCodeProcedure* proc);
void SplitBranches(InterCodeProcedure* proc);
void FollowJumps(void);
@ -567,6 +570,7 @@ protected:
void MergeIndexedLoadStore(void);
void EliminateAliasValues();
void LoadStoreForwarding(InterMemory paramMemory);
void ExpandSelect(void);
void MergeBasicBlocks(void);
void CheckUsedDefinedTemps(void);

View File

@ -2849,7 +2849,100 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_CONDITIONAL:
{
InterInstruction * jins0 = new InterInstruction();
#if 1
if ((exp->mRight->mLeft->mType == EX_CONSTANT || exp->mRight->mLeft->mType == EX_VARIABLE) &&
(exp->mRight->mRight->mType == EX_CONSTANT || exp->mRight->mRight->mType == EX_VARIABLE))
{
ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper);
vl = TranslateExpression(procType, proc, block, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper);
vr = TranslateExpression(procType, proc, block, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper);
vc = Dereference(proc, block, vc);
vl = Dereference(proc, block, vl);
vr = Dereference(proc, block, vr);
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
{
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);
}
}
vc = CoerceType(proc, block, vc, TheBoolTypeDeclaration);
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
#endif
{
InterInstruction* jins0 = new InterInstruction();
jins0->mCode = IC_JUMP;
InterInstruction* jins1 = new InterInstruction();
jins1->mCode = IC_JUMP;
@ -2929,7 +3022,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ttemp = proc->AddTemporary(ttype);
InterInstruction * rins = new InterInstruction();
InterInstruction* rins = new InterInstruction();
rins->mCode = IC_LOAD_TEMPORARY;
rins->mSrc[0].mType = ttype;
rins->mSrc[0].mTemp = vr.mTemp;
@ -2937,7 +3030,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
rins->mDst.mTemp = ttemp;
fblock->Append(rins);
InterInstruction * lins = new InterInstruction();
InterInstruction* lins = new InterInstruction();
lins->mCode = IC_LOAD_TEMPORARY;
lins->mSrc[0].mType = ttype;
lins->mSrc[0].mTemp = vl.mTemp;
@ -2954,6 +3047,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block = eblock;
return ExValue(dtype, ttemp);
}
break;
}

View File

@ -11503,8 +11503,24 @@ bool NativeCodeBasicBlock::OptimizeXYPairUsage(void)
j++;
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++)
{
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;
}
}
@ -11915,6 +11931,49 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
break;
}
#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 (i + 4 < mIns.Size() &&
mIns[i + 0].ChangesAccuAndFlag() &&
@ -20950,7 +21009,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
#if 1
// 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))
{
@ -24463,7 +24522,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
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)))
{
int apos, breg;
@ -24473,7 +24532,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
}
#endif
#if 1
if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO))
{
int apos, breg;
@ -24483,6 +24543,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
}
#endif
#endif

View File

@ -2171,7 +2171,7 @@ Expression* Parser::ParseStatement(void)
conditionExp->mRight->mDecValue->mInteger = endValue;
Expression * unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE);
unrollBody->mLeft = bodyExp;
Expression* bexp = unrollBody;
if (endValue > startValue)
@ -2206,7 +2206,11 @@ Expression* Parser::ParseStatement(void)
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;

View File

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

View File

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

View File

@ -4153,15 +4153,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64"
"ProductCode" = "8:{4AC1A78B-6BCA-4D2F-A54D-DEA5F627B017}"
"PackageCode" = "8:{ED70C89A-F338-434F-9FB2-90C1BD8EB020}"
"ProductCode" = "8:{AAAF5F55-0261-47DA-B051-EF84642395A5}"
"PackageCode" = "8:{A7501921-EE58-422B-AEE2-4491A2249AC0}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.7.140"
"ProductVersion" = "8:1.7.141"
"Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"

View File

@ -46,7 +46,7 @@ void expand(char c, byte f)
byte * fp = font + 8 * c;
// Unroll eight times for each byte in glyph data
// #pragma unroll(full)
//#pragma unroll(full)
for(char y=0; y<8; y++)
{
char t = (fp[y] & f) ? 160 : 32;