Merge changes for Mac build
This commit is contained in:
parent
bffef3e9dd
commit
9eb5412848
|
@ -3,8 +3,8 @@
|
||||||
sources = $(wildcard ../oscar64/*.cpp)
|
sources = $(wildcard ../oscar64/*.cpp)
|
||||||
objects = $(patsubst ../oscar64/%.cpp,%.o,$(sources))
|
objects = $(patsubst ../oscar64/%.cpp,%.o,$(sources))
|
||||||
|
|
||||||
CXX = g++
|
CXX = c++
|
||||||
CPPFLAGS = -g -O2
|
CPPFLAGS = -g -O2 -std=c++11 -Wno-switch
|
||||||
|
|
||||||
|
|
||||||
ifdef WINDIR
|
ifdef WINDIR
|
||||||
|
@ -21,7 +21,7 @@ else
|
||||||
endif
|
endif
|
||||||
|
|
||||||
%.o: ../oscar64/%.cpp
|
%.o: ../oscar64/%.cpp
|
||||||
g++ -c $(CPPFLAGS) $< -o $@
|
$(CXX) -c $(CPPFLAGS) $< -o $@
|
||||||
|
|
||||||
%.d: ../oscar64/%.cpp
|
%.d: ../oscar64/%.cpp
|
||||||
@set -e; rm -f $@; \
|
@set -e; rm -f $@; \
|
||||||
|
@ -30,10 +30,16 @@ endif
|
||||||
rm -f $@.$$$$
|
rm -f $@.$$$$
|
||||||
|
|
||||||
../bin/oscar64 : $(objects)
|
../bin/oscar64 : $(objects)
|
||||||
g++ $(CPPFLAGS) $(linklibs) $(objects) -o ../bin/oscar64
|
$(CXX) $(CPPFLAGS) $(linklibs) $(objects) -o ../bin/oscar64
|
||||||
|
|
||||||
.PHONY : clean
|
.PHONY : clean
|
||||||
clean :
|
clean :
|
||||||
-rm *.o *.d
|
-rm *.o *.d oscar64
|
||||||
|
|
||||||
|
ifeq ($(UNAME_S), Darwin)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
include $(objects:.o=.d)
|
include $(objects:.o=.d)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
|
@ -2473,7 +2473,7 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case IC_RELATIONAL_OPERATOR:
|
case IC_RELATIONAL_OPERATOR:
|
||||||
if (sblock->mInstructions[i + 1]->mCode == IC_BRANCH && sblock->mInstructions[i + 1]->mSFinal[0])
|
if (i + 1 < sblock->mInstructions.Size() && sblock->mInstructions[i + 1]->mCode == IC_BRANCH && sblock->mInstructions[i + 1]->mSFinal[0])
|
||||||
{
|
{
|
||||||
ByteCode code = RelationalOperator(iproc, ins);
|
ByteCode code = RelationalOperator(iproc, ins);
|
||||||
this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), proc->CompileBlock(iproc, sblock->mFalseJump), code);
|
this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), proc->CompileBlock(iproc, sblock->mFalseJump), code);
|
||||||
|
|
|
@ -1019,6 +1019,7 @@ InterInstruction::InterInstruction(void)
|
||||||
|
|
||||||
mSFinal[0] = mSFinal[1] = mSFinal[2] = false;
|
mSFinal[0] = mSFinal[1] = mSFinal[2] = false;
|
||||||
mInUse = false;
|
mInUse = false;
|
||||||
|
mVolatile = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterInstruction::SetCode(const Location& loc, InterCode code)
|
void InterInstruction::SetCode(const Location& loc, InterCode code)
|
||||||
|
@ -3115,7 +3116,7 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(void)
|
||||||
ins->mInvariant = false;
|
ins->mInvariant = false;
|
||||||
else if (ins->mCode == IC_LOAD)
|
else if (ins->mCode == IC_LOAD)
|
||||||
{
|
{
|
||||||
if (ins->mSTemp[0] >= 0)
|
if (ins->mSTemp[0] >= 0 || ins->mVolatile)
|
||||||
{
|
{
|
||||||
ins->mInvariant = false;
|
ins->mInvariant = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,7 +302,7 @@ public:
|
||||||
Location mLocation;
|
Location mLocation;
|
||||||
LinkerObject * mLinkerObject;
|
LinkerObject * mLinkerObject;
|
||||||
|
|
||||||
bool mInUse, mInvariant;
|
bool mInUse, mInvariant, mVolatile;
|
||||||
|
|
||||||
InterInstruction(void);
|
InterInstruction(void);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
||||||
ins->mTType = v.mReference == 1 ? InterTypeOf(v.mType) : IT_POINTER;
|
ins->mTType = v.mReference == 1 ? InterTypeOf(v.mType) : IT_POINTER;
|
||||||
ins->mTTemp = proc->AddTemporary(ins->mTType);
|
ins->mTTemp = proc->AddTemporary(ins->mTType);
|
||||||
ins->mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
|
ins->mOperandSize = v.mReference == 1 ? v.mType->mSize : 2;
|
||||||
|
if (v.mType->mFlags & DTF_VOLATILE)
|
||||||
|
ins->mVolatile = true;
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
|
|
||||||
v = ExValue(v.mType, ins->mTTemp, v.mReference - 1);
|
v = ExValue(v.mType, ins->mTTemp, v.mReference - 1);
|
||||||
|
@ -323,6 +325,8 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
||||||
d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8;
|
d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8;
|
||||||
}
|
}
|
||||||
else if (aexp->mType == DT_LABEL)
|
else if (aexp->mType == DT_LABEL)
|
||||||
|
{
|
||||||
|
if (aexp->mBase)
|
||||||
{
|
{
|
||||||
if (!aexp->mBase->mLinkerObject)
|
if (!aexp->mBase->mLinkerObject)
|
||||||
TranslateAssembler(mod, aexp->mBase->mValue);
|
TranslateAssembler(mod, aexp->mBase->mValue);
|
||||||
|
@ -335,6 +339,9 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
||||||
ref.mRefObject = aexp->mBase->mLinkerObject;
|
ref.mRefObject = aexp->mBase->mLinkerObject;
|
||||||
ref.mRefOffset = aexp->mInteger;
|
ref.mRefOffset = aexp->mInteger;
|
||||||
mLinker->AddReference(ref);
|
mLinker->AddReference(ref);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label");
|
||||||
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,17 @@ typedef unsigned short uint16;
|
||||||
typedef unsigned int uint32;
|
typedef unsigned int uint32;
|
||||||
typedef signed char int8;
|
typedef signed char int8;
|
||||||
typedef signed short int16;
|
typedef signed short int16;
|
||||||
typedef signed short int32;
|
typedef signed int int32;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef __int64 int64;
|
typedef __int64 int64;
|
||||||
typedef unsigned __int64 uint64;
|
typedef unsigned __int64 uint64;
|
||||||
#define MAXPATHLEN _MAX_PATH
|
#define MAXPATHLEN _MAX_PATH
|
||||||
#else
|
#else
|
||||||
|
#if __APPLE__
|
||||||
|
#include "limits.h"
|
||||||
|
#else /* __linux__ */
|
||||||
#include "linux/limits.h"
|
#include "linux/limits.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef long long int64;
|
typedef long long int64;
|
||||||
typedef unsigned long long uint64;
|
typedef unsigned long long uint64;
|
||||||
|
|
|
@ -546,6 +546,650 @@ bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeInstruction::ApplySimulation(const NativeRegisterDataSet& data)
|
||||||
|
{
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ASMIT_LDA:
|
||||||
|
case ASMIT_LDX:
|
||||||
|
case ASMIT_LDY:
|
||||||
|
case ASMIT_CMP:
|
||||||
|
case ASMIT_CPX:
|
||||||
|
case ASMIT_CPY:
|
||||||
|
if (mMode == ASMIM_ZERO_PAGE && data.mRegs[mAddress].mImmediate)
|
||||||
|
{
|
||||||
|
mMode = ASMIM_IMMEDIATE;
|
||||||
|
mAddress = data.mRegs[mAddress].mValue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data)
|
||||||
|
{
|
||||||
|
int reg = -1;
|
||||||
|
if (mMode == ASMIM_ZERO_PAGE)
|
||||||
|
reg = mAddress;
|
||||||
|
else if (mMode == ASMIM_IMPLIED)
|
||||||
|
reg = CPU_REG_A;
|
||||||
|
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case ASMIT_JSR:
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_X].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Y].mImmediate = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
data.mRegs[BC_REG_ACCU + i].mImmediate = false;
|
||||||
|
data.mRegs[BC_REG_WORK + i].mImmediate = false;
|
||||||
|
data.mRegs[BC_REG_ADDR + i].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_ROL:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_C].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue << 1) | data.mRegs[CPU_REG_C].mValue;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[reg].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_ROR:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_C].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue >> 1) | (data.mRegs[CPU_REG_C].mValue << 7);
|
||||||
|
data.mRegs[CPU_REG_C].mValue = data.mRegs[reg].mValue & 1;
|
||||||
|
data.mRegs[reg].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_ASL:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue << 1);
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[reg].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_LSR:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue >> 1);
|
||||||
|
data.mRegs[CPU_REG_C].mValue = data.mRegs[reg].mValue & 1;
|
||||||
|
data.mRegs[reg].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_INC:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mValue = (data.mRegs[reg].mValue + 1) & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[reg].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_DEC:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mValue = (data.mRegs[reg].mValue + 1) & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[reg].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_ADC:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_C].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue + data.mRegs[CPU_REG_A].mValue + data.mRegs[CPU_REG_C].mValue;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_SBC:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_C].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_A].mValue + data.mRegs[CPU_REG_C].mValue;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_AND:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue & data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else if ((data.mRegs[reg].mImmediate && data.mRegs[reg].mValue == 0) || (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == 0))
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mValue = 0;
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = 0;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_ORA:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue | data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else if ((data.mRegs[reg].mImmediate && data.mRegs[reg].mValue == 0xff) || (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == 0xff))
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mValue = 0xff;
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = 0xff;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_EOR:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue | data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_INX:
|
||||||
|
if (data.mRegs[CPU_REG_X].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mValue = (data.mRegs[CPU_REG_X].mValue + 1) & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_DEX:
|
||||||
|
if (data.mRegs[CPU_REG_X].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mValue = (data.mRegs[CPU_REG_X].mValue - 1) & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_INY:
|
||||||
|
if (data.mRegs[CPU_REG_Y].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = (data.mRegs[CPU_REG_Y].mValue + 1) & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_DEY:
|
||||||
|
if (data.mRegs[CPU_REG_Y].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = (data.mRegs[CPU_REG_Y].mValue - 1) & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_TXA:
|
||||||
|
if (data.mRegs[CPU_REG_X].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_TYA:
|
||||||
|
if (data.mRegs[CPU_REG_Y].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_TAX:
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_TAY:
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_CMP:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_A].mValue + 1;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_CPX:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_X].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_X].mValue + 1;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_CPY:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate && data.mRegs[CPU_REG_Y].mImmediate)
|
||||||
|
{
|
||||||
|
int t = (data.mRegs[reg].mValue ^ 0xff) + data.mRegs[CPU_REG_Y].mValue + 1;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = t >= 256;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t & 255;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_LDA:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = t;
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_LDX:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue;
|
||||||
|
data.mRegs[CPU_REG_X].mValue = t;
|
||||||
|
data.mRegs[CPU_REG_X].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_X].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_X].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_LDY:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[reg].mImmediate)
|
||||||
|
{
|
||||||
|
int t = data.mRegs[reg].mValue;
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = t;
|
||||||
|
data.mRegs[CPU_REG_Y].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = t;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_Y].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Y].mImmediate = false;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_STA:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
data.mRegs[reg].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_STX:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[CPU_REG_X].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mValue = data.mRegs[CPU_REG_X].mValue;
|
||||||
|
data.mRegs[reg].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_STY:
|
||||||
|
if (reg >= 0)
|
||||||
|
{
|
||||||
|
if (data.mRegs[CPU_REG_Y].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mValue = data.mRegs[CPU_REG_Y].mValue;
|
||||||
|
data.mRegs[reg].mImmediate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[reg].mImmediate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -4169,6 +4813,73 @@ void NativeCodeBasicBlock::CollectEntryBlocks(NativeCodeBasicBlock* block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeCodeBasicBlock::BuildEntryDataSet(const NativeRegisterDataSet& set)
|
||||||
|
{
|
||||||
|
if (!mVisited)
|
||||||
|
mEntryRegisterDataSet = set;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
|
{
|
||||||
|
if (set.mRegs[i].mImmediate)
|
||||||
|
{
|
||||||
|
if (mEntryRegisterDataSet.mRegs[i].mImmediate && set.mRegs[i].mValue != mEntryRegisterDataSet.mRegs[i].mValue)
|
||||||
|
{
|
||||||
|
mEntryRegisterDataSet.mRegs[i].mImmediate = false;
|
||||||
|
mVisited = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mEntryRegisterDataSet.mRegs[i].mImmediate)
|
||||||
|
{
|
||||||
|
mEntryRegisterDataSet.mRegs[i].mImmediate = false;
|
||||||
|
mVisited = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
NativeRegisterDataSet nset = mEntryRegisterDataSet;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
mIns[i].Simulate(nset);
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->BuildEntryDataSet(nset);
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->BuildEntryDataSet(nset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::ApplyEntryDataSet(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
NativeRegisterDataSet nset = mEntryRegisterDataSet;
|
||||||
|
|
||||||
|
for (int i = 0; i < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].ApplySimulation(nset))
|
||||||
|
changed = true;
|
||||||
|
mIns[i].Simulate(nset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->ApplyEntryDataSet())
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->ApplyEntryDataSet())
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::SameTail(const NativeCodeInstruction& ins) const
|
bool NativeCodeBasicBlock::SameTail(const NativeCodeInstruction& ins) const
|
||||||
{
|
{
|
||||||
if (mIns.Size() > 0)
|
if (mIns.Size() > 0)
|
||||||
|
@ -4544,6 +5255,67 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mIns[sz - 3].mType == ASMIT_INC && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
||||||
|
mIns[sz - 1].mType == ASMIT_CMP && mIns[sz - 1].mMode == ASMIM_ZERO_PAGE && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_X | LIVE_CPU_REG_Y)) &&
|
||||||
|
mBranch == ASMIT_BCC)
|
||||||
|
{
|
||||||
|
// check for usage of Y register
|
||||||
|
|
||||||
|
bool yother = false, yindex = false, lchanged = false;
|
||||||
|
int lreg = mIns[sz - 1].mAddress;
|
||||||
|
int zreg = mIns[sz - 3].mAddress;
|
||||||
|
|
||||||
|
for (int i = 0; i < sz - 4; i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].ChangesAddress())
|
||||||
|
lchanged = true;
|
||||||
|
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
||||||
|
yother = true;
|
||||||
|
else if (mIns[i].mType == ASMIT_LDY)
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
yindex = true;
|
||||||
|
else
|
||||||
|
yother = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDX && mIns[i].mAddress == zreg)
|
||||||
|
yother = true;
|
||||||
|
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
||||||
|
yother = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yother && !lchanged)
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
for (int i = 0; i + 3 < sz; i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType != ASMIT_LDY)
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
|
else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
||||||
|
}
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_ZERO_PAGE, lreg));
|
||||||
|
lblock->mBranch = mBranch;
|
||||||
|
lblock->mTrueJump = lblock;
|
||||||
|
lblock->mFalseJump = eblock;
|
||||||
|
|
||||||
|
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STY, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
eblock->mBranch = ASMIT_JMP;
|
||||||
|
eblock->mTrueJump = mFalseJump;
|
||||||
|
eblock->mFalseJump = nullptr;
|
||||||
|
|
||||||
|
mIns.Clear();
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump = lblock;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4675,6 +5447,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
mIns[i + 0].mLive |= LIVE_CPU_REG_Z;
|
mIns[i + 0].mLive |= LIVE_CPU_REG_Z;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 0].mLive & LIVE_CPU_REG_A))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_STA;
|
||||||
|
mIns[i + 0].mType = ASMIT_ASL;
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
|
@ -4754,11 +5535,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 2].mType = ASMIT_NOP;
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress &&
|
||||||
|
mIns[i + 1].mType == ASMIT_DEC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 0].mAddress &&
|
||||||
|
!(mIns[i + 2].mLive & (LIVE_CPU_REG_C | LIVE_MEM)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_SEC; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_SBC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 1;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
if (
|
if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA &&
|
mIns[i + 1].mType == ASMIT_LDA &&
|
||||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Y)))
|
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & LIVE_MEM))
|
||||||
{
|
{
|
||||||
int apos, breg, ireg;
|
int apos, breg, ireg;
|
||||||
if (FindAddressSumY(i, mIns[i + 2].mAddress, apos, breg, ireg))
|
if (FindAddressSumY(i, mIns[i + 2].mAddress, apos, breg, ireg))
|
||||||
|
@ -4770,6 +5562,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[apos + 6].mType = ASMIT_NOP;
|
mIns[apos + 6].mType = ASMIT_NOP;
|
||||||
mIns[apos + 6].mMode = ASMIM_IMPLIED;
|
mIns[apos + 6].mMode = ASMIM_IMPLIED;
|
||||||
}
|
}
|
||||||
|
if (mIns[i + 2].mLive & LIVE_CPU_REG_Y)
|
||||||
|
{
|
||||||
|
mIns.Insert(i + 3, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
}
|
||||||
if (mIns[i + 1].mMode != ASMIM_INDIRECT_Y && mIns[i + 1].mMode != ASMIM_ABSOLUTE_Y)
|
if (mIns[i + 1].mMode != ASMIM_INDIRECT_Y && mIns[i + 1].mMode != ASMIM_ABSOLUTE_Y)
|
||||||
{
|
{
|
||||||
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
|
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
|
||||||
|
@ -4801,6 +5598,28 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 3].mType = ASMIT_INC;
|
mIns[i + 3].mType = ASMIT_INC;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_SEC && mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
|
||||||
|
(mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
(mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mType = ASMIT_DEC;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff)== 0xff &&
|
||||||
|
(mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
(mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mType = ASMIT_DEC;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4880,7 +5699,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BypassEmptyBlocks(void)
|
||||||
{
|
{
|
||||||
if (mBypassed)
|
if (mBypassed)
|
||||||
return this;
|
return this;
|
||||||
else if (!mFalseJump && mCode.Size() == 0)
|
else if (!mFalseJump && mCode.Size() == 0 && this != mTrueJump)
|
||||||
return mTrueJump->BypassEmptyBlocks();
|
return mTrueJump->BypassEmptyBlocks();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4931,7 +5750,7 @@ void NativeCodeBasicBlock::CopyCode(NativeCodeProcedure * proc, uint8* target)
|
||||||
}
|
}
|
||||||
else if (mTrueJump)
|
else if (mTrueJump)
|
||||||
{
|
{
|
||||||
if (mTrueJump->mOffset != next)
|
if (mTrueJump == this || mTrueJump->mOffset != next)
|
||||||
{
|
{
|
||||||
next += PutJump(proc, mTrueJump->mOffset - next);
|
next += PutJump(proc, mTrueJump->mOffset - next);
|
||||||
}
|
}
|
||||||
|
@ -5286,6 +6105,14 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
if (entryBlock->JoinTailCodeSequences())
|
if (entryBlock->JoinTailCodeSequences())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
NativeRegisterDataSet data;
|
||||||
|
entryBlock->BuildEntryDataSet(data);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
if (entryBlock->ApplyEntryDataSet())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5510,7 +6337,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case IC_RELATIONAL_OPERATOR:
|
case IC_RELATIONAL_OPERATOR:
|
||||||
if (iblock->mInstructions[i + 1]->mCode == IC_BRANCH && iblock->mInstructions[i + 1]->mSFinal[0])
|
if (i + 1 < iblock->mInstructions.Size() && iblock->mInstructions[i + 1]->mCode == IC_BRANCH && iblock->mInstructions[i + 1]->mSFinal[0])
|
||||||
{
|
{
|
||||||
block->RelationalOperator(iproc, ins, this, CompileBlock(iproc, iblock->mTrueJump), CompileBlock(iproc, iblock->mFalseJump));
|
block->RelationalOperator(iproc, ins, this, CompileBlock(iproc, iblock->mTrueJump), CompileBlock(iproc, iblock->mFalseJump));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct NativeRegisterDataSet
|
||||||
void ResetZeroPage(int addr);
|
void ResetZeroPage(int addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const uint32 NCIF_LOWER = 0x00000001;
|
static const uint32 NCIF_LOWER = 0x00000001;
|
||||||
static const uint32 NCIF_UPPER = 0x00000002;
|
static const uint32 NCIF_UPPER = 0x00000002;
|
||||||
static const uint32 NCIF_RUNTIME = 0x00000004;
|
static const uint32 NCIF_RUNTIME = 0x00000004;
|
||||||
|
@ -48,6 +49,8 @@ public:
|
||||||
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
||||||
bool ValueForwarding(NativeRegisterDataSet& data);
|
bool ValueForwarding(NativeRegisterDataSet& data);
|
||||||
|
|
||||||
|
void Simulate(NativeRegisterDataSet& data);
|
||||||
|
bool ApplySimulation(const NativeRegisterDataSet& data);
|
||||||
|
|
||||||
bool LoadsAccu(void) const;
|
bool LoadsAccu(void) const;
|
||||||
bool ChangesAccuAndFlag(void) const;
|
bool ChangesAccuAndFlag(void) const;
|
||||||
|
@ -141,6 +144,10 @@ public:
|
||||||
bool JoinTailCodeSequences(void);
|
bool JoinTailCodeSequences(void);
|
||||||
bool SameTail(const NativeCodeInstruction& ins) const;
|
bool SameTail(const NativeCodeInstruction& ins) const;
|
||||||
|
|
||||||
|
NativeRegisterDataSet mEntryRegisterDataSet;
|
||||||
|
|
||||||
|
void BuildEntryDataSet(const NativeRegisterDataSet& set);
|
||||||
|
bool ApplyEntryDataSet(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeProcedure
|
class NativeCodeProcedure
|
||||||
|
|
|
@ -1920,7 +1920,7 @@ Expression* Parser::ParseAssemblerAddOperand(void)
|
||||||
{
|
{
|
||||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
||||||
ndec->mBase = nexp->mLeft->mDecValue;
|
ndec->mBase = nexp->mLeft->mDecValue;
|
||||||
ndec->mOffset = int(nexp->mRight->mDecValue->mInteger);
|
ndec->mOffset = nexp->mToken == TK_SUB ? -int(nexp->mRight->mDecValue->mInteger) : int(nexp->mRight->mDecValue->mInteger);
|
||||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
exp->mDecValue = ndec;
|
exp->mDecValue = ndec;
|
||||||
}
|
}
|
||||||
|
@ -1933,7 +1933,7 @@ Expression* Parser::ParseAssemblerAddOperand(void)
|
||||||
{
|
{
|
||||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
||||||
ndec->mBase = nexp->mLeft->mDecValue;
|
ndec->mBase = nexp->mLeft->mDecValue;
|
||||||
ndec->mOffset = int(nexp->mRight->mDecValue->mInteger);
|
ndec->mOffset = nexp->mToken == TK_SUB ? -int(nexp->mRight->mDecValue->mInteger) : int(nexp->mRight->mDecValue->mInteger);
|
||||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
exp->mDecValue = ndec;
|
exp->mDecValue = ndec;
|
||||||
}
|
}
|
||||||
|
@ -1946,7 +1946,7 @@ Expression* Parser::ParseAssemblerAddOperand(void)
|
||||||
{
|
{
|
||||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_LABEL_REF);
|
Declaration* ndec = new Declaration(mScanner->mLocation, DT_LABEL_REF);
|
||||||
ndec->mBase = nexp->mLeft->mDecValue;
|
ndec->mBase = nexp->mLeft->mDecValue;
|
||||||
ndec->mOffset = int(nexp->mRight->mDecValue->mInteger);
|
ndec->mOffset = nexp->mToken == TK_SUB ? -int(nexp->mRight->mDecValue->mInteger) : int(nexp->mRight->mDecValue->mInteger);
|
||||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
exp->mDecValue = ndec;
|
exp->mDecValue = ndec;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue