Fix IEC code for non interrupt usage

This commit is contained in:
drmortalwombat 2024-06-11 12:12:29 +02:00
parent 42eea7f8f4
commit 5ccfab0342
7 changed files with 539 additions and 68 deletions

View File

@ -2,7 +2,8 @@
#include <c64/cia.h>
#include <c64/vic.h>
IEC_STATUS iec_status;
IEC_STATUS iec_status;
char iec_queue;
#define CIA2B_ATNOUT 0x08
#define CIA2B_CLKOUT 0x10
@ -25,45 +26,55 @@ static void delay(char n)
}
}
static inline void data_low(void)
static inline void data_true(void)
{
cia2.pra &= ~CIA2B_DATAOUT;
}
static inline void data_high(void)
static inline void data_false(void)
{
cia2.pra |= CIA2B_DATAOUT;
}
static inline void clock_low(void)
static inline void clock_true(void)
{
cia2.pra &= ~CIA2B_CLKOUT;
}
static inline void cdata_low(void)
static inline void cdata_true(void)
{
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
}
static inline void clock_high(void)
static inline void clock_false(void)
{
cia2.pra |= CIA2B_CLKOUT;
}
static inline void atn_low(void)
static inline void atn_true(void)
{
cia2.pra &= ~CIA2B_ATNOUT;
}
static inline void atn_high(void)
static inline void atn_false(void)
{
cia2.pra |= CIA2B_ATNOUT;
}
static inline bool data_in(void)
{
return (cia2.pra & CIA2B_DATAIN) != 0;
}
static inline bool clock_in(void)
{
return (cia2.pra & CIA2B_CLKIN) != 0;
}
static bool data_check(void)
{
char cnt = 100;
while (cnt > 0 && (cia2.pra & CIA2B_DATAIN))
while (cnt > 0 && data_in())
cnt--;
if (cnt)
@ -75,68 +86,106 @@ static bool data_check(void)
}
}
bool iec_eoi(void)
static bool iec_eoib(void)
{
cdata_low();
clock_true();
while (!data_in());
while (!(cia2.pra & CIA2B_DATAIN))
;
delay(40);
return data_check();
}
static bool iec_writeb(char b)
{
clock_true();
while (!data_in());
for(char i=0; i<8; i++)
{
delay(8);
clock_false();
delay(8);
if (b & 1)
data_true();
else
data_false();
clock_true();
b >>= 1;
}
delay(8);
clock_false();
data_true();
return data_check();
}
bool iec_write(char b)
{
cdata_low();
while (!(cia2.pra & CIA2B_DATAIN))
;
clock_high();
for(char i=0; i<8; i++)
if (iec_status == IEC_QUEUED)
{
if (b & 1)
data_low();
else
data_high();
delay(5);
clock_low();
b >>= 1;
delay(5);
clock_high();
data_low();
__asm
{
php
sei
}
iec_status = IEC_OK;
iec_writeb(iec_queue);
__asm
{
plp
}
}
if (iec_status < IEC_ERROR)
{
iec_queue = b;
iec_status = IEC_QUEUED;
return true;
}
return data_check();
return false;
}
char iec_read(void)
{
while (!(cia2.pra & CIA2B_CLKIN))
;
while (!clock_in());
data_low();
__asm
{
php
sei
}
data_true();
char cnt = 100;
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
while (cnt > 0 && clock_in())
cnt--;
if (cnt == 0)
{
iec_status = IEC_EOF;
data_high();
data_false();
delay(4);
data_low();
data_true();
cnt = 200;
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
while (cnt > 0 && clock_in())
cnt--;
if (cnt == 0)
{
iec_status = IEC_TIMEOUT;
__asm
{
plp
}
return 0;
}
}
@ -155,25 +204,32 @@ char iec_read(void)
;
}
data_high();
data_false();
__asm
{
plp
}
return b;
}
void iec_atn(char dev, char sec)
{
cdata_low();
atn_high();
clock_high();
clock_true();
data_true();
atn_false();
clock_false();
delay(200);
iec_write(dev);
if (sec != 0xff)
iec_write(sec);
while (data_in());
data_high();
atn_low();
iec_writeb(dev);
if (sec != 0xff)
iec_writeb(sec);
atn_true();
}
@ -182,7 +238,7 @@ void iec_talk(char dev, char sec)
iec_status = IEC_OK;
iec_atn(dev | 0x40, sec | 0x60);
clock_low();
clock_true();
delay(10);
}
@ -201,7 +257,25 @@ void iec_listen(char dev, char sec)
void iec_unlisten(void)
{
__asm
{
php
sei
}
if (iec_status == IEC_QUEUED)
{
iec_eoib();
iec_writeb(iec_queue);
}
iec_atn(0x3f, 0xff);
clock_true();
__asm
{
plp
}
}
void iec_open(char dev, char sec, const char * fname)
@ -213,8 +287,6 @@ void iec_open(char dev, char sec, const char * fname)
char i = 0;
while (fname[i])
{
if (!fname[i + 1])
iec_eoi();
iec_write(fname[i]);
i++;
}

View File

@ -5,6 +5,7 @@ enum IEC_STATUS
{
IEC_OK = 0x00,
IEC_EOF = 0x01,
IEC_QUEUED = 0x02,
IEC_ERROR = 0x80,
IEC_TIMEOUT,
@ -13,8 +14,6 @@ enum IEC_STATUS
extern IEC_STATUS iec_status;
bool iec_eoi(void);
bool iec_write(char b);
char iec_read(void);

View File

@ -14136,6 +14136,157 @@ bool SameExitCondition(InterCodeBasicBlock* b1, InterCodeBasicBlock* b2)
return false;
}
InterCodeBasicBlock* InterCodeBasicBlock::CheckIsConstBranch(const GrowingInstructionPtrArray& cins)
{
if (!mFalseJump || mInstructions.Size() < 1 || mInstructions[mInstructions.Size() - 1]->mCode != IC_BRANCH)
return nullptr;
GrowingInstructionPtrArray tins(cins);
for (int i = 0; i < mInstructions.Size() - 1; i++)
{
InterInstruction* ins(mInstructions[i]);
InterInstruction* nins = nullptr;
if (IsObservable(ins->mCode))
return nullptr;
if (ins->mDst.mTemp >= 0)
{
if (ins->mCode == IC_CONSTANT)
nins = ins;
else if (ins->mCode == IC_LOAD && !ins->mVolatile)
{
int k = 0;
while (k < tins.Size() && !(tins[k]->mCode == IC_STORE && SameMemAndSize(ins->mSrc[0], tins[k]->mSrc[1])))
k++;
if (k < tins.Size())
{
nins = new InterInstruction(ins->mLocation, IC_CONSTANT);
nins->mDst = ins->mDst;
nins->mConst = tins[k]->mSrc[0];
}
}
if (ins->mDst.mTemp >= 0)
{
int k = 0;
while (k < tins.Size() && tins[k]->mDst.mTemp != ins->mDst.mTemp)
k++;
if (k < tins.Size())
tins.Remove(k);
}
if (nins)
tins.Push(nins);
}
}
InterInstruction* bins = mInstructions[mInstructions.Size() - 1];
int k = 0;
while (k < tins.Size() && tins[k]->mDst.mTemp != bins->mSrc[0].mTemp)
k++;
if (k < tins.Size() && tins[k]->mCode == IC_CONSTANT)
{
InterCodeBasicBlock* tblock = tins[k]->mConst.mIntConst ? mTrueJump : mFalseJump;
InterCodeBasicBlock* xblock = this->Clone();
InterInstruction* bins = xblock->mInstructions.Pop();
InterInstruction* jins = new InterInstruction(bins->mLocation, IC_JUMP);
xblock->mInstructions.Push(jins);
xblock->mTrueJump = tblock;
tblock->mEntryBlocks.Push(xblock);
tblock->mNumEntries++;
return xblock;
}
return nullptr;
}
bool InterCodeBasicBlock::ShortcutConstBranches(const GrowingInstructionPtrArray& cins)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
GrowingInstructionPtrArray tins(cins);
if (mNumEntries > 1)
tins.SetSize(0);
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins(mInstructions[i]);
InterInstruction* nins = nullptr;
if (ins->mCode == IC_CONSTANT)
nins = ins;
else
{
if (IsObservable(ins->mCode))
{
int k = 0;
while (k < tins.Size())
{
if (tins[k]->mCode == IC_STORE && DestroyingMem(tins[k], ins))
tins.Remove(k);
else
k++;
}
}
if (ins->mCode == IC_STORE && !ins->mVolatile && ins->mSrc[0].mTemp < 0)
nins = ins;
}
if (ins->mDst.mTemp >= 0)
{
int k = 0;
while (k < tins.Size() && tins[k]->mDst.mTemp != ins->mDst.mTemp)
k++;
if (k < tins.Size())
tins.Remove(k);
}
if (nins)
tins.Push(nins);
}
if (mTrueJump)
{
InterCodeBasicBlock* tblock = mTrueJump->CheckIsConstBranch(tins);
if (tblock)
{
mTrueJump->mEntryBlocks.RemoveAll(this);
mTrueJump->mNumEntries--;
tblock->mEntryBlocks.Push(this);
tblock->mNumEntries++;
mTrueJump = tblock;
}
if (mTrueJump->ShortcutConstBranches(tins))
changed = true;
}
if (mFalseJump)
{
InterCodeBasicBlock* tblock = mFalseJump->CheckIsConstBranch(tins);
if (tblock)
{
mFalseJump->mEntryBlocks.RemoveAll(this);
mFalseJump->mNumEntries--;
tblock->mEntryBlocks.Push(this);
tblock->mNumEntries++;
mFalseJump = tblock;
}
if (mFalseJump->ShortcutConstBranches(tins))
changed = true;
}
}
return changed;
}
bool InterCodeBasicBlock::MergeLoopTails(void)
{
bool modified = false;
@ -20143,6 +20294,22 @@ void InterCodeProcedure::CheckUsedDefinedTemps(void)
#endif
}
void InterCodeProcedure::ShortcutConstBranches(void)
{
GrowingInstructionPtrArray cins(nullptr);
BuildDataFlowSets();
TempForwarding();
RemoveUnusedInstructions();
do {
ResetVisited();
} while (mEntryBlock->ShortcutConstBranches(cins));
Disassemble("ShortcutConstBranches");
}
void InterCodeProcedure::MoveConditionsOutOfLoop(void)
{
BuildTraces(false);
@ -20831,7 +20998,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main");
CheckFunc = !strcmp(mIdent->mString, "read_decompress");
CheckCase = false;
mEntryBlock = mBlocks[0];
@ -21589,6 +21756,8 @@ void InterCodeProcedure::Close(void)
TempForwarding();
RemoveUnusedInstructions();
ShortcutConstBranches();
DisassembleDebug("Global Constant Prop 1");
BuildDataFlowSets();

View File

@ -604,6 +604,9 @@ public:
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
bool MergeLoopTails(void);
InterCodeBasicBlock* CheckIsConstBranch(const GrowingInstructionPtrArray& cins);
bool ShortcutConstBranches(const GrowingInstructionPtrArray& cins);
InterCodeBasicBlock* BuildLoopPrefix(void);
void BuildLoopSuffix(void);
@ -744,6 +747,7 @@ protected:
void WarnInvalidValueRanges(void);
void PropagateMemoryAliasingInfo(void);
void MoveConditionsOutOfLoop(void);
void ShortcutConstBranches(void);
void CollapseDispatch(void);

View File

@ -4293,7 +4293,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
mMode = ASMIM_IMPLIED;
changed = true;
}
else if (data.mRegs[CPU_REG_A].mMode == NRDM_UNKNOWN)
else if (final || data.mRegs[CPU_REG_A].mMode == NRDM_UNKNOWN)
{
data.ResetAbsolute(mLinkerObject, mAddress);
data.mRegs[CPU_REG_A].mMode = NRDM_ABSOLUTE;
@ -16678,6 +16678,47 @@ bool NativeCodeBasicBlock::GlobalSwapXY(void)
return changed;
}
bool NativeCodeBasicBlock::AlternateXXUsage(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
for (int i = 0; i + 3 < mIns.Size(); i++)
{
if (mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE_X &&
mIns[i + 2].mType == ASMIT_LDX && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ABSOLUTE_X &&
!(mIns[i + 3].mLive & LIVE_CPU_REG_Y))
{
mIns[i + 0].mType = ASMIT_LDY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
changed = true;
}
else if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y &&
mIns[i + 2].mType == ASMIT_LDY && mIns[i + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ABSOLUTE_Y &&
!(mIns[i + 3].mLive & LIVE_CPU_REG_X))
{
mIns[i + 0].mType = ASMIT_LDX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mMode = ASMIM_ABSOLUTE_X;
changed = true;
}
}
if (mTrueJump && mTrueJump->AlternateXXUsage())
changed = true;
if (mFalseJump && mFalseJump->AlternateXXUsage())
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::UntangleXYUsage(void)
{
bool changed = false;
@ -20001,6 +20042,32 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
}
if (mIns.Size() >= 3 && mFalseJump && (mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE))
{
int sz = mIns.Size();
if ((mIns[sz - 3].mType == ASMIT_INC || mIns[sz - 3].mType == ASMIT_DEC) &&
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].SameEffectiveAddress(mIns[sz - 3]) &&
mIns[sz - 1].mType == ASMIT_ORA &&
!(mIns[sz - 1].mLive & LIVE_CPU_REG_A))
{
mIns[sz - 3].mLive |= LIVE_CPU_REG_Z;
NativeCodeBasicBlock* tblock = this->SplitAt(sz - 2);
if (tblock->mBranch == ASMIT_BEQ)
mTrueJump = tblock->mFalseJump;
else
mTrueJump = tblock->mTrueJump;
mBranch = ASMIT_BNE;
mFalseJump = tblock;
mTrueJump->mNumEntries++;
mTrueJump->mEntryBlocks.Push(this);
changed = true;
}
}
if (mIns.Size() >= 8 && mFalseJump && (mBranch == ASMIT_BNE || mBranch == ASMIT_BEQ))
{
int sz = mIns.Size();
@ -20235,6 +20302,33 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
}
#endif
// Simple diamond split
if (mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump && mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 1)
{
if (mBranch == ASMIT_BCC || mBranch == ASMIT_BCS)
{
if (mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1)
{
if (mTrueJump->mIns[0].mType == ASMIT_AND && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
mFalseJump->mIns[0].mType == ASMIT_ORA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
(mTrueJump->mIns[0].mAddress ^ mFalseJump->mIns[0].mAddress) == 0xff)
{
mIns.Push(mTrueJump->mIns[0]);
mTrueJump->mIns.SetSize(0);
changed = true;
}
else if (mTrueJump->mIns[0].mType == ASMIT_ORA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
mFalseJump->mIns[0].mType == ASMIT_AND && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
(mTrueJump->mIns[0].mAddress ^ mFalseJump->mIns[0].mAddress) == 0xff)
{
mIns.Push(mTrueJump->mIns[0]);
mTrueJump->mIns.SetSize(0);
changed = true;
}
}
}
}
if (mFalseJump && mTrueJump->mTrueJump == mFalseJump && !mTrueJump->mFalseJump && mTrueJump->mNumEntries == 1)
{
int sz = mIns.Size();
@ -34760,6 +34854,58 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
}
}
si = 0, ei = mIns.Size() - 1;
while (si < mIns.Size() && !mIns[si].ReferencesXReg())
si++;
while (ei > si && !(mIns[ei].ChangesXReg() || mIns[ei].mType == ASMIT_STX))
ei--;
if (si < ei && mIns[si].mType == ASMIT_LDX && mIns[ei].mType == ASMIT_STX && mIns[si].mMode == ASMIM_ZERO_PAGE && mIns[ei].mMode == ASMIM_ZERO_PAGE && mIns[si].mAddress == mIns[ei].mAddress)
{
int i = 0;
while (i < si && !mIns[i].ChangesZeroPage(mIns[si].mAddress))
i++;
if (i == si)
{
i = ei + 1;
while (i < mIns.Size() && !mIns[i].ChangesZeroPage(mIns[si].mAddress))
i++;
if (i == mIns.Size())
{
if (!prevBlock)
return OptimizeSimpleLoopInvariant(proc, full);
i = 0;
while (i < si)
{
mIns[i].mLive |= LIVE_CPU_REG_X;
i++;
}
i = ei;
while (i < mIns.Size())
{
mIns[i].mLive |= LIVE_CPU_REG_X;
i++;
}
prevBlock->mIns.Push(mIns[si]);
mIns.Remove(si);
mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
CheckLive();
return true;
}
}
}
si = 0;
ei = mIns.Size() - 1;
while (si < mIns.Size() && !mIns[si].ReferencesXReg())
@ -43065,6 +43211,27 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mMode = ASMIM_ABSOLUTE_X;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_TAX &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE_X &&
mIns[i + 2].mType == ASMIT_TAX && !(mIns[i + 2].mLive & LIVE_CPU_REG_Y))
{
mIns[i + 0].mType = ASMIT_TAY; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mType = ASMIT_LDX; mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_TAY &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y &&
mIns[i + 2].mType == ASMIT_TAY && !(mIns[i + 2].mLive & LIVE_CPU_REG_X))
{
mIns[i + 0].mType = ASMIT_TAX; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mMode = ASMIM_ABSOLUTE_X; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
(mIns[i + 0].mType == ASMIT_INX || mIns[i + 0].mType == ASMIT_DEX) &&
@ -44727,6 +44894,34 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
}
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_STY &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_LDA &&
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
{
mIns[i + 3].CopyMode(mIns[i + 2]);
mIns[i + 2].mType = ASMIT_TYA;
mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_STX &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_LDA &&
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
{
mIns[i + 3].CopyMode(mIns[i + 2]);
mIns[i + 2].mType = ASMIT_TXA;
mIns[i + 2].mMode = ASMIM_IMPLIED;
mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mLive |= LIVE_CPU_REG_X;
progress = true;
}
#endif
@ -47951,12 +48146,23 @@ void NativeCodeBasicBlock::ShortcutTailRecursion()
if (!mVisited)
{
mVisited = true;
if (!mFalseJump && mTrueJump && mTrueJump->mIns.Size() == 1 && mTrueJump->mIns[0].mType == ASMIT_RTS && mIns.Size() > 0 && mIns.Last().IsSimpleJSR())
if (!mFalseJump && mTrueJump && mTrueJump->mIns.Size() == 1 && mTrueJump->mIns[0].mType == ASMIT_RTS)
{
this->mCode[this->mCode.Size() - 3] = 0x4c;
mTrueJump->mNumEntries--;
mTrueJump = nullptr;
ShortcutJump(this->mCode.Size() - 3);
if (mIns.Size() > 0 && mIns.Last().IsSimpleJSR())
{
this->mCode[this->mCode.Size() - 3] = 0x4c;
mTrueJump->mNumEntries--;
mTrueJump = nullptr;
ShortcutJump(this->mCode.Size() - 3);
}
#if 0
else
{
this->mCode.Push(0x60);
mTrueJump->mNumEntries--;
mTrueJump = nullptr;
}
#endif
}
else if (!mFalseJump && !mTrueJump)
{
@ -48293,7 +48499,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc = proc;
mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "read_decompress");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "flossiec_read_lzo");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -48829,7 +49035,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
void NativeCodeProcedure::Assemble(void)
{
CheckFunc = !strcmp(mInterProc->mIdent->mString, "longor");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "data_check");
if (mInterProc->mCompilerOptions & COPT_OPTIMIZE_MERGE_CALLS)
{
@ -49362,7 +49568,7 @@ void NativeCodeProcedure::Optimize(void)
CheckBlocks();
#if 1
if (step == 3 || step == 4)
if (step == 3 || step == 4 || (step == 15 && cnt > 0))
{
#if 1
ResetVisited();
@ -49874,7 +50080,22 @@ void NativeCodeProcedure::Optimize(void)
}
#endif
if (step == 15)
#if 1
if (step == 15 && cnt == 0)
{
ResetVisited();
mEntryBlock->RemoveUnusedResultInstructions();
BuildDataFlowSets();
ResetVisited();
if (mEntryBlock->AlternateXXUsage())
changed = true;
}
#endif
if (step == 16)
{
if (mInterProc->mCompilerOptions & COPT_OPTIMIZE_INLINE)
{
@ -49903,7 +50124,7 @@ void NativeCodeProcedure::Optimize(void)
}
#if 1
if (!changed && step < 15)
if (!changed && step < 16)
{
ResetIndexFlipped();

View File

@ -673,6 +673,7 @@ public:
bool GlobalSwapXY(void);
bool LocalSwapXY(void);
bool UntangleXYUsage(void);
bool AlternateXXUsage(void);
bool IsSimpleSubExpression(int at, NativeSimpleSubExpression & ex);
bool PropagateCommonSubExpression(void);

View File

@ -3307,7 +3307,7 @@ void Parser::PrependThisArgument(Declaration* fdec, Declaration* pthis)
{
Declaration* adec = new Declaration(fdec->mLocation, DT_ARGUMENT);
if (fdec->mBase->mType == DT_TYPE_STRUCT)
if (fdec->mBase && fdec->mBase->mType == DT_TYPE_STRUCT)
adec->mVarIndex = 2;
else
adec->mVarIndex = 0;
@ -5103,7 +5103,10 @@ Expression* Parser::ParseLambdaExpression(void)
cdec->mParams = mdec;
}
else
{
mErrors->Error(mScanner->mLocation, ERRO_THIS_OUTSIDE_OF_METHOD, "Use of this outside of method");
mdec->mBase = TheVoidTypeDeclaration;
}
mdec->mOffset = cdec->mSize;
mdec->mSize = mdec->mBase->mSize;
@ -8651,7 +8654,9 @@ Expression* Parser::ParseFunction(Declaration * dec)
}
}
if (dec->mBase->mType == DT_TYPE_AUTO)
if (!dec->mBase)
dec->mBase = TheVoidTypeDeclaration;
else if (dec->mBase->mType == DT_TYPE_AUTO)
dec->mBase->mType = DT_TYPE_VOID;
mScope->End(mScanner->mLocation);