Add enum class

This commit is contained in:
drmortalwombat 2023-11-09 16:33:50 +01:00
parent 70c6fb23cc
commit 3be6d20006
4 changed files with 239 additions and 10 deletions

View File

@ -13419,13 +13419,18 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams)
ins->mExpensive = true; ins->mExpensive = true;
break; break;
case IC_LEA: case IC_LEA:
{
int offset = 0;
if (ins->mSrc[0].mTemp < 0)
offset = ins->mSrc[0].mIntConst;
if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mTemp >= 0) if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[1].mTemp >= 0)
ins->mExpensive = true; ins->mExpensive = true;
else if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mRange.mMaxValue >= 256) else if (ins->mSrc[0].mTemp >= 0 && ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mRange.mMaxValue >= 256)
ins->mExpensive = true; ins->mExpensive = true;
else if (nins && nins->mCode == IC_LEA && nins->mSrc[0].mTemp >= 0 && (nins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_UNBOUND || nins->mSrc[0].mRange.mMaxValue >= 255)) else if (nins && nins->mCode == IC_LEA && nins->mSrc[0].mTemp >= 0 && (nins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_UNBOUND || nins->mSrc[0].mRange.mMaxValue + offset >= 255))
ins->mExpensive = true; ins->mExpensive = true;
break; } break;
case IC_LOAD: case IC_LOAD:
case IC_STORE: case IC_STORE:
ins->mExpensive = true; ins->mExpensive = true;

View File

@ -12138,12 +12138,21 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
else else
{ {
NativeCodeInstruction ainsl(ins, iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg]); NativeCodeInstruction ainsl(ins, iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg]);
if (ins->mSrc[0].IsUByte())
{
NativeCodeInstruction ainsh(ins, iop, ASMIM_IMMEDIATE, 0);
LoadValueToReg(proc, sins1, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp], &ainsl, &ainsh);
}
else
{
NativeCodeInstruction ainsh(ins, iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1); NativeCodeInstruction ainsh(ins, iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1);
LoadValueToReg(proc, sins1, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp], &ainsl, &ainsh); LoadValueToReg(proc, sins1, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp], &ainsl, &ainsh);
} }
} }
} }
}
else if (ins->mSrc[1].mTemp < 0) else if (ins->mSrc[1].mTemp < 0)
{ {
@ -20063,6 +20072,153 @@ bool NativeCodeBasicBlock::IsExitARegZP(int addr, int& index) const
return false; return false;
} }
bool NativeCodeBasicBlock::CanJoinEntryLoadStoreZP(int saddr, int daddr)
{
int at = mIns.Size() - 1;
while (at >= 0)
{
NativeCodeInstruction & ins = mIns[at];
if (ins.ReferencesZeroPage(daddr))
return false;
if (ins.ChangesZeroPage(saddr))
{
if (ins.mType == ASMIT_STA || ins.mType == ASMIT_STX || ins.mType == ASMIT_STY)
return true;
else
return false;
}
at--;
}
return false;
}
bool NativeCodeBasicBlock::DoJoinEntryLoadStoreZP(int saddr, int daddr)
{
int at = mIns.Size() - 1;
while (at >= 0)
{
NativeCodeInstruction& ins = mIns[at];
if (ins.ChangesZeroPage(saddr))
{
if (ins.mType == ASMIT_STA)
{
ins.mLive |= LIVE_CPU_REG_A;
mIns.Insert(at + 1, NativeCodeInstruction(ins.mIns, ASMIT_STA, ASMIM_ZERO_PAGE, daddr));
return true;
}
else if (ins.mType == ASMIT_STX)
{
ins.mLive |= LIVE_CPU_REG_X;
mIns.Insert(at + 1, NativeCodeInstruction(ins.mIns, ASMIT_STX, ASMIM_ZERO_PAGE, daddr));
return true;
}
else if (ins.mType == ASMIT_STY)
{
ins.mLive |= LIVE_CPU_REG_Y;
mIns.Insert(at + 1, NativeCodeInstruction(ins.mIns, ASMIT_STY, ASMIM_ZERO_PAGE, daddr));
return true;
}
}
at--;
}
return false;
}
bool NativeCodeBasicBlock::JoinEntryLoadStoreZP(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
CheckLive();
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].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) ||
mIns[i].mType == ASMIT_LDX && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))
{
int saddr = mIns[i].mAddress, daddr = mIns[i + 1].mAddress;
if (!ReferencesZeroPage(saddr, 0, i) && !ReferencesZeroPage(daddr, 0, i))
{
int n = 0;
for (int j = 0; j < mEntryBlocks.Size(); j++)
{
if (mEntryBlocks[j]->CanJoinEntryLoadStoreZP(saddr, daddr))
n++;
}
if (n == mEntryBlocks.Size())
{
for (int j = 0; j < mEntryBlocks.Size(); j++)
{
mEntryBlocks[j]->DoJoinEntryLoadStoreZP(saddr, daddr);
mEntryBlocks[j]->mExitRequiredRegs += daddr;
}
mEntryRequiredRegs += daddr;
changed = true;
mIns.Remove(i, 2);
i--;
}
else if (n >= 2)
{
NativeCodeBasicBlock* xblock = mProc->AllocateBlock();
int j = 0;
while (j < mEntryBlocks.Size())
{
NativeCodeBasicBlock* eb = mEntryBlocks[j];
if (eb->CanJoinEntryLoadStoreZP(saddr, daddr))
{
eb->DoJoinEntryLoadStoreZP(saddr, daddr);
eb->mExitRequiredRegs += daddr;
j++;
}
else
{
if (eb->mTrueJump == this)
eb->mTrueJump = xblock;
if (eb->mFalseJump == this)
eb->mFalseJump = xblock;
mEntryBlocks.Remove(i);
xblock->mEntryBlocks.Push(eb);
xblock->mNumEntries++;
}
}
xblock->mEntryRequiredRegs = mEntryRequiredRegs;
xblock->mExitRequiredRegs = mEntryRequiredRegs;
xblock->mExitRequiredRegs += daddr;
xblock->mIns.Push(mIns[i + 0]);
xblock->mIns.Push(mIns[i + 1]);
xblock->Close(mIns[i].mIns, this, nullptr, ASMIT_JMP);
mEntryBlocks.Push(xblock);
mNumEntries++;
mEntryRequiredRegs += daddr;
changed = true;
mIns.Remove(i, 2);
i--;
}
}
}
}
if (mTrueJump && mTrueJump->JoinEntryLoadStoreZP())
changed = true;
if (mFalseJump && mFalseJump->JoinEntryLoadStoreZP())
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops) bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool loops)
{ {
@ -25944,6 +26100,9 @@ bool NativeCodeBasicBlock::MoveLoadIndirectTempStoreUp(int at)
mIns[j - 0].mAddress == mIns[at + 1].mAddress + 1 && mIns[j - 0].mAddress == mIns[at + 1].mAddress + 1 &&
mIns[j - 1].mAddress == mIns[j - 3].mAddress + 1) mIns[j - 1].mAddress == mIns[j - 3].mAddress + 1)
{ {
for (int k = j + 1; k < at; k++)
mIns[k].mLive |= mIns[at + 2].mLive & LIVE_CPU_REG_Y;
mIns[at + 0].mLive |= mIns[j].mLive; mIns[at + 0].mLive |= mIns[j].mLive;
mIns[at + 1].mLive |= mIns[j].mLive; mIns[at + 1].mLive |= mIns[j].mLive;
mIns[at + 2].mLive |= mIns[j].mLive; mIns[at + 2].mLive |= mIns[j].mLive;
@ -25985,6 +26144,9 @@ bool NativeCodeBasicBlock::MoveLoadIndirectTempStoreUp(int at)
return false; return false;
} }
for (int k = j + 1; k < at; k++)
mIns[k].mLive |= mIns[at + 2].mLive & LIVE_CPU_REG_Y;
mIns[at + 0].mLive |= mIns[j].mLive; mIns[at + 0].mLive |= mIns[j].mLive;
mIns[at + 1].mLive |= mIns[j].mLive; mIns[at + 1].mLive |= mIns[j].mLive;
mIns[at + 2].mLive |= mIns[j].mLive; mIns[at + 2].mLive |= mIns[j].mLive;
@ -42373,7 +42535,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "A::draw");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -43308,6 +43470,13 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
if (step > 6)
{
ResetVisited();
if (mEntryBlock->JoinEntryLoadStoreZP())
changed = true;
}
#endif #endif
#if _DEBUG #if _DEBUG

View File

@ -515,6 +515,10 @@ public:
bool HasTailSTX(int& addr, int& index) const; bool HasTailSTX(int& addr, int& index) const;
bool HasTailSTY(int& addr, int& index) const; bool HasTailSTY(int& addr, int& index) const;
bool CanJoinEntryLoadStoreZP(int saddr, int daddr);
bool DoJoinEntryLoadStoreZP(int saddr, int daddr);
bool JoinEntryLoadStoreZP(void);
bool IsExitYRegZP(int addr, int& index) const; bool IsExitYRegZP(int addr, int& index) const;
bool IsExitXRegZP(int addr, int& index) const; bool IsExitXRegZP(int addr, int& index) const;
bool IsExitARegZP(int addr, int& index) const; bool IsExitARegZP(int addr, int& index) const;

View File

@ -855,7 +855,16 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
dec->mSize = 1; dec->mSize = 1;
dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS); dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
bool classTemplate = false;
mScanner->NextToken(); mScanner->NextToken();
if (mCompilerOptions & COPT_CPLUSPLUS)
{
if (ConsumeTokenIf(TK_CLASS) || ConsumeTokenIf(TK_STRUCT))
classTemplate = true;
}
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
{ {
dec->mIdent = mScanner->mTokenIdent; dec->mIdent = mScanner->mTokenIdent;
@ -870,6 +879,21 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
mScanner->NextToken(); mScanner->NextToken();
} }
if (mCompilerOptions & COPT_CPLUSPLUS)
{
if (ConsumeTokenIf(TK_COLON))
{
Declaration* pdec = ParseBaseTypeDeclaration(0, false);
if (pdec->mType == DT_TYPE_INTEGER)
{
dec->mSize = pdec->mSize;
dec->mFlags |= pdec->mFlags & DTF_SIGNED;
}
else
mErrors->Error(pdec->mLocation, EERR_INCOMPATIBLE_TYPES, "Integer base type expected");
}
}
int nitem = 0; int nitem = 0;
if (mScanner->mToken == TK_OPEN_BRACE) if (mScanner->mToken == TK_OPEN_BRACE)
{ {
@ -887,7 +911,12 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
{ {
cdec->mIdent = mScanner->mTokenIdent; cdec->mIdent = mScanner->mTokenIdent;
cdec->mQualIdent = mScope->Mangle(cdec->mIdent); cdec->mQualIdent = mScope->Mangle(cdec->mIdent);
Declaration* odec = mScope->Insert(cdec->mIdent, cdec); Declaration* odec;
if (classTemplate)
odec = dec->mScope->Insert(cdec->mIdent, cdec);
else
odec = mScope->Insert(cdec->mIdent, cdec);
if (odec) if (odec)
{ {
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", mScanner->mTokenIdent->mString); mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", mScanner->mTokenIdent->mString);
@ -3684,12 +3713,30 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
} }
else else
{ {
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace"); mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a namespace");
mErrors->Error(dec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition"); mErrors->Error(dec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
} }
} }
return dec; return nullptr;
}
else if (ConsumeTokenIf(TK_ENUM))
{
Declaration* dec = ParseQualIdent();
if (dec)
{
if (dec->mType == DT_TYPE_ENUM)
{
mScope->UseScope(dec->mScope);
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not an enum");
mErrors->Error(dec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
}
}
return nullptr;
} }
else else
{ {
@ -4818,7 +4865,7 @@ Declaration* Parser::ParseQualIdent(void)
{ {
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
{ {
if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT) if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_ENUM)
{ {
Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING); Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING);
@ -5189,6 +5236,10 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
exp = ParseDeclarationExpression(nullptr); exp = ParseDeclarationExpression(nullptr);
break; break;
case TK_USING:
ParseDeclaration(nullptr, true, true);
break;
case TK_CHARACTER: case TK_CHARACTER:
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
dec->mInteger = mCharMap[(unsigned char)mScanner->mTokenInteger]; dec->mInteger = mCharMap[(unsigned char)mScanner->mTokenInteger];
@ -5445,7 +5496,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
{ {
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
{ {
if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT) if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_ENUM)
{ {
Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING); Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING);