diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 7b6f71e..43c3e3e 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -770,7 +770,10 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* decb = decb->mBase; if (decb && decb->mStripe != 1) + { AddGlobalVariableRanges(var->mLinkerObject, decb, 0, nullptr); + var->mLinkerObject->mStripe = decb->mStripe; + } Declaration* type = dec->mBase; while (type->mType == DT_TYPE_ARRAY) diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index 1a4b5ba..d0c4159 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -45,7 +45,7 @@ bool LinkerReference::operator!=(const LinkerReference& ref) } LinkerObject::LinkerObject(void) - : mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr) + : mReferences(nullptr), mNumTemporaries(0), mSize(0), mStripe(0), mAlignment(1), mStackSection(nullptr), mIdent(nullptr), mFullIdent(nullptr), mStartUsed(0x10000), mEndUsed(0x00000), mMemory(nullptr) , mPrefix(nullptr), mSuffix(nullptr), mProc(nullptr), mNativeProc(nullptr) {} diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 47c9dcb..abf7b7c 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -190,7 +190,7 @@ public: LinkerObjectType mType; int mID, mMapID; int mAddress, mRefAddress; - int mSize, mAlignment, mStartUsed, mEndUsed; + int mSize, mAlignment, mStripe, mStartUsed, mEndUsed; LinkerSection * mSection; LinkerRegion * mRegion; uint8 * mData, * mMemory; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8533e92..2efb027 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -32,6 +32,33 @@ static const uint32 LIVE_ALL = 0x000000ff; static int GlobalValueNumber = 0; +static bool IsPowerOf2(unsigned n) +{ + return (n & (n - 1)) == 0; +} + +static int Binlog(unsigned n) +{ + int k = -1; + + while (n) + { + n >>= 1; + k++; + } + + return k; +} + +static unsigned BinMask(unsigned n) +{ + n |= n >> 8; + n |= n >> 4; + n |= n >> 2; + n |= n >> 1; + return n; +} + NativeRegisterData::NativeRegisterData(void) : mMode(NRDM_UNKNOWN), mValue(GlobalValueNumber++), mMask(0) { @@ -1939,6 +1966,23 @@ bool NativeCodeInstruction::MayReference(const NativeCodeInstruction& ins, bool return false; } +bool NativeCodeInstruction::SameLinkerObjectVariableRange(const NativeCodeInstruction& ins, bool sameXY) const +{ + if (mLinkerObject == ins.mLinkerObject) + { + if (mMode == ASMIM_ABSOLUTE && ins.mMode == ASMIM_ABSOLUTE) + return mAddress == ins.mAddress; + else if (mMode == ins.mMode && sameXY) + return mAddress == ins.mAddress; + else if (mLinkerObject && mLinkerObject->mStripe > 1) + return mAddress / mLinkerObject->mStripe == ins.mAddress / mLinkerObject->mStripe; + else + return true; + } + else + return false; +} + bool NativeCodeInstruction::MayBeChangedOnAddress(const NativeCodeInstruction& ins, bool sameXY) const { if (mMode == ASMIM_IMMEDIATE || mMode == ASMIM_IMMEDIATE_ADDRESS) @@ -1974,10 +2018,8 @@ bool NativeCodeInstruction::MayBeChangedOnAddress(const NativeCodeInstruction& i } else if (ins.mMode == ASMIM_ABSOLUTE) { - if (mMode == ASMIM_ABSOLUTE) - return mLinkerObject == ins.mLinkerObject && mAddress == ins.mAddress; - else if (mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y) - return mLinkerObject == ins.mLinkerObject; + if (mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y) + return SameLinkerObjectVariableRange(ins, sameXY); else if (mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_INDIRECT_X) return mAddress != BC_REG_STACK; else @@ -1986,12 +2028,7 @@ bool NativeCodeInstruction::MayBeChangedOnAddress(const NativeCodeInstruction& i else if (ins.mMode == ASMIM_ABSOLUTE_X || ins.mMode == ASMIM_ABSOLUTE_Y) { if (mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y) - { - if (mLinkerObject != ins.mLinkerObject) - return false; - else - return mMode != ins.mMode || !sameXY || mAddress == ins.mAddress; - } + return SameLinkerObjectVariableRange(ins, sameXY); else if (mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_INDIRECT_X) return mAddress != BC_REG_STACK; else @@ -2910,6 +2947,13 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI data.mRegs[CPU_REG_A].mValue ^= 3; changed = true; } + else if (mMode == ASMIM_IMMEDIATE && mAddress + ((data.mRegs[CPU_REG_A].mValue & data.mRegs[CPU_REG_A].mMask) | (~data.mRegs[CPU_REG_A].mMask & 255)) < 256) + { + data.mRegs[CPU_REG_C].mMask = 1; + data.mRegs[CPU_REG_C].mValue = 0; + data.mRegs[CPU_REG_A].mMask = ~BinMask(mAddress + ((data.mRegs[CPU_REG_A].mValue & data.mRegs[CPU_REG_A].mMask) | (~data.mRegs[CPU_REG_A].mMask & 255))) & 255; + data.mRegs[CPU_REG_A].mValue = 0; + } else { data.mRegs[CPU_REG_C].mMask = 0; @@ -9680,32 +9724,6 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProc } } -static bool IsPowerOf2(unsigned n) -{ - return (n & (n - 1)) == 0; -} - -static int Binlog(unsigned n) -{ - int k = -1; - - while (n) - { - n >>= 1; - k++; - } - - return k; -} - -static unsigned BinMask(unsigned n) -{ - n |= n >> 8; - n |= n >> 4; - n |= n >> 2; - n |= n >> 1; - return n; -} void NativeCodeBasicBlock::AddAsrSignedByte(InterCodeProcedure* proc, const InterInstruction* ains, const InterInstruction* sins) { @@ -28610,6 +28628,108 @@ bool NativeCodeBasicBlock::PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* return changed; } + +bool NativeCodeBasicBlock::CheckSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains, bool cleared, bool poisoned) +{ + bool ok = true; + if (!mPatched) + { + if (at == 0) + mPatched = true; + + if (this != block && !IsDominatedBy(block)) + poisoned = true; + + bool used = false; + + for (int i = at; i < mIns.Size() && !cleared; i++) + { + const NativeCodeInstruction& ins(mIns[i]); + + if (ins.SameEffectiveAddress(rins)) + { + if (ins.mType == ASMIT_LDA) + { + if (poisoned) + return false; + used = true; + } + else if (ins.mType == ASMIT_STA || ins.mType == ASMIT_STX || ins.mType == ASMIT_STY) + { + cleared = true; + poisoned = false; + } + else + poisoned = true; + } + else if (poisoned && rins.MayBeSameAddress(ins)) + return false; + else if (rins.MayBeChangedOnAddress(ins, true) || ains.MayBeChangedOnAddress(ins, true)) + poisoned = true; + else if (ins.ChangesXReg() && ains.ReferencesXReg() || ins.ChangesYReg() && ains.ReferencesYReg()) + poisoned = true; + } + + if (this == block && at == 0) + { + mPatchUsed = used; + } + else + { + mPatchUsed = used || !cleared; + + if (mTrueJump && !mTrueJump->CheckSingleUseGlobalLoadStruct(block, rins, 0, ains, cleared, poisoned)) + return false; + if (mFalseJump && !mFalseJump->CheckSingleUseGlobalLoadStruct(block, rins, 0, ains, cleared, poisoned)) + return false; + + mPatchUsed = used || (mTrueJump && mTrueJump->mPatchUsed) || (mFalseJump && mFalseJump->mPatchUsed); + } + } + else if (mPatchUsed && (poisoned || cleared)) + return false; + + return true; +} + +bool NativeCodeBasicBlock::PatchSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains) +{ + bool changed = false; + if (!mPatched) + { + if (at == 0) + mPatched = true; + + bool cleared = false; + for (int i = at; i < mIns.Size() && !cleared; i++) + { + NativeCodeInstruction& ins(mIns[i]); + + if (ins.SameEffectiveAddress(rins)) + { + if (ins.mType == ASMIT_LDA) + { + ins.CopyMode(ains); + changed = true; + } + else if (ins.mType == ASMIT_STA || ins.mType == ASMIT_STX || ins.mType == ASMIT_STY) + cleared = true; + } + } + + if (!cleared) + { + if (mTrueJump && !mTrueJump->PatchSingleUseGlobalLoadStruct(block, rins, 0, ains)) + changed = true; + if (mFalseJump && !mFalseJump->PatchSingleUseGlobalLoadStruct(block, rins, 0, ains)) + changed = true; + } + } + + return changed; +} + + bool NativeCodeBasicBlock::CheckForwardLowYPointer(const NativeCodeBasicBlock* block, int reg, int yreg, int at, int yval) { // Checking only current block as first optimization step @@ -44004,6 +44124,35 @@ void NativeCodeBasicBlock::BlockSizeReduction(NativeCodeProcedure* proc, int xen } break; case ASMIT_ADC: + { + if (mIns[i].mMode == ASMIM_IMMEDIATE) + { + int amax = ((accuVal & accuMask) | (~accuMask & 255)) + mIns[i].mAddress; + if (!carryClear) + amax++; + if (amax < 256) + { + carryClear = true; + carrySet = false; + accuMask = ~BinMask(accuMask) & 255; + accuVal = 0; + } + else + { + accuMask = 0; + accuFlags = true; + carryClear = false; + carrySet = false; + } + } + else + { + accuMask = 0; + accuFlags = true; + carryClear = false; + carrySet = false; + } + } break; case ASMIT_SBC: accuMask = 0; accuFlags = true; @@ -51659,6 +51808,29 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate(int pass) if (mFalseJump) mFalseJump->CheckLive(); +#if 1 + if (pass == 8 && i + 1 < mIns.Size() && (mProc->mCompilerOptions & COPT_OPTIMIZE_BASIC)) + { + if ( + mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_ABSOLUTE_X || mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y) && + !(mIns[i + 0].mFlags & NCIF_VOLATILE) && + mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE && mIns[i + 1].mLinkerObject && + mIns[i + 1].mLinkerObject->mVariable && (mIns[i + 1].mLinkerObject->mFlags & LOBJF_LOCAL_VAR)) + { + mProc->ResetPatched(); + if (CheckSingleUseGlobalLoadStruct(this, mIns[i + 1], i + 2, mIns[i + 0], false, false)) + { + mProc->ResetPatched(); + if (PatchSingleUseGlobalLoadStruct(this, mIns[i + 1], i + 2, mIns[i + 0])) + { + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 1].mMode = ASMIM_IMPLIED; + changed = true; + } + } + } + } +#endif #if 1 if (pass < 10 && i + 1 < mIns.Size()) { @@ -52719,6 +52891,26 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerExits(int pass) } } #endif + + sz = mIns.Size(); + if (sz >= 4 && mFalseJump && (mBranch == ASMIT_BPL || mBranch == ASMIT_BMI)) + { + if (mIns[sz - 4].mType == ASMIT_TAY && + mIns[sz - 3].mType == ASMIT_ASL && mIns[sz - 3].mMode == ASMIM_IMPLIED && + mIns[sz - 2].mType == ASMIT_TAX && + mIns[sz - 1].mType == ASMIT_TYA && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A)) + { + mIns[sz - 3].mLive |= LIVE_CPU_REG_C; + mIns[sz - 2].mLive |= LIVE_CPU_REG_C; + mIns[sz - 1].mType = ASMIT_NOP; + if (mBranch == ASMIT_BPL) + mBranch = ASMIT_BCC; + else + mBranch = ASMIT_BCS; + changed = true; + } + } + #if 1 if (pass > 15 && sz > 0 && (mIns[sz - 1].mType == ASMIT_CMP || mIns[sz - 1].mType == ASMIT_CPX || mIns[sz - 1].mType == ASMIT_CPY)) { @@ -56039,6 +56231,7 @@ void NativeCodeProcedure::ResetPatched(void) NativeCodeBasicBlock* b = mBlocks[i]; b->mPatched = false; b->mPatchFail = false; + b->mPatchUsed = false; b->mPatchChecked = false; b->mPatchStart = false; b->mPatchLoop = false; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index fc78c6c..aab525a 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -198,6 +198,7 @@ public: bool UsesZeroPage(int address) const; bool ReferencesZeroPage(int address) const; + bool SameLinkerObjectVariableRange(const NativeCodeInstruction& ins, bool sameXY = false) const; bool ChangesGlobalMemory(void) const; bool UsesMemoryOf(const NativeCodeInstruction& ins) const; @@ -259,7 +260,7 @@ public: ExpandingArray mEntryBlocks; int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp; - bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit; + bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchUsed, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit; bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked; NativeCodeBasicBlock * mDominator, * mSameBlock; @@ -798,9 +799,20 @@ public: bool CheckGlobalAddressSumYPointer(const NativeCodeBasicBlock * block, int reg, int index, int at, int yval); bool PatchGlobalAddressSumYPointer(const NativeCodeBasicBlock* block, int reg, int index, int at, int yval, LinkerObject * lobj, int address, uint32 flags = NCIF_LOWER | NCIF_UPPER); + // reg : register to replace + // at : start position in block + // ains : instruction loading original data + // cycles : max number of cycles saving bool CheckSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains, int cycles); bool PatchSingleUseGlobalLoad(const NativeCodeBasicBlock* block, int reg, int at, const NativeCodeInstruction& ains); + // rins : instruction storing the data + // at : start position in block + // ains : instruction loading original data + // cycles : max number of cycles saving + bool CheckSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains, bool cleared, bool poisoned); + bool PatchSingleUseGlobalLoadStruct(const NativeCodeBasicBlock* block, const NativeCodeInstruction& rins, int at, const NativeCodeInstruction& ains); + // reg : base register pair to replace // base: new base register // iins : indexing instruction diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 96be63d..de3e69d 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -5935,13 +5935,33 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec) Declaration* Parser::ParseQualIdent(bool lhs) { Declaration* dec = nullptr; - if (mTemplateScope) - { - dec = mTemplateScope->Lookup(mScanner->mTokenIdent); - } - if (!dec) - dec = mScope->Lookup(mScanner->mTokenIdent); + if (mScanner->mToken == TK_COLCOLON) + { + mScanner->NextToken(); + if (mScanner->mToken == TK_IDENT) + { + DeclarationScope* scope = mScope; + while (scope->mLevel > SLEVEL_STATIC) + scope = scope->mParent; + dec = scope->Lookup(mScanner->mTokenIdent); + } + else + { + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected"); + return nullptr; + } + } + else + { + if (mTemplateScope) + { + dec = mTemplateScope->Lookup(mScanner->mTokenIdent); + } + + if (!dec) + dec = mScope->Lookup(mScanner->mTokenIdent); + } if (dec) { @@ -6370,6 +6390,123 @@ Expression* Parser::ParseCastExpression(Expression* exp) return exp; } +Expression* Parser::ParseIdentExpression(const Location & eloc, Declaration* dec, bool lhs, bool tid) +{ + Expression* exp = nullptr; + + if (dec->mTemplate && mScanner->mToken == TK_LESS_THAN) + { + dec = ParseTemplateExpansion(dec->mTemplate, nullptr); + while (ConsumeTokenIf(TK_COLCOLON)) + { + if (mScanner->mToken == TK_IDENT) + { + if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_ENUM) + { + Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING); + + if (ndec) + dec = ndec; + else + mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown identifier", mScanner->mTokenIdent); + } + else + mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace"); + + } + else + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected"); + + mScanner->NextToken(); + } + } + + if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF) + { + exp = new Expression(eloc, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + exp->mConst = true; + } + else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT) + { + if (/*(dec->mFlags & DTF_STATIC) &&*/ (dec->mFlags & DTF_CONST) && dec->mValue) + { + if (dec->mBase->IsNumericType()) + { + if (dec->mValue->mType == EX_CONSTANT) + { + 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; + } + } + } + + if (!exp) + { + exp = new Expression(eloc, EX_VARIABLE); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + } + } + else if (dec->mType == DT_PACK_ARGUMENT) + { + exp = new Expression(mScanner->mLocation, EX_PACK); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + } + else if (dec->mType == DT_PACK_TYPE) + { + exp = new Expression(mScanner->mLocation, EX_PACK_TYPE); + exp->mDecValue = nullptr; + exp->mDecType = dec; + } + else if (dec->mType <= DT_TYPE_FUNCTION) + { + if (lhs) + exp = ParseDeclarationExpression(dec); + else + { + exp = new Expression(mScanner->mLocation, EX_TYPE); + exp->mDecValue = nullptr; + exp->mDecType = ParseTypeID(tid, dec); + } + } + else if (dec->mType == DT_CONST_TEMPLATE) + { + exp = new Expression(mScanner->mLocation, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = TheSignedIntTypeDeclaration; + } + else if (dec->mType == DT_PACK_TEMPLATE) + { + exp = new Expression(mScanner->mLocation, EX_PACK_TYPE); + exp->mDecType = dec; + } + else if (dec->mType == DT_ELEMENT) + { + mErrors->Error(mScanner->mLocation, EERR_NON_STATIC_MEMBER, "Non static member access", mScanner->mTokenIdent); + } + else if (dec->mType == DT_CLABEL) + { + exp = new Expression(dec->mLocation, EX_LABEL); + exp->mDecValue = dec; + } + else + { + mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Invalid identifier", mScanner->mTokenIdent); + } + + return exp; +} + Expression* Parser::ParseSimpleExpression(bool lhs, bool tid) { Declaration* dec = nullptr; @@ -6596,6 +6733,12 @@ Expression* Parser::ParseSimpleExpression(bool lhs, bool tid) mScanner->NextToken(); break; + case TK_COLCOLON: + dec = ParseQualIdent(lhs); + if (dec) + exp = ParseIdentExpression(eloc, dec, lhs); + break; + case TK_IDENT: if (mLambda && mCaptureToken != TK_NONE && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS) && !mLambda->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS)) { @@ -6670,117 +6813,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs, bool tid) if (!dec) dec = ParseQualIdent(lhs); if (dec) - { - if (dec->mTemplate && mScanner->mToken == TK_LESS_THAN) - { - dec = ParseTemplateExpansion(dec->mTemplate, nullptr); - while (ConsumeTokenIf(TK_COLCOLON)) - { - if (mScanner->mToken == TK_IDENT) - { - if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_ENUM) - { - Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_USING); - - if (ndec) - dec = ndec; - else - mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown identifier", mScanner->mTokenIdent); - } - else - mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace"); - - } - else - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected"); - - mScanner->NextToken(); - } - } - - if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF) - { - exp = new Expression(eloc, EX_CONSTANT); - exp->mDecValue = dec; - exp->mDecType = dec->mBase; - exp->mConst = true; - } - else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT) - { - if (/*(dec->mFlags & DTF_STATIC) &&*/ (dec->mFlags & DTF_CONST) && dec->mValue) - { - if (dec->mBase->IsNumericType()) - { - if (dec->mValue->mType == EX_CONSTANT) - { - 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; - } - } - } - - if (!exp) - { - exp = new Expression(eloc, EX_VARIABLE); - exp->mDecValue = dec; - exp->mDecType = dec->mBase; - } - } - else if (dec->mType == DT_PACK_ARGUMENT) - { - exp = new Expression(mScanner->mLocation, EX_PACK); - exp->mDecValue = dec; - exp->mDecType = dec->mBase; - } - else if (dec->mType == DT_PACK_TYPE) - { - exp = new Expression(mScanner->mLocation, EX_PACK_TYPE); - exp->mDecValue = nullptr; - exp->mDecType = dec; - } - else if (dec->mType <= DT_TYPE_FUNCTION) - { - if (lhs) - exp = ParseDeclarationExpression(dec); - else - { - exp = new Expression(mScanner->mLocation, EX_TYPE); - exp->mDecValue = nullptr; - exp->mDecType = ParseTypeID(tid, dec); - } - } - else if (dec->mType == DT_CONST_TEMPLATE) - { - exp = new Expression(mScanner->mLocation, EX_CONSTANT); - exp->mDecValue = dec; - exp->mDecType = TheSignedIntTypeDeclaration; - } - else if (dec->mType == DT_PACK_TEMPLATE) - { - exp = new Expression(mScanner->mLocation, EX_PACK_TYPE); - exp->mDecType = dec; - } - else if (dec->mType == DT_ELEMENT) - { - mErrors->Error(mScanner->mLocation, EERR_NON_STATIC_MEMBER, "Non static member access", mScanner->mTokenIdent); - } - else if (dec->mType == DT_CLABEL) - { - exp = new Expression(dec->mLocation, EX_LABEL); - exp->mDecValue = dec; - } - else - { - mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Invalid identifier", mScanner->mTokenIdent); - } - } + exp = ParseIdentExpression(eloc, dec, lhs, tid); } break; diff --git a/oscar64/Parser.h b/oscar64/Parser.h index c2f54df..54f0e90 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -134,6 +134,7 @@ protected: Declaration* ParseTypeID(bool tid, Declaration * bdec = nullptr); Expression* ParseCastExpression(Expression* exp); + Expression* ParseIdentExpression(const Location & eloc, Declaration* dec, bool lhs, bool tid = false); Expression* ParseSimpleExpression(bool lhs, bool tid = false); Expression* ParsePrefixExpression(bool lhs); Expression* ParsePostfixExpression(bool lhs);