Fix byte to long conversion

This commit is contained in:
drmortalwombat 2022-03-20 21:33:58 +01:00
parent 4dd31f6c69
commit 4538f0295d
4 changed files with 131 additions and 7 deletions

View File

@ -3664,6 +3664,44 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_EXT8TO32S:
{
ByteCodeInstruction lins(BC_LOAD_REG_8);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction cins0(BC_CONV_I8_I16);
cins0.mRegister = BC_REG_ACCU;
mIns.Push(cins0);
ByteCodeInstruction cins1(BC_CONV_I16_I32);
cins1.mRegister = 0;
mIns.Push(cins1);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_EXT8TO32U:
{
ByteCodeInstruction lins(BC_LOAD_REG_8);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction cins(BC_CONV_U16_U32);
cins.mRuntime = "lextu16";
cins.mRegister = 0;
mIns.Push(cins);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
}
}
@ -6300,11 +6338,11 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
entryBlock->Compile(proc, this, proc->mBlocks[0]);
#if 1
bool progress = false;
entryBlock->mLocked = true;
exitBlock->mLocked = true;
#if 1
int phase = 0;

View File

@ -6379,13 +6379,24 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
{
int j = 0, k = 0;
while (j < mLoadStoreInstructions.Size())
{
if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j]))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
while (j < mLoadStoreInstructions.Size() && !SameMem(ins->mSrc[1], mLoadStoreInstructions[j]))
j++;
if (!ins->mVolatile && j < mLoadStoreInstructions.Size() && mLoadStoreInstructions[j]->mCode == IC_LOAD && ins->mSrc[0].mTemp == mLoadStoreInstructions[j]->mDst.mTemp)
{
ins->mCode = IC_NONE;
ins->mNumOperands = 0;
}
else
{
while (j < mLoadStoreInstructions.Size())
{
if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j]))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
mLoadStoreInstructions.SetSize(k);
}
mLoadStoreInstructions.SetSize(k);
if (!ins->mVolatile)
nins = ins;

View File

@ -179,6 +179,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
stemp = xins->mDst.mTemp;
}
}
else if (v.mType->mSize == 1 && type->mSize == 4)
{
if (v.mType->mFlags & DTF_SIGNED)
{
InterInstruction* xins = new InterInstruction();
xins->mCode = IC_CONVERSION_OPERATOR;
xins->mOperator = IA_EXT8TO32S;
xins->mSrc[0].mType = IT_INT8;
xins->mSrc[0].mTemp = stemp;
xins->mDst.mType = IT_INT32;
xins->mDst.mTemp = proc->AddTemporary(IT_INT32);
block->Append(xins);
stemp = xins->mDst.mTemp;
}
else
{
InterInstruction* xins = new InterInstruction();
xins->mCode = IC_CONVERSION_OPERATOR;
xins->mOperator = IA_EXT8TO32U;
xins->mSrc[0].mType = IT_INT8;
xins->mSrc[0].mTemp = stemp;
xins->mDst.mType = IT_INT32;
xins->mDst.mTemp = proc->AddTemporary(IT_INT32);
block->Append(xins);
stemp = xins->mDst.mTemp;
}
}
v.mTemp = stemp;
v.mType = type;

View File

@ -6576,7 +6576,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
case IA_AND:
case IA_XOR:
{
if (ins->mOperator == IA_ADD && (
if (ins->mOperator == IA_ADD && InterTypeSize[ins->mDst.mType] == 1 && (
ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == 1 && !sins1 && ins->mSrc[1].mTemp == ins->mDst.mTemp ||
ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst == 1 && !sins0 && ins->mSrc[0].mTemp == ins->mDst.mTemp))
{
@ -7898,6 +7898,29 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
break;
case IA_EXT8TO32S:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
if (ins->mSrc[0].mTemp != ins->mDst.mTemp)
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
break;
case IA_EXT8TO32U:
if (ins->mSrc[0].mTemp != ins->mDst.mTemp)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]));
}
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
break;
}
}
@ -17111,6 +17134,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 0].mType = ASMIT_LSR;
progress = true;
}
else if (
mIns[i + 0].IsShift() && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
!mIns[i + 1].ReferencesAccu() && (mIns[i + 1].mMode != ASMIM_ZERO_PAGE || mIns[i + 1].mAddress != mIns[i + 0].mAddress) &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Z)))
{
NativeCodeInstruction ins = mIns[i + 2];
mIns.Remove(i + 2);
mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A;
mIns.Insert(i, ins);
progress = true;
}
#if 1
@ -17962,6 +17998,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
progress = true;
}
}
else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE)
{
proc->ResetPatched();
if (CheckSingleUseGlobalLoad(mIns[i + 0].mAddress, i + 2, mIns[i + 1], 2))
{
proc->ResetPatched();
if (PatchSingleUseGlobalLoad(mIns[i + 0].mAddress, i + 2, mIns[i + 1]))
progress = true;
}
}
}
if (i + 5 < mIns.Size())