From 0ea87ea3221e3070d4b0083e6d1949710fb97c92 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 25 Jan 2022 21:05:00 +0100 Subject: [PATCH] Reduce speculation of integer value range analyzer --- oscar64/Disassembler.cpp | 5 + oscar64/InterCode.cpp | 58 +++++++-- oscar64/InterCode.h | 2 +- oscar64/Linker.cpp | 5 + oscar64/NativeCodeGenerator.cpp | 8 +- samples/games/make.bat | 1 + samples/games/maze3d.c | 210 ++++++++++++++++++++++++++++++++ 7 files changed, 273 insertions(+), 16 deletions(-) create mode 100644 samples/games/maze3d.c diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index 48b79fc..ef11601 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -711,6 +711,11 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU); return buffer; } + else if (tmp >= BC_REG_WORK && tmp <= BC_REG_WORK + 7) + { + sprintf_s(buffer, 10, "WORK + %d", tmp - BC_REG_WORK); + return buffer; + } else if (tmp >= BC_REG_STACK && tmp <= BC_REG_STACK + 1) { sprintf_s(buffer, 10, "SP + %d", tmp - BC_REG_STACK); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index cada763..818815e 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -83,7 +83,7 @@ bool IntegerValueRange::IsConstant(void) const return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue; } -bool IntegerValueRange::Merge(const IntegerValueRange& range) +bool IntegerValueRange::Merge(const IntegerValueRange& range, bool head) { bool changed = false; @@ -91,8 +91,16 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range) { if (range.mMinState == S_UNKNOWN) { - if (mMinState == S_BOUND) - mMinState = S_WEAK; + if (head) + { + if (mMinState == S_BOUND) + mMinState = S_WEAK; + } + else if (mMinState != S_UNKNOWN) + { + mMinState = S_UNKNOWN; + changed = true; + } } else if (range.mMinState == S_UNBOUND) { @@ -101,9 +109,12 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range) } else if (mMinState == S_UNKNOWN) { - mMinState = S_WEAK; - mMinValue = range.mMinValue; - changed = true; + if (head) + { + mMinState = S_WEAK; + mMinValue = range.mMinValue; + changed = true; + } } else if (range.mMinValue < mMinValue) { @@ -112,14 +123,27 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range) mMinValue = range.mMinValue; changed = true; } + else if (mMinState == S_BOUND && range.mMinState == S_WEAK && !head) + { + mMinState = S_WEAK; + changed = true; + } } if (mMaxState != S_UNBOUND) { if (range.mMaxState == S_UNKNOWN) { - if (mMaxState == S_BOUND) - mMaxState = S_WEAK; + if (head) + { + if (mMaxState == S_BOUND) + mMaxState = S_WEAK; + } + else if (mMaxState != S_UNKNOWN) + { + mMaxState = S_UNKNOWN; + changed = true; + } } else if (range.mMaxState == S_UNBOUND) { @@ -128,9 +152,12 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range) } else if (mMaxState == S_UNKNOWN) { - mMaxState = S_WEAK; - mMaxValue = range.mMaxValue; - changed = true; + if (head) + { + mMaxState = S_WEAK; + mMaxValue = range.mMaxValue; + changed = true; + } } else if (range.mMaxValue > mMaxValue) { @@ -139,6 +166,11 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range) mMaxValue = range.mMaxValue; changed = true; } + else if (mMaxState == S_BOUND && range.mMaxState == S_WEAK && !head) + { + mMaxState = S_WEAK; + changed = true; + } } return changed; @@ -3982,7 +4014,7 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(void) else { for (int i = 0; i < mLocalValueRange.Size(); i++) - mLocalValueRange[i].Merge(range[i]); + mLocalValueRange[i].Merge(range[i], mLoopHead); } } @@ -9070,7 +9102,7 @@ void InterCodeProcedure::Disassemble(FILE* file) void InterCodeProcedure::Disassemble(const char* name, bool dumpSets) { -#if 0 +#if 1 #ifdef _WIN32 FILE* file; static bool initial = true; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 9d985d6..cb7534b 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -146,7 +146,7 @@ public: } mMinState, mMaxState; bool Same(const IntegerValueRange& range) const; - bool Merge(const IntegerValueRange& range); + bool Merge(const IntegerValueRange& range, bool head); bool IsConstant(void) const; diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index ddc87f2..0abce98 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -376,10 +376,15 @@ void Linker::Link(void) else dp = mCartridge[obj->mRegion->mCartridge] + obj->mAddress - 0x8000 + ref->mOffset; + if (ref->mFlags & LREF_LOWBYTE) + { *dp++ = raddr & 0xff; + } if (ref->mFlags & LREF_HIGHBYTE) + { *dp++ = (raddr >> 8) & 0xff; + } if (ref->mFlags & LREF_TEMPORARY) *dp += obj->mTemporaries[ref->mRefOffset]; } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b97b0e9..b6cb5e6 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -2664,6 +2664,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) rl.mRefOffset += pos; rl.mFlags |= LREF_INBLOCK; } + block->mRelocations.Push(rl); } } @@ -2706,6 +2707,8 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) block->PutByte(uint8(mAddress)); break; case ASMIM_IMMEDIATE: + block->PutByte(uint16(mAddress)); + break; case ASMIM_IMMEDIATE_ADDRESS: if (mLinkerObject) { @@ -2720,6 +2723,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) rl.mRefObject = mLinkerObject; rl.mRefOffset = mAddress; + block->mRelocations.Push(rl); block->PutByte(0); } @@ -2739,6 +2743,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block) rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE; rl.mRefObject = mLinkerObject; rl.mRefOffset = mAddress; + block->mRelocations.Push(rl); block->PutWord(0); } @@ -11676,7 +11681,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(void) !(mIns[i + 2].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z))) { mIns[j + 0].mType = ASMIT_AND; mIns[j + 0].mMode = ASMIM_IMMEDIATE; mIns[j + 0].mAddress = 0x80; - mIns[j + 1].mType = ASMIT_BPL; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 2; + mIns[j + 1].mType = ASMIT_BPL; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = 2; mIns[j + 2].mType = ASMIT_LDA; mIns[j + 2].mMode = ASMIM_IMMEDIATE; mIns[j + 2].mAddress = 0xff; j += 3; i += 4; @@ -14438,7 +14443,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif #endif - } if (progress) diff --git a/samples/games/make.bat b/samples/games/make.bat index ca08359..5bf1843 100644 --- a/samples/games/make.bat +++ b/samples/games/make.bat @@ -1,2 +1,3 @@ call ..\..\bin\oscar64 snake.c call ..\..\bin\oscar64 -n lander.c +call ..\..\bin\oscar64 -n maze3d.c diff --git a/samples/games/maze3d.c b/samples/games/maze3d.c new file mode 100644 index 0000000..870c904 --- /dev/null +++ b/samples/games/maze3d.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include + +#define Screen ((byte *)0x0400) +#define Color ((byte *)0xd800) + + +static const char * maze[16] = +{ + "################", + "#..........#...#", + "#.###.####.###.#", + "#........#.#.#.#", + "##.#####.###.#.#", + "#..#......##.#.#", + "#.##.####......#", + "#.#.....#.####.#", + "#.#####.#....#.#", + "#.......######.#", + "#.##.####......#", + "#.#..##....###.#", + "#.##....#....#.#", + "#.#####.######.#", + "#..............#", + "################", +}; + +void maze_init(void) +{ +} + + +static char zxdist[] = {18, 6, 3, 2, 1, 0}; + +// Put one char on screen +inline void screen_put(byte x, byte y, char ch, char color) +{ + __assume(y < 25); + + Screen[40 * y + x] = ch; + Color[40 * y + x] = color; +} + +// Get one char from screen +inline char screen_get(byte x, byte y) +{ + __assume(y < 25); + + return Screen[40 * y + x]; +} + +sbyte px = 1, py = 3, dx = 1, dy = 0; + +void maze_draw(void) +{ + sbyte ix = px, iy = py; + sbyte sx = 0; + for(char i=0; i<6; i++) + { + sbyte tx = 20 - zxdist[i]; + + sbyte ty = sx / 4; + sbyte by = 25 - sx; + + if (maze[iy][ix] == '#') + { + for(char cy=0; cy