Fix various gcc torture tests

This commit is contained in:
drmortalwombat 2024-09-22 21:40:27 +02:00
parent c87887cbd1
commit 49893f6976
5 changed files with 250 additions and 86 deletions

View File

@ -7,20 +7,17 @@
void itoa(int n, char * s, unsigned radix)
{
bool neg = n < 0;
if (neg)
{
n = - n;
}
unsigned un = neg ? -n : n;
char i = 0;
do {
int d = n % radix;
unsigned d = un % radix;
if (d < 10)
d += '0';
else
d += 'A' - 10;
s[i++] = d;
} while ((n /= radix) > 0);
} while ((un /= radix) > 0);
if (neg)
{

View File

@ -633,7 +633,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* cexp, Expression* exp, Declara
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
dec->mFlags |= DTF_FUNC_CONSTEXPR;
dec->mFlags |= DTF_FUNC_PURE;
Analyze(exp, dec, false);
Analyze(exp, dec, false, false);
Declaration* pdec = dec->mBase->mParams;
int vi = 0;
@ -729,7 +729,7 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
if (dec->mValue)
{
Analyze(dec->mValue, dec, false);
Analyze(dec->mValue, dec, false, false);
}
}
}
@ -739,14 +739,14 @@ void GlobalAnalyzer::AnalyzeInit(Declaration* mdec)
while (mdec)
{
if (mdec->mValue)
RegisterProc(Analyze(mdec->mValue, mdec, false));
RegisterProc(Analyze(mdec->mValue, mdec, false, false));
else if (mdec->mParams)
AnalyzeInit(mdec->mParams);
mdec = mdec->mNext;
}
}
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs)
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing)
{
Declaration* ldec, * rdec;
@ -767,7 +767,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
}
else if (exp->mDecValue->mType == DT_CONST_POINTER)
{
ldec = Analyze(exp->mDecValue->mValue, procDec, true);
ldec = Analyze(exp->mDecValue->mValue, procDec, true, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
RegisterProc(ldec);
@ -791,6 +791,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
if (mCompilerOptions & COPT_DEBUGINFO)
exp->mDecValue->mReferences.Push(exp);
if (aliasing)
{
Declaration* dec = exp->mDecValue;
while (dec->mType == DT_VARIABLE_REF)
dec = dec->mBase;
dec->mFlags |= DTF_VAR_ALIASING;
}
if ((exp->mDecValue->mFlags & DTF_STATIC) || (exp->mDecValue->mFlags & DTF_GLOBAL))
{
Declaration* type = exp->mDecValue->mBase;
@ -821,8 +829,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_ASSIGNMENT:
procDec->mComplexity += 5 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, true);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft, procDec, true, false);
rdec = Analyze(exp->mRight, procDec, false, false);
if (exp->mLeft->mType == EX_VARIABLE && exp->mRight->mType == EX_CALL && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
exp->mLeft->mDecValue->mFlags |= DTF_VAR_ALIASING;
RegisterProc(rdec);
@ -831,31 +839,31 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_BINARY:
procDec->mComplexity += 10 * exp->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, lhs);
rdec = Analyze(exp->mRight, procDec, lhs);
ldec = Analyze(exp->mLeft, procDec, lhs, false);
rdec = Analyze(exp->mRight, procDec, lhs, false);
return ldec;
case EX_RELATIONAL:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
return TheBoolTypeDeclaration;
case EX_PREINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, true);
return Analyze(exp->mLeft, procDec, true, false);
case EX_PREFIX:
if (exp->mToken == TK_BINARY_AND)
{
ldec = Analyze(exp->mLeft, procDec, true);
ldec = Analyze(exp->mLeft, procDec, true, true);
if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING;
}
else if (exp->mToken == TK_MUL)
{
ldec = Analyze(exp->mLeft, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
@ -869,7 +877,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
else
{
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, false);
return Analyze(exp->mLeft, procDec, false, false);
}
break;
case EX_POSTFIX:
@ -878,11 +886,11 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_POSTINCDEC:
procDec->mComplexity += 10 * exp->mLeft->mDecType->mSize;
return Analyze(exp->mLeft, procDec, true);
return Analyze(exp->mLeft, procDec, true, false);
case EX_INDEX:
procDec->mComplexity += 10 * exp->mRight->mDecType->mSize;
ldec = Analyze(exp->mLeft, procDec, lhs);
ldec = Analyze(exp->mLeft, procDec, lhs, false);
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
{
ldec = ldec->mBase;
@ -893,16 +901,16 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
}
rdec = Analyze(exp->mRight, procDec, false);
rdec = Analyze(exp->mRight, procDec, false, false);
if (ldec->mBase)
return ldec->mBase;
break;
case EX_QUALIFY:
Analyze(exp->mLeft, procDec, lhs);
Analyze(exp->mLeft, procDec, lhs, aliasing);
return exp->mDecValue->mBase;
case EX_DISPATCH:
procDec->mFlags |= DTF_PREVENT_INLINE;
Analyze(exp->mLeft, procDec, lhs);
Analyze(exp->mLeft, procDec, lhs, false);
// RegisterCall(procDec, exp->mLeft->mDecType);
break;
case EX_VCALL:
@ -913,7 +921,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_INLINE:
procDec->mComplexity += 10;
ldec = Analyze(exp->mLeft, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
{
@ -1000,7 +1008,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
if (pex->mType == EX_CALL && IsStackParam(pex->mDecType) && !(pdec && (pdec->mBase->mType == DT_TYPE_REFERENCE || pdec->mBase->mType == DT_TYPE_RVALUEREF)))
ldec->mBase->mFlags |= DTF_STACKCALL;
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference()));
RegisterProc(Analyze(pex, procDec, pdec && pdec->mBase->IsReference(), false));
if (pdec)
pdec = pdec->mNext;
@ -1014,12 +1022,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
break;
case EX_LIST:
case EX_COMMA:
RegisterProc(Analyze(exp->mLeft, procDec, false));
return Analyze(exp->mRight, procDec, false);
RegisterProc(Analyze(exp->mLeft, procDec, false, false));
return Analyze(exp->mRight, procDec, false, false);
case EX_RETURN:
if (exp->mLeft)
{
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference()));
RegisterProc(Analyze(exp->mLeft, procDec, procDec->mBase->mBase->IsReference(), false));
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
{
if (procDec->mBase->mBase->mMoveConstructor)
@ -1040,47 +1048,47 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
if (exp->mType == EX_SEQUENCE)
{
if (exp->mLeft)
ldec = Analyze(exp->mLeft, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
exp = exp->mRight;
}
else
return Analyze(exp, procDec, false);
return Analyze(exp, procDec, false, false);
} while (exp);
break;
case EX_SCOPE:
Analyze(exp->mLeft, procDec, false);
Analyze(exp->mLeft, procDec, false, false);
break;
case EX_CONSTRUCT:
if (exp->mLeft->mLeft)
Analyze(exp->mLeft->mLeft, procDec, false);
Analyze(exp->mLeft->mLeft, procDec, false, false);
if (exp->mLeft->mRight)
Analyze(exp->mLeft->mRight, procDec, false);
Analyze(exp->mLeft->mRight, procDec, false, false);
if (exp->mRight)
return Analyze(exp->mRight, procDec, false);
return Analyze(exp->mRight, procDec, false, false);
break;
case EX_CLEANUP:
Analyze(exp->mRight, procDec, false);
return Analyze(exp->mLeft, procDec, lhs);
Analyze(exp->mRight, procDec, false, false);
return Analyze(exp->mLeft, procDec, lhs, false);
case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_IF:
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight->mLeft, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight->mLeft, procDec, false, false);
if (exp->mRight->mRight)
rdec = Analyze(exp->mRight->mRight, procDec, false);
rdec = Analyze(exp->mRight->mRight, procDec, false, false);
break;
case EX_ELSE:
break;
@ -1090,18 +1098,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
procDec->mComplexity += 30;
if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec, false);
ldec = Analyze(exp->mLeft->mRight, procDec, false, false);
if (exp->mLeft->mLeft->mLeft)
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false);
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false, false);
break;
case EX_DO:
procDec->mComplexity += 20;
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_BREAK:
case EX_CONTINUE:
@ -1110,18 +1118,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_TYPE:
break;
case EX_TYPECAST:
return Analyze(exp->mLeft, procDec, false);
return Analyze(exp->mLeft, procDec, false, false);
break;
case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_LOGICAL_OR:
ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
rdec = Analyze(exp->mRight, procDec, false, false);
break;
case EX_LOGICAL_NOT:
ldec = Analyze(exp->mLeft, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
break;
case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER;
@ -1132,14 +1140,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_UNDEFINED:
break;
case EX_SWITCH:
ldec = Analyze(exp->mLeft, procDec, false);
ldec = Analyze(exp->mLeft, procDec, false, false);
exp = exp->mRight;
while (exp)
{
procDec->mComplexity += 10;
if (exp->mLeft->mRight)
rdec = Analyze(exp->mLeft->mRight, procDec, false);
rdec = Analyze(exp->mLeft->mRight, procDec, false, false);
exp = exp->mRight;
}
break;
@ -1150,9 +1158,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
case EX_CONDITIONAL:
procDec->mComplexity += exp->mDecType->mSize * 10;
ldec = Analyze(exp->mLeft, procDec, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs));
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs));
ldec = Analyze(exp->mLeft, procDec, false, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec, lhs, aliasing));
RegisterProc(Analyze(exp->mRight->mRight, procDec, lhs, aliasing));
break;
}

View File

@ -33,7 +33,7 @@ protected:
void AnalyzeInit(Declaration* mdec);
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs);
Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs, bool aliasing);
bool IsStackParam(const Declaration* pdec) const;
bool MarkCycle(Declaration* rootDec, Declaration* procDec);

View File

@ -723,7 +723,10 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
else if (op2.mMemory == IM_GLOBAL)
{
if (op1.mMemoryBase == IM_GLOBAL)
return op1.mVarIndex == op2.mVarIndex && CollidingMemType(type1, type2);
return op1.mVarIndex == op2.mVarIndex && (
mProc->mModule->mGlobalVars[op2.mVarIndex]->mSize == InterTypeSize[type1] ||
mProc->mModule->mGlobalVars[op2.mVarIndex]->mSize == InterTypeSize[type2] ||
CollidingMemType(type1, type2));
else
return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased;
}
@ -732,7 +735,10 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
else if (op2.mMemory == IM_LOCAL)
{
if (op1.mMemoryBase == IM_LOCAL)
return op1.mVarIndex == op2.mVarIndex && CollidingMemType(type1, type2);
return op1.mVarIndex == op2.mVarIndex && (
mProc->mLocalVars[op2.mVarIndex]->mSize == InterTypeSize[type1] ||
mProc->mLocalVars[op2.mVarIndex]->mSize == InterTypeSize[type2] ||
CollidingMemType(type1, type2));
else
return mProc->mLocalVars[op2.mVarIndex]->mAliased && CollidingMemType(type1, type2);
}
@ -758,7 +764,10 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
else if (op1.mMemory == IM_GLOBAL)
{
if (op2.mMemoryBase == IM_GLOBAL)
return op1.mVarIndex == op2.mVarIndex;
return op1.mVarIndex == op2.mVarIndex && (
mProc->mModule->mGlobalVars[op2.mVarIndex]->mSize == InterTypeSize[type1] ||
mProc->mModule->mGlobalVars[op2.mVarIndex]->mSize == InterTypeSize[type2] ||
CollidingMemType(type1, type2));
else
return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased;
}
@ -766,8 +775,11 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
return false;
else if (op1.mMemory == IM_LOCAL)
{
if (op1.mMemoryBase == IM_LOCAL)
return op1.mVarIndex == op2.mVarIndex;
if (op2.mMemoryBase == IM_LOCAL)
return op1.mVarIndex == op2.mVarIndex && (
mProc->mLocalVars[op1.mVarIndex]->mSize == InterTypeSize[type1] ||
mProc->mLocalVars[op1.mVarIndex]->mSize == InterTypeSize[type2] ||
CollidingMemType(type1, type2));
else
return mProc->mLocalVars[op1.mVarIndex]->mAliased && CollidingMemType(type1, type2);
}
@ -3188,7 +3200,11 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
if (tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT8TO16S || tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT8TO32S)
{
int64 ivalue = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst;
if (ivalue < -128)
if (ins->mSrc[1].mType == IT_INT16 && (ivalue < -32768 || ivalue > 32767))
{
}
else if (ivalue < -128)
{
toconst = true;
switch (ins->mOperator)
@ -3359,6 +3375,52 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
}
}
}
else if (tvalue[ins->mSrc[1].mTemp]->mOperator == IA_EXT16TO32S)
{
int64 ivalue = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst;
if (ivalue < -32768)
{
toconst = true;
switch (ins->mOperator)
{
case IA_CMPEQ:
case IA_CMPLES:
case IA_CMPLS:
case IA_CMPLEU:
case IA_CMPLU:
cvalue = 0;
break;
case IA_CMPNE:
case IA_CMPGES:
case IA_CMPGS:
case IA_CMPGEU:
case IA_CMPGU:
cvalue = 1;
break;
}
}
else if (ivalue > 32767)
{
toconst = true;
switch (ins->mOperator)
{
case IA_CMPEQ:
case IA_CMPGES:
case IA_CMPGS:
case IA_CMPGEU:
case IA_CMPGU:
cvalue = 0;
break;
case IA_CMPNE:
case IA_CMPLES:
case IA_CMPLS:
case IA_CMPLEU:
case IA_CMPLU:
cvalue = 1;
break;
}
}
}
if (toconst)
{
@ -5610,6 +5672,7 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
if (mDst.mType == IT_POINTER)
{
const char* vname = "";
bool aliased = false;
if (mConst.mMemory == IM_LOCAL)
{
@ -5639,11 +5702,20 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
else if (!proc->mModule->mGlobalVars[mConst.mVarIndex])
vname = "null";
else if (!proc->mModule->mGlobalVars[mConst.mVarIndex]->mIdent)
{
vname = "";
aliased = proc->mModule->mGlobalVars[mConst.mVarIndex]->mAliased;
}
else
{
vname = proc->mModule->mGlobalVars[mConst.mVarIndex]->mIdent->mString;
aliased = proc->mModule->mGlobalVars[mConst.mVarIndex]->mAliased;
}
}
if (aliased)
fprintf(file, "C%c%d(%d:%d '%s' A)", memchars[mConst.mMemory], mConst.mOperandSize, mConst.mVarIndex, int(mConst.mIntConst), vname);
else
fprintf(file, "C%c%d(%d:%d '%s')", memchars[mConst.mMemory], mConst.mOperandSize, mConst.mVarIndex, int(mConst.mIntConst), vname);
}
else if (mDst.mType == IT_FLOAT)
@ -8057,8 +8129,10 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsForward(const GrowingVariab
{
vr.mMaxState = IntegerValueRange::S_BOUND;
vr.mMaxValue = 127;
vr.mMinState = IntegerValueRange::S_BOUND;
vr.mMinValue = -128;
}
if (vr.mMinState != IntegerValueRange::S_BOUND || vr.mMinValue < -128 || vr.mMinValue > 127)
else if (vr.mMinState != IntegerValueRange::S_BOUND || vr.mMinValue < -128 || vr.mMinValue > 127)
{
vr.mMinState = IntegerValueRange::S_BOUND;
vr.mMinValue = -128;
@ -8372,7 +8446,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSetsForward(const GrowingVariab
if (ins->mSrc[0].mIntConst > 0)
{
if (vr.mMinState == IntegerValueRange::S_BOUND && vr.mMinState >= 0)
if (vr.mMinState == IntegerValueRange::S_BOUND && vr.mMinValue >= 0)
{
switch (ins->mSrc[1].mType)
{
@ -9783,6 +9857,17 @@ bool InterCodeBasicBlock::CalculateSingleAssignmentTemps(FastNumberSet& tassigne
}
}
}
else if (ins->mCode == IC_CONSTANT)
{
if (ins->mConst.mType == IT_POINTER && ins->mConst.mMemory == paramMemory)
{
if (!modifiedParams[ins->mConst.mVarIndex])
{
modifiedParams += ins->mConst.mVarIndex;
changed = true;
}
}
}
}
if (valid)
@ -22365,7 +22450,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main");
CheckFunc = !strcmp(mIdent->mString, "bad");
CheckCase = false;
mEntryBlock = mBlocks[0];

View File

@ -581,12 +581,13 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
}
else
{
#if 0
for (int i = 0; i < 4; i++)
{
requiredTemps -= BC_REG_ACCU + i;
requiredTemps -= BC_REG_WORK + i;
}
#endif
if (mFlags & NICF_USE_WORKREGS)
{
for (int i = 0; i < 10; i++)
@ -2926,6 +2927,19 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI
(opmask & opvalue) &
(data.mRegs[CPU_REG_A].mMask & data.mRegs[CPU_REG_A].mValue);
int changed = (~data.mRegs[CPU_REG_A].mMask | data.mRegs[CPU_REG_A].mValue) & (~opmask | ~opvalue) & 0xff;
if (changed == 0)
{
if (mMode != ASMIM_IMMEDIATE || mAddress != 0xff)
{
mMode = ASMIM_IMMEDIATE;
mAddress = 0xff;
changed = true;
}
}
else
{
data.mRegs[CPU_REG_A].mMask = (ones | zeros) & 0xff;
data.mRegs[CPU_REG_A].mValue = ones & 0xff;
@ -2936,6 +2950,8 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI
mAddress = data.mRegs[CPU_REG_A].mValue;
changed = true;
}
}
} break;
case ASMIT_ORA:
@ -12727,7 +12743,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
li = 0; ri = 1;
}
if (op >= IA_CMPGES && ins->mOperator <= IA_CMPLS)
if (op >= IA_CMPGES && op <= IA_CMPLS)
{
if (ins->mSrc[ri].mTemp >= 0)
{
@ -21106,6 +21122,20 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
}
}
if (mFalseJump && mTrueJump->mIns.Size() == 0 && mFalseJump->mIns.Size() == 0 && (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS))
{
if (mTrueJump->mBranch == ASMIT_BEQ && mFalseJump->mBranch == ASMIT_BNE && mTrueJump->mTrueJump == mFalseJump->mFalseJump)
{
NativeCodeBasicBlock* iblock = proc->AllocateBlock();
iblock->Close(mBranchIns, mTrueJump->mFalseJump, mFalseJump->mTrueJump, mBranch);
mBranch = ASMIT_BEQ;
mTrueJump = mTrueJump->mTrueJump;
mFalseJump = iblock;
changed = true;
}
}
if (mFalseJump && mTrueJump->mTrueJump == mFalseJump && !mTrueJump->mFalseJump && mTrueJump->mNumEntries == 1)
{
int sz = mIns.Size();
@ -24553,7 +24583,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
else if (mIns[0].mType == ASMIT_LDX && mIns[0].mMode == ASMIM_ZERO_PAGE && !(mIns[0].mLive & LIVE_CPU_REG_A))
{
if (lblock->mIns[ls - 2].mType == ASMIT_LDA && lblock->mIns[ls - 2].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 2].mAddress == mIns[0].mAddress &&
lblock->mIns[ls - 1].mType == ASMIT_CMP && !(lblock->mIns[ls - 1].mLive & LIVE_CPU_REG_A))
lblock->mIns[ls - 1].mType == ASMIT_CMP && HasAsmInstructionMode(ASMIT_CPX, lblock->mIns[ls - 1].mMode) && !(lblock->mIns[ls - 1].mLive & LIVE_CPU_REG_A))
{
lblock->mIns[ls - 2].mType = ASMIT_LDX; lblock->mIns[ls - 2].mLive |= LIVE_CPU_REG_X;
lblock->mIns[ls - 1].mType = ASMIT_CPX; lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_X;
@ -38366,7 +38396,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_IMMEDIATE &&
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
{
if (mBranch == ASMIT_BCS && mIns[sz - 2].mAddress < 0xff)
if (mBranch == ASMIT_BCS && mIns[sz - 2].mAddress < 0xff && !(mIns[sz - 1].mLive & LIVE_CPU_REG_Z))
{
int val = mIns[sz - 2].mAddress + 1;
mBranch = ASMIT_BCC;
@ -38374,7 +38404,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc, bool f
mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = val;
mIns[sz - 2].mLive |= mIns[sz - 1].mLive & LIVE_MEM;
}
else if (mBranch == ASMIT_BCC && mIns[sz - 2].mAddress < 0xff)
else if (mBranch == ASMIT_BCC && mIns[sz - 2].mAddress < 0xff && !(mIns[sz - 1].mLive & LIVE_CPU_REG_Z))
{
int val = mIns[sz - 2].mAddress + 1;
mBranch = ASMIT_BCS;
@ -45515,6 +45545,24 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate3(int i, int pass)
mIns[i + 2].mMode = ASMIM_IMPLIED;
return true;
}
else if (
mIns[i + 0].mType == ASMIT_SEC &&
mIns[i + 1].mType == ASMIT_SBC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
mIns[i + 2].mType == ASMIT_CMP && mIns[i + 2].mMode == ASMIM_IMMEDIATE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
mIns[i + 2].mAddress = (mIns[i + 2].mAddress + mIns[i + 1].mAddress) & 0xff;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
return true;
}
else if (
mIns[i + 0].mType == ASMIT_CLC &&
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
mIns[i + 2].mType == ASMIT_CMP && mIns[i + 2].mMode == ASMIM_IMMEDIATE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
{
mIns[i + 2].mAddress = (mIns[i + 2].mAddress - mIns[i + 1].mAddress) & 0xff;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
return true;
}
if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress <= 1 &&
@ -49450,7 +49498,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerExits(int pass)
mIns[sz - 4].mType = ASMIT_NOP; mIns[sz - 4].mMode = ASMIM_IMPLIED;
mIns[sz - 3].mType = ASMIT_NOP; mIns[sz - 3].mMode = ASMIM_IMPLIED;
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = 0; mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
mIns[sz - 1].mType = ASMIT_ORA; mIns[sz - 1].mMode = ASMIM_IMMEDIATE; mIns[sz - 1].mAddress = 0;
mIns[sz - 1].mLive &= ~LIVE_CPU_REG_C;
mIns[sz - 1].mLive |= LIVE_CPU_REG_Z;
mExitRequiredRegs -= CPU_REG_C;
CheckLive();
}
@ -49533,6 +49585,29 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerExits(int pass)
sz -= 1;
CheckLive();
}
else if (pass >= 7 && sz >= 2 &&
mIns[sz - 2].mType == ASMIT_AND && mIns[sz - 2].mMode == ASMIM_IMMEDIATE && mIns[sz - 2].mAddress == 1 &&
mIns[sz - 1].mType == ASMIT_EOR && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 1 &&
!(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)) && !mExitRequiredRegs[CPU_REG_Z])
{
if (mBranch == ASMIT_BNE)
{
mIns[sz - 2].mType = ASMIT_LSR; mIns[sz - 2].mMode = ASMIM_IMPLIED; mIns[sz - 2].mLive |= LIVE_CPU_REG_C;
mBranch = ASMIT_BCC;
mIns.SetSize(sz - 1);
changed = true;
}
else if (mBranch == ASMIT_BEQ)
{
mIns[sz - 2].mType = ASMIT_LSR; mIns[sz - 2].mMode = ASMIM_IMPLIED; mIns[sz - 2].mLive |= LIVE_CPU_REG_C;
mBranch = ASMIT_BCS;
mIns.SetSize(sz - 1);
changed = true;
}
sz -= 1;
CheckLive();
}
if (sz >= 1 &&
mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x80 && !(mIns[sz - 1].mLive & LIVE_CPU_REG_A) &&
@ -51872,7 +51947,6 @@ void NativeCodeProcedure::Optimize(void)
mEntryBlock->CheckAsmCode();
#endif
#if 1
if (step > 2 && !changed)
{