Fix broken left shift optimization due to branch in basic block

This commit is contained in:
drmortalwombat 2021-12-06 22:56:03 +01:00
parent 75ea2ee439
commit 18ab7ce079
7 changed files with 114 additions and 91 deletions

View File

@ -1,6 +1,8 @@
#include <stdio.h>
#include <assert.h>
#pragma region( main, 0x0a00, 0xd000, , , {code, data, bss, heap, stack} )
unsigned shl1b(int n)
{
return 1 << n;
@ -306,6 +308,8 @@ void shr32n(unsigned long xu, long xi)
int main(void)
{
*(volatile char *)0x01 = 0x36;
for(int i=0; i<32; i++)
{
printf("1: %.4x : %.4x | %.4x : %.4x\n", shl1b(i), shl1n(i), shr1b(i), shr1n(i));
@ -327,7 +331,6 @@ int main(void)
assert(shr8b(i) == shr8n(i));
}
shl8xb(0x00, 0x00);
shl8xb(0xff, 0xff);
shl8xb(0x34, 0x34);

View File

@ -183,11 +183,16 @@ float sqrt(float f)
{
if (f >= 0)
{
float fx = f;
int ex = (((int*)&fx)[1] >> 7) - 0x7f;
union {
float f;
int i[2];
} x;
x.f = f;
int ex = (x.i[1] >> 7) - 0x7f;
ex /= 2;
((int*)&fx)[1] = (ex + 0x7f) << 7;
float fq = fx;
x.i[1] = (ex + 0x7f) << 7;
float fq = x.f;
fq = 0.5 * (fq + f / fq);
fq = 0.5 * (fq + f / fq);
fq = 0.5 * (fq + f / fq);

View File

@ -5680,7 +5680,7 @@ void ByteCodeBasicBlock::InitialOffset(int& total, int& linear)
total++;
linear = 0;
}
else
linear += mLinear;
mOffset = total;

View File

@ -640,7 +640,7 @@ int Emulator::Emulate(int startIP)
break;
}
if ((trace & 1) && ip == 0x0851)
if ((trace & 1) && ip == 0x0855)
{
int accu = mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1];
int ptr = mMemory[BC_REG_ADDR] + 256 * mMemory[BC_REG_ADDR + 1];

View File

@ -90,16 +90,91 @@ void ValueSet::FlushFrameAliases(void)
}
}
void ValueSet::FlushCallAliases(void)
static bool MemPtrRange(const InterInstruction* ins, const GrowingInstructionPtrArray& tvalue, InterMemory& mem, int& vindex, int& offset)
{
while (ins && ins->mCode == IC_LEA && ins->mSrc[1].mMemory == IM_INDIRECT)
ins = tvalue[ins->mSrc[1].mTemp];
if (ins)
{
if (ins->mCode == IC_CONSTANT)
{
mem = ins->mConst.mMemory;
vindex = ins->mConst.mVarIndex;
offset = ins->mConst.mIntConst;
return true;
}
else if (ins->mCode == IC_LEA)
{
mem = ins->mSrc[1].mMemory;
vindex = ins->mSrc[1].mVarIndex;
offset = ins->mSrc[1].mIntConst;
return true;
}
}
return false;
}
static bool MemRange(const InterInstruction* ins, const GrowingInstructionPtrArray& tvalue, InterMemory& mem, int& vindex, int& offset, int& size)
{
if (ins->mCode == IC_LOAD && ins->mSrc[0].mMemory == IM_INDIRECT)
{
size = ins->mSrc[0].mOperandSize;
return MemPtrRange(tvalue[ins->mSrc[0].mTemp], tvalue, mem, vindex, offset);
}
else if (ins->mSrc[1].mMemory == IM_INDIRECT)
{
size = ins->mSrc[1].mOperandSize;
return MemPtrRange(tvalue[ins->mSrc[1].mTemp], tvalue, mem, vindex, offset);
}
if (ins)
{
if (ins->mCode == IC_LOAD)
{
mem = ins->mSrc[0].mMemory;
vindex = ins->mSrc[0].mVarIndex;
offset = ins->mSrc[0].mIntConst;
size = ins->mSrc[0].mOperandSize;
}
else
{
mem = ins->mSrc[1].mMemory;
vindex = ins->mSrc[1].mVarIndex;
offset = ins->mSrc[1].mIntConst;
size = ins->mSrc[1].mOperandSize;
}
return true;
}
return false;
}
void ValueSet::FlushCallAliases(const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
{
int i;
i = 0;
InterMemory mem;
int vindex;
int offset;
int size;
i = 0;
while (i < mNum)
{
if ((mInstructions[i]->mCode == IC_LOAD && mInstructions[i]->mSrc[0].mMemory != IM_PARAM && mInstructions[i]->mSrc[0].mMemory != IM_LOCAL) ||
(mInstructions[i]->mCode == IC_STORE && mInstructions[i]->mSrc[1].mMemory != IM_PARAM && mInstructions[i]->mSrc[1].mMemory != IM_LOCAL))
if (mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE)
{
if (MemRange(mInstructions[i], tvalue, mem, vindex, offset, size) &&
((mem == IM_PARAM && !aliasedParams[vindex]) ||
(mem == IM_LOCAL && !aliasedLocals[vindex])))
i++;
else
{
//
// potential alias load
@ -110,6 +185,7 @@ void ValueSet::FlushCallAliases(void)
mInstructions[i] = mInstructions[mNum];
}
}
}
else
i++;
}
@ -373,71 +449,6 @@ void ValueSet::InsertValue(InterInstruction * ins)
mInstructions[mNum++] = ins;
}
static bool MemPtrRange(const InterInstruction* ins, const GrowingInstructionPtrArray& tvalue, InterMemory& mem, int& vindex, int& offset)
{
while (ins && ins->mCode == IC_LEA && ins->mSrc[1].mMemory == IM_INDIRECT)
ins = tvalue[ins->mSrc[1].mTemp];
if (ins)
{
if (ins->mCode == IC_CONSTANT)
{
mem = ins->mConst.mMemory;
vindex = ins->mConst.mVarIndex;
offset = ins->mConst.mIntConst;
return true;
}
else if (ins->mCode == IC_LEA)
{
mem = ins->mSrc[1].mMemory;
vindex = ins->mSrc[1].mVarIndex;
offset = ins->mSrc[1].mIntConst;
return true;
}
}
return false;
}
static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, InterMemory& mem, int& vindex, int& offset, int& size)
{
if (ins->mCode == IC_LOAD && ins->mSrc[0].mMemory == IM_INDIRECT)
{
size = ins->mSrc[0].mOperandSize;
return MemPtrRange(tvalue[ins->mSrc[0].mTemp], tvalue, mem, vindex, offset);
}
else if (ins->mSrc[1].mMemory == IM_INDIRECT)
{
size = ins->mSrc[1].mOperandSize;
return MemPtrRange(tvalue[ins->mSrc[1].mTemp], tvalue, mem, vindex, offset);
}
if (ins)
{
if (ins->mCode == IC_LOAD)
{
mem = ins->mSrc[0].mMemory;
vindex = ins->mSrc[0].mVarIndex;
offset = ins->mSrc[0].mIntConst;
size = ins->mSrc[0].mOperandSize;
}
else
{
mem = ins->mSrc[1].mMemory;
vindex = ins->mSrc[1].mVarIndex;
offset = ins->mSrc[1].mIntConst;
size = ins->mSrc[1].mOperandSize;
}
return true;
}
return false;
}
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
{
InterMemory lmem, smem;
@ -1463,7 +1474,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
break;
case IC_CALL:
case IC_CALL_NATIVE:
FlushCallAliases();
FlushCallAliases(tvalue, aliasedLocals, aliasedParams);
break;
}

View File

@ -141,7 +141,7 @@ public:
ValueSet& operator=(const ValueSet& values);
void FlushAll(void);
void FlushCallAliases(void);
void FlushCallAliases(const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
void FlushFrameAliases(void);

View File

@ -5698,6 +5698,9 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
}
else
{
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x0f));
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
@ -5720,14 +5723,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
}
mIns.Push(NativeCodeInstruction(ASMIT_CPX, ASMIM_IMMEDIATE, 0x00));
mIns.Push(NativeCodeInstruction(ASMIT_BEQ, ASMIM_RELATIVE, 2 + 1 + 1 + 2));
this->Close(lblock, eblock, ASMIT_BNE);
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -(2 + 1 + 1 + 2)));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_ZERO_PAGE, treg));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
lblock->Close(lblock, eblock, ASMIT_BNE);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
return eblock;
}
} break;
case IA_SHR: