diff --git a/include/opp/string.cpp b/include/opp/string.cpp index f5468d6..5c15b2e 100644 --- a/include/opp/string.cpp +++ b/include/opp/string.cpp @@ -8,6 +8,14 @@ static inline void smemcpy(char * dp, const char * sp, char s) dp[i] = sp[i]; } +static inline char sstrlen(const char * sp) +{ + char n = 0; + while (sp[n]) + n++; + return n; +} + string::string(void) : cstr(nullptr) {} @@ -16,7 +24,7 @@ string::string(const string & s) if (s.cstr) { char l = s.cstr[0]; - cstr = malloc(l + 2); + cstr = malloc(char(l + 2)); smemcpy(cstr, s.cstr, l + 2); } else @@ -25,10 +33,10 @@ string::string(const string & s) string::string(const char * s) { - char l = strlen(s); + char l = sstrlen(s); if (l) { - cstr = malloc(l + 2); + cstr = malloc(char(l + 2)); cstr[0] = l; smemcpy(cstr + 1, s, l + 1); } @@ -64,7 +72,7 @@ string & string::operator=(const string & s) if (s.cstr) { char l = s.cstr[0]; - cstr = malloc(l + 2); + cstr = malloc(char(l + 2)); smemcpy(cstr, s.cstr, l + 2); } else @@ -77,10 +85,10 @@ string & string::operator=(const string & s) string & string::operator=(const char * s) { free(cstr); - char l = strlen(s); + char l = sstrlen(s); if (l) { - cstr = malloc(l + 2); + cstr = malloc(char(l + 2)); cstr[0] = l; smemcpy(cstr + 1, s, l + 1); } @@ -97,7 +105,7 @@ string & string::operator+=(const string & s) if (cstr) { char l = cstr[0] + s.cstr[0]; - char * c = malloc(l + 2); + char * c = malloc(char(l + 2)); c[0] = l; smemcpy(c + 1, cstr + 1, cstr[0]); smemcpy(c + 1 + cstr[0], s.cstr + 1, s.cstr[0] + 1); @@ -107,7 +115,7 @@ string & string::operator+=(const string & s) else { char l = s.cstr[0]; - cstr = malloc(l + 2); + cstr = malloc(char(l + 2)); smemcpy(cstr, s.cstr, l + 2); } } @@ -116,13 +124,13 @@ string & string::operator+=(const string & s) string & string::operator+=(const char * s) { - char sl = strlen(s); + char sl = sstrlen(s); if (sl) { if (cstr) { char l = sl + cstr[0]; - char * c = malloc(l + 2); + char * c = malloc(char(l + 2)); c[0] = l; smemcpy(c + 1, cstr + 1, cstr[0]); smemcpy(c + 1 + cstr[0], s, sl + 1); @@ -131,7 +139,7 @@ string & string::operator+=(const char * s) } else { - cstr = malloc(sl + 2); + cstr = malloc(char(sl + 2)); cstr[0] = sl; smemcpy(cstr + 1, s, sl + 1); } @@ -144,7 +152,7 @@ string & string::operator+=(char c) if (cstr) { char l = cstr[0] + 1; - char * p = malloc(l + 2); + char * p = malloc(char(l + 2)); p[0] = l; smemcpy(p + 1, cstr + 1, cstr[0]); p[l] = c; @@ -185,7 +193,7 @@ string string::operator+(const string & s) const if (s.cstr) { char l = cstr[0] + s.cstr[0]; - char * p = malloc(l + 2); + char * p = malloc(char(l + 2)); smemcpy(p + 1, cstr + 1, cstr[0]); smemcpy(p + 1 + cstr[0], s.cstr + 1, s.cstr[0]); return string(l, p); @@ -201,11 +209,11 @@ string string::operator+(const char * s) const { if (cstr) { - char sl = strlen(s); + char sl = sstrlen(s); if (sl) { char l = cstr[0] + sl; - char * p = malloc(l + 2); + char * p = malloc(char(l + 2)); smemcpy(p + 1, cstr + 1, cstr[0]); smemcpy(p + 1 + cstr[0], s, sl); return string(l, p); @@ -222,7 +230,7 @@ string string::operator+(char c) const if (cstr) { char l = cstr[0] + 1; - char * p = malloc(l + 2); + char * p = malloc(char(l + 2)); smemcpy(p + 1, cstr + 1, cstr[0]); p[l] = c; return string(l, p); @@ -472,7 +480,7 @@ int string::find(const char * s, char pos) const if (cstr) { char l = cstr[0]; - char sl = strlen(s); + char sl = sstrlen(s); if (sl <= l) { l -= sl; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 91b1108..4c209e4 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -11863,7 +11863,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) for (int i = 0; i < path.Size(); i++) printf("path %d\n", path[i]->mIndex); #endif - bool hasCall = false, hasFrame = false; + bool hasCall = false, hasFrame = false, hasStore = false; for (int bi = 0; bi < body.Size(); bi++) { InterCodeBasicBlock* block = body[bi]; @@ -11877,6 +11877,17 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) hasCall = true; else if (ins->mCode == IC_PUSH_FRAME) hasFrame = true; + else if (ins->mCode == IC_STORE) + { + if (ins->mSrc[1].mTemp >= 0) + hasStore = true; + else if ((ins->mSrc[1].mMemory == IM_PARAM || ins->mSrc[1].mMemory == IM_FPARAM) && !aliasedParams[ins->mSrc[1].mVarIndex]) + ; + else + hasStore = true; + } + else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY) + hasStore = true; } } @@ -11897,7 +11908,11 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) ins->mInvariant = false; else if (ins->mCode == IC_LOAD) { - if (ins->mSrc[0].mTemp >= 0 || ins->mVolatile) + if (ins->mVolatile) + { + ins->mInvariant = false; + } + else if (ins->mSrc[0].mTemp >= 0 && (hasStore || hasCall)) { ins->mInvariant = false; } @@ -16129,7 +16144,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "test_find"); + CheckFunc = !strcmp(mIdent->mString, "string::find"); mEntryBlock = mBlocks[0]; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 8908ed9..1403b4c 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -969,6 +969,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro if (vp.mTemp != vr.mTemp) { InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY); + cins->mNumOperands = 2; cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mTemp = vr.mTemp; @@ -1276,6 +1277,8 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I else { InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY); + cins->mNumOperands = 2; + cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mTemp = vr.mTemp; cins->mSrc[0].mMemory = IM_INDIRECT; @@ -1753,6 +1756,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (vr.mTemp != vl.mTemp) { InterInstruction* ins = new InterInstruction(exp->mLocation, IC_COPY); + ins->mNumOperands = 2; + ins->mSrc[0].mType = IT_POINTER; ins->mSrc[0].mTemp = vr.mTemp; ins->mSrc[0].mMemory = IM_INDIRECT; @@ -2118,8 +2123,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* crins->mDst.mTemp = proc->AddTemporary(crins->mDst.mType); block->Append(crins); + int s = vl.mType->Stride(); + bool binary = !(s & (s - 1)); + if (binary) + { + int n = 0; + while (s > 1) + { + s >>= 1; + n++; + } + s = n; + } + InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONSTANT); - cins->mConst.mIntConst = vl.mType->Stride(); + cins->mConst.mIntConst = s; cins->mDst.mType = IT_INT16; cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); block->Append(cins); @@ -2134,7 +2152,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* sins->mDst.mTemp = proc->AddTemporary(sins->mDst.mType); block->Append(sins); - dins->mOperator = IA_DIVS; + dins->mOperator = binary ? IA_SAR : IA_DIVS; dins->mSrc[0].mType = IT_INT16; dins->mSrc[0].mTemp = cins->mDst.mTemp; dins->mSrc[1].mType = IT_INT16; @@ -2834,6 +2852,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* mErrors->Error(sex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); InterInstruction* ins = new InterInstruction(exp->mLocation, IC_COPY); + ins->mNumOperands = 2; + ins->mSrc[0].mType = IT_POINTER; ins->mSrc[0].mMemory = IM_INDIRECT; ins->mSrc[0].mTemp = vr.mTemp; @@ -2931,6 +2951,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* else { fins = new InterInstruction(exp->mLocation, IC_PUSH_FRAME); + fins->mNumOperands = 0; fins->mConst.mIntConst = atotal; block->Append(fins); } @@ -3228,6 +3249,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* fins->mConst.mIntConst = atotal; InterInstruction* xins = new InterInstruction(exp->mLocation, IC_POP_FRAME); + xins->mNumOperands = 0; xins->mConst.mIntConst = atotal; block->Append(xins); } @@ -3690,6 +3712,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, destack, inlineMapper); InterInstruction* ins = new InterInstruction(exp->mLocation, IC_UNREACHABLE); + ins->mNumOperands = 0; fblock->Append(ins); fblock->Close(nullptr, nullptr); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 95f6dcc..2ed7b73 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -34974,7 +34974,31 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass progress = true; } #endif - + else if ( + mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 1].mLive & LIVE_MEM)) + { + if (!(mIns[i + 0].mLive & LIVE_CPU_REG_X)) + { + mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X; + mIns.Insert(i + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_INX)); + mIns[i + 2].mType = ASMIT_TXA; mIns[i + 2].mMode = ASMIM_IMPLIED; + progress = true; + } + else if (!(mIns[i + 0].mLive & LIVE_CPU_REG_Y)) + { + mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y; + mIns.Insert(i + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_INY)); + mIns[i + 2].mType = ASMIT_TYA; mIns[i + 2].mMode = ASMIM_IMPLIED; + progress = true; + } + else if (!(mIns[i + 0].mLive & LIVE_CPU_REG_C)) + { + mIns.Insert(i + 1, NativeCodeInstruction(mIns[i + 1].mIns, ASMIT_CLC)); + mIns[i + 2].mType = ASMIT_ADC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 1; + progress = true; + } + } #if 0 else if ( mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && @@ -39859,6 +39883,45 @@ bool NativeCodeBasicBlock::CalculateOffset(int& total) return changed; } +void NativeCodeBasicBlock::ShortcutJump(int offset) +{ + if (mCode[offset] == 0x4c) + { + int i = 0; + while (i < mRelocations.Size() && mRelocations[i].mOffset != offset + 1) + i++; + if (i < mRelocations.Size()) + { + LinkerReference& ref(mRelocations[i]); + if (ref.mRefObject && ref.mRefObject->mData) + { + LinkerObject* lo = ref.mRefObject; + + if (lo->mData[ref.mRefOffset] == 0x4c || lo->mData[ref.mRefOffset] == 0x6c) + { + int j = 0; + while (j < lo->mReferences.Size() && lo->mReferences[j]->mOffset != ref.mRefOffset + 1) + j++; + if (j < lo->mReferences.Size()) + { + mCode[offset] = lo->mData[ref.mRefOffset]; + ref.mRefObject = lo->mReferences[j]->mRefObject; + ref.mRefOffset = lo->mReferences[j]->mRefOffset; + ref.mFlags = lo->mReferences[j]->mFlags; + } + else + { + mCode[offset] = lo->mData[ref.mRefOffset]; + mCode[offset + 1] = lo->mData[ref.mRefOffset + 1]; + mCode[offset + 2] = lo->mData[ref.mRefOffset + 2]; + mRelocations.Remove(i); + } + } + } + } + } +} + void NativeCodeBasicBlock::ShortcutTailRecursion() { if (!mVisited) @@ -39869,6 +39932,7 @@ void NativeCodeBasicBlock::ShortcutTailRecursion() this->mCode[this->mCode.Size() - 3] = 0x4c; mTrueJump->mNumEntries--; mTrueJump = nullptr; + ShortcutJump(this->mCode.Size() - 3); } else if (!mFalseJump && !mTrueJump) { @@ -39877,6 +39941,7 @@ void NativeCodeBasicBlock::ShortcutTailRecursion() { this->mCode.Remove(this->mCode.Size() - 1); this->mCode[this->mCode.Size() - 3] = 0x4c; + ShortcutJump(this->mCode.Size() - 3); } } diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 6db7ec7..5be97e3 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -269,6 +269,7 @@ public: void PrependInstruction(const NativeCodeInstruction& ins); void ShortcutTailRecursion(); + void ShortcutJump(int offset); bool ReferencesAccu(int from = 0, int to = 65536) const; bool ReferencesYReg(int from = 0, int to = 65536) const; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index cb9c3fa..623cb0a 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1337,7 +1337,7 @@ Expression* Parser::BuildMemberInitializer(Expression* vexp) mScanner->NextToken(); if (mScanner->mToken != TK_CLOSE_PARENTHESIS) { - fexp->mRight = ParseListExpression(); + fexp->mRight = ParseListExpression(false); ConsumeToken(TK_CLOSE_PARENTHESIS); } else @@ -2887,7 +2887,7 @@ void Parser::ParseVariableInit(Declaration* ndec) mScanner->NextToken(); if (mScanner->mToken != TK_CLOSE_PARENTHESIS) { - pexp = ParseListExpression(); + pexp = ParseListExpression(false); ConsumeToken(TK_CLOSE_PARENTHESIS); } else @@ -4332,7 +4332,7 @@ Expression* Parser::ParseQualify(Expression* exp) nexp->mRight = nullptr; else { - nexp->mRight = ParseListExpression(); + nexp->mRight = ParseListExpression(false); ConsumeToken(TK_CLOSE_PARENTHESIS); } @@ -4530,7 +4530,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs) mScanner->NextToken(); if (mScanner->mToken != TK_CLOSE_PARENTHESIS) { - pexp = ParseListExpression(); + pexp = ParseListExpression(false); ConsumeToken(TK_CLOSE_PARENTHESIS); } else @@ -4641,7 +4641,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs) nexp->mLeft = exp; if (mScanner->mToken != TK_CLOSE_PARENTHESIS) { - nexp->mRight = ParseListExpression(); + nexp->mRight = ParseListExpression(false); ConsumeToken(TK_CLOSE_PARENTHESIS); } else @@ -4876,7 +4876,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs) { if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS)) { - pexp = ParseListExpression(); + pexp = ParseListExpression(false); mdec = dec->mScope->Lookup(dec->mIdent); @@ -5717,16 +5717,16 @@ Expression* Parser::ParseExpression(bool lhs) return ParseAssignmentExpression(lhs); } -Expression* Parser::ParseListExpression(void) +Expression* Parser::ParseListExpression(bool lhs) { - Expression* exp = ParseExpression(true); + Expression* exp = ParseExpression(lhs); if (mScanner->mToken == TK_COMMA) { Expression* nexp = new Expression(mScanner->mLocation, EX_LIST); nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseListExpression(); + nexp->mRight = ParseListExpression(false); exp = nexp; } return exp; @@ -6183,7 +6183,7 @@ Expression* Parser::ParseStatement(void) break; default: - exp = CleanupExpression(ParseListExpression()); + exp = CleanupExpression(ParseListExpression(true)); ConsumeToken(TK_SEMICOLON); } } diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 8691e9e..ee0bcc4 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -105,7 +105,7 @@ protected: Expression* ParseAssignmentExpression(bool lhs); Expression* ParseExpression(bool lhs); Expression* ParseRExpression(void); - Expression* ParseListExpression(void); + Expression* ParseListExpression(bool lhs); Expression* ParseParenthesisExpression(void);