From 230dc8ab51c0d0cc43f30f1fa58eb4879126e00b Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 22 Sep 2024 21:40:27 +0200 Subject: [PATCH] Fix various gcc torture tests --- include/stdlib.c | 9 +-- oscar64/GlobalAnalyzer.cpp | 118 +++++++++++++++++--------------- oscar64/GlobalAnalyzer.h | 2 +- oscar64/InterCode.cpp | 105 +++++++++++++++++++++++++--- oscar64/NativeCodeGenerator.cpp | 102 +++++++++++++++++++++++---- 5 files changed, 250 insertions(+), 86 deletions(-) diff --git a/include/stdlib.c b/include/stdlib.c index c9f2ab6..2e9a08e 100644 --- a/include/stdlib.c +++ b/include/stdlib.c @@ -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) { diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 5ed4dea..017b333 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -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; } diff --git a/oscar64/GlobalAnalyzer.h b/oscar64/GlobalAnalyzer.h index 6e63662..03050a1 100644 --- a/oscar64/GlobalAnalyzer.h +++ b/oscar64/GlobalAnalyzer.h @@ -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); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 8f2346b..ac8f492 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -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,12 +5702,21 @@ 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; + } } - fprintf(file, "C%c%d(%d:%d '%s')", memchars[mConst.mMemory], mConst.mOperandSize, mConst.mVarIndex, int(mConst.mIntConst), vname); + 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) fprintf(file, "CF:%f", mConst.mFloatConst); @@ -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]; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index fc1c75e..bcd689f 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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,16 +2927,31 @@ bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmI (opmask & opvalue) & (data.mRegs[CPU_REG_A].mMask & data.mRegs[CPU_REG_A].mValue); - data.mRegs[CPU_REG_A].mMask = (ones | zeros) & 0xff; - data.mRegs[CPU_REG_A].mValue = ones & 0xff; + int changed = (~data.mRegs[CPU_REG_A].mMask | data.mRegs[CPU_REG_A].mValue) & (~opmask | ~opvalue) & 0xff; - if (data.mRegs[CPU_REG_A].mMask == 0xff) + if (changed == 0) { - mType = ASMIT_LDA; - mMode = ASMIM_IMMEDIATE; - mAddress = data.mRegs[CPU_REG_A].mValue; - changed = true; + 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; + + if (data.mRegs[CPU_REG_A].mMask == 0xff) + { + mType = ASMIT_LDA; + mMode = ASMIM_IMMEDIATE; + 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) {