Reduce speculation of integer value range analyzer

This commit is contained in:
drmortalwombat 2022-01-25 21:05:00 +01:00
parent f25bf80a0f
commit 0ea87ea322
7 changed files with 273 additions and 16 deletions

View File

@ -711,6 +711,11 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU); sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
return buffer; 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) else if (tmp >= BC_REG_STACK && tmp <= BC_REG_STACK + 1)
{ {
sprintf_s(buffer, 10, "SP + %d", tmp - BC_REG_STACK); sprintf_s(buffer, 10, "SP + %d", tmp - BC_REG_STACK);

View File

@ -83,7 +83,7 @@ bool IntegerValueRange::IsConstant(void) const
return mMinState == S_BOUND && mMaxState == S_BOUND && mMinValue == mMaxValue; 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; bool changed = false;
@ -91,8 +91,16 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range)
{ {
if (range.mMinState == S_UNKNOWN) if (range.mMinState == S_UNKNOWN)
{ {
if (mMinState == S_BOUND) if (head)
mMinState = S_WEAK; {
if (mMinState == S_BOUND)
mMinState = S_WEAK;
}
else if (mMinState != S_UNKNOWN)
{
mMinState = S_UNKNOWN;
changed = true;
}
} }
else if (range.mMinState == S_UNBOUND) else if (range.mMinState == S_UNBOUND)
{ {
@ -101,9 +109,12 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range)
} }
else if (mMinState == S_UNKNOWN) else if (mMinState == S_UNKNOWN)
{ {
mMinState = S_WEAK; if (head)
mMinValue = range.mMinValue; {
changed = true; mMinState = S_WEAK;
mMinValue = range.mMinValue;
changed = true;
}
} }
else if (range.mMinValue < mMinValue) else if (range.mMinValue < mMinValue)
{ {
@ -112,14 +123,27 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range)
mMinValue = range.mMinValue; mMinValue = range.mMinValue;
changed = true; changed = true;
} }
else if (mMinState == S_BOUND && range.mMinState == S_WEAK && !head)
{
mMinState = S_WEAK;
changed = true;
}
} }
if (mMaxState != S_UNBOUND) if (mMaxState != S_UNBOUND)
{ {
if (range.mMaxState == S_UNKNOWN) if (range.mMaxState == S_UNKNOWN)
{ {
if (mMaxState == S_BOUND) if (head)
mMaxState = S_WEAK; {
if (mMaxState == S_BOUND)
mMaxState = S_WEAK;
}
else if (mMaxState != S_UNKNOWN)
{
mMaxState = S_UNKNOWN;
changed = true;
}
} }
else if (range.mMaxState == S_UNBOUND) else if (range.mMaxState == S_UNBOUND)
{ {
@ -128,9 +152,12 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range)
} }
else if (mMaxState == S_UNKNOWN) else if (mMaxState == S_UNKNOWN)
{ {
mMaxState = S_WEAK; if (head)
mMaxValue = range.mMaxValue; {
changed = true; mMaxState = S_WEAK;
mMaxValue = range.mMaxValue;
changed = true;
}
} }
else if (range.mMaxValue > mMaxValue) else if (range.mMaxValue > mMaxValue)
{ {
@ -139,6 +166,11 @@ bool IntegerValueRange::Merge(const IntegerValueRange& range)
mMaxValue = range.mMaxValue; mMaxValue = range.mMaxValue;
changed = true; changed = true;
} }
else if (mMaxState == S_BOUND && range.mMaxState == S_WEAK && !head)
{
mMaxState = S_WEAK;
changed = true;
}
} }
return changed; return changed;
@ -3982,7 +4014,7 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(void)
else else
{ {
for (int i = 0; i < mLocalValueRange.Size(); i++) 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) void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
{ {
#if 0 #if 1
#ifdef _WIN32 #ifdef _WIN32
FILE* file; FILE* file;
static bool initial = true; static bool initial = true;

View File

@ -146,7 +146,7 @@ public:
} mMinState, mMaxState; } mMinState, mMaxState;
bool Same(const IntegerValueRange& range) const; bool Same(const IntegerValueRange& range) const;
bool Merge(const IntegerValueRange& range); bool Merge(const IntegerValueRange& range, bool head);
bool IsConstant(void) const; bool IsConstant(void) const;

View File

@ -376,10 +376,15 @@ void Linker::Link(void)
else else
dp = mCartridge[obj->mRegion->mCartridge] + obj->mAddress - 0x8000 + ref->mOffset; dp = mCartridge[obj->mRegion->mCartridge] + obj->mAddress - 0x8000 + ref->mOffset;
if (ref->mFlags & LREF_LOWBYTE) if (ref->mFlags & LREF_LOWBYTE)
{
*dp++ = raddr & 0xff; *dp++ = raddr & 0xff;
}
if (ref->mFlags & LREF_HIGHBYTE) if (ref->mFlags & LREF_HIGHBYTE)
{
*dp++ = (raddr >> 8) & 0xff; *dp++ = (raddr >> 8) & 0xff;
}
if (ref->mFlags & LREF_TEMPORARY) if (ref->mFlags & LREF_TEMPORARY)
*dp += obj->mTemporaries[ref->mRefOffset]; *dp += obj->mTemporaries[ref->mRefOffset];
} }

View File

@ -2664,6 +2664,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
rl.mRefOffset += pos; rl.mRefOffset += pos;
rl.mFlags |= LREF_INBLOCK; rl.mFlags |= LREF_INBLOCK;
} }
block->mRelocations.Push(rl); block->mRelocations.Push(rl);
} }
} }
@ -2706,6 +2707,8 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
block->PutByte(uint8(mAddress)); block->PutByte(uint8(mAddress));
break; break;
case ASMIM_IMMEDIATE: case ASMIM_IMMEDIATE:
block->PutByte(uint16(mAddress));
break;
case ASMIM_IMMEDIATE_ADDRESS: case ASMIM_IMMEDIATE_ADDRESS:
if (mLinkerObject) if (mLinkerObject)
{ {
@ -2720,6 +2723,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
rl.mRefObject = mLinkerObject; rl.mRefObject = mLinkerObject;
rl.mRefOffset = mAddress; rl.mRefOffset = mAddress;
block->mRelocations.Push(rl); block->mRelocations.Push(rl);
block->PutByte(0); block->PutByte(0);
} }
@ -2739,6 +2743,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE; rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
rl.mRefObject = mLinkerObject; rl.mRefObject = mLinkerObject;
rl.mRefOffset = mAddress; rl.mRefOffset = mAddress;
block->mRelocations.Push(rl); block->mRelocations.Push(rl);
block->PutWord(0); block->PutWord(0);
} }
@ -11676,7 +11681,7 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
!(mIns[i + 2].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z))) !(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 + 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; mIns[j + 2].mType = ASMIT_LDA; mIns[j + 2].mMode = ASMIM_IMMEDIATE; mIns[j + 2].mAddress = 0xff;
j += 3; j += 3;
i += 4; i += 4;
@ -14438,7 +14443,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
#endif #endif
#endif #endif
} }
if (progress) if (progress)

View File

@ -1,2 +1,3 @@
call ..\..\bin\oscar64 snake.c call ..\..\bin\oscar64 snake.c
call ..\..\bin\oscar64 -n lander.c call ..\..\bin\oscar64 -n lander.c
call ..\..\bin\oscar64 -n maze3d.c

210
samples/games/maze3d.c Normal file
View File

@ -0,0 +1,210 @@
#include <c64/joystick.h>
#include <c64/vic.h>
#include <c64/sprites.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#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<ty; cy++)
{
for(char cx=sx; cx<20; cx++)
{
screen_put( cx, cy, 32, 0);
screen_put(39 - cx, cy, 32, 0);
}
}
for(char cy=ty; cy<by; cy++)
{
for(char cx=sx; cx<20; cx++)
{
screen_put( cx, cy, 102, 0);
screen_put(39 - cx, cy, 102, 0);
}
}
for(char cy=by; cy<25; cy++)
{
for(char cx=sx; cx<20; cx++)
{
screen_put( cx, cy, 32, 0);
screen_put(39 - cx, cy, 32, 0);
}
}
return ;
}
if (maze[iy - dx][ix + dy] == '#')
{
for(char x=sx; x<tx; x++)
{
sbyte ty = x / 4;
sbyte by = 25 - x;
for(char cy=0; cy<ty; cy++)
screen_put(x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(x, cy, 160, 0);
for(char cy=by; cy<25; cy++)
screen_put(x, cy, 32, 0);
}
}
else
{
sbyte ty = tx / 4;
sbyte by = 25 - tx;
for(char x=sx; x<tx; x++)
{
for(char cy=0; cy<ty; cy++)
screen_put(x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(x, cy, 102, 0);
for(char cy=by; cy<25; cy++)
screen_put(x, cy, 32, 0);
}
}
if (maze[iy + dx][ix - dy] == '#')
{
for(char x=sx; x<tx; x++)
{
sbyte ty = x / 4;
sbyte by = 25 - x;
for(char cy=0; cy<ty; cy++)
screen_put(39 - x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(39 - x, cy, 160, 0);
for(char cy=by; cy<25; cy++)
screen_put(39 - x, cy, 32, 0);
}
}
else
{
sbyte ty = tx / 4;
sbyte by = 25 - tx;
for(char x=sx; x<tx; x++)
{
for(char cy=0; cy<ty; cy++)
screen_put(39 - x, cy, 32, 0);
for(char cy=ty; cy<by; cy++)
screen_put(39 - x, cy, 102, 0);
for(char cy=by; cy<25; cy++)
screen_put(39 - x, cy, 32, 0);
}
}
sx = tx;
ix += dx;
iy += dy;
}
}
int main(void)
{
#if 0
for(char i=0; i<8; i++)
{
float z = 0.5 + i;
float x = 9.0 / z;
printf("%d : %f / %f : %d\n", i, z, x, (int)x);
}
return 0;
#endif
bool rotate = false;
for(;;)
{
maze_draw();
joy_poll(1);
sbyte tx = px - dx * joyy[1];
sbyte ty = py - dy * joyy[1];
if (maze[ty][tx] != '#')
{
px = tx;
py = ty;
}
if (!rotate)
{
if (joyx[1] == 1)
{
sbyte t = dx; dx = - dy; dy = t;
rotate = true;
}
else if (joyx[1] == -1)
{
sbyte t = dx; dx = dy; dy = -t;
rotate = true;
}
}
else if (!joyx[1])
{
rotate = false;
}
}
return 0;
}