Cross function constant propagation

This commit is contained in:
drmortalwombat 2023-06-14 14:40:59 +02:00
parent 72687b7581
commit c83804a76c
13 changed files with 249 additions and 39 deletions

View File

@ -27,7 +27,6 @@ There are still several open areas, but most targets have been reached. The cur
### Language ### Language
* Missing const checks for structs and enums
* Missing warnings for all kind of abuses * Missing warnings for all kind of abuses
### Linker ### Linker

View File

@ -15,7 +15,7 @@ int main(void)
ftoa(x, xb); float xr = atof(xb); ftoa(x, xb); float xr = atof(xb);
ftoa(y, yb); float yr = atof(yb); ftoa(y, yb); float yr = atof(yb);
printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y); printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, yr, fabs(x - xr) / x, fabs(y - yr) / y);
if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001) if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001)
return -1; return -1;

View File

@ -603,7 +603,8 @@ Expression* Expression::ConstantFold(Errors * errors)
Declaration::Declaration(const Location& loc, DecType type) Declaration::Declaration(const Location& loc, DecType type)
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), : mLocation(loc), mEndLocation(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), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1), mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
mCompilerOptions(0), mUseCount(0) mCompilerOptions(0), mUseCount(0)
{} {}
@ -727,16 +728,20 @@ Declaration* Declaration::ToConstType(void)
if (mFlags & DTF_CONST) if (mFlags & DTF_CONST)
return this; return this;
Declaration* ndec = new Declaration(mLocation, mType); if (!mConst)
ndec->mSize = mSize; {
ndec->mStride = mStride; Declaration* ndec = new Declaration(mLocation, mType);
ndec->mBase = mBase; ndec->mSize = mSize;
ndec->mFlags = mFlags | DTF_CONST; ndec->mStride = mStride;
ndec->mScope = mScope; ndec->mBase = mBase;
ndec->mParams = mParams; ndec->mFlags = mFlags | DTF_CONST;
ndec->mIdent = mIdent; ndec->mScope = mScope;
ndec->mParams = mParams;
ndec->mIdent = mIdent;
mConst = ndec;
}
return ndec; return mConst;
} }
bool Declaration::IsSubType(const Declaration* dec) const bool Declaration::IsSubType(const Declaration* dec) const

View File

@ -87,9 +87,13 @@ static const uint64 DTF_FUNC_INTRSAVE = (1ULL << 37);
static const uint64 DTF_FUNC_INTRCALLED = (1ULL << 38); static const uint64 DTF_FUNC_INTRCALLED = (1ULL << 38);
static const uint64 DTF_FUNC_PURE = (1ULL << 39); static const uint64 DTF_FUNC_PURE = (1ULL << 39);
static const uint64 DTF_FPARAM_CONST = (1ULL << 40);
static const uint64 DTF_FPARAM_NOCONST = (1ULL << 41);
static const uint64 DTF_VAR_ALIASING = (1ULL << 48); static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
class Declaration; class Declaration;
class DeclarationScope class DeclarationScope
@ -188,7 +192,7 @@ public:
Location mLocation, mEndLocation; Location mLocation, mEndLocation;
DecType mType; DecType mType;
Token mToken; Token mToken;
Declaration* mBase, *mParams, * mNext; Declaration* mBase, *mParams, * mNext, * mConst;
Expression* mValue; Expression* mValue;
DeclarationScope* mScope; DeclarationScope* mScope;
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe; int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;

View File

@ -205,11 +205,42 @@ void GlobalAnalyzer::AutoInline(void)
} while (changed); } while (changed);
for (int i = 0; i < mFunctions.Size(); i++) for (int i = 0; i < mFunctions.Size(); i++)
{ {
CheckFastcall(mFunctions[i], true); CheckFastcall(mFunctions[i], true);
} }
for (int i = 0; i < mFunctions.Size(); i++)
{
Declaration* dec = mFunctions[i];
Declaration* pdec = dec->mBase->mParams;
while (pdec)
{
if (pdec->mFlags & DTF_FPARAM_CONST)
{
pdec->mVarIndex = dec->mNumVars++;
Expression* aexp = new Expression(pdec->mLocation, EX_ASSIGNMENT);
Expression* pexp = new Expression(pdec->mLocation, EX_VARIABLE);
Expression* lexp = new Expression(dec->mLocation, EX_SEQUENCE);
pexp->mDecType = pdec->mBase;
pexp->mDecValue = pdec;
aexp->mDecType = pdec->mBase;
aexp->mToken = TK_ASSIGN;
aexp->mLeft = pexp;
aexp->mRight = pdec->mValue;
lexp->mLeft = aexp;
lexp->mRight = dec->mValue;
dec->mValue = lexp;
}
pdec = pdec->mNext;
}
}
} }
bool GlobalAnalyzer::MarkCycle(Declaration* rootDec, Declaration* procDec) bool GlobalAnalyzer::MarkCycle(Declaration* rootDec, Declaration* procDec)
@ -635,13 +666,55 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
{ {
// Check for struct to struct forwarding // Check for struct to struct forwarding
Expression* rex = exp->mRight; Expression* rex = exp->mRight;
Declaration* pdec = ldec->mBase->mParams;
while (rex) while (rex)
{ {
Expression* pex = rex->mType == EX_LIST ? rex->mLeft : rex; Expression* pex = rex->mType == EX_LIST ? rex->mLeft : rex;
if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER)))
{
#if 1
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
{
if (!(pdec->mFlags & DTF_FPARAM_NOCONST))
{
if (pex->mType == EX_CONSTANT)
{
if (pdec->mFlags & DTF_FPARAM_CONST)
{
if (!pex->mDecValue->IsSame(pdec->mValue->mDecValue))
{
pdec->mFlags |= DTF_FPARAM_NOCONST;
pdec->mFlags &= ~DTF_FPARAM_CONST;
}
}
else
{
pdec->mValue = pex;
pdec->mFlags |= DTF_FPARAM_CONST;
}
}
else
{
pdec->mFlags |= DTF_FPARAM_NOCONST;
pdec->mFlags &= ~DTF_FPARAM_CONST;
}
}
}
else
{
pdec->mFlags |= DTF_FPARAM_NOCONST;
pdec->mFlags &= ~DTF_FPARAM_CONST;
}
#endif
}
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT) if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT)
ldec->mBase->mFlags |= DTF_STACKCALL; ldec->mBase->mFlags |= DTF_STACKCALL;
if (pdec)
pdec = pdec->mNext;
if (rex->mType == EX_LIST) if (rex->mType == EX_LIST)
rex = rex->mRight; rex = rex->mRight;
else else
@ -800,7 +873,17 @@ void GlobalAnalyzer::RegisterProc(Declaration* to)
{ {
if (to->mType == DT_CONST_FUNCTION) if (to->mType == DT_CONST_FUNCTION)
{ {
to->mFlags |= DTF_FUNC_VARIABLE; if (!(to->mFlags & DTF_FUNC_VARIABLE))
mVariableFunctions.Push(to); {
to->mFlags |= DTF_FUNC_VARIABLE;
mVariableFunctions.Push(to);
Declaration* pdec = to->mParams;
while (pdec)
{
pdec->mFlags |= DTF_FPARAM_NOCONST;
pdec->mFlags &= ~DTF_FPARAM_CONST;
pdec = pdec->mNext;
}
}
} }
} }

View File

@ -3351,8 +3351,19 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
} }
break; break;
case IC_BRANCH:
if (mSrc[0].mTemp >= 0 && ctemps[mSrc[0].mTemp])
{
InterInstruction* ains = ctemps[mSrc[0].mTemp];
mSrc[0] = ains->mConst;
this->ConstantFolding();
return true;
}
break;
} }
return false; return false;
} }
@ -4076,6 +4087,24 @@ bool InterInstruction::ConstantFolding(void)
return true; return true;
} }
break; break;
case IC_BRANCH:
if (mSrc[0].mTemp < 0)
{
if (IsIntegerType(mSrc[0].mType))
mSrc[0].mIntConst = mSrc[0].mIntConst != 0;
else if (mSrc[0].mType == IT_FLOAT)
mSrc[0].mIntConst = mSrc[0].mFloatConst != 0;
else if (mSrc[0].mType == IT_POINTER)
{
if (mSrc[0].mMemory == IM_ABSOLUTE)
mSrc[0].mIntConst = mSrc[0].mIntConst != 0;
else
mSrc[0].mIntConst = 1;
}
mSrc[0].mType = IT_BOOL;
return true;
}
break;
} }
return false; return false;
@ -15987,7 +16016,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "tile_draw_p"); CheckFunc = !strcmp(mIdent->mString, "main");
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -16790,6 +16819,7 @@ void InterCodeProcedure::Close(void)
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc) void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)
{ {
assert(proc != nullptr);
mCalledFunctions.Push(proc); mCalledFunctions.Push(proc);
} }

View File

@ -873,7 +873,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
if (pdec) if (pdec)
{ {
nmapper.mParams[pdec->mVarIndex] = nindex; if (!(pdec->mFlags & DTF_FPARAM_CONST))
nmapper.mParams[pdec->mVarIndex] = nindex;
vdec->mVarIndex = nindex; vdec->mVarIndex = nindex;
vdec->mBase = pdec->mBase; vdec->mBase = pdec->mBase;
@ -972,7 +973,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
wins->mSrc[1].mOperandSize = vr.mType->mSize; wins->mSrc[1].mOperandSize = vr.mType->mSize;
else else
wins->mSrc[1].mOperandSize = 2; wins->mSrc[1].mOperandSize = 2;
block->Append(wins);
if (!pdec || !(pdec->mFlags & DTF_FPARAM_CONST))
block->Append(wins);
} }
if (pdec) if (pdec)
@ -1255,7 +1258,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
int ref = 1; int ref = 1;
if (dec->mType == DT_ARGUMENT) if (dec->mType == DT_ARGUMENT)
{ {
if (inlineMapper) if (dec->mFlags & DTF_FPARAM_CONST)
{
ins->mConst.mMemory = IM_LOCAL;
if (inlineMapper)
ins->mConst.mVarIndex += inlineMapper->mVarIndex;
InitLocalVariable(proc, dec, ins->mConst.mVarIndex);
}
else if (inlineMapper)
{ {
ins->mConst.mMemory = IM_LOCAL; ins->mConst.mMemory = IM_LOCAL;
ins->mConst.mVarIndex = inlineMapper->mParams[dec->mVarIndex]; ins->mConst.mVarIndex = inlineMapper->mParams[dec->mVarIndex];
@ -2633,10 +2643,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else else
wins->mSrc[1].mOperandSize = 2; wins->mSrc[1].mOperandSize = 2;
if (ftype->mFlags & DTF_FASTCALL) if (!pdec || !(pdec->mFlags & DTF_FPARAM_CONST))
defins.Push(wins); {
else if (ftype->mFlags & DTF_FASTCALL)
block->Append(wins); defins.Push(wins);
else
block->Append(wins);
}
atotal += wins->mSrc[1].mOperandSize; atotal += wins->mSrc[1].mOperandSize;
} }
@ -2747,7 +2760,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (vdec->mType == DT_ARGUMENT) if (vdec->mType == DT_ARGUMENT)
{ {
vins->mConst.mVarIndex = vdec->mVarIndex; vins->mConst.mVarIndex = vdec->mVarIndex;
if (inlineMapper) if (vdec->mFlags & DTF_FPARAM_CONST)
{
vins->mConst.mMemory = IM_LOCAL;
if (inlineMapper)
vins->mConst.mVarIndex += inlineMapper->mVarIndex;
}
else if (inlineMapper)
{ {
vins->mConst.mMemory = IM_LOCAL; vins->mConst.mMemory = IM_LOCAL;
vins->mConst.mVarIndex = inlineMapper->mParams[vdec->mVarIndex]; vins->mConst.mVarIndex = inlineMapper->mParams[vdec->mVarIndex];
@ -3795,6 +3814,33 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
{ {
if (mCompilerOptions & COPT_VERBOSE2) if (mCompilerOptions & COPT_VERBOSE2)
printf("Generate intermediate code <%s>\n", proc->mIdent->mString); printf("Generate intermediate code <%s>\n", proc->mIdent->mString);
#if 0
Declaration* pdec = dec->mBase->mParams;
while (pdec)
{
if (pdec->mFlags & DTF_FPARAM_CONST)
{
pdec->mVarIndex = proc->mNumLocals;
proc->mNumLocals ++;
dec->mNumVars++;
InitParameter(proc, pdec, pdec->mVarIndex + proc->mFastCallBase);
Expression* aexp = new Expression(pdec->mLocation, EX_ASSIGNMENT);
Expression* pexp = new Expression(pdec->mLocation, EX_VARIABLE);
pexp->mDecType = pdec->mBase;
pexp->mDecValue = pdec;
aexp->mDecType = pdec->mBase;
aexp->mToken = TK_ASSIGN;
aexp->mLeft = pexp;
aexp->mRight = pdec->mValue;
TranslateExpression(dec->mBase, proc, exitBlock, aexp, nullptr, nullptr, nullptr);
}
pdec = pdec->mNext;
}
#endif
TranslateExpression(dec->mBase, proc, exitBlock, exp, nullptr, nullptr, nullptr); TranslateExpression(dec->mBase, proc, exitBlock, exp, nullptr, nullptr, nullptr);
} }

View File

@ -12921,6 +12921,23 @@ bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet&
} }
} }
break; break;
case ASMIM_ZERO_PAGE_X:
if (mIns[i].ChangesAddress())
{
if (i > 1 && i + 2 < mIns.Size())
{
if (mIns[i - 2].mType == ASMIT_LDX && mIns[i - 2].mMode == ASMIM_IMMEDIATE &&
mIns[i - 1].mType == ASMIT_LDA &&
mIns[i + 0].mType == ASMIT_STA &&
mIns[i + 1].mType == ASMIT_DEX &&
mIns[i + 2].mType == ASMIT_BPL)
{
for (int j = 0; j < mIns[i - 2].mAddress; j++)
locals += mIns[i].mAddress + j;
}
}
}
break;
} }
} }
@ -19640,6 +19657,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
mIns[ns - 2].mType = ASMIT_STX; mIns[ns - 2].mType = ASMIT_STX;
mTrueJump->mIns.Insert(0, ins); mTrueJump->mIns.Insert(0, ins);
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_C; mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_C;
if (mTrueJump->mEntryRequiredRegs[CPU_REG_A])
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_A;
mIns.Remove(ns - 2); mIns.Remove(ns - 2);
mTrueJump->mEntryRequiredRegs += CPU_REG_X; mTrueJump->mEntryRequiredRegs += CPU_REG_X;
mTrueJump->CheckLive(); mTrueJump->CheckLive();
@ -19651,6 +19670,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
mIns[ns - 2].mType = ASMIT_STX; mIns[ns - 2].mType = ASMIT_STX;
mFalseJump->mIns.Insert(0, ins); mFalseJump->mIns.Insert(0, ins);
mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C; mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C;
if (mFalseJump->mEntryRequiredRegs[CPU_REG_A])
mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_A;
mIns.Remove(ns - 2); mIns.Remove(ns - 2);
mFalseJump->mEntryRequiredRegs += CPU_REG_X; mFalseJump->mEntryRequiredRegs += CPU_REG_X;
mFalseJump->CheckLive(); mFalseJump->CheckLive();
@ -24716,6 +24737,7 @@ bool NativeCodeBasicBlock::ReplaceZeroPageDown(int at)
{ {
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress) if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[at].mAddress)
{ {
mIns[i].mLive |= LIVE_CPU_REG_A;
mIns[at + 1].mLive |= mIns[i].mLive; mIns[at + 1].mLive |= mIns[i].mLive;
mIns.Insert(i + 1, mIns[at + 1]); mIns.Insert(i + 1, mIns[at + 1]);
mIns.Remove(at, 2); mIns.Remove(at, 2);
@ -36285,6 +36307,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 0].mType = ASMIT_EOR; mIns[i + 0].mType = ASMIT_EOR;
mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mMode = ASMIM_IMMEDIATE;
mIns[i + 0].mAddress = 0xff; mIns[i + 0].mAddress = 0xff;
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 3].mType = ASMIT_ADC; mIns[i + 3].mType = ASMIT_ADC;
mIns[i + 3].mAddress = mIns[i + 1].mAddress; mIns[i + 3].mAddress = mIns[i + 1].mAddress;
@ -36302,6 +36325,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 0].mType = ASMIT_EOR; mIns[i + 0].mType = ASMIT_EOR;
mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mMode = ASMIM_IMMEDIATE;
mIns[i + 0].mAddress = 0xff; mIns[i + 0].mAddress = 0xff;
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
mIns[i + 3].mType = ASMIT_ADC; mIns[i + 3].mType = ASMIT_ADC;
mIns[i + 3].mAddress = mIns[i + 2].mAddress; mIns[i + 3].mAddress = mIns[i + 2].mAddress;
@ -36318,6 +36343,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
{ {
mIns[i + 3].CopyMode(mIns[i + 1]); mIns[i + 3].CopyMode(mIns[i + 1]);
mIns[i + 3].mType = ASMIT_ADC; mIns[i + 3].mType = ASMIT_ADC;
mIns[i + 2].mLive |= LIVE_CPU_REG_A;
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
@ -39056,7 +39082,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
if (mBranch == ASMIT_BEQ && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0) if (mBranch == ASMIT_BEQ && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0)
{ {
mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(mBranchIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(mBranchIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C; mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C | LIVE_CPU_REG_A;
mIns.Push(NativeCodeInstruction(mBranchIns, ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(mBranchIns, ASMIT_ROL, ASMIM_IMPLIED));
mExitProvidedRegs += CPU_REG_A; mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;
@ -39069,7 +39095,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
else if (mBranch == ASMIT_BNE && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1) else if (mBranch == ASMIT_BNE && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1)
{ {
mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(mBranchIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0)); mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(mBranchIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C; mIns[mIns.Size() - 1].mType = ASMIT_CMP; mIns[mIns.Size() - 1].mLive |= LIVE_CPU_REG_C | LIVE_CPU_REG_A;
mIns.Push(NativeCodeInstruction(mBranchIns, ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(mBranchIns, ASMIT_ROL, ASMIM_IMPLIED));
mExitProvidedRegs += CPU_REG_A; mExitProvidedRegs += CPU_REG_A;
mBranch = ASMIT_JMP; mBranch = ASMIT_JMP;

View File

@ -1551,16 +1551,27 @@ Expression* Parser::ParseSimpleExpression(void)
} }
else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT) else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT)
{ {
if ((dec->mFlags & DTF_STATIC) && (dec->mFlags & DTF_CONST) && dec->mValue && dec->mBase->IsNumericType()) if (/*(dec->mFlags & DTF_STATIC) &&*/ (dec->mFlags & DTF_CONST) && dec->mValue)
{ {
exp = dec->mValue; if (dec->mBase->IsNumericType())
exp = dec->mValue;
else if (dec->mBase->mType == DT_TYPE_POINTER)
{
if (dec->mValue->mType == EX_CONSTANT)
{
if (dec->mValue->mDecValue->mType == DT_CONST_ADDRESS || dec->mValue->mDecValue->mType == DT_CONST_POINTER)
exp = dec->mValue;
}
}
} }
else
if (!exp)
{ {
exp = new Expression(mScanner->mLocation, EX_VARIABLE); exp = new Expression(mScanner->mLocation, EX_VARIABLE);
exp->mDecValue = dec; exp->mDecValue = dec;
exp->mDecType = dec->mBase; exp->mDecType = dec->mBase;
} }
mScanner->NextToken(); mScanner->NextToken();
} }
else if (dec->mType <= DT_TYPE_FUNCTION) else if (dec->mType <= DT_TYPE_FUNCTION)
@ -1747,6 +1758,9 @@ Expression* Parser::ParsePostfixExpression(void)
{ {
nexp->mDecValue = mdec; nexp->mDecValue = mdec;
nexp->mDecType = mdec->mBase; nexp->mDecType = mdec->mBase;
if (exp->mDecType->mFlags & DTF_CONST)
nexp->mDecType = nexp->mDecType->ToConstType();
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
} }
else else
@ -1776,6 +1790,9 @@ Expression* Parser::ParsePostfixExpression(void)
{ {
nexp->mDecValue = mdec; nexp->mDecValue = mdec;
nexp->mDecType = mdec->mBase; nexp->mDecType = mdec->mBase;
if (exp->mDecType->mFlags & DTF_CONST)
nexp->mDecType = nexp->mDecType->ToConstType();
exp = nexp->ConstantFold(mErrors); exp = nexp->ConstantFold(mErrors);
} }
else else

View File

@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.19.204"); strcpy(strProductVersion, "1.20.205");
#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,19,204,0 FILEVERSION 1,20,205,0
PRODUCTVERSION 1,19,204,0 PRODUCTVERSION 1,20,205,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.19.204.0" VALUE "FileVersion", "1.20.205.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.19.204.0" VALUE "ProductVersion", "1.20.205.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -5233,15 +5233,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{F70E375C-D170-4C0A-A338-9F17D3559C99}" "ProductCode" = "8:{9DBE9E77-8642-420D-8EE1-3D5CFDCE1BD0}"
"PackageCode" = "8:{7E82B938-0057-4512-9C0B-5E1EF0CC779C}" "PackageCode" = "8:{D0A5FA0F-5C04-421E-84FF-05F7F4AB42EB}"
"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.19.204" "ProductVersion" = "8:1.20.205"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"

Binary file not shown.