Direct parameter forwarding
This commit is contained in:
parent
003306f961
commit
8ab46e29dd
|
@ -1,5 +1,6 @@
|
|||
#include "Declaration.h"
|
||||
#include "Constexpr.h"
|
||||
#include "Linker.h"
|
||||
#include <math.h>
|
||||
|
||||
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)
|
||||
{
|
||||
switch (mToken)
|
||||
|
@ -944,7 +968,7 @@ Declaration::Declaration(const Location& loc, DecType type)
|
|||
mConst(nullptr), mMutable(nullptr),
|
||||
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr), mMoveConstructor(nullptr), mMoveAssignment(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),
|
||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr),
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
class LinkerObject;
|
||||
class LinkerSection;
|
||||
class Linker;
|
||||
class Parser;
|
||||
|
||||
enum DecType
|
||||
|
@ -244,7 +245,7 @@ public:
|
|||
bool mConst;
|
||||
|
||||
Expression* LogicInvertExpression(void);
|
||||
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection);
|
||||
Expression* ConstantFold(Errors * errors, LinkerSection* dataSection, Linker * linker = nullptr);
|
||||
bool HasSideEffects(void) const;
|
||||
|
||||
bool IsSame(const Expression* exp) const;
|
||||
|
@ -268,6 +269,7 @@ public:
|
|||
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment, * mMoveConstructor, * mMoveAssignment;
|
||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
||||
Declaration * mVTable, * mClass, * mTemplate;
|
||||
Declaration * mForwardParam, * mForwardCall;
|
||||
|
||||
Expression* mValue, * mReturn;
|
||||
DeclarationScope* mScope;
|
||||
|
|
|
@ -305,7 +305,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
{
|
||||
CheckFastcall(vf, false);
|
||||
|
||||
int n = vf->mBase->mFastCallBase + vf->mBase->mFastCallSize;
|
||||
int n = vf->mBase->mFastCallSize;
|
||||
if (n > nbase)
|
||||
nbase = n;
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
// procDec->mBase->mFlags |= DTF_STACKCALL;
|
||||
|
||||
cf = cf->mBase;
|
||||
int n = cf->mFastCallBase + cf->mFastCallSize;
|
||||
int n = cf->mFastCallSize;
|
||||
if (n > nbase)
|
||||
nbase = n;
|
||||
}
|
||||
|
@ -359,7 +359,16 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
|
||||
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->mFastCallSize = cf->mFastCallSize = maxf->mBase->mFastCallSize;
|
||||
}
|
||||
|
@ -373,9 +382,9 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
}
|
||||
|
||||
procDec->mFastCallBase = nbase;
|
||||
procDec->mFastCallSize = 0;
|
||||
procDec->mFastCallSize = nbase;
|
||||
procDec->mBase->mFastCallBase = nbase;
|
||||
procDec->mBase->mFastCallSize = 0;
|
||||
procDec->mBase->mFastCallSize = nbase;
|
||||
|
||||
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))
|
||||
{
|
||||
int nparams = 0, npalign = 0;
|
||||
int nparams = nbase, npalign = 0;
|
||||
int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
|
||||
int fplimit = numfpzero;
|
||||
|
||||
|
@ -407,50 +416,68 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
|||
nparams += 2;
|
||||
}
|
||||
|
||||
int cnparams = nparams;
|
||||
Declaration* dec = procDec->mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
// 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);
|
||||
nparams += npalign;
|
||||
npalign = numfpzero - nparams;
|
||||
cnparams += npalign;
|
||||
}
|
||||
nparams += dec->mBase->mSize;
|
||||
cnparams += dec->mBase->mSize;
|
||||
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->mFastCallSize = nparams;
|
||||
procDec->mBase->mFastCallBase = nbase;
|
||||
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;
|
||||
#if 0
|
||||
printf("FASTCALL %s\n", f->mIdent->mString);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("STACKCALL %s, %d %d\n", procDec->mIdent->mString, cnparams, fplimit);
|
||||
procDec->mBase->mFlags |= DTF_STACKCALL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("STACKCALL %s, F%d\n", procDec->mIdent->mString, !!(procDec->mFlags& DTF_FUNC_VARIABLE));
|
||||
procDec->mBase->mFlags |= DTF_STACKCALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalAnalyzer::CheckInterrupt(void)
|
||||
{
|
||||
|
@ -759,6 +786,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
|
||||
return exp->mDecType;
|
||||
}
|
||||
else if (exp->mToken == TK_BANKOF)
|
||||
{
|
||||
return TheUnsignedCharTypeDeclaration;
|
||||
}
|
||||
else
|
||||
{
|
||||
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
|
||||
|
|
|
@ -18,7 +18,9 @@ static const uint64 OPTF_VAR_CONST = (1ULL << 9);
|
|||
static const uint64 OPTF_VAR_NOCONST = (1ULL << 10);
|
||||
static const uint64 OPTF_SINGLE_RETURN = (1ULL << 11);
|
||||
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)
|
||||
: mErrors(errors), mLinker(linker)
|
||||
|
@ -45,6 +47,7 @@ void GlobalOptimizer::Reset(void)
|
|||
while (pdec)
|
||||
{
|
||||
pdec->mOptFlags = 0;
|
||||
pdec->mForwardParam = nullptr;
|
||||
pdec = pdec->mNext;
|
||||
}
|
||||
}
|
||||
|
@ -278,6 +281,17 @@ bool GlobalOptimizer::Optimize(void)
|
|||
if (CheckConstReturns(func->mValue))
|
||||
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_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)
|
||||
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;
|
||||
case EX_INITIALIZATION:
|
||||
case EX_ASSIGNMENT:
|
||||
|
@ -679,6 +699,10 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
}
|
||||
else
|
||||
{
|
||||
if (procDec->mOptFlags & OPTF_SINGLE_CALL)
|
||||
procDec->mOptFlags |= OPTF_MULTI_CALL;
|
||||
else
|
||||
procDec->mOptFlags |= OPTF_SINGLE_CALL;
|
||||
RegisterCall(procDec, ldec);
|
||||
}
|
||||
|
||||
|
@ -771,7 +795,22 @@ Declaration* GlobalOptimizer::Analyze(Expression* exp, Declaration* procDec, uin
|
|||
if (pdec && (pdec->mFlags & DTF_FPARAM_UNUSED))
|
||||
RegisterProc(Analyze(pex, procDec, 0));
|
||||
else if (pdec && pdec->mBase->IsReference())
|
||||
{
|
||||
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
|
||||
RegisterProc(Analyze(pex, procDec, ANAFL_RHS));
|
||||
|
||||
|
|
|
@ -3314,7 +3314,7 @@ void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& sta
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2032,7 +2032,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else if (procType->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
ins->mConst.mMemory = IM_FPARAM;
|
||||
ins->mConst.mVarIndex += procType->mFastCallBase;
|
||||
// ins->mConst.mVarIndex += procType->mFastCallBase;
|
||||
InitParameter(proc, dec, ins->mConst.mVarIndex);
|
||||
}
|
||||
else
|
||||
|
@ -3505,7 +3505,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
{
|
||||
ains->mConst.mMemory = IM_FFRAME;
|
||||
ains->mConst.mIntConst = 0;
|
||||
ains->mConst.mVarIndex += ftype->mFastCallBase;
|
||||
// ains->mConst.mVarIndex += ftype->mFastCallBase;
|
||||
}
|
||||
else
|
||||
ains->mConst.mMemory = IM_FRAME;
|
||||
|
@ -3787,7 +3787,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else if (procType->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
vins->mConst.mMemory = IM_FPARAM;
|
||||
vins->mConst.mVarIndex += procType->mFastCallBase;
|
||||
// vins->mConst.mVarIndex += procType->mFastCallBase;
|
||||
}
|
||||
else
|
||||
vins->mConst.mMemory = IM_PARAM;
|
||||
|
@ -5181,15 +5181,48 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
{
|
||||
proc->mFastCallProcedure = true;
|
||||
|
||||
if (dec->mFastCallSize > 0 && dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
|
||||
if (dec->mFastCallSize > 0)
|
||||
{
|
||||
proc->mFastCallBase = dec->mFastCallBase;
|
||||
|
||||
if (dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS && dec->mFastCallSize > dec->mFastCallBase)
|
||||
{
|
||||
dec->mLinkerObject->mNumTemporaries = 1;
|
||||
dec->mLinkerObject->mTemporaries[0] = BC_REG_FPARAMS + dec->mFastCallBase;
|
||||
if (dec->mFastCallBase + dec->mFastCallBase < BC_REG_FPARAMS_END - BC_REG_FPARAMS)
|
||||
dec->mLinkerObject->mTempSizes[0] = dec->mFastCallSize;
|
||||
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 - BC_REG_FPARAMS - dec->mFastCallBase;
|
||||
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
|
||||
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
|
||||
|
|
|
@ -34,7 +34,7 @@ bool LinkerReference::operator==(const LinkerReference& ref)
|
|||
mFlags == ref.mFlags &&
|
||||
mOffset == ref.mOffset &&
|
||||
mRefOffset == ref.mRefOffset &&
|
||||
mObject->mMapID == ref.mObject->mMapID &&
|
||||
// mObject->mMapID == ref.mObject->mMapID &&
|
||||
mRefObject->mMapID == ref.mRefObject->mMapID;
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,7 @@ void Linker::CombineSameConst(void)
|
|||
if (i == sobj->mSize)
|
||||
{
|
||||
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++;
|
||||
if (i == sobj->mReferences.Size())
|
||||
{
|
||||
|
@ -1246,6 +1246,8 @@ bool Linker::WriteCrtFile(const char* filename, uint16 id)
|
|||
|
||||
bool Linker::WriteMapFile(const char* filename)
|
||||
{
|
||||
bool banked = mCartridgeBankUsed[0];
|
||||
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
|
@ -1275,6 +1277,17 @@ bool Linker::WriteMapFile(const char* filename)
|
|||
|
||||
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)
|
||||
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
|
||||
|
@ -1282,7 +1295,7 @@ bool Linker::WriteMapFile(const char* filename)
|
|||
}
|
||||
}
|
||||
|
||||
if (mCartridgeBankUsed[0])
|
||||
if (banked)
|
||||
{
|
||||
fprintf(file, "\nbanks\n");
|
||||
|
||||
|
@ -1315,6 +1328,18 @@ bool Linker::WriteMapFile(const char* filename)
|
|||
for (int i = 0; i < so.Size(); 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -6377,6 +6377,66 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc
|
|||
|
||||
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
|
||||
return false;
|
||||
}
|
||||
|
@ -19561,6 +19621,8 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
|
|||
mTempRegs += ins.mAddress;
|
||||
mTempRegs += ins.mAddress + 1;
|
||||
}
|
||||
else if (ins.mType == ASMIT_JSR)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -26794,11 +26856,12 @@ bool NativeCodeBasicBlock::MoveLDXUp(int at)
|
|||
{
|
||||
if (ins.mLive & LIVE_CPU_REG_Z)
|
||||
return false;
|
||||
ins.mLive |= LIVE_CPU_REG_A;
|
||||
|
||||
mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAX));
|
||||
mIns.Remove(at + 1);
|
||||
|
||||
while (i < at)
|
||||
while (i <= at)
|
||||
{
|
||||
mIns[i].mLive |= LIVE_CPU_REG_X;
|
||||
i++;
|
||||
|
@ -26825,11 +26888,12 @@ bool NativeCodeBasicBlock::MoveLDYUp(int at)
|
|||
{
|
||||
if (ins.mLive & LIVE_CPU_REG_Z)
|
||||
return false;
|
||||
ins.mLive |= LIVE_CPU_REG_A;
|
||||
|
||||
mIns.Insert(i + 1, NativeCodeInstruction(lins.mIns, ASMIT_TAY));
|
||||
mIns.Remove(at + 1);
|
||||
|
||||
while (i < at)
|
||||
while (i <= at)
|
||||
{
|
||||
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||
i++;
|
||||
|
@ -32931,6 +32995,9 @@ bool NativeCodeBasicBlock::OptimizeXYSimpleLoop(void)
|
|||
mIns.Insert(sz - 2, NativeCodeInstruction(mIns[i - 3].mIns, ASMIT_INX));
|
||||
sz++;
|
||||
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 (
|
||||
mIns[i + 0].mType == ASMIT_STA &&
|
||||
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 + 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;
|
||||
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 (
|
||||
mIns[i + 0].ChangesAccuAndFlag() &&
|
||||
(mIns[i + 1].mType == ASMIT_INC || mIns[i + 1].mType == ASMIT_DEC) &&
|
||||
|
@ -43527,7 +43623,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
{
|
||||
mInterProc = proc;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "interpret_expression");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "valinc");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
@ -44325,8 +44421,8 @@ void NativeCodeProcedure::Optimize(void)
|
|||
ResetVisited();
|
||||
if (mEntryBlock->PeepHoleOptimizer(this, step))
|
||||
changed = true;
|
||||
|
||||
#endif
|
||||
|
||||
if (step == 2)
|
||||
{
|
||||
ResetVisited();
|
||||
|
@ -44546,6 +44642,11 @@ void NativeCodeProcedure::Optimize(void)
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
#if _DEBUG
|
||||
ResetVisited();
|
||||
mEntryBlock->CheckBlocks();
|
||||
#endif
|
||||
|
||||
|
||||
if (step > 4 && !changed)
|
||||
{
|
||||
|
@ -44561,6 +44662,10 @@ void NativeCodeProcedure::Optimize(void)
|
|||
changed = true;
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
ResetVisited();
|
||||
mEntryBlock->CheckBlocks();
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (step == 5 || step == 6)
|
||||
|
@ -44921,7 +45026,7 @@ void NativeCodeProcedure::Optimize(void)
|
|||
|
||||
if (step == 11)
|
||||
{
|
||||
if (changed)
|
||||
if (changed && cnt < 20)
|
||||
swappedXY = false;
|
||||
else if (!swappedXY)
|
||||
{
|
||||
|
|
|
@ -7233,7 +7233,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
|
|||
nexp->mDecType = nexp->mLeft->mDecType;
|
||||
}
|
||||
nexp = CheckOperatorOverload(nexp);
|
||||
return nexp->ConstantFold(mErrors, mDataSection);
|
||||
return nexp->ConstantFold(mErrors, mDataSection, mCompilationUnits->mLinker);
|
||||
}
|
||||
else
|
||||
return ParsePostfixExpression(lhs);
|
||||
|
|
Loading…
Reference in New Issue