Direct parameter forwarding

This commit is contained in:
drmortalwombat 2023-12-02 10:58:20 +01:00
parent 003306f961
commit 8ab46e29dd
9 changed files with 310 additions and 51 deletions

View File

@ -1,5 +1,6 @@
#include "Declaration.h" #include "Declaration.h"
#include "Constexpr.h" #include "Constexpr.h"
#include "Linker.h"
#include <math.h> #include <math.h>
DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name) DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name)
@ -451,10 +452,33 @@ Expression* Expression::LogicInvertExpression(void)
} }
} }
Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection) Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSection, Linker* linker)
{ {
if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT) if (mType == EX_PREFIX && mToken == TK_BANKOF && linker)
{ {
LinkerRegion* rgn;
if (mLeft->mDecValue->mSection && (rgn = linker->FindRegionOfSection(mLeft->mDecValue->mSection)))
{
uint64 i = 0;
while (i < 64 && rgn->mCartridgeBanks != (1ULL << i))
i++;
if (i < 64)
{
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = TheUnsignedCharTypeDeclaration;
dec->mInteger = i;
ex->mDecValue = dec;
ex->mDecType = dec->mBase;
return ex;
}
}
return this;
}
else if (mType == EX_PREFIX && mLeft->mType == EX_CONSTANT)
{
if (mLeft->mDecValue->mType == DT_CONST_INTEGER) if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
{ {
switch (mToken) switch (mToken)
@ -944,7 +968,7 @@ Declaration::Declaration(const Location& loc, DecType type)
mConst(nullptr), mMutable(nullptr), mConst(nullptr), mMutable(nullptr),
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr), mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(nullptr),
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr), mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
mVTable(nullptr), mTemplate(nullptr), mVTable(nullptr), mTemplate(nullptr), mForwardParam(nullptr), mForwardCall(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr),
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), mTokens(nullptr), mParser(nullptr), mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr),

View File

@ -8,6 +8,7 @@
class LinkerObject; class LinkerObject;
class LinkerSection; class LinkerSection;
class Linker;
class Parser; class Parser;
enum DecType enum DecType
@ -244,7 +245,7 @@ public:
bool mConst; bool mConst;
Expression* LogicInvertExpression(void); Expression* LogicInvertExpression(void);
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection); Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
bool HasSideEffects(void) const; bool HasSideEffects(void) const;
bool IsSame(const Expression* exp) const; bool IsSame(const Expression* exp) const;
@ -268,6 +269,7 @@ public:
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment; Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment; Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
Declaration * mVTable, * mClass, * mTemplate; Declaration * mVTable, * mClass, * mTemplate;
Declaration * mForwardParam, * mForwardCall;
Expression* mValue, * mReturn; Expression* mValue, * mReturn;
DeclarationScope* mScope; DeclarationScope* mScope;

View File

@ -305,7 +305,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
{ {
CheckFastcall(vf, false); CheckFastcall(vf, false);
int n = vf->mBase->mFastCallBase + vf->mBase->mFastCallSize; int n = vf->mBase->mFastCallSize;
if (n > nbase) if (n > nbase)
nbase = n; nbase = n;
} }
@ -323,7 +323,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
// procDec->mBase->mFlags |= DTF_STACKCALL; // procDec->mBase->mFlags |= DTF_STACKCALL;
cf = cf->mBase; cf = cf->mBase;
int n = cf->mFastCallBase + cf->mFastCallSize; int n = cf->mFastCallSize;
if (n > nbase) if (n > nbase)
nbase = n; nbase = n;
} }
@ -359,7 +359,16 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
if (cf != maxf) if (cf != maxf)
{ {
cf->mParams = maxf->mParams; Declaration* fp = cf->mBase->mParams, * mp = maxf->mBase->mParams;
while (fp)
{
fp->mVarIndex = mp->mVarIndex;
fp = fp->mNext;
mp = mp->mNext;
}
assert(!mp);
cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase; cf->mBase->mFastCallBase = cf->mFastCallBase = maxf->mBase->mFastCallBase;
cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize; cf->mBase->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
} }
@ -373,9 +382,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
} }
procDec->mFastCallBase = nbase; procDec->mFastCallBase = nbase;
procDec->mFastCallSize = 0; procDec->mFastCallSize = nbase;
procDec->mBase->mFastCallBase = nbase; procDec->mBase->mFastCallBase = nbase;
procDec->mBase->mFastCallSize = 0; procDec->mBase->mFastCallSize = nbase;
procDec->mFlags &= ~DTF_FUNC_ANALYZING; procDec->mFlags &= ~DTF_FUNC_ANALYZING;
@ -390,7 +399,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
} }
else if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_DYNSTACK)) else if (!(procDec->mBase->mFlags & DTF_VARIADIC) && !(procDec->mFlags & DTF_FUNC_VARIABLE) && !(procDec->mFlags & DTF_DYNSTACK))
{ {
int nparams = 0, npalign = 0; int nparams = nbase, npalign = 0;
int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS; int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
int fplimit = numfpzero; int fplimit = numfpzero;
@ -407,48 +416,66 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
nparams += 2; nparams += 2;
} }
int cnparams = nparams;
Declaration* dec = procDec->mBase->mParams; Declaration* dec = procDec->mBase->mParams;
while (dec) while (dec)
{ {
// Check for parameter crossing boundary // Check for parameter crossing boundary
if (nbase + nparams < numfpzero && nbase + nparams + dec->mBase->mSize > numfpzero) if (cnparams < numfpzero && cnparams + dec->mBase->mSize > numfpzero)
{ {
npalign = numfpzero - (nbase + nparams); npalign = numfpzero - nparams;
nparams += npalign; cnparams += npalign;
} }
nparams += dec->mBase->mSize; cnparams += dec->mBase->mSize;
dec = dec->mNext; dec = dec->mNext;
} }
if (nbase + nparams <= fplimit) if (cnparams <= fplimit)
{ {
npalign = 0;
dec = procDec->mBase->mParams;
while (dec)
{
if (dec->mForwardParam && (dec->mForwardCall->mBase->mFlags & DTF_FASTCALL) && !(dec->mForwardCall->mFlags & DTF_INLINE))
{
dec->mVarIndex = dec->mForwardParam->mVarIndex;
}
else
{
dec->mForwardParam = nullptr;
// Check for parameter crossing boundary
if (nparams < numfpzero && nparams + dec->mBase->mSize > numfpzero)
{
npalign = numfpzero - nparams;
nparams += npalign;
}
dec->mVarIndex = nparams;
nparams += dec->mBase->mSize;
}
dec = dec->mNext;
}
procDec->mFastCallBase = nbase; procDec->mFastCallBase = nbase;
procDec->mFastCallSize = nparams; procDec->mFastCallSize = nparams;
procDec->mBase->mFastCallBase = nbase; procDec->mBase->mFastCallBase = nbase;
procDec->mBase->mFastCallSize = nparams; procDec->mBase->mFastCallSize = nparams;
// Align fast call parameters to avoid crossing the zero page boundary
if (npalign)
{
Declaration* dec = procDec->mBase->mParams;
while (dec)
{
if (nbase + dec->mVarIndex + dec->mBase->mSize > numfpzero)
dec->mVarIndex += npalign;
dec = dec->mNext;
}
}
procDec->mBase->mFlags |= DTF_FASTCALL; procDec->mBase->mFlags |= DTF_FASTCALL;
#if 0 #if 0
printf("FASTCALL %s\n", f->mIdent->mString); printf("FASTCALL %s\n", f->mIdent->mString);
#endif #endif
} }
else else
{
// printf("STACKCALL %s, %d %d\n", procDec->mIdent->mString, cnparams, fplimit);
procDec->mBase->mFlags |= DTF_STACKCALL; procDec->mBase->mFlags |= DTF_STACKCALL;
}
} }
else else
{
// printf("STACKCALL %s, F%d\n", procDec->mIdent->mString, !!(procDec->mFlags& DTF_FUNC_VARIABLE));
procDec->mBase->mFlags |= DTF_STACKCALL; procDec->mBase->mFlags |= DTF_STACKCALL;
}
} }
} }
@ -759,6 +786,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
return exp->mDecType; return exp->mDecType;
} }
else if (exp->mToken == TK_BANKOF)
{
return TheUnsignedCharTypeDeclaration;
}
else else
{ {
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize; procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;

View File

@ -18,7 +18,9 @@ static const uint64 OPTF_VAR_CONST = (1ULL << 9);
static const uint64 OPTF_VAR_NOCONST = (1ULL << 10); static const uint64 OPTF_VAR_NOCONST = (1ULL << 10);
static const uint64 OPTF_SINGLE_RETURN = (1ULL << 11); static const uint64 OPTF_SINGLE_RETURN = (1ULL << 11);
static const uint64 OPTF_MULTI_RETURN = (1ULL << 12); static const uint64 OPTF_MULTI_RETURN = (1ULL << 12);
static const uint64 OPTF_VAR_NO_FORWARD = (1UL << 13);
static const uint64 OPTF_SINGLE_CALL = (1ULL << 14);
static const uint64 OPTF_MULTI_CALL = (1ULL << 15);
GlobalOptimizer::GlobalOptimizer(Errors* errors, Linker* linker) GlobalOptimizer::GlobalOptimizer(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker) : mErrors(errors), mLinker(linker)
@ -45,6 +47,7 @@ void GlobalOptimizer::Reset(void)
while (pdec) while (pdec)
{ {
pdec->mOptFlags = 0; pdec->mOptFlags = 0;
pdec->mForwardParam = nullptr;
pdec = pdec->mNext; pdec = pdec->mNext;
} }
} }
@ -278,6 +281,17 @@ bool GlobalOptimizer::Optimize(void)
if (CheckConstReturns(func->mValue)) if (CheckConstReturns(func->mValue))
changed = true; changed = true;
if (func->mOptFlags & OPTF_MULTI_CALL)
{
Declaration* pdata = ftype->mParams;
while (pdata)
{
pdata->mForwardCall = nullptr;
pdata->mForwardParam = nullptr;
pdata = pdata->mNext;
}
}
if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL)) if (!(func->mOptFlags & OPTF_FUNC_VARIABLE) && !(func->mBase->mFlags & DTF_VIRTUAL))
{ {
if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference())) if (!(func->mOptFlags & OPTF_VAR_USED) && func->mBase->mBase && (func->mBase->mBase->IsSimpleType() || func->mBase->mBase->IsReference()))
@ -601,6 +615,12 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (flags & ANAFL_LHS) if (flags & ANAFL_LHS)
exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS; exp->mDecValue->mOptFlags |= OPTF_VAR_ADDRESS;
} }
if (exp->mDecValue->mType == DT_ARGUMENT)
{
exp->mDecValue->mOptFlags |= OPTF_VAR_NO_FORWARD;
exp->mDecValue->mForwardParam = nullptr;
exp->mDecValue->mForwardCall = nullptr;
}
return exp->mDecValue; return exp->mDecValue;
case EX_INITIALIZATION: case EX_INITIALIZATION:
case EX_ASSIGNMENT: case EX_ASSIGNMENT:
@ -679,6 +699,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
} }
else else
{ {
if (procDec->mOptFlags & OPTF_SINGLE_CALL)
procDec->mOptFlags |= OPTF_MULTI_CALL;
else
procDec->mOptFlags |= OPTF_SINGLE_CALL;
RegisterCall(procDec, ldec); RegisterCall(procDec, ldec);
} }
@ -771,7 +795,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
if (pdec && (pdec->mFlags & DTF_FPARAM_UNUSED)) if (pdec && (pdec->mFlags & DTF_FPARAM_UNUSED))
RegisterProc(Analyze(pex, procDec, 0)); RegisterProc(Analyze(pex, procDec, 0));
else if (pdec && pdec->mBase->IsReference()) else if (pdec && pdec->mBase->IsReference())
RegisterProc(Analyze(pex, procDec, ANAFL_LHS | ANAFL_RHS)); {
if (!(procDec->mBase->mFlags & DTF_VIRTUAL) && pdec && pex && pex->mType == EX_VARIABLE && pex->mDecValue->mType == DT_ARGUMENT && pex->mDecValue->mBase->IsReference() && !pex->mDecValue->mForwardParam && !(pex->mDecValue->mOptFlags & OPTF_VAR_NO_FORWARD))
{
pex->mDecValue->mOptFlags |= OPTF_VAR_USED | OPTF_VAR_ADDRESS;
pex->mDecValue->mForwardParam = pdec;
pex->mDecValue->mForwardCall = ldec;
}
else
RegisterProc(Analyze(pex, procDec, ANAFL_LHS | ANAFL_RHS));
}
else if (!(procDec->mBase->mFlags & DTF_VIRTUAL) && pdec && pex && pex->mType == EX_VARIABLE && pex->mDecValue->mType == DT_ARGUMENT && !pex->mDecValue->mForwardParam && !(pex->mDecValue->mOptFlags & OPTF_VAR_NO_FORWARD))
{
pex->mDecValue->mOptFlags |= OPTF_VAR_USED;
pex->mDecValue->mForwardParam = pdec;
pex->mDecValue->mForwardCall = ldec;
}
else else
RegisterProc(Analyze(pex, procDec, ANAFL_RHS)); RegisterProc(Analyze(pex, procDec, ANAFL_RHS));

View File

@ -3314,7 +3314,7 @@ void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& sta
{ {
for (int i = 0; i < staticVars.Size(); i++) for (int i = 0; i < staticVars.Size(); i++)
{ {
if (staticVars[i]->mAliased && !providedVars[i]) if (staticVars[i]->mAliased && !providedVars.RangeFilled(staticVars[i]->mByteIndex, staticVars[i]->mSize))
requiredVars.AddRange(staticVars[i]->mByteIndex, staticVars[i]->mSize); requiredVars.AddRange(staticVars[i]->mByteIndex, staticVars[i]->mSize);
} }
} }

View File

@ -2032,7 +2032,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (procType->mFlags & DTF_FASTCALL) else if (procType->mFlags & DTF_FASTCALL)
{ {
ins->mConst.mMemory = IM_FPARAM; ins->mConst.mMemory = IM_FPARAM;
ins->mConst.mVarIndex += procType->mFastCallBase; // ins->mConst.mVarIndex += procType->mFastCallBase;
InitParameter(proc, dec, ins->mConst.mVarIndex); InitParameter(proc, dec, ins->mConst.mVarIndex);
} }
else else
@ -3505,7 +3505,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{ {
ains->mConst.mMemory = IM_FFRAME; ains->mConst.mMemory = IM_FFRAME;
ains->mConst.mIntConst = 0; ains->mConst.mIntConst = 0;
ains->mConst.mVarIndex += ftype->mFastCallBase; // ains->mConst.mVarIndex += ftype->mFastCallBase;
} }
else else
ains->mConst.mMemory = IM_FRAME; ains->mConst.mMemory = IM_FRAME;
@ -3787,7 +3787,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (procType->mFlags & DTF_FASTCALL) else if (procType->mFlags & DTF_FASTCALL)
{ {
vins->mConst.mMemory = IM_FPARAM; vins->mConst.mMemory = IM_FPARAM;
vins->mConst.mVarIndex += procType->mFastCallBase; // vins->mConst.mVarIndex += procType->mFastCallBase;
} }
else else
vins->mConst.mMemory = IM_PARAM; vins->mConst.mMemory = IM_PARAM;
@ -5181,15 +5181,48 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
{ {
proc->mFastCallProcedure = true; proc->mFastCallProcedure = true;
if (dec->mFastCallSize > 0 && dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS) if (dec->mFastCallSize > 0)
{ {
proc->mFastCallBase = dec->mFastCallBase; proc->mFastCallBase = dec->mFastCallBase;
dec->mLinkerObject->mNumTemporaries = 1;
dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase; if (dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS && dec->mFastCallSize > dec->mFastCallBase)
if (dec->mFastCallBase + dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS) {
dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize; dec->mLinkerObject->mNumTemporaries = 1;
else dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase;
dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - BC_REG_FPARAMS - dec->mFastCallBase; if (dec->mFastCallSize < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize - dec->mFastCallBase;
else
dec->mLinkerObject->mTempSizes[0] = BC_REG_FPARAMS_END - dec->mFastCallBase;
}
Declaration* pdec = dec->mBase->mParams;
while (pdec)
{
int start = pdec->mVarIndex + BC_REG_FPARAMS, end = start + pdec->mSize;
if (start < BC_REG_FPARAMS_END)
{
if (end > BC_REG_FPARAMS_END)
end = BC_REG_FPARAMS_END;
int i = 0;
while (i < dec->mLinkerObject->mNumTemporaries && (dec->mLinkerObject->mTemporaries[i] > end || dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < start))
i++;
if (i < dec->mLinkerObject->mNumTemporaries)
{
if (dec->mLinkerObject->mTemporaries[i] > start)
dec->mLinkerObject->mTemporaries[i] = start;
if (dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < end)
dec->mLinkerObject->mTempSizes[i] = end - dec->mLinkerObject->mTemporaries[i];
}
else
{
dec->mLinkerObject->mTemporaries[i] = start;
dec->mLinkerObject->mTempSizes[i] = end - start;
dec->mLinkerObject->mNumTemporaries++;
}
}
pdec = pdec->mNext;
}
} }
else else
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS; proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;

View File

@ -34,7 +34,7 @@ bool LinkerReference::operator==(const LinkerReference& ref)
mFlags == ref.mFlags && mFlags == ref.mFlags &&
mOffset == ref.mOffset && mOffset == ref.mOffset &&
mRefOffset == ref.mRefOffset && mRefOffset == ref.mRefOffset &&
mObject->mMapID == ref.mObject->mMapID && // mObject->mMapID == ref.mObject->mMapID &&
mRefObject->mMapID == ref.mRefObject->mMapID; mRefObject->mMapID == ref.mRefObject->mMapID;
} }
@ -355,7 +355,7 @@ void Linker::CombineSameConst(void)
if (i == sobj->mSize) if (i == sobj->mSize)
{ {
i = 0; i = 0;
while (i < sobj->mReferences.Size() && sobj->mReferences[i] == dobj->mReferences[i]) while (i < sobj->mReferences.Size() && *sobj->mReferences[i] == *dobj->mReferences[i])
i++; i++;
if (i == sobj->mReferences.Size()) if (i == sobj->mReferences.Size())
{ {
@ -1246,6 +1246,8 @@ bool Linker::WriteCrtFile(const char* filename, uint16 id)
bool Linker::WriteMapFile(const char* filename) bool Linker::WriteMapFile(const char* filename)
{ {
bool banked = mCartridgeBankUsed[0];
FILE* file; FILE* file;
fopen_s(&file, filename, "wb"); fopen_s(&file, filename, "wb");
if (file) if (file)
@ -1275,6 +1277,17 @@ bool Linker::WriteMapFile(const char* filename)
if (obj->mFlags & LOBJF_REFERENCED) if (obj->mFlags & LOBJF_REFERENCED)
{ {
if (banked)
{
int k = 0;
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
k++;
if (k < 64)
fprintf(file, "%02x:", k);
else
fprintf(file, "--:");
}
if (obj->mIdent) if (obj->mIdent)
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString); fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString);
else else
@ -1282,7 +1295,7 @@ bool Linker::WriteMapFile(const char* filename)
} }
} }
if (mCartridgeBankUsed[0]) if (banked)
{ {
fprintf(file, "\nbanks\n"); fprintf(file, "\nbanks\n");
@ -1315,6 +1328,18 @@ bool Linker::WriteMapFile(const char* filename)
for (int i = 0; i < so.Size(); i++) for (int i = 0; i < so.Size(); i++)
{ {
const LinkerObject* obj = so[i]; const LinkerObject* obj = so[i];
if (banked)
{
int k = 0;
while (k < 64 && !(obj->mRegion->mCartridgeBanks & (1ull << k)))
k++;
if (k < 64)
fprintf(file, "%02x:", k);
else
fprintf(file, "--:");
}
fprintf(file, "%04x (%04x) : %s, %s:%s\n", obj->mAddress, obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString); fprintf(file, "%04x (%04x) : %s, %s:%s\n", obj->mAddress, obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString);
} }

View File

@ -6377,6 +6377,66 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc
return true; return true;
} }
#if 1
else if (rins1->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins0->mSrc[0].mMemory == IM_FPARAM)
{
if (rins1->mSrc[0].mTemp == wins->mSrc[1].mTemp && rins1->mSrc[0].mIntConst == wins->mSrc[1].mIntConst && rins1->mSrc[0].mStride == wins->mSrc[1].mStride &&
wins->mSrc[0].mFinal && wins->mSrc[1].mFinal)
{
int size = InterTypeSize[oins->mDst.mType];
AsmInsType aop;
switch (oins->mOperator)
{
case IA_ADD:
mIns.Push(NativeCodeInstruction(oins, ASMIT_CLC));
aop = ASMIT_ADC;
break;
case IA_OR:
aop = ASMIT_ORA;
break;
case IA_XOR:
aop = ASMIT_EOR;
break;
case IA_AND:
aop = ASMIT_AND;
break;
default:
return false;
}
int offset = int(wins->mSrc[1].mIntConst);
for (int i = 0; i < size; i++)
{
while (offset >= 256)
{
mIns.Push(NativeCodeInstruction(rins1, ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp] + 1));
offset -= 256;
}
mIns.Push(NativeCodeInstruction(rins1, ASMIT_LDY, ASMIM_IMMEDIATE, offset));
mIns.Push(NativeCodeInstruction(rins1, ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]));
mIns.Push(NativeCodeInstruction(oins, ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + rins0->mSrc[0].mVarIndex + int(rins0->mSrc[0].mIntConst) + i));
mIns.Push(NativeCodeInstruction(wins, ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]));
offset += wins->mSrc[1].mStride;
}
return true;
}
return false;
}
else if (rins0->mSrc[0].mMemory == IM_INDIRECT && wins->mSrc[1].mMemory == IM_INDIRECT && rins1->mSrc[0].mMemory == IM_FPARAM)
{
printf("OOpsie0\n");
return false;
}
#endif
else else
return false; return false;
} }
@ -19561,6 +19621,8 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
mTempRegs += ins.mAddress; mTempRegs += ins.mAddress;
mTempRegs += ins.mAddress + 1; mTempRegs += ins.mAddress + 1;
} }
else if (ins.mType == ASMIT_JSR)
break;
} }
} }
#endif #endif
@ -26794,11 +26856,12 @@ bool NativeCodeBasicBlock::MoveLDXUp(int at)
{ {
if (ins.mLive & LIVE_CPU_REG_Z) if (ins.mLive & LIVE_CPU_REG_Z)
return false; return false;
ins.mLive |= LIVE_CPU_REG_A;
mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAX)); mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAX));
mIns.Remove(at + 1); mIns.Remove(at + 1);
while (i < at) while (i <= at)
{ {
mIns[i].mLive |= LIVE_CPU_REG_X; mIns[i].mLive |= LIVE_CPU_REG_X;
i++; i++;
@ -26825,11 +26888,12 @@ bool NativeCodeBasicBlock::MoveLDYUp(int at)
{ {
if (ins.mLive & LIVE_CPU_REG_Z) if (ins.mLive & LIVE_CPU_REG_Z)
return false; return false;
ins.mLive |= LIVE_CPU_REG_A;
mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAY)); mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAY));
mIns.Remove(at + 1); mIns.Remove(at + 1);
while (i < at) while (i <= at)
{ {
mIns[i].mLive |= LIVE_CPU_REG_Y; mIns[i].mLive |= LIVE_CPU_REG_Y;
i++; i++;
@ -32931,6 +32995,9 @@ bool NativeCodeBasicBlock::OptimizeXYSimpleLoop(void)
mIns.Insert(sz - 2, NativeCodeInstruction(mIns[i - 3].mIns, ASMIT_INX)); mIns.Insert(sz - 2, NativeCodeInstruction(mIns[i - 3].mIns, ASMIT_INX));
sz++; sz++;
changed = true; changed = true;
mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
pblock->mExitRequiredRegs += CPU_REG_X;
} }
} }
} }
@ -38371,7 +38438,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
else if ( else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mType == ASMIT_STA &&
mIns[i + 1].IsShiftOrInc() && mIns[i + 1].IsShiftOrInc() &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) && !mIns[i + 2].SameEffectiveAddress(mIns[i + 1]) && !(mIns[i + 2].mLive & LIVE_CPU_REG_Z)) mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) &&
!mIns[i + 2].SameEffectiveAddress(mIns[i + 1]) &&
!(mIns[i + 2].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mAddress == mIns[i + 2].mAddress || mIns[i + 1].mAddress == mIns[i + 2].mAddress + 1)) &&
!(mIns[i + 2].mLive & LIVE_CPU_REG_Z))
{ {
mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
@ -39451,6 +39521,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_LDX && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) && !(mIns[i + 0].mFlags & NCIF_VOLATILE) &&
mIns[i + 1].mType == ASMIT_STX && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE) &&
mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 2].mFlags & NCIF_VOLATILE) &&
!mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].SameEffectiveAddress(mIns[i + 2]))
{
NativeCodeInstruction ins(mIns[i + 2]);
mIns.Remove(i + 2);
mIns.Insert(i, ins);
mIns[i + 1].mLive |= ins.mLive & LIVE_CPU_REG_A;
mIns[i + 2].mLive |= ins.mLive & LIVE_CPU_REG_A;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_LDY && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS) && !(mIns[i + 0].mFlags & NCIF_VOLATILE) &&
mIns[i + 1].mType == ASMIT_STY && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 1].mFlags & NCIF_VOLATILE) &&
mIns[i + 2].mType == ASMIT_STA && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && !(mIns[i + 2].mFlags & NCIF_VOLATILE) &&
!mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].SameEffectiveAddress(mIns[i + 2]))
{
NativeCodeInstruction ins(mIns[i + 2]);
mIns.Remove(i + 2);
mIns.Insert(i, ins);
mIns[i + 1].mLive |= ins.mLive & LIVE_CPU_REG_A;
mIns[i + 2].mLive |= ins.mLive & LIVE_CPU_REG_A;
progress = true;
}
else if ( else if (
mIns[i + 0].ChangesAccuAndFlag() && mIns[i + 0].ChangesAccuAndFlag() &&
(mIns[i + 1].mType == ASMIT_INC || mIns[i + 1].mType == ASMIT_DEC) && (mIns[i + 1].mType == ASMIT_INC || mIns[i + 1].mType == ASMIT_DEC) &&
@ -43527,7 +43623,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_expression"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "valinc");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -44325,8 +44421,8 @@ void NativeCodeProcedure::Optimize(void)
ResetVisited(); ResetVisited();
if (mEntryBlock->PeepHoleOptimizer(this, step)) if (mEntryBlock->PeepHoleOptimizer(this, step))
changed = true; changed = true;
#endif #endif
if (step == 2) if (step == 2)
{ {
ResetVisited(); ResetVisited();
@ -44546,6 +44642,11 @@ void NativeCodeProcedure::Optimize(void)
#endif #endif
} }
#endif #endif
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
if (step > 4 && !changed) if (step > 4 && !changed)
{ {
@ -44561,6 +44662,10 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#if _DEBUG
ResetVisited();
mEntryBlock->CheckBlocks();
#endif
#if 1 #if 1
if (step == 5 || step == 6) if (step == 5 || step == 6)
@ -44921,7 +45026,7 @@ void NativeCodeProcedure::Optimize(void)
if (step == 11) if (step == 11)
{ {
if (changed) if (changed && cnt < 20)
swappedXY = false; swappedXY = false;
else if (!swappedXY) else if (!swappedXY)
{ {

View File

@ -7233,7 +7233,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
nexp->mDecType = nexp->mLeft->mDecType; nexp->mDecType = nexp->mLeft->mDecType;
} }
nexp = CheckOperatorOverload(nexp); nexp = CheckOperatorOverload(nexp);
return nexp->ConstantFold(mErrors, mDataSection); return nexp->ConstantFold(mErrors, mDataSection, mCompilationUnits->mLinker);
} }
else else
return ParsePostfixExpression(lhs); return ParsePostfixExpression(lhs);