Add warning for static buffer overflow
This commit is contained in:
parent
755c9234e1
commit
611f672b81
|
@ -40,6 +40,7 @@ enum ErrorID
|
||||||
EWARN_NUMERIC_0_USED_AS_NULLPTR,
|
EWARN_NUMERIC_0_USED_AS_NULLPTR,
|
||||||
EWARN_FLOAT_TO_INT,
|
EWARN_FLOAT_TO_INT,
|
||||||
EWARN_UNDEFINED_POINTER_ARITHMETIC,
|
EWARN_UNDEFINED_POINTER_ARITHMETIC,
|
||||||
|
EWARN_INVALID_VALUE_RANGE,
|
||||||
|
|
||||||
EERR_GENERIC = 3000,
|
EERR_GENERIC = 3000,
|
||||||
EERR_FILE_NOT_FOUND,
|
EERR_FILE_NOT_FOUND,
|
||||||
|
|
|
@ -118,6 +118,11 @@ void IntegerValueRange::LimitMaxWeak(int64 value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IntegerValueRange::IsInvalid(void) const
|
||||||
|
{
|
||||||
|
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue > mMaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
bool IntegerValueRange::IsConstant(void) const
|
bool IntegerValueRange::IsConstant(void) const
|
||||||
{
|
{
|
||||||
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue;
|
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue;
|
||||||
|
@ -8077,6 +8082,12 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
||||||
|
|
||||||
vr.mMaxValue <<= ins->mSrc[0].mIntConst;
|
vr.mMaxValue <<= ins->mSrc[0].mIntConst;
|
||||||
vr.mMinValue <<= ins->mSrc[0].mIntConst;
|
vr.mMinValue <<= ins->mSrc[0].mIntConst;
|
||||||
|
|
||||||
|
if (ins->mDst.mType == IT_INT8 && vr.mMaxState == IntegerValueRange::S_BOUND && vr.mMaxValue > 255)
|
||||||
|
{
|
||||||
|
vr.mMinState = IntegerValueRange::S_UNBOUND;
|
||||||
|
vr.mMaxState = IntegerValueRange::S_UNBOUND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].IsUByte() && ins->mSrc[0].mRange.mMaxValue < 16)
|
else if (ins->mSrc[0].IsUByte() && ins->mSrc[0].mRange.mMaxValue < 16)
|
||||||
{
|
{
|
||||||
|
@ -10519,7 +10530,7 @@ bool InterCodeBasicBlock::SimplifyIntegerNumeric(const GrowingInstructionPtrArra
|
||||||
nins->mSrc[0] = ains->mSrc[1];
|
nins->mSrc[0] = ains->mSrc[1];
|
||||||
nins->mDst.mTemp = spareTemps++;
|
nins->mDst.mTemp = spareTemps++;
|
||||||
nins->mDst.mType = IT_INT16;
|
nins->mDst.mType = IT_INT16;
|
||||||
nins->mDst.mRange = pins->mDst.mRange;
|
nins->mDst.mRange = ains->mSrc[1].mRange;
|
||||||
mInstructions.Insert(i, nins);
|
mInstructions.Insert(i, nins);
|
||||||
|
|
||||||
ins->mSrc[0] = nins->mDst;
|
ins->mSrc[0] = nins->mDst;
|
||||||
|
@ -19140,6 +19151,31 @@ void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::WarnInvalidValueRanges(void)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
InterInstruction* ins = mInstructions[i];
|
||||||
|
|
||||||
|
for (int j = 0; j < ins->mNumOperands; j++)
|
||||||
|
{
|
||||||
|
if (ins->mSrc[j].mTemp >= 0 && ins->mSrc[j].mRange.IsInvalid())
|
||||||
|
{
|
||||||
|
mProc->mModule->mErrors->Error(ins->mLocation, EWARN_INVALID_VALUE_RANGE, "Invalid value range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->WarnInvalidValueRanges();
|
||||||
|
if (mFalseJump) mFalseJump->WarnInvalidValueRanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterCodeBasicBlock::WarnUsedUndefinedVariables(void)
|
void InterCodeBasicBlock::WarnUsedUndefinedVariables(void)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
|
@ -19883,6 +19919,16 @@ void InterCodeProcedure::WarnUsedUndefinedVariables(void)
|
||||||
mEntryBlock->WarnUsedUndefinedVariables();
|
mEntryBlock->WarnUsedUndefinedVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::WarnInvalidValueRanges(void)
|
||||||
|
{
|
||||||
|
ResetEntryBlocks();
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->CollectEntryBlocks(nullptr);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mEntryBlock->WarnInvalidValueRanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterCodeProcedure::TempForwarding(bool reverse, bool checkloops)
|
void InterCodeProcedure::TempForwarding(bool reverse, bool checkloops)
|
||||||
{
|
{
|
||||||
|
@ -20503,7 +20549,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "addGameObjectCannon");
|
CheckFunc = !strcmp(mIdent->mString, "opp::ostream::operator<<");
|
||||||
CheckCase = false;
|
CheckCase = false;
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
@ -21409,6 +21455,8 @@ void InterCodeProcedure::Close(void)
|
||||||
BuildTraces(false, false, true);
|
BuildTraces(false, false, true);
|
||||||
DisassembleDebug("Final Merged basic blocks");
|
DisassembleDebug("Final Merged basic blocks");
|
||||||
|
|
||||||
|
WarnInvalidValueRanges();
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
|
|
||||||
MapCallerSavedTemps();
|
MapCallerSavedTemps();
|
||||||
|
|
|
@ -172,6 +172,7 @@ public:
|
||||||
void SetLimit(int64 minValue, int64 maxValue);
|
void SetLimit(int64 minValue, int64 maxValue);
|
||||||
|
|
||||||
bool IsConstant(void) const;
|
bool IsConstant(void) const;
|
||||||
|
bool IsInvalid(void) const;
|
||||||
|
|
||||||
void LimitMin(int64 value);
|
void LimitMin(int64 value);
|
||||||
void LimitMax(int64 value);
|
void LimitMax(int64 value);
|
||||||
|
@ -619,6 +620,7 @@ public:
|
||||||
bool SameExitCode(const InterCodeBasicBlock* block) const;
|
bool SameExitCode(const InterCodeBasicBlock* block) const;
|
||||||
|
|
||||||
void WarnUsedUndefinedVariables(void);
|
void WarnUsedUndefinedVariables(void);
|
||||||
|
void WarnInvalidValueRanges(void);
|
||||||
void CheckValueReturn(void);
|
void CheckValueReturn(void);
|
||||||
void CheckNullptrDereference(void);
|
void CheckNullptrDereference(void);
|
||||||
|
|
||||||
|
@ -732,6 +734,7 @@ protected:
|
||||||
void MergeBasicBlocks(void);
|
void MergeBasicBlocks(void);
|
||||||
void CheckUsedDefinedTemps(void);
|
void CheckUsedDefinedTemps(void);
|
||||||
void WarnUsedUndefinedVariables(void);
|
void WarnUsedUndefinedVariables(void);
|
||||||
|
void WarnInvalidValueRanges(void);
|
||||||
void PropagateMemoryAliasingInfo(void);
|
void PropagateMemoryAliasingInfo(void);
|
||||||
void MoveConditionsOutOfLoop(void);
|
void MoveConditionsOutOfLoop(void);
|
||||||
|
|
||||||
|
|
|
@ -9245,6 +9245,14 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
|
|
||||||
int sreg0 = ins->mSrc[sop0].mTemp < 0 ? -1 : BC_REG_TMP + proc->mTempOffset[ins->mSrc[sop0].mTemp];
|
int sreg0 = ins->mSrc[sop0].mTemp < 0 ? -1 : BC_REG_TMP + proc->mTempOffset[ins->mSrc[sop0].mTemp];
|
||||||
|
|
||||||
|
if (ins->mSrc[sop1].mTemp >= 0 && ins->mSrc[sop0].mTemp >= 0 && sins1 && sins1 == sins0)
|
||||||
|
{
|
||||||
|
LoadValueToReg(proc, sins1, BC_REG_ACCU, nullptr, nullptr);
|
||||||
|
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplitx")));
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER | NCIF_USE_ZP_32_X, BC_REG_ACCU));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (ins->mSrc[sop1].mTemp < 0)
|
if (ins->mSrc[sop1].mTemp < 0)
|
||||||
{
|
{
|
||||||
union { float f; unsigned int v; } cc;
|
union { float f; unsigned int v; } cc;
|
||||||
|
@ -9326,16 +9334,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
||||||
{
|
{
|
||||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplitx")));
|
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplitx")));
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER | NCIF_USE_ZP_32_X, sreg0));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER | NCIF_USE_ZP_32_X, sreg0));
|
||||||
#if 0
|
}
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 0));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 1));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 2));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg0 + 3));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49481,25 +49480,42 @@ NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* i
|
||||||
return mRuntime[i];
|
return mRuntime[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool isfparam(const NativeCodeInstruction & cins, const NativeCodeInstruction & ins)
|
||||||
|
{
|
||||||
|
if (cins.mFlags & NCIF_RUNTIME)
|
||||||
|
{
|
||||||
|
if (ins.mAddress >= BC_REG_WORK && ins.mAddress < BC_REG_WORK + 8)
|
||||||
|
return true;
|
||||||
|
if (ins.mAddress >= BC_REG_ACCU && ins.mAddress < BC_REG_ACCU + 4)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ins.mAddress >= BC_REG_FPARAMS && ins.mAddress < BC_REG_FPARAMS_END)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void NativeCodeGenerator::RegisterFunctionCall(NativeCodeBasicBlock* block, int at)
|
void NativeCodeGenerator::RegisterFunctionCall(NativeCodeBasicBlock* block, int at)
|
||||||
{
|
{
|
||||||
LinkerObject* lo = block->mIns[at].mLinkerObject;
|
LinkerObject* lo = block->mIns[at].mLinkerObject;
|
||||||
if (lo->mIdent && !(block->mIns[at].mFlags & NCIF_USE_ZP_32_X))
|
if (lo->mIdent)// && !(block->mIns[at].mFlags & NCIF_USE_ZP_32_X))
|
||||||
{
|
{
|
||||||
uint64 fpmask = 0;
|
uint64 fpmask = 0;
|
||||||
|
|
||||||
int i = at;
|
int i = at;
|
||||||
while (i >= 2 &&
|
while (i >= 2 &&
|
||||||
block->mIns[i - 1].mType == ASMIT_STA && block->mIns[i - 1].mMode == ASMIM_ZERO_PAGE &&
|
block->mIns[i - 1].mType == ASMIT_STA && block->mIns[i - 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
block->mIns[i - 1].mAddress >= BC_REG_FPARAMS && block->mIns[i - 1].mAddress < BC_REG_FPARAMS_END &&
|
isfparam(block->mIns[at], block->mIns[i - 1]) &&
|
||||||
block->mIns[i - 2].mType == ASMIT_LDA && (block->mIns[i - 2].mMode == ASMIM_IMMEDIATE || block->mIns[i - 2].mMode == ASMIM_IMMEDIATE_ADDRESS || block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE || block->mIns[i - 2].mMode == ASMIM_ABSOLUTE))
|
block->mIns[i - 2].mType == ASMIT_LDA && (block->mIns[i - 2].mMode == ASMIM_IMMEDIATE || block->mIns[i - 2].mMode == ASMIM_IMMEDIATE_ADDRESS || block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE || block->mIns[i - 2].mMode == ASMIM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
if (block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE && block->mIns[i - 2].mAddress >= BC_REG_FPARAMS && block->mIns[i - 2].mAddress < BC_REG_FPARAMS_END)
|
if (block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE && block->mIns[i - 2].mAddress >= BC_REG_FPARAMS && block->mIns[i - 2].mAddress < BC_REG_FPARAMS_END)
|
||||||
{
|
{
|
||||||
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_FPARAMS)))
|
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_WORK)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_FPARAMS);
|
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_WORK);
|
||||||
|
|
||||||
i -= 2;
|
i -= 2;
|
||||||
}
|
}
|
||||||
|
@ -49508,16 +49524,18 @@ void NativeCodeGenerator::RegisterFunctionCall(NativeCodeBasicBlock* block, int
|
||||||
{
|
{
|
||||||
FunctionCall* ncp = new FunctionCall();
|
FunctionCall* ncp = new FunctionCall();
|
||||||
ncp->mLinkerObject = lo;
|
ncp->mLinkerObject = lo;
|
||||||
|
ncp->mOffset = block->mIns[at].mAddress;
|
||||||
|
|
||||||
ncp->mProxyObject = nullptr;
|
ncp->mProxyObject = nullptr;
|
||||||
ncp->mCount = 1;
|
ncp->mCount = 1;
|
||||||
while (i < at)
|
while (i < at)
|
||||||
{
|
{
|
||||||
ncp->mIns[block->mIns[i + 1].mAddress - BC_REG_FPARAMS] = block->mIns[i];
|
ncp->mIns[block->mIns[i + 1].mAddress - BC_REG_WORK] = block->mIns[i];
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCall* cp = mFunctionCalls;
|
FunctionCall* cp = mFunctionCalls;
|
||||||
while (cp && cp->mLinkerObject != ncp->mLinkerObject)
|
while (cp && (cp->mLinkerObject != ncp->mLinkerObject || cp->mOffset != ncp->mOffset))
|
||||||
cp = cp->mNext;
|
cp = cp->mNext;
|
||||||
if (!cp)
|
if (!cp)
|
||||||
{
|
{
|
||||||
|
@ -49556,15 +49574,15 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
||||||
int i = at;
|
int i = at;
|
||||||
while (i >= 2 &&
|
while (i >= 2 &&
|
||||||
block->mIns[i - 1].mType == ASMIT_STA && block->mIns[i - 1].mMode == ASMIM_ZERO_PAGE &&
|
block->mIns[i - 1].mType == ASMIT_STA && block->mIns[i - 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
block->mIns[i - 1].mAddress >= BC_REG_FPARAMS && block->mIns[i - 1].mAddress < BC_REG_FPARAMS_END &&
|
isfparam(block->mIns[at], block->mIns[i - 1]) &&
|
||||||
block->mIns[i - 2].mType == ASMIT_LDA && (block->mIns[i - 2].mMode == ASMIM_IMMEDIATE || block->mIns[i - 2].mMode == ASMIM_IMMEDIATE_ADDRESS || block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE || block->mIns[i - 2].mMode == ASMIM_ABSOLUTE))
|
block->mIns[i - 2].mType == ASMIT_LDA && (block->mIns[i - 2].mMode == ASMIM_IMMEDIATE || block->mIns[i - 2].mMode == ASMIM_IMMEDIATE_ADDRESS || block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE || block->mIns[i - 2].mMode == ASMIM_ABSOLUTE))
|
||||||
{
|
{
|
||||||
if (block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE && block->mIns[i - 2].mAddress >= BC_REG_FPARAMS && block->mIns[i - 2].mAddress < BC_REG_FPARAMS_END)
|
if (block->mIns[i - 2].mMode == ASMIM_ZERO_PAGE && block->mIns[i - 2].mAddress >= BC_REG_FPARAMS && block->mIns[i - 2].mAddress < BC_REG_FPARAMS_END)
|
||||||
{
|
{
|
||||||
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_FPARAMS)))
|
if (fpmask & (1ull << (block->mIns[i - 2].mAddress - BC_REG_WORK)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_FPARAMS);
|
fpmask |= 1ull << (block->mIns[i - 1].mAddress - BC_REG_WORK);
|
||||||
|
|
||||||
i -= 2;
|
i -= 2;
|
||||||
}
|
}
|
||||||
|
@ -49573,15 +49591,16 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
||||||
{
|
{
|
||||||
FunctionCall ncp;
|
FunctionCall ncp;
|
||||||
ncp.mLinkerObject = lo;
|
ncp.mLinkerObject = lo;
|
||||||
|
ncp.mOffset = block->mIns[at].mAddress;
|
||||||
int j = i;
|
int j = i;
|
||||||
while (i < at)
|
while (i < at)
|
||||||
{
|
{
|
||||||
ncp.mIns[block->mIns[i + 1].mAddress - BC_REG_FPARAMS] = block->mIns[i];
|
ncp.mIns[block->mIns[i + 1].mAddress - BC_REG_WORK] = block->mIns[i];
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCall* cp = mFunctionCalls;
|
FunctionCall* cp = mFunctionCalls;
|
||||||
while (cp && cp->mLinkerObject != ncp.mLinkerObject)
|
while (cp && (cp->mLinkerObject != ncp.mLinkerObject || cp->mOffset != ncp.mOffset))
|
||||||
cp = cp->mNext;
|
cp = cp->mNext;
|
||||||
if (cp)
|
if (cp)
|
||||||
{
|
{
|
||||||
|
@ -49607,7 +49626,7 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
||||||
{
|
{
|
||||||
while (j < at)
|
while (j < at)
|
||||||
{
|
{
|
||||||
if (bcp->mIns[block->mIns[j + 1].mAddress - BC_REG_FPARAMS].mType != ASMIT_INV)
|
if (bcp->mIns[block->mIns[j + 1].mAddress - BC_REG_WORK].mType != ASMIT_INV)
|
||||||
{
|
{
|
||||||
block->mIns[j + 0].mType = ASMIT_NOP; block->mIns[j + 0].mMode = ASMIM_IMPLIED;
|
block->mIns[j + 0].mType = ASMIT_NOP; block->mIns[j + 0].mMode = ASMIM_IMPLIED;
|
||||||
block->mIns[j + 1].mType = ASMIT_NOP; block->mIns[j + 1].mMode = ASMIM_IMPLIED;
|
block->mIns[j + 1].mType = ASMIT_NOP; block->mIns[j + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
@ -49615,6 +49634,7 @@ bool NativeCodeGenerator::MergeFunctionCall(NativeCodeBasicBlock* block, int at)
|
||||||
j += 2;
|
j += 2;
|
||||||
}
|
}
|
||||||
block->mIns[j].mLinkerObject = bcp->mProxyObject;
|
block->mIns[j].mLinkerObject = bcp->mProxyObject;
|
||||||
|
block->mIns[j].mAddress = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49675,13 +49695,13 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
||||||
|
|
||||||
ocalls.Remove(besti);
|
ocalls.Remove(besti);
|
||||||
|
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||||
{
|
{
|
||||||
if (fi->mIns[i - BC_REG_FPARAMS].mType != ASMIT_INV)
|
if (fi->mIns[i - BC_REG_WORK].mType != ASMIT_INV)
|
||||||
{
|
{
|
||||||
if (!fi->mIns[i - BC_REG_FPARAMS].IsSame(fj->mIns[i - BC_REG_FPARAMS]))
|
if (!fi->mIns[i - BC_REG_WORK].IsSame(fj->mIns[i - BC_REG_WORK]))
|
||||||
{
|
{
|
||||||
fi->mIns[i - BC_REG_FPARAMS].mType = ASMIT_INV;
|
fi->mIns[i - BC_REG_WORK].mType = ASMIT_INV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49709,9 +49729,9 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
||||||
ncp->mProxyObject = mLinker->AddObject(ncp->mLinkerObject->mLocation, ncp->mLinkerObject->mIdent->Mangle("@proxy"), ncp->mLinkerObject->mSection, ncp->mLinkerObject->mType);
|
ncp->mProxyObject = mLinker->AddObject(ncp->mLinkerObject->mLocation, ncp->mLinkerObject->mIdent->Mangle("@proxy"), ncp->mLinkerObject->mSection, ncp->mLinkerObject->mType);
|
||||||
|
|
||||||
ExpandingArray<uint8> code;
|
ExpandingArray<uint8> code;
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||||
{
|
{
|
||||||
NativeCodeInstruction& ins(ncp->mIns[i - BC_REG_FPARAMS]);
|
NativeCodeInstruction& ins(ncp->mIns[i - BC_REG_WORK]);
|
||||||
if (ins.mType == ASMIT_LDA)
|
if (ins.mType == ASMIT_LDA)
|
||||||
{
|
{
|
||||||
switch (ins.mMode)
|
switch (ins.mMode)
|
||||||
|
@ -49792,7 +49812,7 @@ void NativeCodeGenerator::BuildFunctionProxies(void)
|
||||||
rl.mObject = ncp->mProxyObject;
|
rl.mObject = ncp->mProxyObject;
|
||||||
rl.mOffset = code.Size();
|
rl.mOffset = code.Size();
|
||||||
rl.mRefObject = ncp->mLinkerObject;
|
rl.mRefObject = ncp->mLinkerObject;
|
||||||
rl.mRefOffset = 0;
|
rl.mRefOffset = ncp->mOffset;
|
||||||
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
|
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
|
||||||
ncp->mProxyObject->AddReference(rl);
|
ncp->mProxyObject->AddReference(rl);
|
||||||
code.Push(0);
|
code.Push(0);
|
||||||
|
@ -49818,8 +49838,8 @@ void NativeCodeGenerator::RegisterRuntime(const Ident* ident, LinkerObject* obje
|
||||||
|
|
||||||
bool NativeCodeGenerator::FunctionCall::IsSame(const FunctionCall* fc) const
|
bool NativeCodeGenerator::FunctionCall::IsSame(const FunctionCall* fc) const
|
||||||
{
|
{
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||||
if (!mIns[i - BC_REG_FPARAMS].IsSame(fc->mIns[i - BC_REG_FPARAMS]))
|
if (!mIns[i - BC_REG_WORK].IsSame(fc->mIns[i - BC_REG_WORK]))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -49828,11 +49848,11 @@ int NativeCodeGenerator::FunctionCall::Matches(const FunctionCall* fc) const
|
||||||
{
|
{
|
||||||
int match = 0;
|
int match = 0;
|
||||||
|
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||||
{
|
{
|
||||||
if (fc->mIns[i - BC_REG_FPARAMS].mType != ASMIT_INV)
|
if (fc->mIns[i - BC_REG_WORK].mType != ASMIT_INV)
|
||||||
{
|
{
|
||||||
if (!mIns[i - BC_REG_FPARAMS].IsSame(fc->mIns[i - BC_REG_FPARAMS]))
|
if (!mIns[i - BC_REG_WORK].IsSame(fc->mIns[i - BC_REG_WORK]))
|
||||||
return -1;
|
return -1;
|
||||||
match++;
|
match++;
|
||||||
}
|
}
|
||||||
|
@ -49845,11 +49865,11 @@ int NativeCodeGenerator::FunctionCall::PotentialMatches(const FunctionCall* fc)
|
||||||
{
|
{
|
||||||
int match = 0;
|
int match = 0;
|
||||||
|
|
||||||
for (int i = BC_REG_FPARAMS; i < BC_REG_FPARAMS_END; i++)
|
for (int i = BC_REG_WORK; i < BC_REG_ACCU + 4; i++)
|
||||||
{
|
{
|
||||||
if (fc->mIns[i - BC_REG_FPARAMS].mType != ASMIT_INV)
|
if (fc->mIns[i - BC_REG_WORK].mType != ASMIT_INV)
|
||||||
{
|
{
|
||||||
if (mIns[i - BC_REG_FPARAMS].IsSame(fc->mIns[i - BC_REG_FPARAMS]))
|
if (mIns[i - BC_REG_WORK].IsSame(fc->mIns[i - BC_REG_WORK]))
|
||||||
match++;
|
match++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -840,7 +840,7 @@ public:
|
||||||
LinkerObject * mLinkerObject, * mProxyObject;
|
LinkerObject * mLinkerObject, * mProxyObject;
|
||||||
NativeCodeInstruction mIns[64];
|
NativeCodeInstruction mIns[64];
|
||||||
FunctionCall * mNext, * mSame;
|
FunctionCall * mNext, * mSame;
|
||||||
int mCount;
|
int mCount, mOffset;
|
||||||
|
|
||||||
bool IsSame(const FunctionCall* fc) const;
|
bool IsSame(const FunctionCall* fc) const;
|
||||||
int Matches(const FunctionCall* fc) const;
|
int Matches(const FunctionCall* fc) const;
|
||||||
|
|
|
@ -212,6 +212,8 @@ int main2(int argc, const char** argv)
|
||||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_CONST_PARAMS;
|
compiler->mCompilerOptions |= COPT_OPTIMIZE_CONST_PARAMS;
|
||||||
else if (arg[2] == 'g')
|
else if (arg[2] == 'g')
|
||||||
compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL;
|
compiler->mCompilerOptions |= COPT_OPTIMIZE_GLOBAL;
|
||||||
|
else if (arg[2] == 'm')
|
||||||
|
compiler->mCompilerOptions |= COPT_OPTIMIZE_MERGE_CALLS;
|
||||||
}
|
}
|
||||||
else if (arg[1] == 'e')
|
else if (arg[1] == 'e')
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue