Fix over eager const expression inliner

This commit is contained in:
drmortalwombat 2022-02-19 12:16:33 +01:00
parent 3aa142957c
commit 6bd3ecb689
12 changed files with 558 additions and 108 deletions

View File

@ -187,6 +187,7 @@ bool Compiler::GenerateCode(void)
mGlobalAnalyzer->AnalyzeGlobalVariable(dec);
}
mGlobalAnalyzer->AutoInline();
//mGlobalAnalyzer->DumpCallGraph();
mInterCodeGenerator->mCompilerOptions = mCompilerOptions;
mNativeCodeGenerator->mCompilerOptions = mCompilerOptions;

View File

@ -484,7 +484,7 @@ Expression* Expression::ConstantFold(Errors * errors)
Declaration::Declaration(const Location& loc, DecType type)
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
mInteger(0), mNumber(0)
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL)
{}
Declaration::~Declaration(void)

View File

@ -176,7 +176,7 @@ public:
Expression* mValue;
DeclarationScope* mScope;
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment;
int64 mInteger;
int64 mInteger, mMinValue, mMaxValue;
double mNumber;
uint64 mFlags;
const Ident * mIdent;

View File

@ -645,7 +645,7 @@ void NativeCodeDisassembler::DumpMemory(FILE* file, const uint8* memory, int ban
for (int i = 0; i < n; i++)
{
int k = memory[ip + i];
if (k >= 32 && k < 128)
if (k >= 32 && k < 127)
fprintf(file, "%c", k);
else
fprintf(file, ".");

View File

@ -262,6 +262,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
{
RegisterProc(Analyze(exp->mDecValue->mValue, procDec));
}
else if (exp->mDecValue->mType == DT_CONST_ADDRESS)
{
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
else if (exp->mDecValue->mType == DT_CONST_ASSEMBLER)
{
AnalyzeAssembler(exp->mDecValue->mValue, procDec);

View File

@ -4181,6 +4181,9 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
switch (ins->mCode)
{
case IC_LOAD:
vr = ins->mDst.mRange;
break;
case IC_CONSTANT:
vr.mMaxState = vr.mMinState = IntegerValueRange::S_BOUND;
vr.mMinValue = vr.mMaxValue = ins->mConst.mIntConst;
@ -9404,7 +9407,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{
#if 1
#if 0
#ifdef _WIN32
FILE* file;
static bool initial = true;

View File

@ -49,6 +49,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
ins->mDst.mType = v.mReference == 1 ? InterTypeOf(v.mType) : IT_POINTER;
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ins->mSrc[0].mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
if (v.mReference == 1 && v.mType->mType == DT_TYPE_ENUM)
{
ins->mDst.mRange.LimitMin(v.mType->mMinValue);
ins->mDst.mRange.LimitMax(v.mType->mMaxValue);
}
if (v.mType->mFlags & DTF_VOLATILE)
ins->mVolatile = true;
block->Append(ins);

View File

@ -6961,6 +6961,57 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
if (ins->mSrc[0].mTemp < 0)
{
int shift = ins->mSrc[0].mIntConst & 15;
if (ins->mSrc[1].IsUByte())
{
if (shift == 0)
{
if (ins->mSrc[1].mTemp != ins->mDst.mTemp)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
}
else if (shift == 7)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
}
else if (shift == 6)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
else if (shift >= 8)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
for (int i = 0; i < shift; i++)
mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
}
else
{
if (shift == 0)
{
if (ins->mSrc[1].mTemp != ins->mDst.mTemp)
@ -7057,6 +7108,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
}
}
}
else if (ins->mSrc[1].mTemp < 0 && IsPowerOf2(ins->mSrc[1].mIntConst & 0xffff))
{
int l = Binlog(ins->mSrc[1].mIntConst & 0xffff);
@ -9011,6 +9063,27 @@ bool NativeCodeBasicBlock::LocalRegisterXYMap(void)
for (int i = 0; i < mIns.Size(); i++)
{
if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_LDA && (mIns[i].mMode != ASMIM_ZERO_PAGE || (xregs[mIns[i].mAddress] < 0 && xregs[mIns[i].mAddress] < 0) || (mIns[i + 1].mLive & LIVE_MEM)))
{
if (mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE)
{
if (xregs[mIns[i + 1].mAddress] >= 0 && !(mIns[i + 1].mLive & LIVE_MEM))
{
int addr = mIns[i + 1].mAddress;
mIns[i + 1].CopyMode(mIns[i]);
mIns[i].mMode = ASMIM_ZERO_PAGE;
mIns[i].mAddress = addr;
}
else if (yregs[mIns[i + 1].mAddress] >= 0 && !(mIns[i + 1].mLive & LIVE_MEM))
{
int addr = mIns[i + 1].mAddress;
mIns[i + 1].CopyMode(mIns[i]);
mIns[i].mMode = ASMIM_ZERO_PAGE;
mIns[i].mAddress = addr;
}
}
}
const NativeCodeInstruction& ins(mIns[i]);
if (ins.ChangesXReg())
@ -9437,6 +9510,61 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(void)
}
}
}
#endif
#if 1
if (mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump && mFalseJump->mNumEntries == 1)
{
int s = mIns.Size();
if (s > 0 && mIns[s - 1].mType == ASMIT_CMP && mIns[s - 1].mMode == ASMIM_IMMEDIATE && !(mIns[s - 1].mLive & LIVE_CPU_REG_X))
{
while (mTrueJump->mIns.Size() > 1 && mFalseJump->mIns.Size() > 1 &&
((mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[1].mType == ASMIT_STA && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
(mTrueJump->mIns[0].mType == ASMIT_LDX && mTrueJump->mIns[1].mType == ASMIT_STX && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
((mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[1].mType == ASMIT_STA && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
(mFalseJump->mIns[0].mType == ASMIT_LDX && mFalseJump->mIns[1].mType == ASMIT_STX && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
mTrueJump->mIns[0].SameEffectiveAddress(mFalseJump->mIns[0]) && mTrueJump->mIns[1].SameEffectiveAddress(mFalseJump->mIns[1]) &&
HasAsmInstructionMode(ASMIT_LDX, mTrueJump->mIns[0].mMode) && HasAsmInstructionMode(ASMIT_STX, mTrueJump->mIns[1].mMode))
{
mTrueJump->mIns[0].mType = ASMIT_LDX;
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_X;
mTrueJump->mIns[1].mType = ASMIT_STX;
mIns.Insert(s - 1, mTrueJump->mIns[0]);
mIns.Insert(s, mTrueJump->mIns[1]);
s += 2;
mTrueJump->mIns.Remove(0); mTrueJump->mIns.Remove(0);
mFalseJump->mIns.Remove(0); mFalseJump->mIns.Remove(0);
changed = true;
}
}
else if (s > 0 && mIns[s - 1].mType == ASMIT_LDA && !(mIns[s - 1].mLive & LIVE_CPU_REG_X))
{
while (mTrueJump->mIns.Size() > 1 && mFalseJump->mIns.Size() > 1 &&
((mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[1].mType == ASMIT_STA && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
(mTrueJump->mIns[0].mType == ASMIT_LDX && mTrueJump->mIns[1].mType == ASMIT_STX && !(mTrueJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
((mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[1].mType == ASMIT_STA && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z))) ||
(mFalseJump->mIns[0].mType == ASMIT_LDX && mFalseJump->mIns[1].mType == ASMIT_STX && !(mFalseJump->mIns[1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))) &&
mTrueJump->mIns[0].SameEffectiveAddress(mFalseJump->mIns[0]) && mTrueJump->mIns[1].SameEffectiveAddress(mFalseJump->mIns[1]) &&
HasAsmInstructionMode(ASMIT_LDX, mTrueJump->mIns[0].mMode) && HasAsmInstructionMode(ASMIT_STX, mTrueJump->mIns[1].mMode) &&
!mIns[s - 1].MayBeChangedOnAddress(mTrueJump->mIns[1]))
{
mTrueJump->mIns[0].mType = ASMIT_LDX;
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_X;
mTrueJump->mIns[1].mType = ASMIT_STX;
mIns.Insert(s - 1, mTrueJump->mIns[0]);
mIns.Insert(s, mTrueJump->mIns[1]);
s += 2;
mTrueJump->mIns.Remove(0); mTrueJump->mIns.Remove(0);
mFalseJump->mIns.Remove(0); mFalseJump->mIns.Remove(0);
changed = true;
}
}
}
#endif
if (mTrueJump && mTrueJump->JoinTailCodeSequences())
changed = true;
@ -10179,6 +10307,121 @@ bool NativeCodeBasicBlock::FindDirectAddressSumY(int at, int reg, int& apos, int
return false;
}
bool NativeCodeBasicBlock::FindExternAddressSumY(int at, int reg, int& breg, int& ireg)
{
int j = at - 7;
while (j >= 0)
{
if (
mIns[j + 0].mType == ASMIT_CLC &&
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 1].mAddress + 1 &&
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
{
breg = mIns[j + 1].mAddress;
ireg = mIns[j + 2].mAddress;
if (ireg == breg || reg == breg || ireg == reg)
return false;
int k = j + 7;
while (k < at)
{
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
return false;
k++;
}
return true;
}
else if (
mIns[j + 0].mType == ASMIT_CLC &&
mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 2].mAddress + 1 &&
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
{
breg = mIns[j + 2].mAddress;
ireg = mIns[j + 1].mAddress;
if (ireg == breg || reg == breg || ireg == reg)
return false;
int k = j + 7;
while (k < at)
{
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
return false;
k++;
}
return true;
}
else if (
mIns[j + 0].mType == ASMIT_STA && mIns[j + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 1].mType == ASMIT_CLC &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 2].mAddress + 1 &&
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
{
breg = mIns[j + 2].mAddress;
ireg = mIns[j + 0].mAddress;
if (ireg == breg || reg == breg || ireg == reg)
return false;
int k = j + 7;
while (k < at)
{
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
return false;
k++;
}
return true;
}
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
return false;
j--;
}
if (mFromJump)
{
while (j >= -6)
{
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
return false;
j--;
}
if (mFromJump->FindExternAddressSumY(mFromJump->mIns.Size(), reg, breg, ireg))
{
int k = 0;
while (k < at)
{
if (mIns[k].mMode == ASMIM_ZERO_PAGE && (mIns[k].mAddress == breg || mIns[k].mAddress == breg + 1 || mIns[k].mAddress == ireg) && mIns[k].ChangesAddress())
return false;
k++;
}
return true;
}
}
return false;
}
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg)
{
int j = at - 7;
@ -10984,6 +11227,18 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
{
bool changed = false;
if (mIns.Size() == 2 && (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && mIns[0].mType == ASMIT_LDA && mIns[1].mType == ASMIT_CMP && !(mIns[1].mFlags & NCIF_VOLATILE) && !(mIns[1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
if (!prevBlock)
return OptimizeSimpleLoopInvariant(proc);
mIns[1].mType = ASMIT_LDA; mIns[1].mLive |= LIVE_CPU_REG_A;
mIns[0].mType = ASMIT_CMP; mIns[0].mLive |= LIVE_CPU_REG_Z;
prevBlock->mIns.Push(mIns[1]);
mIns.Remove(1);
return true;
}
int ai = 0;
while (ai < mIns.Size() && !mIns[ai].ChangesAccu())
ai++;
@ -11255,7 +11510,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
mTrueJump = this;
}
if (sz > 3 && sz < 200 && mNumEntries == 2 && mTrueJump == this)
if (sz == 2 && mTrueJump == this)
{
changed = OptimizeSimpleLoopInvariant(proc, nullptr, nullptr);
}
else if (sz > 3 && sz < 200 && mNumEntries == 2 && mTrueJump == this)
{
bool simple = true;
@ -13415,6 +13674,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
}
}
#endif
else if (FindExternAddressSumY(i, sreg, breg, ireg))
{
#if 1
if (mIns[i + 0].mLive & LIVE_CPU_REG_Y)
{
mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
}
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM;
mIns[i + 1].mAddress = breg;
mIns[i + 1].mFlags &= ~NCIF_YZERO;
progress = true;
#endif
}
}
#endif
@ -14380,6 +14656,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
mIns[i + 1].mType = ASMIT_ASL; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDA &&
mIns[i + 1].mType == ASMIT_ROR && mIns[i + 1].mMode == ASMIM_IMPLIED &&
mIns[i + 2].mType == ASMIT_AND && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x80 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mAddress = 0;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
#if 1
else if (
mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
@ -14553,6 +14838,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
}
#endif
else if (
mIns[i + 0].mType == ASMIT_LDA && !mIns[i + 0].RequiresXReg() &&
mIns[i + 1].mType == ASMIT_LDX &&
mIns[i + 2].mType == ASMIT_STX && !(mIns[i + 2].mLive & LIVE_CPU_REG_X) && !mIns[i + 0].MayBeChangedOnAddress(mIns[i + 2]))
{
NativeCodeInstruction ins = mIns[i + 0];
mIns[i + 0] = mIns[i + 1];
mIns[i + 1] = mIns[i + 2];
mIns[i + 2] = ins;
mIns[i + 0].mType = ASMIT_LDA; mIns[i + 0].mLive |= LIVE_CPU_REG_A | mIns[i + 2].mLive;
mIns[i + 1].mType = ASMIT_STA; mIns[i + 1].mLive |= mIns[i + 2].mLive;
progress = true;
}
#if 1
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
@ -15600,6 +15899,17 @@ void NativeCodeBasicBlock::BuildPlacement(GrowingArray<NativeCodeBasicBlock*>& p
mTrueJump->BuildPlacement(placement);
mFalseJump->BuildPlacement(placement);
}
#if 1
else if (!mTrueJump->mFalseJump && mTrueJump->mTrueJump && mFalseJump->mFalseJump && !mTrueJump->mTrueJump->mPlaced && mTrueJump->mTrueJump->mNumEntries > 1)
{
mTrueJump->mPlaced = true;
mTrueJump->mPlace = placement.Size();
placement.Push(mTrueJump);
mFalseJump->BuildPlacement(placement);
mTrueJump->mTrueJump->BuildPlacement(placement);
}
#endif
else
{
mFalseJump->BuildPlacement(placement);

View File

@ -224,6 +224,7 @@ public:
bool PatchAddressSumY(int at, int reg, int apos, int breg, int ireg);
bool FindGlobalAddress(int at, int reg, int& apos);
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr);
bool FindExternAddressSumY(int at, int reg, int& breg, int& ireg);
bool FindPageStartAddress(int at, int reg, int& addr);
bool MoveStoreXUp(int at);
bool MoveStoreHighByteDown(int at);

View File

@ -77,6 +77,13 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
{
if (!(mdec->mBase->mFlags & DTF_DEFINED))
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration");
if (mdec->mType != DT_VARIABLE)
{
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected");
break;
}
mdec->mType = DT_ELEMENT;
mdec->mOffset = offset;
@ -319,6 +326,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
break;
}
dec->mMinValue = minValue;
dec->mMaxValue = maxValue;
if (minValue < 0)
{
dec->mFlags |= DTF_SIGNED;

View File

@ -2,13 +2,14 @@
#include <c64/memmap.h>
#include <c64/sprites.h>
#include <c64/joystick.h>
#include <c64/cia.h>
#include <string.h>
#include <stdlib.h>
byte * const Screen = (byte *)0xc800;
byte * const Font = (byte *)0xd000;
byte * const Font = (byte *)0xe000;
byte * const Color = (byte *)0xd800;
byte * const Sprites = (byte *)0xd800;
byte * const Sprites = (byte *)0xd000;
// Character set
char charset[2048] = {
@ -19,24 +20,35 @@ char tileset[] = {
#embed "../../../assets/uridium1 - Tiles.bin"
};
char tilemap[64 * 5] = {
#embed "../../../assets/uridium1 - Map (64x5).bin"
char tilemap[128 * 5] = {
#embed "../../../assets/uridium1 - Map (128x5).bin"
};
char spriteset[2048] = {
#embed 2048 0 "../../../assets/uridium1 - Sprites.bin"
};
char xtileset[16][20];
char xtileset[16][64];
char xtilemap[144 * 5];
char stars[24];
#pragma align(xtileset, 64);
void tiles_unpack(void)
{
for(char t=0; t<20; t++)
for(char t=0; t<64; t++)
{
for(char i=0; i<16; i++)
xtileset[i][t] = tileset[16 * t + i];
}
for(char y=0; y<5; y++)
{
for(char x=0; x<144; x++)
{
xtilemap[y * 144 + x] = tilemap[y * 128 + (x & 127)];
}
}
}
void tiles_draw0(char * dp, char * tm)
@ -156,22 +168,42 @@ void tiles_draw1(char * dp, char * tm)
}
}
struct Shot
{
char x, y, dx, n;
} shots[5][4];
inline void shot_draw(char * dp, char i, char xp, char yp)
{
char c = dp[xp];
char * fsp = Font + 8 * c;
char * fdp = Font + 8 * i;
fdp[0] = fsp[0]; fdp[1] = fsp[1]; fdp[2] = fsp[2]; fdp[3] = fsp[3];
fdp[4] = fsp[4]; fdp[5] = fsp[5]; fdp[6] = fsp[6]; fdp[7] = fsp[7];
fdp[yp] = 0x00;
dp[xp] = i;
}
void tiles_draw(unsigned x)
{
char xs = 7 - (x & 7);
vic.ctrl2 = VIC_CTRL2_MCM + xs;
x >>= 3;
char xl = x >> 2, xr = x & 3;
char yl = 0;
char ci = 192;
char cs = xs | 248;
for(int iy=0; iy<5; iy++)
{
char * dp = Screen + 80 + 160 * iy;
char * cp = Color + 80 + 160 * iy;
char * tp = tilemap + xl + 64 * iy;
char * tp = xtilemap + xl + 144 * iy;
switch (xr)
{
@ -191,15 +223,13 @@ void tiles_draw(unsigned x)
__assume(false);
}
xs |= 248;
char k = stars[yl + 0] + 0;
if (dp[k])
cp[k] = 8;
else
{
cp[k] = 0;
dp[k] = xs;
dp[k] = cs;
}
k = stars[yl + 1];
@ -208,7 +238,7 @@ void tiles_draw(unsigned x)
else
{
cp[k] = 0;
dp[k] = xs;
dp[k] = cs;
}
k = stars[yl + 2];
@ -217,7 +247,7 @@ void tiles_draw(unsigned x)
else
{
cp[k] = 0;
dp[k] = xs;
dp[k] = cs;
}
k = stars[yl + 3];
@ -226,15 +256,32 @@ void tiles_draw(unsigned x)
else
{
cp[k] = 0;
dp[k] = xs;
dp[k] = cs;
}
Shot * s = shots[iy];
for(char si=0; si<4; si++)
{
if (s->n)
{
s->x += s->dx;
s->n--;
shot_draw(dp, ci++, s->x, s->y);
}
s++;
}
yl += 4;
}
vic.ctrl2 = VIC_CTRL2_MCM + xs;
}
int main(void)
{
cia_init();
mmap_trampoline();
// Install character set
@ -254,8 +301,8 @@ int main(void)
}
}
memcpy(Sprites, spriteset, 2048);
mmap_set(MMAP_NO_BASIC);
memcpy(Sprites, spriteset, 4096);
mmap_set(MMAP_NO_ROM);
tiles_unpack();
@ -265,10 +312,10 @@ int main(void)
spr_init(Screen);
// Change colors
vic.color_border = VCOL_BLUE;
vic.color_border = VCOL_BLACK;
vic.color_back = VCOL_WHITE;
vic.color_back1 = VCOL_LT_GREY;
vic.color_back2 = VCOL_DARK_GREY;
vic.color_back2 = VCOL_MED_GREY;
vic.spr_mcolor0 = VCOL_DARK_GREY;
vic.spr_mcolor1 = VCOL_WHITE;
@ -279,12 +326,24 @@ int main(void)
for(int i=0; i<24; i++)
stars[i] = rand() % 40 + 40 * (i & 3);
spr_set(0, true, 160, 100, 96, 6, true, false, false);
for(int i=0; i<5; i++)
{
for(int j=0; j<8; j++)
{
shots[i][j].x = rand() % 160;
shots[i][j].y = rand() & 7;
}
}
spr_set(0, true, 160, 100, 64, VCOL_BLUE, true, false, false);
spr_set(1, true, 160, 100, 64 + 16, VCOL_MED_GREY, true, false, false);
vic.spr_priority = 2;
int spx = 40;
int vpx = 16;
int ax = 0;
char spy = 100;
char fdelay = 0;
for(;;)
{
@ -294,39 +353,96 @@ int main(void)
ax = joyx[0];
spy += 2 * joyy[0];
if (spy < 6)
spy = 6;
else if (spy > 6 + 159)
spy = 6 + 159;
if (ax > 0)
{
if (vpx < 16)
if (vpx < 32)
vpx++;
if (vpx == 16)
{
spr_image(0, 96);
else
ax = 0;
if (vpx >= 32)
{
spr_image(0, 64);
spr_image(1, 64 + 16);
}
else
spr_image(0, 108 + (vpx >> 2));
{
spr_image(0, 76 + (vpx >> 3));
spr_image(1, 76 + (vpx >> 3) + 16);
}
}
else if (ax < 0)
{
if (vpx > -15)
if (vpx > - 32)
vpx--;
if (vpx == -15)
{
spr_image(0, 104);
else
ax = 0;
if (vpx <= -32)
{
spr_image(0, 72);
spr_image(1, 72 + 16);
}
else
spr_image(0, 100 - (vpx >> 2));
{
spr_image(0, 68 - (vpx >> 3));
spr_image(1, 68 - (vpx >> 3) + 16);
}
}
spr_move(0, 160 - 4 * vpx, 50 + spy);
if (fdelay)
fdelay--;
else if (joyb[0] && vpx != 0)
{
char py = spy - 6;
char gy = py >> 5;
char ey = (py >> 3) & 3;
char ry = py & 7;
vic_waitFrame();
Shot * s = shots[gy];
char i = 0;
while (i < 4 && s[i].n != 0)
i++;
if (i < 4)
{
s[i].y = ry;
if (vpx < 0)
{
s[i].dx = -1;
char x = (148 - 4 * vpx) >> 3;
s[i].n = x - 1;
s[i].x = 40 * ey + x;
}
else if (vpx > 0)
{
s[i].dx = 1;
char x = (156 - 4 * vpx) >> 3;
s[i].x = 40 * ey + x;
s[i].n = 39 - x;
}
fdelay = 4;
}
}
spr_move(0, 172 - 4 * vpx, 50 + spy);
spr_move(1, 180 - 4 * vpx, 58 + spy);
vic.color_border++;
vic_waitLine(82);
vic.color_border++;
tiles_draw(spx);
vic.color_border--;
vic.color_border--;
spx += vpx >> 1;
spx &= 4095;
}
return 0;

Binary file not shown.