diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 047e15e..6c2e492 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -72,6 +72,8 @@ static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000; static const uint32 DTF_FUNC_RECURSIVE = 0x00100000; static const uint32 DTF_FUNC_ANALYZING = 0x00200000; +static const uint32 DTF_VAR_ALIASING = 0x00400000; + class Declaration; diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index ee40051..c82a85f 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -535,6 +535,13 @@ int Emulator::Emulate(int startIP) mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1; mRegS += 2; } + else if (mIP == 0xffcf) + { + int ch = getchar(); + mRegA = ch; + mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1; + mRegS += 2; + } uint8 opcode = mMemory[mIP]; AsmInsData d = DecInsData[opcode]; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 12c561d..41824d7 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -280,6 +280,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) case EX_PREINCDEC: return Analyze(exp->mLeft, procDec); case EX_PREFIX: + ldec = Analyze(exp->mLeft, procDec); + if (exp->mToken == TK_BINARY_AND) + { + if (ldec->mType == DT_VARIABLE) + ldec->mFlags |= DTF_VAR_ALIASING; + } break; case EX_POSTFIX: break; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 1c64103..e73901d 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -433,7 +433,7 @@ static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrAr return false; } -static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams) +static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars) { InterMemory lmem, smem; int lvindex, svindex; @@ -457,6 +457,8 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* return aliasedLocals[lvindex]; else if (lmem == IM_PARAM || lmem == IM_FPARAM) return aliasedParams[lvindex]; + else if (lmem == IM_GLOBAL) + return staticVars[lvindex]->mAliased; } return true; @@ -514,7 +516,7 @@ bool InterInstruction::IsEqual(const InterInstruction* ins) const } -void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams) +void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars) { int i, value, temp; @@ -609,7 +611,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr i = 0; while (i < mNum) { - if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams)) + if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams, staticVars)) { mNum--; if (mNum > 0) @@ -627,7 +629,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr i = 0; while (i < mNum) { - if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams)) + if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams, staticVars)) { mNum--; if (mNum > 0) @@ -787,7 +789,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -806,7 +808,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[1].mTemp = -1; assert(ins->mSrc[0].mTemp >= 0); - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -817,7 +819,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -832,7 +834,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[1].mTemp = -1; assert(ins->mSrc[0].mTemp >= 0); - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -844,7 +846,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -854,7 +856,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mOperator = IA_NEG; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -868,7 +870,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -878,7 +880,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[1].mTemp = -1; assert(ins->mSrc[0].mTemp >= 0); - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); return; } @@ -1093,7 +1095,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); } break; case IT_POINTER: @@ -1107,7 +1109,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); } else if (ins->mSrc[1].mTemp == ins->mSrc[0].mTemp) { @@ -1133,7 +1135,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr ins->mSrc[0].mTemp = -1; ins->mSrc[1].mTemp = -1; - UpdateValue(ins, tvalue, aliasedLocals, aliasedParams); + UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars); } break; } @@ -1298,7 +1300,11 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV { if (mSrc[0].mMemory == IM_INDIRECT) { - requiredVars.OrNot(providedVars); + for (int i = 0; i < staticVars.Size(); i++) + { + if (staticVars[i]->mAliased && !providedVars[i]) + requiredVars += i; + } } else if (mSrc[0].mMemory == IM_GLOBAL) { @@ -1310,7 +1316,11 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV { if (mSrc[1].mMemory == IM_INDIRECT) { - requiredVars.OrNot(providedVars); + for (int i = 0; i < staticVars.Size(); i++) + { + if (staticVars[i]->mAliased && !providedVars[i]) + requiredVars += i; + } } else if (mSrc[1].mMemory == IM_GLOBAL) { @@ -1565,7 +1575,11 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable { if (mSrc[0].mMemory == IM_INDIRECT) { - requiredVars.Fill(); + for (int i = 0; i < staticVars.Size(); i++) + { + if (staticVars[i]->mAliased) + requiredVars += i; + } } else if (mSrc[0].mMemory == IM_GLOBAL) { @@ -3185,7 +3199,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr } -void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps) +void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps, const GrowingVariableArray& staticVars) { int i; @@ -3441,12 +3455,12 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra } #endif - lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams); + lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams, staticVars); mInstructions[i]->PerformValueForwarding(ltvalue, tvalid); } - if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps); - if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps); + if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps, staticVars); + if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps, staticVars); } } @@ -4885,7 +4899,7 @@ void InterCodeProcedure::Close(void) tvalidSet.Reset(numTemps + 32); ResetVisited(); - mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps); + mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps, mModule->mGlobalVars); ResetVisited(); eliminated = mEntryBlock->EliminateDeadBranches(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 99e22da..404328b 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -148,7 +148,7 @@ public: void RemoveValue(int index); void InsertValue(InterInstruction * ins); - void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams); + void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); void Intersect(ValueSet& set); }; @@ -475,7 +475,7 @@ public: void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue); void PerformTempForwarding(TempForwardingTable& forwardingTable); - void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps); + void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); bool EliminateDeadBranches(void); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index ed3cdbc..a0a2445 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -837,6 +837,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* var->mIdent = dec->mIdent; var->mOffset = 0; var->mSize = dec->mSize; + if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY) + var->mAliased = true; var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA); dec->mLinkerObject = var->mLinkerObject; var->mLinkerObject->AddData(dec->mData, dec->mSize); diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 6904027..92af247 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -6,7 +6,8 @@ #include "MachineTypes.h" -const char* TokenNames[] = { +const char* TokenNames[] = +{ "tk_none", "tk_eof", "tk_error", @@ -16,129 +17,129 @@ const char* TokenNames[] = { "'else'", "'while'", "'do'", - "'for'", - "'void'", - "'int'", - "'char'", - "'float'", - "'unsigned'", - "'signed'", - "'switch'", - "'case'", - "'default'", - "'break'", - "'return'", - "'short'", - "'long'", - "'continue'", - "'integer'", - "'integeru'", - "'integerl'", - "'integerul'", - "'bool'", - "'const'", - "'volatile'", - "'typedef'", - "'struct'", - "'union'", - "'enum'", - "'sizeof'", - "'static'", - "'extern'", - "'inline'", + "'for'", + "'void'", + "'int'", + "'char'", + "'float'", + "'unsigned'", + "'signed'", + "'switch'", + "'case'", + "'default'", + "'break'", + "'return'", + "'short'", + "'long'", + "'continue'", + "'integer'", + "'integeru'", + "'integerl'", + "'integerul'", + "'bool'", + "'const'", + "'volatile'", + "'typedef'", + "'struct'", + "'union'", + "'enum'", + "'sizeof'", + "'static'", + "'extern'", + "'inline'", - "__asm", + "__asm", - "number", - "char", - "string literal", - "identifier", - "'true'", - "'false'", - "'nullptr'", + "number", + "char", + "string literal", + "identifier", + "'true'", + "'false'", + "'nullptr'", - "'+'", - "'-'", - "'*'", - "'/'", - "'%'", + "'+'", + "'-'", + "'*'", + "'/'", + "'%'", - "'<<'", - "'>>'", + "'<<'", + "'>>'", - "'++'", - "'--'", + "'++'", + "'--'", - "'!'", - "'&&'", - "'||'", + "'!'", + "'&&'", + "'||'", - "'~'", - "'&'", - "'|'", - "'^'", + "'~'", + "'&'", + "'|'", + "'^'", - "'=='", - "'!='", - "'>'", - "'>='", - "'<'", - "'<='", + "'=='", + "'!='", + "'>'", + "'>='", + "'<'", + "'<='", - "'='", - "'+='", - "'-='", - "'*='", - "'/='", - "'%='", - "'<<='", - "'>>='", - "'&='", - "'^='", - "'|='", + "'='", + "'+='", + "'-='", + "'*='", + "'/='", + "'%='", + "'<<='", + "'>>='", + "'&='", + "'^='", + "'|='", - "'->'", - "'#'", - "'$'", + "'->'", + "'#'", + "'$'", - "'('", - "')'", + "'('", + "')'", - "'{'", - "'}'", + "'{'", + "'}'", - "'['", - "']'", + "'['", + "']'", - "'.'", - "'..'", - "'...'", - "','", - "';'", - "':'", - "'?'", + "'.'", + "'..'", + "'...'", + "','", + "';'", + "':'", + "'?'", - "embedded", + "embedded", - "'#define'", - "'#include'", - "'#if'", - "'#elif'", - "'#else'", - "'#endif'", - "'#ifdef'", - "'#ifndef'", - "'#pragma'", + "'#define'", + "'#include'", + "'#if'", + "'#elif'", + "'#else'", + "'#endif'", + "'#ifdef'", + "'#ifndef'", + "'#pragma'", - "'#assign'", - "'#repeat'", - "'#until'", - "'#embed'" + "'#assign'", + "'#repeat'", + "'#until'", + "'#embed'" }; Macro::Macro(const Ident* ident) - : mIdent(ident), mString(nullptr), mNumArguments(0) + : mIdent(ident), mString(nullptr), mNumArguments(-1) { } @@ -471,6 +472,8 @@ void Scanner::NextToken(void) if (mTokenChar == '(') { + macro->mNumArguments = 0; + NextRawToken(); if (mTokenChar == ')') @@ -635,7 +638,21 @@ void Scanner::NextToken(void) { MacroExpansion* ex = new MacroExpansion(); ex->mDefinedArguments = mDefineArguments; - if (def->mNumArguments) + + if (def->mNumArguments == 0) + { + NextRawToken(); + if (mToken != TK_OPEN_PARENTHESIS) + mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Missing '(' for macro expansion"); + else + NextRawToken(); + if (mToken != TK_CLOSE_PARENTHESIS) + mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Missing ')' for macro expansion"); + else + NextRawToken(); + + } + else if (def->mNumArguments > 0) { mDefineArguments = new MacroDict(); NextRawToken(); @@ -712,9 +729,8 @@ void Scanner::NextRawToken(void) { if (mToken != TK_EOF) { - Token pt = mToken; - mToken = TK_ERROR; + mStartOfLine = false; while (IsWhitespace(mTokenChar)) { @@ -1011,7 +1027,7 @@ void Scanner::NextRawToken(void) case '#': { - if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1) + if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1 || mStartOfLine) { int n = 0; char tkprep[128]; @@ -1375,6 +1391,7 @@ bool Scanner::NextChar(void) else if (mPreprocessor->NextLine()) { mOffset = 0; + mStartOfLine = true; } else { @@ -1603,6 +1620,40 @@ int64 Scanner::PrepParseSimple(void) else mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected"); break; + case TK_IDENT: + if (strcmp(mTokenIdent->mString, "defined") == 0) + { + NextToken(); + if (mToken == TK_OPEN_PARENTHESIS) + { + NextRawToken(); + if (mToken == TK_IDENT) + { + Macro* def = nullptr; + if (mDefineArguments) + def = mDefineArguments->Lookup(mTokenIdent); + if (!def) + def = mDefines->Lookup(mTokenIdent); + if (def) + v = 1; + else + v = 0; + NextToken(); + } + else + mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected"); + + if (mToken == TK_CLOSE_PARENTHESIS) + NextToken(); + else + mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected"); + } + else + mErrors->Error(mLocation, ERRR_PREPROCESSOR, "'(' expected"); + } + else + mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor symbol", mTokenIdent->mString); + break; default: mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken)); if (mToken != TK_EOL) diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index d071a00..ec0743a 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -192,6 +192,7 @@ public: int mOffset; const char * mLine; + bool mStartOfLine; const Ident * mTokenIdent; char mTokenString[1024], mTokenChar;