From aa601a5727636aa1b51cf43e0e8f0768a8a1da26 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 24 Mar 2024 11:22:13 +0100 Subject: [PATCH] Change memset and memclr to intrinsic functions --- include/crt.c | 57 ++++ include/crt.h | 4 +- include/string.h | 4 + oscar64/ByteCodeGenerator.cpp | 51 +++- oscar64/ByteCodeGenerator.h | 5 +- oscar64/Disassembler.cpp | 8 + oscar64/Errors.h | 1 + oscar64/InterCode.cpp | 158 +++++++--- oscar64/InterCode.h | 1 + oscar64/InterCodeGenerator.cpp | 78 +++++ oscar64/NativeCodeGenerator.cpp | 506 ++++++++++++++++++++++++++------ oscar64/NativeCodeGenerator.h | 5 +- 12 files changed, 744 insertions(+), 134 deletions(-) diff --git a/include/crt.c b/include/crt.c index 48a951d..29deb16 100644 --- a/include/crt.c +++ b/include/crt.c @@ -2666,6 +2666,23 @@ inp_call_addr: #pragma bytecode(BC_CALL_ADDR, inp_call.inp_call_addr) #pragma bytecode(BC_CALL_ABS, inp_call) +__asm inp_fill +{ + lda (ip), y + sty tmpy + tay + + lda accu +L1: dey + sta (addr), y + bne L1 + + ldy tmpy + jmp startup.yexec +} + +#pragma bytecode(BC_FILL, inp_fill) + __asm inp_copy { lda (ip), y @@ -2700,6 +2717,46 @@ L1: iny #pragma bytecode(BC_STRCPY, inp_strcpy) +__asm inp_filll +{ + lda (ip), y + sta tmp + iny + lda (ip), y + tax + sty tmpy + + beq W1 + ldy #0 + + lda accu +Loop1: + sta (addr), y + iny + bne Loop1 + inc accu + 1 + inc addr + 1 + dex + bne Loop1 +W1: + lda accu + ldy tmp + beq W2 + dey + beq W3 +Loop2: + sta (addr), y + dey + bne Loop2 +W3: + sta (addr), y +W2: + ldy tmpy + jmp startup.yexec +} + +#pragma bytecode(BC_FILL_LONG, inp_filll) + __asm inp_copyl { lda (ip), y diff --git a/include/crt.h b/include/crt.h index 2cc7fc0..5d5630a 100644 --- a/include/crt.h +++ b/include/crt.h @@ -144,8 +144,8 @@ enum ByteCode BC_LOOP_U8, BC_MALLOC, BC_FREE, - BC_UNUSED_4, - BC_UNUSED_5, + BC_FILL, + BC_FILL_LONG, BC_UNUSED_6, BC_JSR, diff --git a/include/string.h b/include/string.h index c79fc18..29ac884 100644 --- a/include/string.h +++ b/include/string.h @@ -25,6 +25,10 @@ void * memmove(void * dst, const void * src, int size); #pragma intrinsic(memcpy) +#pragma intrinsic(memset) + +#pragma intrinsic(memclr) + #pragma compile("string.c") #endif diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index c3c9b03..b0093d7 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -144,8 +144,8 @@ static const char* ByteCodeNames[] = { "LOOP_U8", "MALLOC", "FREE", - nullptr, - nullptr, + "FILL", + "FILL_LONG", nullptr, "JSR", //114 @@ -680,6 +680,8 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used) used = 0xffffffff; break; + case BC_FILL: + case BC_FILL_LONG: case BC_COPY: case BC_COPY_LONG: case BC_STRCPY: @@ -780,7 +782,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const return true; if (mCode == BC_LEA_ACCU_INDEX) return true; - if (mCode == BC_COPY || mCode == BC_STRCPY) + if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL) return true; if (mCode == BC_BINOP_ADDA_16) return true; @@ -793,7 +795,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const if (mCode >= BC_LOAD_ADDR_8 && mCode <= BC_STORE_ADDR_32) return true; - if (mCode == BC_COPY || mCode == BC_STRCPY) + if (mCode == BC_COPY || mCode == BC_STRCPY || mCode == BC_FILL) return true; if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS) @@ -1212,6 +1214,20 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl block->PutByte(mValue); break; + case BC_FILL: + case BC_FILL_LONG: + if (mValue < 256) + { + block->PutCode(generator, BC_FILL); + block->PutByte(uint8(mValue)); + } + else + { + block->PutCode(generator, BC_FILL_LONG); + block->PutWord(uint16(mValue)); + } + break; + case BC_COPY: case BC_COPY_LONG: if (mValue < 256) @@ -1567,6 +1583,30 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr } +void ByteCodeBasicBlock::FillValue(InterCodeProcedure* proc, const InterInstruction* ins) +{ + LoadOperandAddress(proc, ins->mSrc[1], BC_REG_ADDR); + + if (ins->mSrc[0].mTemp < 0) + { + ByteCodeInstruction cins(BC_CONST_8); + cins.mRegister = BC_REG_ACCU; + cins.mValue = int(ins->mSrc[0].mIntConst); + mIns.Push(cins); + } + else + { + ByteCodeInstruction lins(BC_LOAD_REG_8); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + lins.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(lins); + } + + ByteCodeInstruction cins(BC_FILL); + cins.mValue = ins->mConst.mOperandSize; + mIns.Push(cins); +} + void ByteCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction * ins) { LoadOperandAddress(proc, ins->mSrc[0], BC_REG_ACCU); @@ -4320,6 +4360,9 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p else LoadDirectValue(iproc, ins); break; + case IC_FILL: + FillValue(iproc, ins); + break; case IC_COPY: CopyValue(iproc, ins); break; diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index fac6acb..955c675 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -145,8 +145,8 @@ enum ByteCode BC_LOOP_U8, BC_MALLOC, BC_FREE, - BC_UNUSED_4, - BC_UNUSED_5, + BC_FILL, + BC_FILL_LONG, BC_UNUSED_6, BC_JSR, @@ -281,6 +281,7 @@ public: void IntConstToAddr(int64 val); void FloatConstToAccu(double val); void FloatConstToWork(double val); + void FillValue(InterCodeProcedure* proc, const InterInstruction* ins); void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins); void StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins); void CallMalloc(InterCodeProcedure* proc, const InterInstruction* ins); diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index 04db667..b5a8f6b 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -429,6 +429,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank i += 1; break; + case BC_FILL: + fprintf(file, "FILL\t#%d", memory[start + i + 0]); + i++; + break; case BC_COPY: fprintf(file, "COPY\t#%d", memory[start + i + 0]); i++; @@ -441,6 +445,10 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank fprintf(file, "COPYL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); i += 2; break; + case BC_FILL_LONG: + fprintf(file, "FILLL\t#%d", uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); + i += 2; + break; case BC_OP_NEGATE_16: fprintf(file, "NEG\tACCU"); diff --git a/oscar64/Errors.h b/oscar64/Errors.h index 747bffb..dca73cc 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -39,6 +39,7 @@ enum ErrorID EWARN_DESTRUCTOR_MISMATCH, EWARN_NUMERIC_0_USED_AS_NULLPTR, EWARN_FLOAT_TO_INT, + EWARN_UNDEFINED_POINTER_ARITHMETIC, EERR_GENERIC = 3000, EERR_FILE_NOT_FOUND, diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index f5b78c4..45328ec 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -418,7 +418,7 @@ static bool MemRange(const InterInstruction* ins, const GrowingInstructionPtrArr } else if (ins->mSrc[1].mMemory == IM_INDIRECT) { - if (ins->mCode == IC_COPY) + if (ins->mCode == IC_COPY ||ins->mCode == IC_FILL) size = ins->mConst.mOperandSize; else size = ins->mSrc[1].mOperandSize; @@ -593,6 +593,8 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op, InterType type, c return CollidingMem(op, type, ins->mSrc[0], ins->mDst.mType); else if (ins->mCode == IC_STORE) return CollidingMem(op, type, ins->mSrc[1], ins->mSrc[0].mType); + else if (ins->mCode == IC_FILL) + return CollidingMem(op, type, ins->mSrc[1], IT_NONE); else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY) return CollidingMem(op, type, ins->mSrc[0], IT_NONE) || CollidingMem(op, type, ins->mSrc[1], IT_NONE); else @@ -605,6 +607,8 @@ bool InterCodeBasicBlock::CollidingMem(const InterInstruction* ins1, const Inter return CollidingMem(ins1->mSrc[0], ins1->mDst.mType, ins2); else if (ins1->mCode == IC_STORE) return CollidingMem(ins1->mSrc[1], ins1->mSrc[0].mType, ins2); + else if (ins1->mCode == IC_FILL) + return CollidingMem(ins1->mSrc[1], IT_NONE, ins2); else if (ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY) return CollidingMem(ins1->mSrc[0], IT_NONE, ins2) || CollidingMem(ins1->mSrc[1], IT_NONE, ins2); else @@ -617,6 +621,8 @@ bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const Inte return false; else if (sins->mCode == IC_STORE) return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins); + else if (sins->mCode == IC_FILL) + return CollidingMem(sins->mSrc[1], IT_NONE, lins); else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY) return CollidingMem(sins->mSrc[1], IT_NONE, lins); else if (sins->mCode == IC_CALL || sins->mCode == IC_CALL_NATIVE) @@ -631,6 +637,8 @@ bool InterCodeBasicBlock::DestroyingMem(const InterInstruction* lins, const Inte opmask = 1; else if (lins->mCode == IC_STORE) opmask = 2; + else if (lins->mCode == IC_FILL) + opmask = 2; else if (lins->mCode == IC_COPY) opmask = 3; @@ -876,7 +884,7 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons else return false; } - else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) + else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL) return false; } if (ins0->mCode == IC_CALL || ins0->mCode == IC_CALL_NATIVE || ins0->mCode == IC_ASSEMBLER) @@ -885,7 +893,7 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons ins1->mCode == IC_PUSH_FRAME || ins1->mCode == IC_POP_FRAME || ins1->mCode == IC_MALLOC || ins1->mCode == IC_FREE) return false; - if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY) + if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY || ins1->mCode == IC_FILL) return false; } @@ -897,12 +905,12 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons if (ins0->mCode == IC_FREE) { - if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY) + if (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY || ins1->mCode == IC_FILL) return false; } if (ins1->mCode == IC_FREE) { - if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) + if (ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL) return false; } @@ -943,8 +951,8 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons return false; } - if ((ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) && - (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY)) + if ((ins0->mCode == IC_LOAD || ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL) && + (ins1->mCode == IC_LOAD || ins1->mCode == IC_STORE || ins1->mCode == IC_COPY || ins1->mCode == IC_STRCPY || ins1->mCode == IC_FILL)) { if (ins0->mVolatile || ins1->mVolatile) return false; @@ -959,7 +967,7 @@ bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, cons if (DestroyingMem(ins1, ins0)) return false; } - else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY) + else if (ins0->mCode == IC_STORE || ins0->mCode == IC_COPY || ins0->mCode == IC_STRCPY || ins0->mCode == IC_FILL) { if (CollidingMem(ins0, ins1)) return false; @@ -1665,12 +1673,12 @@ static bool HasSideEffect(InterCode code) static bool IsObservable(InterCode code) { - return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_MALLOC || code == IC_FREE; + return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_FILL || code == IC_MALLOC || code == IC_FREE; } static bool IsMoveable(InterCode code) { - if (HasSideEffect(code) || code == IC_COPY || code == IC_STRCPY || code == IC_STORE || code == IC_BRANCH || code == IC_POP_FRAME || code == IC_PUSH_FRAME || code == IC_MALLOC || code == IC_FREE) + if (HasSideEffect(code) || code == IC_COPY || code == IC_STRCPY || code == IC_STORE || code == IC_FILL || code == IC_BRANCH || code == IC_POP_FRAME || code == IC_PUSH_FRAME || code == IC_MALLOC || code == IC_FREE) return false; if (code == IC_RETURN || code == IC_RETURN_STRUCT || code == IC_RETURN_VALUE || code == IC_DISPATCH) return false; @@ -1682,7 +1690,7 @@ static bool IsMoveable(InterCode code) static bool CanBypassLoad(const InterInstruction* lins, const InterInstruction* bins) { // Check ambiguity - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_FILL) return false; // Side effects @@ -1737,7 +1745,7 @@ static bool CanBypassLoad(const InterInstruction* lins, const InterInstruction* static bool CanBypassStoreDown(const InterInstruction* sins, const InterInstruction* bins) { // Check ambiguity - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_FILL) return false; // Side effects @@ -1830,7 +1838,7 @@ static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins bins->mCode == IC_RETURN || bins->mCode == IC_RETURN_STRUCT || bins->mCode == IC_RETURN_VALUE || bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_POP_FRAME) return false; - if (bins->mCode == IC_LOAD || bins->mCode == IC_STORE || bins->mCode == IC_COPY) + if (bins->mCode == IC_LOAD || bins->mCode == IC_STORE || bins->mCode == IC_COPY || bins->mCode == IC_FILL) return false; } @@ -1878,9 +1886,9 @@ static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bi if (bins->mDst.mTemp == lins->mSrc[i].mTemp) return false; } - if (lins->mCode == IC_STORE || lins->mCode == IC_COPY) + if (lins->mCode == IC_STORE || lins->mCode == IC_COPY || lins->mCode == IC_FILL) { - if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD || bins->mCode == IC_COPY || bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE) + if (bins->mCode == IC_STORE || bins->mCode == IC_LOAD || bins->mCode == IC_COPY || bins->mCode == IC_FILL || bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE) return false; } @@ -1896,7 +1904,7 @@ static bool CanBypassUp(const InterInstruction* lins, const InterInstruction* bi static bool CanBypassLoadUp(const InterInstruction* lins, const InterInstruction* bins) { // Check ambiguity - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY) + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_FILL) return false; // Side effects @@ -1965,7 +1973,7 @@ static bool IsChained(const InterInstruction* ins, const InterInstruction* nins) static bool CanBypassStore(const InterInstruction* sins, const InterInstruction* bins) { - if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME) + if (bins->mCode == IC_COPY || bins->mCode == IC_STRCPY || bins->mCode == IC_PUSH_FRAME || bins->mCode == IC_FILL) return false; // True data dependency @@ -2424,6 +2432,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr if (!ins->mVolatile) InsertValue(ins); break; + case IC_FILL: case IC_COPY: case IC_STRCPY: i = 0; @@ -3793,7 +3802,7 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV } } } - else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH) + else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH || mCode == IC_FILL) { requiredVars.OrNot(providedVars); } @@ -3841,7 +3850,7 @@ void InterInstruction::FilterStaticVarsByteUsage(const GrowingVariableArray& sta } } } - else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH) + else if (mCode == IC_COPY || mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE || mCode == IC_STRCPY || mCode == IC_DISPATCH || mCode == IC_FILL) { requiredVars.OrNot(providedVars); } @@ -3912,6 +3921,23 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu providedParams += mSrc[1].mVarIndex; } } + else if (mCode == IC_FILL) + { + if (mSrc[1].mMemory == IM_LOCAL) + { + assert(mSrc[1].mTemp < 0); + if (!providedVars[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != localVars[mSrc[1].mVarIndex]->mSize)) + requiredVars += mSrc[1].mVarIndex; + providedVars += mSrc[1].mVarIndex; + } + else if (mSrc[1].mMemory == paramMemory) + { + assert(mSrc[1].mTemp < 0); + if (!providedParams[mSrc[1].mVarIndex] && (mSrc[1].mIntConst != 0 || mSrc[1].mOperandSize != params[mSrc[1].mVarIndex]->mSize)) + requiredParams += mSrc[1].mVarIndex; + providedParams += mSrc[1].mVarIndex; + } + } else if (mCode == IC_COPY || mCode == IC_STRCPY) { if (mSrc[0].mMemory == IM_LOCAL) @@ -4478,7 +4504,7 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(InterCodeBasicBlock* } } } - else if (mCode == IC_COPY || mCode == IC_STRCPY) + else if (mCode == IC_COPY || mCode == IC_STRCPY || mCode == IC_FILL) { requiredVars.Fill(); storeIns.SetSize(0); @@ -4534,7 +4560,7 @@ bool InterInstruction::RemoveUnusedStaticStoreByteInstructions(InterCodeBasicBlo } } } - else if (mCode == IC_COPY || mCode == IC_STRCPY) + else if (mCode == IC_COPY || mCode == IC_STRCPY || mCode == IC_FILL) { requiredVars.Fill(); } @@ -4771,6 +4797,12 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum else if ((mSrc[0].mMemory == IM_PARAM || mSrc[0].mMemory == IM_FPARAM) && mSrc[0].mTemp < 0) complexParams += mSrc[0].mVarIndex; break; + case IC_FILL: + if (mSrc[1].mMemory == IM_LOCAL && mSrc[1].mTemp < 0) + complexLocals += mSrc[1].mVarIndex; + else if ((mSrc[1].mMemory == IM_PARAM || mSrc[1].mMemory == IM_FPARAM) && mSrc[1].mTemp < 0) + complexParams += mSrc[1].mVarIndex; + break; case IC_CONSTANT: if (mDst.mType == IT_POINTER && mConst.mMemory == IM_LOCAL) complexLocals += mConst.mVarIndex; @@ -5220,6 +5252,13 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc) else fprintf(file, "COPY%d:%c%c", mSrc[0].mOperandSize, memchars[mSrc[0].mMemory], memchars[mSrc[1].mMemory]); break; + case IC_FILL: + assert(mNumOperands == 2); + if (mSrc[1].mStride != 1) + fprintf(file, "FILL%c%d:%d", memchars[mSrc[1].mMemory], mSrc[1].mOperandSize, mSrc[1].mStride); + else + fprintf(file, "FILL%c%d", memchars[mSrc[1].mMemory], mSrc[1].mOperandSize); + break; case IC_MALLOC: assert(mNumOperands == 1); @@ -5948,6 +5987,16 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI OptimizeAddress(ins, tvalue, 1); break; + case IC_FILL: + if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT) + { + ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst; + ins->mSrc[0].mTemp = -1; + } + + OptimizeAddress(ins, tvalue, 1); + break; + case IC_COPY: OptimizeAddress(ins, tvalue, 0); OptimizeAddress(ins, tvalue, 1); @@ -6819,6 +6868,19 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray ltemps.SetSize(j); break; + case IC_FILL: + j = 0; + for (int k = 0; k < ltemps.Size(); k++) + { + if (!CollidingMem(ltemps[k], ins)) + { + ltemps[j++] = ltemps[k]; + } + } + ltemps.SetSize(j); + break; + + case IC_COPY: for (int k = 0; k < ltemps.Size(); k++) { @@ -8285,6 +8347,11 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray mMemoryValueSize[ins->mSrc[0].mTemp] = int64max(mMemoryValueSize[ins->mSrc[0].mTemp], ins->mSrc[0].mIntConst + InterTypeSize[ins->mDst.mType]); else if (ins->mCode == IC_STORE && ins->mSrc[1].mMemory == IM_INDIRECT && ins->mSrc[1].mTemp >= 0) mMemoryValueSize[ins->mSrc[1].mTemp] = int64max(mMemoryValueSize[ins->mSrc[1].mTemp], ins->mSrc[1].mIntConst + InterTypeSize[ins->mSrc[0].mType]); + else if (ins->mCode == IC_FILL) + { + if (ins->mSrc[1].mMemory == IM_INDIRECT && ins->mSrc[1].mTemp >= 0) + mMemoryValueSize[ins->mSrc[1].mTemp] = ins->mConst.mOperandSize; + } else if (ins->mCode == IC_COPY) { if (ins->mSrc[0].mMemory == IM_INDIRECT && ins->mSrc[0].mTemp >= 0) @@ -8901,7 +8968,7 @@ bool InterCodeBasicBlock::PropagateConstOperationsUp(void) { const InterInstruction* ins = mInstructions[i]; - if (!HasSideEffect(ins->mCode) && ins->mCode != IC_CONSTANT && ins->mCode != IC_STORE && ins->mCode != IC_COPY) + if (!HasSideEffect(ins->mCode) && ins->mCode != IC_CONSTANT && ins->mCode != IC_STORE && ins->mCode != IC_COPY && ins->mCode != IC_FILL) { bool isProvided = false; if (ins->mDst.mTemp >= 0) @@ -9432,7 +9499,7 @@ bool InterCodeBasicBlock::RemoveUnusedLocalStoreInstructions(void) break; else if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) break; - else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY) + else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY || ins->mCode == IC_FILL) break; } } @@ -10164,6 +10231,13 @@ bool InterCodeBasicBlock::ForwardShortLoadStoreOffsets(void) mins->mSrc[1].mIntConst += lins->mSrc[0].mIntConst; changed = true; } + else if (mins->mCode == IC_FILL && mins->mSrc[1].mTemp == lins2->mDst.mTemp && mins->mSrc[1].mFinal) + { + lins2->mSrc[1].mTemp = lins->mSrc[1].mTemp; + lins->mSrc[1].mFinal = false; + mins->mSrc[1].mIntConst += lins->mSrc[0].mIntConst; + changed = true; + } } } @@ -11569,7 +11643,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& nins = ins; #endif } - else if (ins->mCode == IC_STRCPY) + else if (ins->mCode == IC_STRCPY || ins->mCode == IC_FILL) flushMem = true; else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_CONVERSION_OPERATOR) { @@ -11628,7 +11702,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& if (lins->mCode == IC_LOAD) opmask = 1; - else if (lins->mCode == IC_STORE) + else if (lins->mCode == IC_STORE || lins->mCode == IC_FILL) opmask = 2; else if (lins->mCode == IC_COPY) opmask = 3; @@ -11678,7 +11752,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& while (j < mLoadStoreInstructions.Size()) { - if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE || mLoadStoreInstructions[j]->mCode == IC_COPY)) + if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE || mLoadStoreInstructions[j]->mCode == IC_COPY || mLoadStoreInstructions[j]->mCode == IC_FILL)) ; else if (t < 0) mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; @@ -11923,6 +11997,7 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing case IC_STORE: case IC_LEA: + case IC_FILL: if (mInstructions[i]->mSrc[1].mTemp < 0 && mInstructions[i]->mSrc[1].mMemory == IM_LOCAL) { localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true; @@ -12075,7 +12150,7 @@ bool InterCodeBasicBlock::CanMoveInstructionDown(int si, int ti) const InterInstruction* ins = mInstructions[si]; #if 1 - if (ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || + if (ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || ins->mCode == IC_FILL || ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE || ins->mCode == IC_DISPATCH) return false; @@ -12137,7 +12212,7 @@ bool InterCodeBasicBlock::CanMoveInstructionBeforeBlock(int ii, const InterInstr { #if 1 - if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE || ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || + if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE || ins->mCode == IC_COPY || ins->mCode == IC_PUSH_FRAME || ins->mCode == IC_POP_FRAME || ins->mCode == IC_FILL || ins->mCode == IC_RETURN || ins->mCode == IC_RETURN_STRUCT || ins->mCode == IC_RETURN_VALUE || ins->mCode == IC_DISPATCH) return false; @@ -12946,7 +13021,7 @@ void InterCodeBasicBlock::RemoveNonRelevantStatics(void) for (i = 0; i < mInstructions.Size(); i++) { InterInstruction* ins(mInstructions[i]); - if (ins->mCode == IC_STORE || ins->mCode == IC_COPY) + if (ins->mCode == IC_STORE || ins->mCode == IC_COPY || ins->mCode == IC_FILL) { if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && !ins->mVolatile) { @@ -13294,7 +13369,7 @@ void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVa if (mInstructions[i]->mCode == IC_LOAD) ApplyStaticStack(mInstructions[i]->mSrc[0],localVars); - else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA) + else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA || mInstructions[i]->mCode == IC_FILL) ApplyStaticStack(mInstructions[i]->mSrc[1], localVars); else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER) ApplyStaticStack(mInstructions[i]->mConst, localVars); @@ -13336,7 +13411,7 @@ void InterCodeBasicBlock::PromoteStaticStackParams(LinkerObject* paramlobj) { if (mInstructions[i]->mCode == IC_LOAD) PromoteStaticStackParam(mInstructions[i]->mSrc[0], paramlobj); - else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA) + else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA || mInstructions[i]->mCode == IC_FILL) PromoteStaticStackParam(mInstructions[i]->mSrc[1], paramlobj); else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER) PromoteStaticStackParam(mInstructions[i]->mConst, paramlobj); @@ -14663,7 +14738,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) else hasStore = true; } - else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY) + else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY || ins->mCode == IC_FILL) hasStore = true; } } @@ -14726,7 +14801,7 @@ void InterCodeBasicBlock::InnerLoopOptimization(const NumberSet& aliasedParams) ins->mInvariant = false; } } - else if (sins->mCode == IC_COPY) + else if (sins->mCode == IC_COPY || sins->mCode == IC_FILL) { ins->mInvariant = false; } @@ -16445,7 +16520,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa ins->mInvariant = false; } } - else if (sins->mCode == IC_COPY) + else if (sins->mCode == IC_COPY || sins->mCode == IC_FILL) { ins->mInvariant = false; } @@ -18945,6 +19020,20 @@ void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals, else if (ins->mSrc[1].mTemp >= 0 && (ins->mSrc[1].mMemoryBase == IM_NONE || ins->mSrc[1].mMemoryBase == IM_INDIRECT)) storesIndirect = true; break; + case IC_FILL: + if (ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mMemory == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0) + { + referencedGlobals += ins->mSrc[1].mVarIndex; + modifiedGlobals += ins->mSrc[1].mVarIndex; + } + else if (ins->mSrc[1].mMemoryBase == IM_GLOBAL && ins->mSrc[1].mVarIndex >= 0) + { + referencedGlobals += ins->mSrc[1].mVarIndex; + modifiedGlobals += ins->mSrc[1].mVarIndex; + } + else if (ins->mSrc[1].mTemp >= 0 && (ins->mSrc[1].mMemoryBase == IM_NONE || ins->mSrc[1].mMemoryBase == IM_INDIRECT)) + storesIndirect = true; + break; case IC_COPY: case IC_STRCPY: if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[0].mVarIndex >= 0) @@ -19148,6 +19237,7 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro case IC_STORE: case IC_LOAD: case IC_COPY: + case IC_FILL: case IC_STRCPY: case IC_CALL_NATIVE: case IC_ASSEMBLER: diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 8adc51f..bde17b3 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -24,6 +24,7 @@ enum InterCode IC_LEA, IC_COPY, // Copy from src[0] to src[1] IC_STRCPY, + IC_FILL, // Fill src[1] with src[0] IC_MALLOC, IC_FREE, IC_TYPECAST, diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 1919b7e..a75ce0f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -3471,6 +3471,84 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } } } + else if (!strcmp(iname->mString, "memset")) + { + if (exp->mRight->mType == EX_LIST) + { + Expression* tex = exp->mRight->mLeft, * sex = exp->mRight->mRight->mLeft, * nex = exp->mRight->mRight->mRight; + if (nex && nex->mType == EX_CONSTANT && nex->mDecValue->mType == DT_CONST_INTEGER && nex->mDecValue->mInteger <= 1024) + { + vl = TranslateExpression(procType, proc, block, tex, destack, breakBlock, continueBlock, inlineMapper); + if (vl.mType->mType == DT_TYPE_ARRAY) + vl = Dereference(proc, exp, block, inlineMapper, vl, 1); + else + vl = Dereference(proc, exp, block, inlineMapper, vl); + + vr = TranslateExpression(procType, proc, block, sex, destack, breakBlock, continueBlock, inlineMapper); + vr = Dereference(proc, exp, block, inlineMapper, vr); + + if (!TheVoidPointerTypeDeclaration->CanAssign(vl.mType)) + mErrors->Error(tex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); + if (!TheConstCharTypeDeclaration->CanAssign(vr.mType)) + mErrors->Error(sex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); + + InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_FILL); + ins->mNumOperands = 2; + + ins->mSrc[0].mType = IT_INT8; + ins->mSrc[0].mTemp = vr.mTemp; + ins->mSrc[1].mType = IT_POINTER; + ins->mSrc[1].mMemory = IM_INDIRECT; + ins->mSrc[1].mTemp = vl.mTemp; + ins->mSrc[0].mOperandSize = 1; + ins->mSrc[1].mOperandSize = int(nex->mDecValue->mInteger); + ins->mConst.mOperandSize = int(nex->mDecValue->mInteger); + block->Append(ins); + + return vl; + } + } + } + else if (!strcmp(iname->mString, "memclr")) + { + if (exp->mRight->mType == EX_LIST) + { + Expression* tex = exp->mRight->mLeft, * nex = exp->mRight->mRight; + if (nex && nex->mType == EX_CONSTANT && nex->mDecValue->mType == DT_CONST_INTEGER && nex->mDecValue->mInteger <= 1024) + { + vl = TranslateExpression(procType, proc, block, tex, destack, breakBlock, continueBlock, inlineMapper); + if (vl.mType->mType == DT_TYPE_ARRAY) + vl = Dereference(proc, exp, block, inlineMapper, vl, 1); + else + vl = Dereference(proc, exp, block, inlineMapper, vl); + + if (!TheVoidPointerTypeDeclaration->CanAssign(vl.mType)) + mErrors->Error(tex->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); + + InterInstruction * zins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONSTANT); + zins->mDst.mType = IT_INT8; + zins->mDst.mTemp = proc->AddTemporary(zins->mDst.mType); + zins->mConst.mType = IT_INT8; + zins->mConst.mIntConst = 0; + block->Append(zins); + + InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_FILL); + ins->mNumOperands = 2; + + ins->mSrc[0].mType = IT_INT8; + ins->mSrc[0].mTemp = zins->mDst.mTemp; + ins->mSrc[1].mType = IT_POINTER; + ins->mSrc[1].mMemory = IM_INDIRECT; + ins->mSrc[1].mTemp = vl.mTemp; + ins->mSrc[0].mOperandSize = 1; + ins->mSrc[1].mOperandSize = int(nex->mDecValue->mInteger); + ins->mConst.mOperandSize = int(nex->mDecValue->mInteger); + block->Append(ins); + + return vl; + } + } + } else { mErrors->Error(exp->mLeft->mDecValue->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown intrinsic function", iname); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 3c8b1e7..42da5ea 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -406,7 +406,9 @@ NativeCodeInstruction::NativeCodeInstruction(const InterInstruction* ins, AsmIns if (mode == ASMIM_IMMEDIATE_ADDRESS) { +#if _DEBUG assert(address >= 0); +#endif assert((mFlags & (NCIF_LOWER | NCIF_UPPER)) != (NCIF_LOWER | NCIF_UPPER)); assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE)); } @@ -5071,6 +5073,9 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In { if (ins->mConst.mMemory == IM_GLOBAL) { + if (ins->mConst.mIntConst < 0 || ins->mConst.mIntConst > ins->mConst.mLinkerObject->mSize) + proc->mModule->mErrors->Error(ins->mLocation, EWARN_UNDEFINED_POINTER_ARITHMETIC, "Undefined constant pointer arithmetic"); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mConst.mIntConst, ins->mConst.mLinkerObject, NCIF_LOWER)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mConst.mIntConst, ins->mConst.mLinkerObject, NCIF_UPPER)); @@ -7803,6 +7808,349 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, } } +NativeCodeBasicBlock* NativeCodeBasicBlock::FillValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc) +{ + int size = ins->mConst.mOperandSize; + int msize = 4, dstride = ins->mSrc[1].mStride; + + uint32 flags = NCIF_LOWER | NCIF_UPPER; + if (ins->mVolatile) + flags |= NCIF_VOLATILE; + + if (dstride > 1) + msize = 32; + else if (nproc->mInterProc->mCompilerOptions & COPT_OPTIMIZE_AUTO_UNROLL) + msize = 8; + else if (nproc->mInterProc->mCompilerOptions & COPT_OPTIMIZE_CODE_SIZE) + msize = 2; +#if 1 + if (ins->mSrc[1].mTemp < 0) + { + if ((ins->mSrc[1].mMemory == IM_FRAME || ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) && size < 256 && dstride == 1) + { + int areg = BC_REG_STACK; + + int index = int(ins->mSrc[1].mIntConst); + if (ins->mSrc[1].mMemory == IM_FRAME) + index += ins->mSrc[1].mVarIndex + 2; + else + { + if (!mNoFrame) + areg = BC_REG_LOCALS; + + if (ins->mSrc[1].mMemory == IM_LOCAL) + index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset; + else + index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2; + index += mFrameOffset; + } + CheckFrameIndex(ins, areg, index, size, BC_REG_ADDR); + + if (ins->mSrc[0].mTemp < 0) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + else + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + + if (size <= msize) + { + for (int i = 0; i < size; i++) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, index + i * dstride)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); + } + + return this; + } + else + { + NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); + NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); + + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, index)); + this->Close(ins, lblock, nullptr, ASMIT_JMP); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_INY, ASMIM_IMPLIED)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_CPY, ASMIM_IMMEDIATE, (index + size) & 255)); + lblock->Close(ins, lblock, eblock, ASMIT_BNE); + + return eblock; + } + } + else if (ins->mSrc[1].mMemory == IM_GLOBAL || ins->mSrc[1].mMemory == IM_ABSOLUTE) + { + NativeCodeBasicBlock* block = this; + + if (ins->mSrc[0].mTemp < 0) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + else + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + + int offset = 0; + if (size >= 256) + { + block = nproc->AllocateBlock(); + + NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); + + if (size > 256) + { + if (size < 512 && !(size & 1)) + { + int step = size >> 1; + + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, step)); + this->Close(ins, lblock, nullptr, ASMIT_JMP); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + step, ins->mSrc[1].mLinkerObject, flags)); + lblock->Close(ins, lblock, block, ASMIT_BNE); + + return block; + } + else if (size < 1024 && !(size & 3)) + { + int step = size >> 2; + + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, step)); + this->Close(ins, lblock, nullptr, ASMIT_JMP); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + step, ins->mSrc[1].mLinkerObject, flags)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + 2 * step, ins->mSrc[1].mLinkerObject, flags)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + 3 * step, ins->mSrc[1].mLinkerObject, flags)); + lblock->Close(ins, lblock, block, ASMIT_BNE); + + return block; + } + } + + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + this->Close(ins, lblock, nullptr, ASMIT_JMP); + while (offset + 255 < size) + { + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + offset, ins->mSrc[1].mLinkerObject, flags)); + offset += 256; + } + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_INY, ASMIM_IMPLIED)); + lblock->Close(ins, lblock, block, ASMIT_BNE); + + size &= 255; + } + + if (size <= msize) + { + for (int i = 0; i < size; i++) + block->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + offset + i * dstride, ins->mSrc[1].mLinkerObject, flags)); + } + else + { + NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); + NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); + + block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, size)); + block->Close(ins, lblock, nullptr, ASMIT_JMP); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ABSOLUTE_Y, ins->mSrc[1].mIntConst + offset, ins->mSrc[1].mLinkerObject, flags)); + lblock->Close(ins, lblock, eblock, ASMIT_BNE); + + block = eblock; + } + + return block; + } + else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME) + { + if (ins->mSrc[0].mTemp < 0) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + else + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + + for (int i = 0; i < size; i++) + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + i * dstride)); + + return this; + } + } +#endif + + int dreg; + int di = 0; + + if (ins->mSrc[1].mTemp < 0) + { + if (ins->mSrc[1].mMemory == IM_GLOBAL) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_LOWER)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + else if (ins->mSrc[1].mMemory == IM_ABSOLUTE) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 0)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + else if (ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) + { + int index = int(ins->mSrc[1].mIntConst); + dreg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS; + if (ins->mSrc[1].mMemory == IM_LOCAL) + index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset; + else + index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2; + index += mFrameOffset; + CheckFrameIndex(ins, dreg, index, 256, BC_REG_ADDR); + } + else if (ins->mSrc[1].mMemory == IM_FRAME) + { + int index = ins->mSrc[1].mVarIndex + int(ins->mSrc[1].mIntConst) + 2; + + mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + } + else if (ins->mSrc[1].mIntConst != 0) + { + int index = int(ins->mSrc[1].mIntConst); + if (size <= msize && (size - 1) * dstride + 1 + index <= 256) + { + di = index; + dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + } + else + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + } + else if (size * dstride > 256 && !ins->mSrc[1].mFinal) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + else + { + dreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + } + + if (size <= msize) + { + if (ins->mSrc[0].mTemp < 0) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + else + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + + for (int i = 0; i < size; i++) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, di)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg)); + + di += dstride; + if (di >= 256) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_INC, ASMIM_ZERO_PAGE, dreg + 1)); + di &= 0xff; + } + } + + return this; + } + else + { + NativeCodeBasicBlock* block = this; + + if (size >= 256) + { + block = nproc->AllocateBlock(); + + if (dreg != BC_REG_ADDR && !ins->mSrc[1].mFinal) + { + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, dreg)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, dreg + 1)); + mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1)); + dreg = BC_REG_ADDR; + } + + if (ins->mSrc[0].mTemp < 0) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + else + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + + NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); + NativeCodeBasicBlock* lblock2 = nproc->AllocateBlock(); + + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + if (size >= 512) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDX, ASMIM_IMMEDIATE, size >> 8)); + this->Close(ins, lblock, nullptr, ASMIT_JMP); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_INY, ASMIM_IMPLIED)); + lblock->Close(ins, lblock, lblock2, ASMIT_BNE); + lblock2->mIns.Push(NativeCodeInstruction(ins, ASMIT_INC, ASMIM_ZERO_PAGE, dreg + 1)); + if (size >= 512) + { + lblock2->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEX, ASMIM_IMPLIED)); + lblock2->Close(ins, lblock, block, ASMIT_BNE); + } + else + lblock2->Close(ins, block, nullptr, ASMIT_JMP); + + size &= 0xff; + } + else + { + if (ins->mSrc[0].mTemp < 0) + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + else + mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + } + + if (size > 0) + { + NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); + NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); + + block->mIns.Push(NativeCodeInstruction(ins, ASMIT_LDY, ASMIM_IMMEDIATE, size)); + block->Close(ins, lblock, nullptr, ASMIT_JMP); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEY, ASMIM_IMPLIED)); + lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_INDIRECT_Y, dreg, nullptr, flags)); + lblock->Close(ins, lblock, eblock, ASMIT_BNE); + + block = eblock; + } + + return block; + } +} + void NativeCodeBasicBlock::CallMalloc(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc) { if (ins->mSrc[0].mTemp < 0) @@ -22517,6 +22865,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool } } + if (mTrueJump) mTrueJump->CheckLive(); + if (mFalseJump) mFalseJump->CheckLive(); #if 1 if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2) { @@ -23080,6 +23430,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool mTrueJump->mIns.Insert(0, pb->mIns[ps - 1]); mTrueJump->mEntryRequiredRegs += CPU_REG_X; + mFalseJump->BuildSingleExit(proc, this); + mFalseJump->mIns.Insert(0, pb->mIns[ps - 1]); mFalseJump->mEntryRequiredRegs += CPU_REG_X; @@ -23108,6 +23460,8 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool mTrueJump->mIns.Insert(0, pb->mIns[ps - 1]); mTrueJump->mEntryRequiredRegs += CPU_REG_Y; + mFalseJump->BuildSingleExit(proc, this); + mFalseJump->mIns.Insert(0, pb->mIns[ps - 1]); mFalseJump->mEntryRequiredRegs += CPU_REG_Y; @@ -23559,6 +23913,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool } CheckLive(); + mProc->CheckBlocks(); if (mTrueJump && mTrueJump->JoinTailCodeSequences(proc, loops)) changed = true; @@ -45639,9 +45994,9 @@ void NativeCodeBasicBlock::CheckAsmCode(void) void NativeCodeBasicBlock::CheckBlocks(bool sequence) { #if _DEBUG - if (!mVisited) + if (!mChecked) { - mVisited = true; + mChecked = true; assert(this != mProc->mEntryBlock || mNumEntries < 2); @@ -45666,6 +46021,12 @@ void NativeCodeBasicBlock::CheckLive(void) #if _DEBUG uint32 live = 0; + if (mFalseJump && mFalseJump->mEntryRequiredRegs.Size() > 0 && mFalseJump->mEntryRequiredRegs[CPU_REG_X]) + { + if (mFalseJump->mIns.Size() > 0 && mFalseJump->mIns[0].RequiresXReg()) + assert(mExitRequiredRegs[CPU_REG_X]); + } + assert(mBranch == ASMIT_RTS || (mBranch == ASMIT_JMP) == (mFalseJump == nullptr)); if (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS) @@ -46403,7 +46764,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "test3"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "chareditor"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -47010,6 +47371,14 @@ void NativeCodeProcedure::RebuildEntry(void) mEntryBlock->BuildDominatorTree(nullptr, stacks); } +void NativeCodeProcedure::CheckBlocks(bool sequence) +{ +#if _DEBUG + ResetChecked(); + mEntryBlock->CheckBlocks(); +#endif +} + void NativeCodeProcedure::Optimize(void) { #if 1 @@ -47019,10 +47388,7 @@ void NativeCodeProcedure::Optimize(void) CheckCase = false; -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); bool changed, xmapped = false, ymapped = false; do @@ -47168,10 +47534,7 @@ void NativeCodeProcedure::Optimize(void) { changed = true; -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); BuildDataFlowSets(); ResetVisited(); @@ -47186,10 +47549,7 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->AbsoluteValueForwarding(pairs)) { changed = true; -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); BuildDataFlowSets(); ResetVisited(); @@ -47197,10 +47557,7 @@ void NativeCodeProcedure::Optimize(void) } } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); #if 1 @@ -47297,10 +47654,7 @@ void NativeCodeProcedure::Optimize(void) RebuildEntry(); -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(true); -#endif + CheckBlocks(); #if 1 if (step == 2) @@ -47326,10 +47680,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(true); -#endif + CheckBlocks(); #if 1 @@ -47377,10 +47728,7 @@ void NativeCodeProcedure::Optimize(void) #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(true); -#endif + CheckBlocks(); #if 1 if (step == 3 || step == 4) @@ -47391,10 +47739,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(true); -#endif + CheckBlocks(true); #if 1 ResetVisited(); @@ -47402,16 +47747,14 @@ void NativeCodeProcedure::Optimize(void) changed = true; #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(true); -#endif + CheckBlocks(true); #if 1 ResetVisited(); if (mEntryBlock->ReduceLocalYPressure()) changed = true; #endif + CheckBlocks(true); #if 1 if (step == 4) @@ -47422,17 +47765,23 @@ void NativeCodeProcedure::Optimize(void) } #endif + CheckBlocks(true); #if 1 ResetVisited(); if (!changed && mEntryBlock->ShortcutZeroPageCopyUp(this)) changed = true; #endif + + CheckBlocks(true); + #if 1 ResetVisited(); if (!changed && mEntryBlock->CrossBlockXYShortcut()) changed = true; #endif + CheckBlocks(true); + #if 1 ResetVisited(); if (!changed && mEntryBlock->CrossBlockXYPreservation()) @@ -47441,10 +47790,7 @@ void NativeCodeProcedure::Optimize(void) } #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); if (step > 4 && !changed) @@ -47461,10 +47807,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); #if 1 if (step == 5 || step == 6) @@ -47554,10 +47897,7 @@ void NativeCodeProcedure::Optimize(void) } #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); #if 1 ResetVisited(); @@ -47615,10 +47955,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); if (step == 7) { @@ -47636,10 +47973,8 @@ void NativeCodeProcedure::Optimize(void) #if 1 if (step == 9 && cnt < 10) { -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); + ResetVisited(); while (mEntryBlock->OptimizeXYSpilling()) { @@ -47650,10 +47985,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); } #endif @@ -47672,10 +48004,7 @@ void NativeCodeProcedure::Optimize(void) } #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); #if 1 ResetVisited(); @@ -47695,10 +48024,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; #endif -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); #if 1 if (step == 6) @@ -47707,18 +48033,13 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->SimplifyDiamond(this)) changed = true; -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); + ResetVisited(); if (mEntryBlock->SimplifyLoopEnd(this)) changed = true; -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); } #endif @@ -47751,10 +48072,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); if (step == 6 || step == 7) { @@ -47771,10 +48089,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); #if 1 @@ -47979,10 +48294,7 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->RemoveUnusedResultInstructions()) changed = true; -#if _DEBUG - ResetVisited(); - mEntryBlock->CheckBlocks(); -#endif + CheckBlocks(); if (!changed) { @@ -48125,6 +48437,15 @@ void NativeCodeProcedure::ResetPatched(void) } } +void NativeCodeProcedure::ResetChecked(void) +{ + for (int i = 0; i < mBlocks.Size(); i++) + { + mBlocks[i]->mChecked = false; + + } +} + void NativeCodeProcedure::ResetVisited(void) { for (int i = 0; i < mBlocks.Size(); i++) @@ -48286,6 +48607,9 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode else block->LoadValue(iproc, ins); break; + case IC_FILL: + block = block->FillValue(iproc, ins, this); + break; case IC_COPY: block = block->CopyValue(iproc, ins, this); break; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index a533885..99cb9db 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -239,7 +239,7 @@ public: int mOffset, mSize, mPlace, mNumEntries, mNumEntered, mFrameOffset, mTemp; bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited, mLoopHead, mVisiting, mLocked, mPatched, mPatchFail, mPatchChecked, mPatchStart, mPatchLoop, mPatchLoopChanged, mPatchExit; - bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX; + bool mEntryRegA, mEntryRegX, mEntryRegY, mExitRegA, mExitRegX, mChecked; NativeCodeBasicBlock * mDominator, * mSameBlock; NativeCodeBasicBlock* mLoopHeadBlock, * mLoopTailBlock; @@ -354,6 +354,7 @@ public: void BinaryDivModPair(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins1, const InterInstruction* ins2); void NumericConversion(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins); + NativeCodeBasicBlock * FillValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc); NativeCodeBasicBlock * CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc); NativeCodeBasicBlock * StrcpyValue(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc); void AddAsrSignedByte(InterCodeProcedure* proc, const InterInstruction* ains, const InterInstruction* sins); @@ -784,10 +785,12 @@ class NativeCodeProcedure void BuildDataFlowSets(void); void ResetEntryBlocks(void); + void ResetChecked(void); void ResetVisited(void); void ResetPatched(void); void RebuildEntry(void); void ResetIndexFlipped(void); + void CheckBlocks(bool sequence = false); void SaveTempsToStack(int tempSave); void LoadTempsFromStack(int tempSave);