Fix broken left shift optimization due to branch in basic block
This commit is contained in:
parent
75ea2ee439
commit
18ab7ce079
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -5680,7 +5680,7 @@ void ByteCodeBasicBlock::InitialOffset(int& total, int& linear)
|
|||
total++;
|
||||
linear = 0;
|
||||
}
|
||||
else
|
||||
|
||||
linear += mLinear;
|
||||
|
||||
mOffset = total;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue