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

View File

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

View File

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

View File

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

View File

@ -90,24 +90,100 @@ 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; int i;
i = 0; InterMemory mem;
int vindex;
int offset;
int size;
i = 0;
while (i < mNum) while (i < mNum)
{ {
if ((mInstructions[i]->mCode == IC_LOAD && mInstructions[i]->mSrc[0].mMemory != IM_PARAM && mInstructions[i]->mSrc[0].mMemory != IM_LOCAL) || if (mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE)
(mInstructions[i]->mCode == IC_STORE && mInstructions[i]->mSrc[1].mMemory != IM_PARAM && mInstructions[i]->mSrc[1].mMemory != IM_LOCAL))
{ {
// if (MemRange(mInstructions[i], tvalue, mem, vindex, offset, size) &&
// potential alias load ((mem == IM_PARAM && !aliasedParams[vindex]) ||
// (mem == IM_LOCAL && !aliasedLocals[vindex])))
mNum--; i++;
if (i < mNum) else
{ {
mInstructions[i] = mInstructions[mNum]; //
// potential alias load
//
mNum--;
if (i < mNum)
{
mInstructions[i] = mInstructions[mNum];
}
} }
} }
else else
@ -373,71 +449,6 @@ void ValueSet::InsertValue(InterInstruction * ins)
mInstructions[mNum++] = 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) static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
{ {
InterMemory lmem, smem; InterMemory lmem, smem;
@ -1463,7 +1474,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
break; break;
case IC_CALL: case IC_CALL:
case IC_CALL_NATIVE: case IC_CALL_NATIVE:
FlushCallAliases(); FlushCallAliases(tvalue, aliasedLocals, aliasedParams);
break; break;
} }

View File

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

View File

@ -5698,6 +5698,9 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
} }
else 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_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_AND, ASMIM_IMMEDIATE, 0x0f));
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); 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_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)); lblock->mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); lblock->mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED)); lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -(2 + 1 + 1 + 2))); 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; } break;
case IA_SHR: case IA_SHR: