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);
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);

View File

@ -83,28 +83,39 @@ 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;
if (mMinState != S_UNBOUND)
{
if (range.mMinState == S_UNKNOWN)
{
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)
{
mMinState = S_UNBOUND;
changed = true;
}
else if (mMinState == S_UNKNOWN)
{
if (head)
{
mMinState = S_WEAK;
mMinValue = range.mMinValue;
changed = true;
}
}
else if (range.mMinValue < mMinValue)
{
if (range.mMinState == S_WEAK)
@ -112,26 +123,42 @@ 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 (head)
{
if (mMaxState == S_BOUND)
mMaxState = S_WEAK;
}
else if (mMaxState != S_UNKNOWN)
{
mMaxState = S_UNKNOWN;
changed = true;
}
}
else if (range.mMaxState == S_UNBOUND)
{
mMaxState = S_UNBOUND;
changed = true;
}
else if (mMaxState == S_UNKNOWN)
{
if (head)
{
mMaxState = S_WEAK;
mMaxValue = range.mMaxValue;
changed = true;
}
}
else if (range.mMaxValue > mMaxValue)
{
if (range.mMaxState == S_WEAK)
@ -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;

View File

@ -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;

View File

@ -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];
}

View File

@ -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);
}
@ -14438,7 +14443,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
}
#endif
#endif
}
if (progress)

View File

@ -1,2 +1,3 @@
call ..\..\bin\oscar64 snake.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;
}