From 4117c9a5533098d133d3f0bf54b3f60d21e30c25 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sat, 25 Feb 2023 21:02:06 +0100 Subject: [PATCH] More functions for reu library --- autotest/testint32.c | 20 +++++++ include/c64/reu.c | 95 ++++++++++++++++++++++++++++++++ include/c64/reu.h | 18 ++++++ oscar64/Declaration.h | 1 + oscar64/GlobalAnalyzer.cpp | 1 + oscar64/InterCode.cpp | 37 +++++++++++++ oscar64/InterCodeGenerator.cpp | 5 +- oscar64/NativeCodeGenerator.cpp | 45 ++++++++++++++- oscar64/Parser.cpp | 12 ++++ oscar64/Parser.h | 1 + oscar64setup/oscar64setup.vdproj | 52 +++++++++++++++++ 11 files changed, 285 insertions(+), 2 deletions(-) diff --git a/autotest/testint32.c b/autotest/testint32.c index 6deba40..fd188d8 100644 --- a/autotest/testint32.c +++ b/autotest/testint32.c @@ -65,11 +65,22 @@ int main(void) testmuli( 1, -1, -1); testmuli(5, 5, 25); + testmuli( 127, 255, 32385); testmuli(-127, 255, -32385); testmuli( 127, -255, -32385); testmuli(-127, -255, 32385); + testmuli( 1237, 1024, 1266688l); + testmuli(-1237, 1024, -1266688l); + testmuli( 1237, -1024, -1266688l); + testmuli(-1237, -1024, 1266688l); + + testmuli( 1024, 1237, 1266688l); + testmuli( 1024,-1237, -1266688l); + testmuli( -1024, 1237, -1266688l); + testmuli( -1024,-1237, 1266688l); + testdivi( 1, 1, 1); testdivi(-1, 1, -1); testdivi( 1, -1, -1); @@ -119,5 +130,14 @@ int main(void) d -= 10000; } + long e = 0, f = 0; + for(long i=0; i<177000l; i += 1000) + { + assert( 1024 * i == e); + assert(-1024 * i == f); + e += 1024000l; + f -= 1024000l; + } + return 0; } diff --git a/include/c64/reu.c b/include/c64/reu.c index 8f7b402..1f821ba 100644 --- a/include/c64/reu.c +++ b/include/c64/reu.c @@ -1,2 +1,97 @@ #include "reu.h" +int reu_count_pages(void) +{ + volatile char c, d; + + c = 0; + reu_store(0, &c, 1); + reu_load(0, &d, 1); + + if (d == 0) + { + c = 0x47; + reu_store(0, &c, 1); + reu_load(0, &d, 1); + + if (d == 0x47) + { + for(int i=1; i<256; i++) + { + long l = (long)i << 16; + c = 0x47; + reu_store(l, &c, 1); + c = 0x00; + reu_store(0, &c, 1); + + reu_load(l, &d, 1); + if (d != 0x47) + return i; + } + + return 256; + } + } + + return 0; +} + +inline void reu_store(unsigned long raddr, const volatile char * sp, unsigned length) +{ + reu.laddr = (word)sp; + reu.raddr = raddr; + reu.rbank = raddr >> 16; + reu.length = length; + reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR; + reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_STORE; + +} + +inline void reu_load(unsigned long raddr, volatile char * dp, unsigned length) +{ + reu.laddr = (word)dp; + reu.raddr = raddr; + reu.rbank = raddr >> 16; + reu.length = length; + reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR; + reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_LOAD; +} + +inline void reu_fill(unsigned long raddr, char c, unsigned length) +{ + reu.laddr = (word)&c; + reu.raddr = raddr; + reu.rbank = raddr >> 16; + reu.length = length; + reu.ctrl = REU_CTRL_FIXL | REU_CTRL_INCR; + reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_STORE; +} + +inline void reu_load2d(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride) +{ + reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR; + reu.laddr = (word)dp; + for(char i=0; i> 16; + reu.cmd = REU_CMD_EXEC | REU_CMD_FF00 | REU_CMD_LOAD; + raddr += stride; + } +} + +inline void reu_load2dpage(unsigned long raddr, volatile char * dp, char height, unsigned width, unsigned stride) +{ + reu.ctrl = REU_CTRL_INCL | REU_CTRL_INCR; + reu.laddr = (word)dp; + reu.rbank = raddr >> 16; + for(char i=0; imLeft, procDec); return exp->mDecValue->mBase; case EX_CALL: + case EX_INLINE: ldec = Analyze(exp->mLeft, procDec); if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue) { diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index e17852c..4444095 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -4383,6 +4383,18 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA } +static bool ispow2(int64 v) +{ + if (v > 0) + { + while (!(v & 1)) + v >>= 1; + return v == 1; + } + + return 0; +} + void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle) { switch (ins->mCode) @@ -4791,6 +4803,20 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI ins->mSrc[0].mTemp = -1; ins->mSrc[0].mIntConst = 3; } + else if (ins->mSrc[0].mType == IT_INT32 && ispow2(ins->mSrc[1].mIntConst)) + { + __int64 s = ins->mSrc[1].mIntConst; + ins->mOperator = IA_SHL; + ins->mSrc[1].mTemp = ins->mSrc[0].mTemp; + ins->mSrc[1].mType = ins->mSrc[0].mType; + ins->mSrc[0].mTemp = -1; + ins->mSrc[0].mIntConst = 0; + while (s > 1) + { + ins->mSrc[0].mIntConst++; + s >>= 1; + } + } } #endif @@ -4834,6 +4860,17 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI ins->mOperator = IA_SHL; ins->mSrc[0].mIntConst = 3; } + else if (ins->mSrc[1].mType == IT_INT32 && ispow2(ins->mSrc[0].mIntConst)) + { + __int64 s = ins->mSrc[0].mIntConst; + ins->mOperator = IA_SHL; + ins->mSrc[0].mIntConst = 0; + while (s > 1) + { + ins->mSrc[0].mIntConst++; + s >>= 1; + } + } } else if (ins->mOperator == IA_MODU && (ins->mSrc[0].mIntConst & (ins->mSrc[0].mIntConst - 1)) == 0) { diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index c250644..67b1c07 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2041,6 +2041,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } case EX_CALL: + case EX_INLINE: { if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INTRINSIC)) { @@ -2217,7 +2218,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } } - if (inlineConstexpr) + if (exp->mType == EX_INLINE) + doInline = true; + else if (inlineConstexpr) doInline = true; else if (exp->mLeft->mDecValue->mFlags & DTF_INLINE) { diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 37ab119..e7c4d44 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -14726,6 +14726,49 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc) iblock->mIns.Push(mIns[i + 6]); + mIns.SetSize(i + 4); + iblock->mIns[0].mType = ASMIT_INC; + + iblock->mTrueJump = fblock; + iblock->mBranch = ASMIT_JMP; + + mTrueJump = fblock; + mFalseJump = iblock; + mBranch = ASMIT_BNE; + break; + } + + if (mIns[i + 0].mType == ASMIT_TYA && + mIns[i + 1].mType == ASMIT_CLC && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && + mIns[i + 3].mType == ASMIT_TAY && + mIns[i + 4].mType == ASMIT_LDA && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 && + mIns[i + 6].mType == ASMIT_STA && mIns[i + 4].SameEffectiveAddress(mIns[i + 6]) && + HasAsmInstructionMode(ASMIT_INC, mIns[i + 6].mMode) && + !(mIns[i + 6].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z))) + { + changed = true; + + NativeCodeBasicBlock* iblock = proc->AllocateBlock(); + NativeCodeBasicBlock* fblock = proc->AllocateBlock(); + + fblock->mTrueJump = mTrueJump; + fblock->mFalseJump = mFalseJump; + fblock->mBranch = mBranch; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_INY; mIns[i + 3].mLive |= LIVE_CPU_REG_Z; + + fblock->mIns.Push(mIns[i + 4]); + + for (int j = i + 7; j < mIns.Size(); j++) + fblock->mIns.Push(mIns[j]); + iblock->mIns.Push(mIns[i + 6]); + + mIns.SetSize(i + 4); iblock->mIns[0].mType = ASMIT_INC; @@ -35581,7 +35624,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "digger_decide"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "rscreen_copy"); #if 1 int step = 0; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index f8c9ff3..b7215cf 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -15,6 +15,7 @@ Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUn mUnrollLoop = 0; mUnrollLoopPage = false; + mInlineCall = false; for (int i = 0; i < 256; i++) mCharMap[i] = i; @@ -1666,6 +1667,10 @@ Expression* Parser::ParsePostfixExpression(void) mScanner->NextToken(); Expression* nexp = new Expression(mScanner->mLocation, EX_CALL); + if (mInlineCall) + nexp->mType = EX_INLINE; + mInlineCall = false; + nexp->mLeft = exp; nexp->mDecType = exp->mDecType->mBase; if (mScanner->mToken != TK_CLOSE_PARENTHESIS) @@ -3935,6 +3940,13 @@ void Parser::ParsePragma(void) ConsumeToken(TK_CLOSE_PARENTHESIS); } + else if (!strcmp(mScanner->mTokenIdent->mString, "callinline")) + { + mScanner->NextToken(); + ConsumeToken(TK_OPEN_PARENTHESIS); + ConsumeToken(TK_CLOSE_PARENTHESIS); + mInlineCall = true; + } else { mScanner->NextToken(); diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 397fc6f..8449e75 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -26,6 +26,7 @@ protected: char mCharMap[256]; int mUnrollLoop; bool mUnrollLoopPage; + bool mInlineCall; uint8* ParseStringLiteral(int msize); diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 7818e98..a5d77db 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -124,6 +124,12 @@ } "Entry" { + "MsmKey" = "8:_1EB5CE4736F1417ABD479DFD92E19FD2" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_1ED10FB93DDA4801BF72003E21B2CE55" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -358,6 +364,12 @@ } "Entry" { + "MsmKey" = "8:_64C12019C1114C3282B32CD6B866C20A" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_65286F9E8B2F496B95A50DA63A1F0D5B" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -1427,6 +1439,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1EB5CE4736F1417ABD479DFD92E19FD2" + { + "SourcePath" = "8:..\\include\\c64\\reu.c" + "TargetName" = "8:reu.c" + "Tag" = "8:" + "Folder" = "8:_247D4CAD3CB843B3A8A4DC2D90F47C28" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1ED10FB93DDA4801BF72003E21B2CE55" { "SourcePath" = "8:..\\samples\\games\\missile.c" @@ -2207,6 +2239,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_64C12019C1114C3282B32CD6B866C20A" + { + "SourcePath" = "8:..\\include\\c64\\reu.h" + "TargetName" = "8:reu.h" + "Tag" = "8:" + "Folder" = "8:_247D4CAD3CB843B3A8A4DC2D90F47C28" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_65286F9E8B2F496B95A50DA63A1F0D5B" { "SourcePath" = "8:..\\samples\\resources\\maze3dchars.bin"