Optimize long shifts
This commit is contained in:
parent
4115bdcb4f
commit
18c21b3fda
|
@ -1311,10 +1311,10 @@ bool Declaration::IsSameValue(const Declaration* dec) const
|
|||
|
||||
bool Declaration::CanAssign(const Declaration* fromType) const
|
||||
{
|
||||
if (fromType->mType == DT_TYPE_REFERENCE)
|
||||
return this->CanAssign(fromType->mBase);
|
||||
if (mType == DT_TYPE_REFERENCE)
|
||||
return mBase->IsSubType(fromType);
|
||||
else if (fromType->mType == DT_TYPE_REFERENCE)
|
||||
return this->CanAssign(fromType->mBase);
|
||||
|
||||
if (this->IsSame(fromType))
|
||||
return true;
|
||||
|
|
|
@ -4682,7 +4682,7 @@ bool InterCodeBasicBlock::MergeSameConditionTraces(void)
|
|||
if (mb1 && mb1->mNumEntries == 2 && mb0 != mb1)
|
||||
{
|
||||
int tc = mInstructions.Last()->mSrc[0].mTemp;
|
||||
if (tc == mb0->mInstructions.Last()->mSrc[0].mTemp)
|
||||
if (tc >= 0 && tc == mb0->mInstructions.Last()->mSrc[0].mTemp)
|
||||
{
|
||||
if (!mTrueJump->mLocalModifiedTemps[tc] && !mFalseJump->mLocalModifiedTemps[tc] && !mb0->mLocalModifiedTemps[tc])
|
||||
{
|
||||
|
@ -6464,6 +6464,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_EXT8TO16S:
|
||||
case IA_EXT8TO32S:
|
||||
vr = ins->mSrc[0].mRange;
|
||||
if (vr.mMaxState != IntegerValueRange::S_BOUND || vr.mMaxValue < -128 || vr.mMaxValue > 127)
|
||||
{
|
||||
|
@ -6477,7 +6478,22 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
}
|
||||
break;
|
||||
|
||||
case IA_EXT16TO32S:
|
||||
vr = ins->mSrc[0].mRange;
|
||||
if (vr.mMaxState != IntegerValueRange::S_BOUND || vr.mMaxValue < -65536 || vr.mMaxValue > 65535)
|
||||
{
|
||||
vr.mMaxState = IntegerValueRange::S_BOUND;
|
||||
vr.mMaxValue = 65535;
|
||||
}
|
||||
if (vr.mMinState != IntegerValueRange::S_BOUND || vr.mMinValue < -65536 || vr.mMinValue > 65535)
|
||||
{
|
||||
vr.mMinState = IntegerValueRange::S_BOUND;
|
||||
vr.mMinValue = -65536;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA_EXT8TO16U:
|
||||
case IA_EXT8TO32U:
|
||||
vr = ins->mSrc[0].mRange;
|
||||
if (vr.mMaxState != IntegerValueRange::S_BOUND || vr.mMaxValue < 0 || vr.mMaxValue > 255 || vr.mMinValue < 0 ||
|
||||
vr.mMinState != IntegerValueRange::S_BOUND)
|
||||
|
@ -6493,6 +6509,22 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
vr.mMinValue = 0;
|
||||
}
|
||||
break;
|
||||
case IA_EXT16TO32U:
|
||||
vr = ins->mSrc[0].mRange;
|
||||
if (vr.mMaxState != IntegerValueRange::S_BOUND || vr.mMaxValue < 0 || vr.mMaxValue > 65535 || vr.mMinValue < 0 ||
|
||||
vr.mMinState != IntegerValueRange::S_BOUND)
|
||||
{
|
||||
vr.mMaxState = IntegerValueRange::S_BOUND;
|
||||
vr.mMaxValue = 65535;
|
||||
vr.mMinState = IntegerValueRange::S_BOUND;
|
||||
vr.mMinValue = 0;
|
||||
}
|
||||
if (vr.mMinState != IntegerValueRange::S_BOUND || vr.mMinValue < 0 || vr.mMinValue > 65535)
|
||||
{
|
||||
vr.mMinState = IntegerValueRange::S_BOUND;
|
||||
vr.mMinValue = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
|
||||
|
@ -10502,7 +10534,7 @@ bool InterCodeBasicBlock::ForwardDiamondMovedTemp(void)
|
|||
|
||||
if (fblock && tblock)
|
||||
{
|
||||
if (tblock->mInstructions[0]->IsEqual(fblock->mInstructions.Last()) && !fblock->mLocalModifiedTemps[tblock->mInstructions[0]->mSrc[0].mTemp])
|
||||
if (tblock->mInstructions[0]->IsEqual(fblock->mInstructions.Last()) && (tblock->mInstructions[0]->mSrc[0].mTemp < 0 || !fblock->mLocalModifiedTemps[tblock->mInstructions[0]->mSrc[0].mTemp]))
|
||||
{
|
||||
fblock->mTrueJump = tblock;
|
||||
fblock->mFalseJump = nullptr;
|
||||
|
|
|
@ -83,7 +83,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
|||
|
||||
if (type->mType == DT_TYPE_REFERENCE)
|
||||
{
|
||||
if (!type->mBase->IsSubType(v.mType))
|
||||
if (v.mType->mType == DT_TYPE_REFERENCE)
|
||||
{
|
||||
if (!type->mBase->IsSubType(v.mType->mBase))
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Incompatible type for reference");
|
||||
}
|
||||
else if (!type->mBase->IsSubType(v.mType))
|
||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Incompatible type for reference");
|
||||
|
||||
return v;
|
||||
|
@ -998,7 +1003,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
if (pdec)
|
||||
{
|
||||
if (!pdec->mBase->CanAssign(vr.mType))
|
||||
{
|
||||
pdec->mBase->CanAssign(vr.mType);
|
||||
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||
}
|
||||
vr = CoerceType(proc, texp, block, vr, pdec->mBase);
|
||||
}
|
||||
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
|
||||
|
@ -3221,7 +3229,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CALL);
|
||||
cins->mNumOperands = 1;
|
||||
if (funcexp->mDecValue && (funcexp->mDecValue->mFlags & DTF_NATIVE))
|
||||
if (funcexp->mDecValue && (funcexp->mDecValue->mFlags & DTF_NATIVE) || (mCompilerOptions & COPT_NATIVE))
|
||||
cins->mCode = IC_CALL_NATIVE;
|
||||
else
|
||||
cins->mCode = IC_CALL;
|
||||
|
|
|
@ -7434,6 +7434,75 @@ bool NativeCodeBasicBlock::CheckPredAccuStore(int reg)
|
|||
return true;
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::ShiftRegisterRight(const InterInstruction* ins, int reg, int shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
{
|
||||
}
|
||||
else if (shift == 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, reg));
|
||||
}
|
||||
else if (shift == 15)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ASL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 0));
|
||||
}
|
||||
else if (shift == 14)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ASL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_AND, ASMIM_IMMEDIATE, 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
}
|
||||
else if (shift >= 8)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
for (int i = 8; i < shift; i++)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
}
|
||||
else if (shift >= 5)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDX, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STX, ASMIM_ZERO_PAGE, reg));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ASL, ASMIM_IMPLIED));
|
||||
for (int i = shift; i < 8; i++)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROL, ASMIM_IMPLIED));
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_AND, ASMIM_IMMEDIATE, 0xff >> shift));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_ZERO_PAGE, reg + 1));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_IMPLIED));
|
||||
for (int i = 1; i < shift; i++)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_IMPLIED));
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::ShiftRegisterLeft(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
|
@ -8687,7 +8756,23 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
int shift = ins->mSrc[0].mIntConst & 31;
|
||||
|
||||
int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
|
||||
int nregs = 4;
|
||||
int nvbits = 32;
|
||||
if (ins->mSrc[1].IsUnsigned() && ins->mSrc[1].mRange.mMaxState == IntegerValueRange::S_BOUND)
|
||||
{
|
||||
int64 mv = ins->mSrc[1].mRange.mMaxValue;
|
||||
while (nvbits > 0 && mv < (1LL << (nvbits - 1)))
|
||||
nvbits--;
|
||||
}
|
||||
|
||||
if (shift >= nvbits)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
|
||||
return this;
|
||||
}
|
||||
|
||||
if (shift >= 24)
|
||||
{
|
||||
|
@ -8699,7 +8784,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
|
||||
sreg = treg;
|
||||
shift -= 24;
|
||||
nregs = 1;
|
||||
nvbits -= 24;
|
||||
}
|
||||
else if (shift >= 16)
|
||||
{
|
||||
|
@ -8712,7 +8797,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
|
||||
sreg = treg;
|
||||
shift -= 16;
|
||||
nregs = 2;
|
||||
nvbits -= 16;
|
||||
}
|
||||
else if (shift >= 8)
|
||||
{
|
||||
|
@ -8727,7 +8812,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
|
||||
sreg = treg;
|
||||
shift -= 8;
|
||||
nregs = 3;
|
||||
nvbits -= 8;
|
||||
}
|
||||
|
||||
if (shift == 0)
|
||||
|
@ -8800,9 +8885,6 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
|
||||
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
||||
|
||||
if (sreg != treg)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
|
||||
|
@ -8815,22 +8897,44 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, treg + nregs - 1));
|
||||
int nregs = (nvbits + 7) >> 3;
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDX, ASMIM_IMMEDIATE, shift));
|
||||
this->Close(ins, lblock, nullptr, ASMIT_JMP);
|
||||
if ((nvbits & 7) == 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_ZERO_PAGE, treg + nregs - 1));
|
||||
for (int i = nregs - 1; i > 0; i--)
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + i - 1));
|
||||
nvbits--;
|
||||
nregs--;
|
||||
shift--;
|
||||
}
|
||||
|
||||
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_IMPLIED));
|
||||
for(int i=nregs -1; i>0 ; i--)
|
||||
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + i - 1));
|
||||
if (nregs <= 2)
|
||||
{
|
||||
ShiftRegisterRight(ins, treg, shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
|
||||
NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
|
||||
|
||||
// lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + 1));
|
||||
// lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + 0));
|
||||
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEX, ASMIM_IMPLIED));
|
||||
lblock->Close(ins, lblock, eblock, ASMIT_BNE);
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, treg + nregs - 1));
|
||||
|
||||
eblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + nregs - 1));
|
||||
return eblock;
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDX, ASMIM_IMMEDIATE, shift));
|
||||
this->Close(ins, lblock, nullptr, ASMIT_JMP);
|
||||
|
||||
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_LSR, ASMIM_IMPLIED));
|
||||
for (int i = nregs - 1; i > 0; i--)
|
||||
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + i - 1));
|
||||
|
||||
// lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + 1));
|
||||
// lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_ROR, ASMIM_ZERO_PAGE, treg + 0));
|
||||
lblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_DEX, ASMIM_IMPLIED));
|
||||
lblock->Close(ins, lblock, eblock, ASMIT_BNE);
|
||||
|
||||
eblock->mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg + nregs - 1));
|
||||
return eblock;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -352,6 +352,7 @@ public:
|
|||
void CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
|
||||
void ShiftRegisterRight( const InterInstruction* ins, int reg, int shift);
|
||||
void ShiftRegisterLeft(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift);
|
||||
void ShiftRegisterLeftByte(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift);
|
||||
void ShiftRegisterLeftFromByte(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift, int max);
|
||||
|
|
|
@ -3453,6 +3453,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
if (ldec && ldec != pdec)
|
||||
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition");
|
||||
}
|
||||
else if (!pdec)
|
||||
mErrors->Error(ndec->mLocation, EERR_OBJECT_NOT_FOUND, "Object not declarared in scope", ndec->mQualIdent);
|
||||
|
||||
}
|
||||
else
|
||||
pdec = mScope->Insert(ndec->mIdent, ndec);
|
||||
|
|
Loading…
Reference in New Issue