Add optimization -Ox to simplify pointer arithmetic by non page crossing
This commit is contained in:
parent
b26cc4ede7
commit
05ef25a61e
|
@ -277,6 +277,15 @@ exit /b %errorlevel%
|
||||||
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
|
..\bin\oscar64 -e -O2 -n -dHEAPCHECK %~1
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\bin\oscar64 -e -O2 -xz -Oz -n %~1
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
..\bin\oscar64 -e -O0 -bc %~1
|
..\bin\oscar64 -e -O0 -bc %~1
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@ -337,6 +346,9 @@ exit /b %errorlevel%
|
||||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@exit /b 0
|
@exit /b 0
|
||||||
|
|
||||||
:testb
|
:testb
|
||||||
|
@ -379,4 +391,7 @@ exit /b %errorlevel%
|
||||||
..\bin\oscar64 -e -O2 -Oo -n %~1
|
..\bin\oscar64 -e -O2 -Oo -n %~1
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\bin\oscar64 -e -O2 -Ox -n %~1
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@exit /b 0
|
@exit /b 0
|
||||||
|
|
|
@ -15,6 +15,7 @@ static const uint64 COPT_OPTIMIZE_CONST_PARAMS = 1ULL << 9;
|
||||||
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
|
static const uint64 COPT_OPTIMIZE_MERGE_CALLS = 1ULL << 10;
|
||||||
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11;
|
static const uint64 COPT_OPTIMIZE_GLOBAL = 1ULL << 11;
|
||||||
static const uint64 COPT_OPTIMIZE_OUTLINE = 1ULL << 12;
|
static const uint64 COPT_OPTIMIZE_OUTLINE = 1ULL << 12;
|
||||||
|
static const uint64 COPT_OPTIMIZE_PAGE_CROSSING = 1ULL << 13;
|
||||||
|
|
||||||
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16;
|
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 1ULL << 16;
|
||||||
static const uint64 COPT_NATIVE = 1ULL << 17;
|
static const uint64 COPT_NATIVE = 1ULL << 17;
|
||||||
|
|
|
@ -3042,6 +3042,22 @@ bool Declaration::IsIndexed(void) const
|
||||||
return mType == DT_TYPE_ARRAY || mType == DT_TYPE_POINTER;
|
return mType == DT_TYPE_ARRAY || mType == DT_TYPE_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Declaration::ContainsArray(void) const
|
||||||
|
{
|
||||||
|
if (mType == DT_TYPE_ARRAY)
|
||||||
|
return true;
|
||||||
|
else if (mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
Declaration* p = mParams;
|
||||||
|
while (p)
|
||||||
|
{
|
||||||
|
if (p->mType == DT_ELEMENT && p->mBase->ContainsArray())
|
||||||
|
return true;
|
||||||
|
p = p->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Declaration::IsSimpleType(void) const
|
bool Declaration::IsSimpleType(void) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,6 +127,7 @@ static const uint64 DTF_FPARAM_UNUSED = (1ULL << 49);
|
||||||
static const uint64 DTF_DEPRECATED = (1ULL << 50);
|
static const uint64 DTF_DEPRECATED = (1ULL << 50);
|
||||||
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
||||||
static const uint64 DTF_PLACED = (1ULL << 52);
|
static const uint64 DTF_PLACED = (1ULL << 52);
|
||||||
|
static const uint64 DTF_NO_PAGE_CROSS = (1ULL << 53);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,6 +334,7 @@ public:
|
||||||
bool IsSimpleType(void) const;
|
bool IsSimpleType(void) const;
|
||||||
bool IsReference(void) const;
|
bool IsReference(void) const;
|
||||||
bool IsIndexed(void) const;
|
bool IsIndexed(void) const;
|
||||||
|
bool ContainsArray(void) const;
|
||||||
|
|
||||||
void SetDefined(void);
|
void SetDefined(void);
|
||||||
|
|
||||||
|
|
|
@ -17506,7 +17506,7 @@ void InterCodeBasicBlock::RemoveUnusedMallocs(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue)
|
void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
|
@ -17536,6 +17536,57 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (loops && mNumEntries == 2)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* tail, * post;
|
||||||
|
|
||||||
|
if (mEntryBlocks[0] == mLoopPrefix)
|
||||||
|
tail = mEntryBlocks[1];
|
||||||
|
else
|
||||||
|
tail = mEntryBlocks[0];
|
||||||
|
|
||||||
|
if (tail->mTrueJump == this)
|
||||||
|
post = tail->mFalseJump;
|
||||||
|
else
|
||||||
|
post = tail->mTrueJump;
|
||||||
|
|
||||||
|
if (post && post->mNumEntries == 1)
|
||||||
|
{
|
||||||
|
GrowingArray<InterCodeBasicBlock*> body(nullptr);
|
||||||
|
|
||||||
|
if (tail->CollectSingleHeadLoopBody(this, tail, body))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ltvalue.Size(); i++)
|
||||||
|
{
|
||||||
|
if (ltvalue[i])
|
||||||
|
{
|
||||||
|
bool fail = false;
|
||||||
|
|
||||||
|
for (int k = 0; k < body.Size() && !fail; k++)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* b = body[k];
|
||||||
|
for (int j = 0; j < b->mInstructions.Size() && !fail; j++)
|
||||||
|
{
|
||||||
|
InterInstruction* ins = b->mInstructions[j];
|
||||||
|
if (ins->mDst.mTemp == i)
|
||||||
|
{
|
||||||
|
if (ins->mCode == IC_LEA && ins->mSrc[1].mTemp == i)
|
||||||
|
;
|
||||||
|
else
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fail)
|
||||||
|
{
|
||||||
|
ltvalue[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ltvalue.Clear();
|
ltvalue.Clear();
|
||||||
}
|
}
|
||||||
|
@ -17567,18 +17618,22 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
|
|
||||||
for (int j = 0; j < ins->mNumOperands; j++)
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[j].mTemp > 0 && ltvalue[ins->mSrc[j].mTemp] && ins->mSrc[j].mType == IT_POINTER)
|
if (ins->mSrc[j].mTemp >= 0 && ltvalue[ins->mSrc[j].mTemp] && ins->mSrc[j].mType == IT_POINTER)
|
||||||
{
|
{
|
||||||
ins->mSrc[j].mRestricted = ltvalue[ins->mSrc[j].mTemp]->mDst.mRestricted;
|
ins->mSrc[j].mRestricted = ltvalue[ins->mSrc[j].mTemp]->mDst.mRestricted;
|
||||||
ins->mSrc[j].mMemoryBase = ltvalue[ins->mSrc[j].mTemp]->mDst.mMemoryBase;
|
ins->mSrc[j].mMemoryBase = ltvalue[ins->mSrc[j].mTemp]->mDst.mMemoryBase;
|
||||||
ins->mSrc[j].mVarIndex = ltvalue[ins->mSrc[j].mTemp]->mDst.mVarIndex;
|
ins->mSrc[j].mVarIndex = ltvalue[ins->mSrc[j].mTemp]->mDst.mVarIndex;
|
||||||
ins->mSrc[j].mLinkerObject = ltvalue[ins->mSrc[j].mTemp]->mDst.mLinkerObject;
|
ins->mSrc[j].mLinkerObject = ltvalue[ins->mSrc[j].mTemp]->mDst.mLinkerObject;
|
||||||
|
if (ins->mSrc[j].mMemory == IM_NONE && ins->mSrc[j].mMemoryBase != IM_NONE)
|
||||||
|
ins->mSrc[j].mMemory = IM_INDIRECT;
|
||||||
|
|
||||||
assert(ins->mSrc[j].mMemoryBase != IM_LOCAL || ins->mSrc[j].mVarIndex >= 0);
|
assert(ins->mSrc[j].mMemoryBase != IM_LOCAL || ins->mSrc[j].mVarIndex >= 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ins->mCode == IC_LEA)
|
if (ins->mCode == IC_LEA)
|
||||||
{
|
{
|
||||||
|
ins->mDst.mMemory = ins->mSrc[1].mMemory;
|
||||||
ins->mDst.mRestricted = ins->mSrc[1].mRestricted;
|
ins->mDst.mRestricted = ins->mSrc[1].mRestricted;
|
||||||
if (ins->mSrc[1].mMemory != IM_INDIRECT)
|
if (ins->mSrc[1].mMemory != IM_INDIRECT)
|
||||||
ins->mSrc[1].mMemoryBase = ins->mSrc[1].mMemory;
|
ins->mSrc[1].mMemoryBase = ins->mSrc[1].mMemory;
|
||||||
|
@ -17588,6 +17643,7 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
}
|
}
|
||||||
else if (ins->mCode == IC_LOAD_TEMPORARY)
|
else if (ins->mCode == IC_LOAD_TEMPORARY)
|
||||||
{
|
{
|
||||||
|
ins->mDst.mMemory = ins->mSrc[0].mMemory;
|
||||||
ins->mDst.mRestricted = ins->mSrc[0].mRestricted;
|
ins->mDst.mRestricted = ins->mSrc[0].mRestricted;
|
||||||
ins->mDst.mMemoryBase = ins->mSrc[0].mMemoryBase;
|
ins->mDst.mMemoryBase = ins->mSrc[0].mMemoryBase;
|
||||||
ins->mDst.mVarIndex = ins->mSrc[0].mVarIndex;
|
ins->mDst.mVarIndex = ins->mSrc[0].mVarIndex;
|
||||||
|
@ -17595,6 +17651,7 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
}
|
}
|
||||||
else if (ins->mCode == IC_CONSTANT)
|
else if (ins->mCode == IC_CONSTANT)
|
||||||
{
|
{
|
||||||
|
ins->mDst.mMemory = ins->mConst.mMemory;
|
||||||
ins->mDst.mRestricted = ins->mConst.mRestricted;
|
ins->mDst.mRestricted = ins->mConst.mRestricted;
|
||||||
ins->mDst.mMemoryBase = ins->mConst.mMemory;
|
ins->mDst.mMemoryBase = ins->mConst.mMemory;
|
||||||
ins->mDst.mVarIndex = ins->mConst.mVarIndex;
|
ins->mDst.mVarIndex = ins->mConst.mVarIndex;
|
||||||
|
@ -17611,8 +17668,8 @@ void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mTrueJump) mTrueJump->PropagateMemoryAliasingInfo(ltvalue);
|
if (mTrueJump) mTrueJump->PropagateMemoryAliasingInfo(ltvalue, loops);
|
||||||
if (mFalseJump) mFalseJump->PropagateMemoryAliasingInfo(ltvalue);
|
if (mFalseJump) mFalseJump->PropagateMemoryAliasingInfo(ltvalue, loops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22801,12 +22858,21 @@ void InterCodeProcedure::EliminateDoubleLoopCounter(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterCodeProcedure::PropagateMemoryAliasingInfo(void)
|
void InterCodeProcedure::PropagateMemoryAliasingInfo(bool loops)
|
||||||
{
|
{
|
||||||
GrowingInstructionPtrArray tvalue(nullptr);
|
GrowingInstructionPtrArray tvalue(nullptr);
|
||||||
|
|
||||||
|
if (loops)
|
||||||
|
{
|
||||||
|
BuildTraces(0);
|
||||||
|
BuildLoopPrefix();
|
||||||
|
ResetEntryBlocks();
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->PropagateMemoryAliasingInfo(tvalue);
|
mEntryBlock->PropagateMemoryAliasingInfo(tvalue, loops);
|
||||||
|
|
||||||
Disassemble("PropagateMemoryAliasingInfo");
|
Disassemble("PropagateMemoryAliasingInfo");
|
||||||
}
|
}
|
||||||
|
@ -23401,7 +23467,7 @@ void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory)
|
||||||
|
|
||||||
bool changed;
|
bool changed;
|
||||||
do {
|
do {
|
||||||
PropagateMemoryAliasingInfo();
|
PropagateMemoryAliasingInfo(false);
|
||||||
|
|
||||||
GrowingInstructionPtrArray gipa(nullptr);
|
GrowingInstructionPtrArray gipa(nullptr);
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
@ -23506,7 +23572,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "mbox::show");
|
CheckFunc = !strcmp(mIdent->mString, "mbox::configure_animations");
|
||||||
CheckCase = false;
|
CheckCase = false;
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
@ -23984,6 +24050,8 @@ void InterCodeProcedure::Close(void)
|
||||||
SingleTailLoopOptimization(paramMemory);
|
SingleTailLoopOptimization(paramMemory);
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
|
PropagateMemoryAliasingInfo(true);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ExpandSelect();
|
ExpandSelect();
|
||||||
|
|
||||||
|
@ -24179,6 +24247,8 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PropagateMemoryAliasingInfo(true);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->SimplifyIntegerRangeRelops();
|
mEntryBlock->SimplifyIntegerRangeRelops();
|
||||||
|
|
||||||
|
|
|
@ -638,7 +638,7 @@ public:
|
||||||
void SingleLoopCountZeroCheck(void);
|
void SingleLoopCountZeroCheck(void);
|
||||||
bool PostDecLoopOptimization(void);
|
bool PostDecLoopOptimization(void);
|
||||||
|
|
||||||
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
|
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue, bool loops);
|
||||||
void RemoveUnusedMallocs(void);
|
void RemoveUnusedMallocs(void);
|
||||||
|
|
||||||
bool PullStoreUpToConstAddress(void);
|
bool PullStoreUpToConstAddress(void);
|
||||||
|
@ -804,7 +804,7 @@ protected:
|
||||||
void CheckUsedDefinedTemps(void);
|
void CheckUsedDefinedTemps(void);
|
||||||
void WarnUsedUndefinedVariables(void);
|
void WarnUsedUndefinedVariables(void);
|
||||||
void WarnInvalidValueRanges(void);
|
void WarnInvalidValueRanges(void);
|
||||||
void PropagateMemoryAliasingInfo(void);
|
void PropagateMemoryAliasingInfo(bool loops);
|
||||||
void MoveConditionsOutOfLoop(void);
|
void MoveConditionsOutOfLoop(void);
|
||||||
void ShortcutConstBranches(void);
|
void ShortcutConstBranches(void);
|
||||||
void ShortcutDuplicateBranches(void);
|
void ShortcutDuplicateBranches(void);
|
||||||
|
|
|
@ -782,6 +782,16 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
|
||||||
var->mLinkerObject->mFlags |= LOBJF_CONST;
|
var->mLinkerObject->mFlags |= LOBJF_CONST;
|
||||||
if (dec->mFlags & DTF_ZEROPAGE)
|
if (dec->mFlags & DTF_ZEROPAGE)
|
||||||
var->mLinkerObject->mFlags |= LOBJF_ZEROPAGE;
|
var->mLinkerObject->mFlags |= LOBJF_ZEROPAGE;
|
||||||
|
if (dec->mFlags & DTF_NO_PAGE_CROSS)
|
||||||
|
var->mLinkerObject->mFlags |= LOBJF_NEVER_CROSS | LOBJF_NO_CROSS;
|
||||||
|
if (mCompilerOptions & COPT_OPTIMIZE_PAGE_CROSSING)
|
||||||
|
{
|
||||||
|
if (dec->mSize <= 256 && dec->mSize > 1)
|
||||||
|
{
|
||||||
|
if (dec->mBase->ContainsArray())
|
||||||
|
var->mLinkerObject->mFlags |= LOBJF_NEVER_CROSS | LOBJF_NO_CROSS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var->mIndex = mod->mGlobalVars.Size();
|
var->mIndex = mod->mGlobalVars.Size();
|
||||||
var->mDeclaration = dec;
|
var->mDeclaration = dec;
|
||||||
|
|
|
@ -650,7 +650,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
||||||
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
int start = (mFreeChunks[i].mStart + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||||
int end = start + lobj->mSize;
|
int end = start + lobj->mSize;
|
||||||
|
|
||||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||||
;
|
;
|
||||||
else if (end <= mFreeChunks[i].mEnd)
|
else if (end <= mFreeChunks[i].mEnd)
|
||||||
{
|
{
|
||||||
|
@ -702,7 +702,7 @@ bool LinkerRegion::Allocate(Linker * linker, LinkerObject* lobj, bool merge, boo
|
||||||
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
int start = (mStart + mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
|
||||||
int end = start + lobj->mSize;
|
int end = start + lobj->mSize;
|
||||||
|
|
||||||
if (!(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00) && !(lobj->mSection->mFlags & LSECF_PACKED))
|
if (((lobj->mFlags & LOBJF_NEVER_CROSS) || !(linker->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) && !retry && (lobj->mFlags & LOBJF_NO_CROSS) && !(lobj->mSection->mFlags & LSECF_PACKED)) && !(lobj->mFlags & LOBJF_FORCE_ALIGN) && lobj->mSize <= 256 && (start & 0xff00) != ((end - 1) & 0xff00))
|
||||||
{
|
{
|
||||||
start = (start + 0x00ff) & 0xff00;
|
start = (start + 0x00ff) & 0xff00;
|
||||||
end = start + lobj->mSize;
|
end = start + lobj->mSize;
|
||||||
|
|
|
@ -156,6 +156,7 @@ static const uint32 LOBJF_NO_CROSS = 0x00000080;
|
||||||
static const uint32 LOBJF_ZEROPAGE = 0x00000100;
|
static const uint32 LOBJF_ZEROPAGE = 0x00000100;
|
||||||
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
|
static const uint32 LOBJF_FORCE_ALIGN = 0x00000200;
|
||||||
static const uint32 LOBJF_ZEROPAGESET = 0x00000400;
|
static const uint32 LOBJF_ZEROPAGESET = 0x00000400;
|
||||||
|
static const uint32 LOBJF_NEVER_CROSS = 0x00000800;
|
||||||
|
|
||||||
static const uint32 LOBJF_ARG_REG_A = 0x00001000;
|
static const uint32 LOBJF_ARG_REG_A = 0x00001000;
|
||||||
static const uint32 LOBJF_ARG_REG_X = 0x00002000;
|
static const uint32 LOBJF_ARG_REG_X = 0x00002000;
|
||||||
|
|
|
@ -3617,6 +3617,62 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
|
||||||
data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE;
|
data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE;
|
||||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_A].mValue >= mAddress;
|
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_A].mValue >= mAddress;
|
||||||
}
|
}
|
||||||
|
else if (mMode == ASMIM_IMMEDIATE_ADDRESS && data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE_ADDRESS)
|
||||||
|
{
|
||||||
|
if (mLinkerObject == data.mRegs[CPU_REG_A].mLinkerObject)
|
||||||
|
{
|
||||||
|
if (mLinkerObject)
|
||||||
|
{
|
||||||
|
if (mLinkerObject->mFlags & LOBJF_NEVER_CROSS)
|
||||||
|
{
|
||||||
|
if (mFlags & NCIF_LOWER)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = (data.mRegs[CPU_REG_A].mValue - mAddress) & 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mFlags & NCIF_LOWER)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = (data.mRegs[CPU_REG_A].mValue & 0xff) == (mAddress & 0xff) ? 0 : 1;
|
||||||
|
}
|
||||||
|
else if (data.mRegs[CPU_REG_A].mValue == mAddress)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mFlags & NCIF_LOWER)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = (data.mRegs[CPU_REG_A].mValue - mAddress) & 0xff;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = ((data.mRegs[CPU_REG_A].mValue - mAddress) >> 8) & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = 1;
|
||||||
|
}
|
||||||
|
data.mRegs[CPU_REG_C].Reset();
|
||||||
|
}
|
||||||
else if (mMode == ASMIM_IMMEDIATE && mAddress == 0)
|
else if (mMode == ASMIM_IMMEDIATE && mAddress == 0)
|
||||||
{
|
{
|
||||||
data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE;
|
data.mRegs[CPU_REG_C].mMode = NRDM_IMMEDIATE;
|
||||||
|
@ -14223,6 +14279,10 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
bool crossing = true;
|
||||||
|
if (ins->mSrc[1].mMemoryBase == IM_GLOBAL && ins->mSrc[1].mLinkerObject && (ins->mSrc[1].mLinkerObject->mFlags & LOBJF_NEVER_CROSS))
|
||||||
|
crossing = false;
|
||||||
|
|
||||||
if (ins->mSrc[0].mTemp >= 0 || ins->mSrc[0].mIntConst != 0)
|
if (ins->mSrc[0].mTemp >= 0 || ins->mSrc[0].mIntConst != 0)
|
||||||
mIns.Push(NativeCodeInstruction(ins, isub ? ASMIT_SEC : ASMIT_CLC, ASMIM_IMPLIED));
|
mIns.Push(NativeCodeInstruction(ins, isub ? ASMIT_SEC : ASMIT_CLC, ASMIM_IMPLIED));
|
||||||
|
|
||||||
|
@ -14240,15 +14300,18 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
|
||||||
|
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1));
|
||||||
|
|
||||||
if (ins->mSrc[0].mTemp < 0)
|
if (crossing)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[0].mIntConst)
|
if (ins->mSrc[0].mTemp < 0)
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
{
|
||||||
|
if (ins->mSrc[0].mIntConst)
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
|
||||||
|
}
|
||||||
|
else if (ins->mSrc[0].IsUByte())
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_IMMEDIATE, 0));
|
||||||
|
else
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1));
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].IsUByte())
|
|
||||||
mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_IMMEDIATE, 0));
|
|
||||||
else
|
|
||||||
mIns.Push(NativeCodeInstruction(ins, iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1));
|
|
||||||
|
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||||
}
|
}
|
||||||
|
@ -50945,6 +51008,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterateN(int i, int pass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i + 6 < mIns.Size() && pass > 3 &&
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE_ADDRESS && mIns[i + 1].mLinkerObject &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_IMMEDIATE_ADDRESS && mIns[i + 1].mLinkerObject == mIns[i + 3].mLinkerObject &&
|
||||||
|
mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 &&
|
||||||
|
mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1)
|
||||||
|
{
|
||||||
|
if (mIns[i + 1].mLinkerObject->mFlags & LOBJF_NEVER_CROSS)
|
||||||
|
{
|
||||||
|
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (i + 7 < mIns.Size() && pass > 3 &&
|
if (i + 7 < mIns.Size() && pass > 3 &&
|
||||||
mIns[i + 0].mType == ASMIT_CLC &&
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
@ -54650,7 +54729,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
|
|
||||||
mInterProc->mLinkerObject->mNativeProc = this;
|
mInterProc->mLinkerObject->mNativeProc = this;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "mbox::show");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
|
|
@ -13728,6 +13728,27 @@ void Parser::ParsePragma(void)
|
||||||
|
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "nocross"))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent);
|
||||||
|
if (dec && dec->mType == DT_VARIABLE && (dec->mFlags & DTF_GLOBAL))
|
||||||
|
dec->mFlags |= DTF_NO_PAGE_CROSS;
|
||||||
|
else if (dec && dec->mType == DT_CONST_FUNCTION)
|
||||||
|
dec->mFlags |= DTF_NO_PAGE_CROSS;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Variable not found");
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Variable name expected");
|
||||||
|
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
else if (!strcmp(mScanner->mTokenIdent->mString, "align"))
|
else if (!strcmp(mScanner->mTokenIdent->mString, "align"))
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
|
@ -265,6 +265,8 @@ int main2(int argc, const char** argv)
|
||||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS;
|
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS;
|
||||||
else if (arg[2] == 'o' && !arg[3])
|
else if (arg[2] == 'o' && !arg[3])
|
||||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_OUTLINE;
|
compiler->mCompilerOptions |= COPT_OPTIMIZE_OUTLINE;
|
||||||
|
else if (arg[2] == 'x' && !arg[3])
|
||||||
|
compiler->mCompilerOptions |= COPT_OPTIMIZE_PAGE_CROSSING;
|
||||||
else
|
else
|
||||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue