Merge changes for Mac build

This commit is contained in:
drmortalwombat 2021-09-27 13:38:45 +02:00
parent bffef3e9dd
commit 9eb5412848
9 changed files with 878 additions and 26 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
} }

View File

@ -302,7 +302,7 @@ public:
Location mLocation; Location mLocation;
LinkerObject * mLinkerObject; LinkerObject * mLinkerObject;
bool mInUse, mInvariant; bool mInUse, mInvariant, mVolatile;
InterInstruction(void); InterInstruction(void);

View File

@ -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);
@ -324,17 +326,22 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
} }
else if (aexp->mType == DT_LABEL) else if (aexp->mType == DT_LABEL)
{ {
if (!aexp->mBase->mLinkerObject) if (aexp->mBase)
TranslateAssembler(mod, aexp->mBase->mValue); {
if (!aexp->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mValue);
LinkerReference ref; LinkerReference ref;
ref.mObject = dec->mLinkerObject; ref.mObject = dec->mLinkerObject;
ref.mOffset = offset; ref.mOffset = offset;
ref.mHighByte = true; ref.mHighByte = true;
ref.mLowByte = true; ref.mLowByte = true;
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;
} }

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
} }