Static call graph analysis for function arguments
This commit is contained in:
parent
761206d009
commit
02db5b5eb1
|
@ -83,6 +83,7 @@ The compiler is command line driven, and creates an executable .prg file.
|
|||
* -d64 : create a d64 disk image
|
||||
* -f : add a binary file to the disk image
|
||||
* -fz : add a compressed binary file to the disk image
|
||||
* -xz : extended zero page usage, more zero page space, but no return to basic
|
||||
|
||||
|
||||
A list of source files can be provided.
|
||||
|
|
|
@ -49,6 +49,22 @@ void Compiler::AddDefine(const Ident* ident, const char* value)
|
|||
|
||||
bool Compiler::ParseSource(void)
|
||||
{
|
||||
if (mCompilerOptions & COPT_EXTENDED_ZERO_PAGE)
|
||||
{
|
||||
BC_REG_FPARAMS = 0x0d;
|
||||
BC_REG_FPARAMS_END = 0x25;
|
||||
|
||||
BC_REG_IP = 0x25;
|
||||
BC_REG_ACCU = 0x27;
|
||||
BC_REG_ADDR = 0x2b;
|
||||
BC_REG_STACK = 0x2f;
|
||||
BC_REG_LOCALS = 0x31;
|
||||
#if 1
|
||||
BC_REG_TMP = 0x33;
|
||||
BC_REG_TMP_SAVED = 0x53;
|
||||
#endif
|
||||
}
|
||||
|
||||
mPreprocessor->mCompilerOptions = mCompilerOptions;
|
||||
mLinker->mCompilerOptions = mCompilerOptions;
|
||||
|
||||
|
@ -220,6 +236,8 @@ bool Compiler::GenerateCode(void)
|
|||
regionMain->mSections.Push(mCompilationUnits->mSectionStack);
|
||||
}
|
||||
|
||||
mInterCodeModule->InitParamStack(mCompilationUnits->mSectionStack);
|
||||
|
||||
dcrtstart->mSection = sectionStartup;
|
||||
|
||||
mGlobalAnalyzer->mCompilerOptions = mCompilerOptions;
|
||||
|
|
|
@ -12,6 +12,8 @@ static const uint64 COPT_OPTIMIZE_CONST_EXPRESSIONS = 0x00000080;
|
|||
|
||||
static const uint64 COPT_OPTIMIZE_CODE_SIZE = 0x00000100;
|
||||
|
||||
static const uint64 COPT_EXTENDED_ZERO_PAGE = 0x00010000;
|
||||
|
||||
static const uint64 COPT_TARGET_PRG = 0x100000000ULL;
|
||||
static const uint64 COPT_TARGET_CRT16 = 0x200000000ULL;
|
||||
static const uint64 COPT_TARGET_CRT512 = 0x400000000ULL;
|
||||
|
|
|
@ -797,7 +797,7 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
|
|||
sprintf_s(buffer, 10, "P%d", tmp - BC_REG_FPARAMS);
|
||||
return buffer;
|
||||
}
|
||||
else if (tmp >= BC_REG_LOCALS && tmp <= BC_REG_LOCALS + 3)
|
||||
else if (tmp >= BC_REG_LOCALS && tmp <= BC_REG_LOCALS + 1)
|
||||
{
|
||||
sprintf_s(buffer, 10, "FP + %d", tmp - BC_REG_LOCALS);
|
||||
return buffer;
|
||||
|
|
|
@ -156,25 +156,52 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec)
|
|||
nbase = 1000;
|
||||
}
|
||||
|
||||
int nparams = 0;
|
||||
int nparams = 0, npalign = 0;
|
||||
int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
|
||||
int fplimit = numfpzero;
|
||||
|
||||
if (!(procDec->mFlags & DTF_FUNC_INTRCALLED))
|
||||
fplimit += 256;
|
||||
|
||||
if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
if (nbase < numfpzero && nbase + 2 > numfpzero)
|
||||
nbase = numfpzero;
|
||||
nparams += 2;
|
||||
}
|
||||
|
||||
Declaration* dec = procDec->mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
// Check for paramter crossing boundary
|
||||
if (nbase + nparams < numfpzero && nbase + nparams + dec->mBase->mSize > numfpzero)
|
||||
{
|
||||
npalign = numfpzero - (nbase + nparams);
|
||||
nparams += npalign;
|
||||
}
|
||||
nparams += dec->mBase->mSize;
|
||||
dec = dec->mNext;
|
||||
}
|
||||
|
||||
if (nbase + nparams <= BC_REG_FPARAMS_END - BC_REG_FPARAMS)
|
||||
if (nbase + nparams <= fplimit)
|
||||
{
|
||||
procDec->mFastCallBase = nbase;
|
||||
procDec->mFastCallSize = nparams;
|
||||
procDec->mBase->mFastCallBase = nbase;
|
||||
procDec->mBase->mFastCallSize = nparams;
|
||||
|
||||
// Align fast call parameters to avoid crossing the zero page boundary
|
||||
if (npalign)
|
||||
{
|
||||
Declaration* dec = procDec->mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
if (nbase + dec->mVarIndex + dec->mBase->mSize > numfpzero)
|
||||
dec->mVarIndex += npalign;
|
||||
dec = dec->mNext;
|
||||
}
|
||||
}
|
||||
|
||||
procDec->mBase->mFlags |= DTF_FASTCALL;
|
||||
#if 0
|
||||
printf("FASTCALL %s\n", f->mIdent->mString);
|
||||
|
@ -410,16 +437,39 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
|
|||
return exp->mDecValue->mBase;
|
||||
case EX_CALL:
|
||||
ldec = Analyze(exp->mLeft, procDec);
|
||||
RegisterCall(procDec, ldec);
|
||||
if (!(GetProcFlags(ldec) & (DTF_FUNC_INTRSAVE | DTF_INTERRUPT)))
|
||||
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
|
||||
{
|
||||
procDec->mFlags &= ~DTF_FUNC_INTRSAVE;
|
||||
if (procDec->mFlags & DTF_INTERRUPT)
|
||||
mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mIdent);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
RegisterCall(procDec, ldec);
|
||||
if (!(GetProcFlags(ldec) & (DTF_FUNC_INTRSAVE | DTF_INTERRUPT)))
|
||||
{
|
||||
procDec->mFlags &= ~DTF_FUNC_INTRSAVE;
|
||||
if (procDec->mFlags & DTF_INTERRUPT)
|
||||
mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mIdent);
|
||||
}
|
||||
}
|
||||
|
||||
if (exp->mRight)
|
||||
{
|
||||
// Check for struct to struct forwarding
|
||||
Expression* rex = exp->mRight;
|
||||
while (rex)
|
||||
{
|
||||
Expression* pex = rex->mType == EX_LIST ? rex->mLeft : rex;
|
||||
|
||||
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT)
|
||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||
|
||||
if (rex->mType == EX_LIST)
|
||||
rex = rex->mRight;
|
||||
else
|
||||
rex = nullptr;
|
||||
}
|
||||
RegisterProc(Analyze(exp->mRight, procDec));
|
||||
}
|
||||
break;
|
||||
case EX_LIST:
|
||||
RegisterProc(Analyze(exp->mLeft, procDec));
|
||||
|
|
|
@ -85,7 +85,7 @@ void IntegerValueRange::LimitMaxBound(int64 value)
|
|||
|
||||
void IntegerValueRange::LimitMinWeak(int64 value)
|
||||
{
|
||||
if (mMinState == S_UNBOUND || mMinValue < value)
|
||||
if (mMinState == S_UNBOUND || mMinState != S_UNKNOWN && mMinValue < value)
|
||||
{
|
||||
mMinState = S_BOUND;
|
||||
mMinValue = value;
|
||||
|
@ -95,7 +95,7 @@ void IntegerValueRange::LimitMinWeak(int64 value)
|
|||
|
||||
void IntegerValueRange::LimitMaxWeak(int64 value)
|
||||
{
|
||||
if (mMaxState == S_UNBOUND || mMaxValue > value)
|
||||
if (mMaxState == S_UNBOUND || mMinState != S_UNKNOWN && mMaxValue > value)
|
||||
{
|
||||
mMaxState = S_BOUND;
|
||||
mMaxValue = value;
|
||||
|
@ -6130,6 +6130,7 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray
|
|||
default:
|
||||
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (ins->mDst.mType == IT_INT8)
|
||||
{
|
||||
|
@ -6600,6 +6601,11 @@ void InterCodeBasicBlock::RestartLocalIntegerRangeSets(int num, const GrowingVar
|
|||
mMemoryValueSize.SetSize(num, false);
|
||||
mEntryMemoryValueSize.SetSize(num, false);
|
||||
|
||||
mEntryParamValueRange.SetSize(paramVars.Size(), false);
|
||||
mTrueParamValueRange.SetSize(paramVars.Size(), false);
|
||||
mFalseParamValueRange.SetSize(paramVars.Size(), false);
|
||||
mLocalParamValueRange.SetSize(paramVars.Size(), false);
|
||||
|
||||
for (int i = 0; i < mEntryValueRange.Size(); i++)
|
||||
{
|
||||
IntegerValueRange& vr(mEntryValueRange[i]);
|
||||
|
@ -10080,7 +10086,7 @@ void ApplyStaticStack(InterOperand & iop, const GrowingVariableArray& localVars)
|
|||
iop.mMemory = IM_GLOBAL;
|
||||
iop.mLinkerObject = localVars[iop.mVarIndex]->mLinkerObject;
|
||||
iop.mVarIndex = localVars[iop.mVarIndex]->mIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVariableArray& localVars)
|
||||
|
@ -10095,7 +10101,7 @@ void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVa
|
|||
lobj->mStackSection->mSections.Push(mInstructions[i]->mSrc[0].mLinkerObject->mStackSection);
|
||||
|
||||
if (mInstructions[i]->mCode == IC_LOAD)
|
||||
ApplyStaticStack(mInstructions[i]->mSrc[0], localVars);
|
||||
ApplyStaticStack(mInstructions[i]->mSrc[0],localVars);
|
||||
else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA)
|
||||
ApplyStaticStack(mInstructions[i]->mSrc[1], localVars);
|
||||
else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER)
|
||||
|
@ -10112,6 +10118,47 @@ void InterCodeBasicBlock::CollectStaticStack(LinkerObject* lobj, const GrowingVa
|
|||
}
|
||||
}
|
||||
|
||||
void PromoteStaticStackParam(InterOperand& iop, LinkerObject* paramlobj)
|
||||
{
|
||||
if (iop.mMemory == IM_FFRAME || iop.mMemory == IM_FPARAM)
|
||||
{
|
||||
if (iop.mVarIndex >= BC_REG_FPARAMS_END - BC_REG_FPARAMS)
|
||||
{
|
||||
int offset = iop.mVarIndex - (BC_REG_FPARAMS_END - BC_REG_FPARAMS);
|
||||
iop.mMemory = IM_GLOBAL;
|
||||
iop.mIntConst += offset;
|
||||
iop.mLinkerObject = paramlobj;
|
||||
paramlobj->EnsureSpace(iop.mIntConst, iop.mOperandSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::PromoteStaticStackParams(LinkerObject* paramlobj)
|
||||
{
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
if (mInstructions[i]->mCode == IC_LOAD)
|
||||
PromoteStaticStackParam(mInstructions[i]->mSrc[0], paramlobj);
|
||||
else if (mInstructions[i]->mCode == IC_STORE || mInstructions[i]->mCode == IC_LEA)
|
||||
PromoteStaticStackParam(mInstructions[i]->mSrc[1], paramlobj);
|
||||
else if (mInstructions[i]->mCode == IC_CONSTANT && mInstructions[i]->mDst.mType == IT_POINTER)
|
||||
PromoteStaticStackParam(mInstructions[i]->mConst, paramlobj);
|
||||
else if (mInstructions[i]->mCode == IC_COPY)
|
||||
{
|
||||
PromoteStaticStackParam(mInstructions[i]->mSrc[0], paramlobj);
|
||||
PromoteStaticStackParam(mInstructions[i]->mSrc[1], paramlobj);
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->PromoteStaticStackParams(paramlobj);
|
||||
if (mFalseJump) mFalseJump->PromoteStaticStackParams(paramlobj);
|
||||
}
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::DropUnreachable(void)
|
||||
{
|
||||
if (!mVisited)
|
||||
|
@ -14333,6 +14380,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
mLinkerObject->mFlags |= LOBJF_STATIC_STACK;
|
||||
mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent->Mangle("@stack"), LST_STATIC_STACK);
|
||||
mLinkerObject->mStackSection->mSections.Push(mModule->mParamLinkerSection);
|
||||
|
||||
for (int i = 0; i < mLocalVars.Size(); i++)
|
||||
{
|
||||
|
@ -14458,14 +14506,17 @@ void InterCodeProcedure::Close(void)
|
|||
|
||||
MapCallerSavedTemps();
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->PromoteStaticStackParams(mModule->mParamLinkerObject);
|
||||
|
||||
if (mValueReturn)
|
||||
{
|
||||
ResetVisited();
|
||||
mEntryBlock->CheckValueReturn(this);
|
||||
}
|
||||
|
||||
if (mSaveTempsLinkerObject && mTempSize > 16)
|
||||
mSaveTempsLinkerObject->AddSpace(mTempSize - 16);
|
||||
if (mSaveTempsLinkerObject && mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP)
|
||||
mSaveTempsLinkerObject->AddSpace(mTempSize - (BC_REG_TMP_SAVED - BC_REG_TMP));
|
||||
}
|
||||
|
||||
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)
|
||||
|
@ -14867,10 +14918,10 @@ void InterCodeProcedure::MapCallerSavedTemps(void)
|
|||
ResetVisited();
|
||||
mEntryBlock->BuildCallerSaveTempSet(callerSaved);
|
||||
|
||||
int callerSavedTemps = 0, calleeSavedTemps = 16, freeCallerSavedTemps = 0, freeTemps = 0;
|
||||
int callerSavedTemps = 0, calleeSavedTemps = BC_REG_TMP_SAVED - BC_REG_TMP, freeCallerSavedTemps = 0, freeTemps = 0;
|
||||
|
||||
if (mCallsFunctionPointer)
|
||||
freeCallerSavedTemps = 16;
|
||||
freeCallerSavedTemps = BC_REG_TMP_SAVED - BC_REG_TMP;
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < mCalledFunctions.Size(); i++)
|
||||
|
@ -14939,8 +14990,8 @@ void InterCodeProcedure::MapCallerSavedTemps(void)
|
|||
printf("T%02d : %d, %d\n", i, mTempOffset[i], mTempSizes[i]);
|
||||
#endif
|
||||
|
||||
if (mSaveTempsLinkerObject && mTempSize > 16)
|
||||
mSaveTempsLinkerObject->AddSpace(mTempSize - 16);
|
||||
if (mSaveTempsLinkerObject && mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP)
|
||||
mSaveTempsLinkerObject->AddSpace(mTempSize - (BC_REG_TMP_SAVED - BC_REG_TMP));
|
||||
|
||||
// printf("Map %s, %d, %d, %d, %d\n", mIdent->mString, freeTemps, callerSavedTemps, calleeSavedTemps, freeCallerSavedTemps);
|
||||
}
|
||||
|
@ -15004,7 +15055,7 @@ void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
|
|||
}
|
||||
|
||||
InterCodeModule::InterCodeModule(Errors* errors, Linker * linker)
|
||||
: mErrors(errors), mLinker(linker), mGlobalVars(nullptr), mProcedures(nullptr), mCompilerOptions(0)
|
||||
: mErrors(errors), mLinker(linker), mGlobalVars(nullptr), mProcedures(nullptr), mCompilerOptions(0), mParamLinkerObject(nullptr), mParamLinkerSection(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15013,6 +15064,15 @@ InterCodeModule::~InterCodeModule(void)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void InterCodeModule::InitParamStack(LinkerSection* stackSection)
|
||||
{
|
||||
mParamLinkerSection = mLinker->AddSection(Ident::Unique("sstack"), LST_STATIC_STACK);
|
||||
stackSection->mSections.Push(mParamLinkerSection);
|
||||
|
||||
mParamLinkerObject = mLinker->AddObject(Location(), Ident::Unique("sstack"), mParamLinkerSection, LOT_STACK);
|
||||
}
|
||||
|
||||
bool InterCodeModule::Disassemble(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
|
|
|
@ -518,6 +518,7 @@ public:
|
|||
|
||||
bool CheckStaticStack(void);
|
||||
void CollectStaticStack(LinkerObject * lobj, const GrowingVariableArray& localVars);
|
||||
void PromoteStaticStackParams(LinkerObject* paramlobj);
|
||||
|
||||
bool SameExitCode(const InterCodeBasicBlock* block) const;
|
||||
|
||||
|
@ -622,11 +623,15 @@ public:
|
|||
InterCodeModule(Errors* errors, Linker * linker);
|
||||
~InterCodeModule(void);
|
||||
|
||||
void InitParamStack(LinkerSection * stackSection);
|
||||
|
||||
bool Disassemble(const char* name);
|
||||
|
||||
GrowingInterCodeProcedurePtrArray mProcedures;
|
||||
|
||||
GrowingVariableArray mGlobalVars;
|
||||
LinkerObject * mParamLinkerObject;
|
||||
LinkerSection * mParamLinkerSection;
|
||||
|
||||
Linker * mLinker;
|
||||
Errors* mErrors;
|
||||
|
|
|
@ -704,6 +704,186 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
|
|||
}
|
||||
}
|
||||
|
||||
InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr)
|
||||
{
|
||||
Declaration* dec;
|
||||
ExValue vl, vr;
|
||||
|
||||
Declaration* fdec = exp->mLeft->mDecValue;
|
||||
Expression* fexp = fdec->mValue;
|
||||
Declaration* ftype = fdec->mBase;
|
||||
|
||||
InlineMapper nmapper;
|
||||
nmapper.mReturn = new InterCodeBasicBlock();
|
||||
nmapper.mVarIndex = proc->mNumLocals;
|
||||
nmapper.mConstExpr = inlineConstexpr;
|
||||
proc->mNumLocals += fdec->mNumVars;
|
||||
if (inlineMapper)
|
||||
nmapper.mDepth = inlineMapper->mDepth + 1;
|
||||
proc->Append(nmapper.mReturn);
|
||||
|
||||
Declaration* pdec = ftype->mParams;
|
||||
Expression* pex = exp->mRight;
|
||||
while (pex)
|
||||
{
|
||||
int nindex = proc->mNumLocals++;
|
||||
Declaration* vdec = new Declaration(pex->mLocation, DT_VARIABLE);
|
||||
|
||||
InterInstruction* ains = new InterInstruction(pex->mLocation, IC_CONSTANT);
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||
ains->mConst.mMemory = IM_LOCAL;
|
||||
ains->mConst.mVarIndex = nindex;
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
nmapper.mParams[pdec->mVarIndex] = nindex;
|
||||
|
||||
vdec->mVarIndex = nindex;
|
||||
vdec->mBase = pdec->mBase;
|
||||
if (pdec->mBase->mType == DT_TYPE_ARRAY)
|
||||
ains->mConst.mOperandSize = 2;
|
||||
else
|
||||
ains->mConst.mOperandSize = pdec->mSize;
|
||||
vdec->mSize = ains->mConst.mOperandSize;
|
||||
vdec->mIdent = pdec->mIdent;
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(pex->mLocation, EERR_WRONG_PARAMETER, "Too many arguments for function call");
|
||||
}
|
||||
|
||||
block->Append(ains);
|
||||
|
||||
Expression* texp;
|
||||
|
||||
if (pex->mType == EX_LIST)
|
||||
{
|
||||
texp = pex->mLeft;
|
||||
pex = pex->mRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
texp = pex;
|
||||
pex = nullptr;
|
||||
}
|
||||
|
||||
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
|
||||
|
||||
vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper, &vp);
|
||||
|
||||
if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)
|
||||
{
|
||||
if (pdec && !pdec->mBase->CanAssign(vr.mType))
|
||||
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||
|
||||
vr = Dereference(proc, texp, block, vr, 1);
|
||||
|
||||
if (vr.mReference != 1)
|
||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an adressable expression");
|
||||
|
||||
if (vp.mTemp != vr.mTemp)
|
||||
{
|
||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
|
||||
|
||||
cins->mSrc[0].mType = IT_POINTER;
|
||||
cins->mSrc[0].mTemp = vr.mTemp;
|
||||
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||
cins->mSrc[0].mOperandSize = vr.mType->mSize;
|
||||
cins->mSrc[0].mStride = vr.mType->mStripe;
|
||||
|
||||
cins->mSrc[1].mType = IT_POINTER;
|
||||
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
cins->mSrc[1].mOperandSize = vr.mType->mSize;
|
||||
|
||||
cins->mConst.mOperandSize = vr.mType->mSize;
|
||||
block->Append(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
|
||||
vr = Dereference(proc, texp, block, vr, 1);
|
||||
else
|
||||
vr = Dereference(proc, texp, block, vr);
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (!pdec->mBase->CanAssign(vr.mType))
|
||||
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||
vr = CoerceType(proc, texp, block, vr, pdec->mBase);
|
||||
}
|
||||
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
|
||||
{
|
||||
vr = CoerceType(proc, texp, block, vr, TheSignedIntTypeDeclaration);
|
||||
}
|
||||
|
||||
InterInstruction* wins = new InterInstruction(texp->mLocation, IC_STORE);
|
||||
wins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
|
||||
wins->mSrc[0].mTemp = vr.mTemp;
|
||||
wins->mSrc[1].mType = IT_POINTER;
|
||||
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||
if (pdec)
|
||||
{
|
||||
if (pdec->mBase->mType == DT_TYPE_ARRAY)
|
||||
wins->mSrc[1].mOperandSize = 2;
|
||||
else
|
||||
wins->mSrc[1].mOperandSize = pdec->mSize;
|
||||
}
|
||||
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY)
|
||||
wins->mSrc[1].mOperandSize = vr.mType->mSize;
|
||||
else
|
||||
wins->mSrc[1].mOperandSize = 2;
|
||||
block->Append(wins);
|
||||
}
|
||||
|
||||
if (pdec)
|
||||
pdec = pdec->mNext;
|
||||
}
|
||||
|
||||
if (pdec)
|
||||
mErrors->Error(exp->mLocation, EERR_WRONG_PARAMETER, "Not enough arguments for function call");
|
||||
|
||||
Declaration* rdec = nullptr;
|
||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
||||
{
|
||||
int nindex = proc->mNumLocals++;
|
||||
nmapper.mResult = nindex;
|
||||
|
||||
rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
|
||||
rdec->mVarIndex = nindex;
|
||||
rdec->mBase = ftype->mBase;
|
||||
rdec->mSize = rdec->mBase->mSize;
|
||||
}
|
||||
|
||||
vl = TranslateExpression(ftype, proc, block, fexp, nullptr, nullptr, &nmapper);
|
||||
|
||||
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||
block->Append(jins);
|
||||
|
||||
block->Close(nmapper.mReturn, nullptr);
|
||||
block = nmapper.mReturn;
|
||||
|
||||
if (rdec)
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
ins->mDst.mType = IT_POINTER;
|
||||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||
ins->mConst.mOperandSize = rdec->mSize;
|
||||
ins->mConst.mIntConst = rdec->mOffset;
|
||||
ins->mConst.mVarIndex = rdec->mVarIndex;
|
||||
ins->mConst.mMemory = IM_LOCAL;
|
||||
|
||||
block->Append(ins);
|
||||
|
||||
return ExValue(rdec->mBase, ins->mDst.mTemp, 1);
|
||||
}
|
||||
else
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
}
|
||||
|
||||
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, ExValue* lrexp)
|
||||
{
|
||||
Declaration* dec;
|
||||
|
@ -2048,179 +2228,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
if (doInline)
|
||||
{
|
||||
Declaration* fdec = exp->mLeft->mDecValue;
|
||||
Expression* fexp = fdec->mValue;
|
||||
Declaration* ftype = fdec->mBase;
|
||||
|
||||
InlineMapper nmapper;
|
||||
nmapper.mReturn = new InterCodeBasicBlock();
|
||||
nmapper.mVarIndex = proc->mNumLocals;
|
||||
nmapper.mConstExpr = inlineConstexpr;
|
||||
proc->mNumLocals += fdec->mNumVars;
|
||||
if (inlineMapper)
|
||||
nmapper.mDepth = inlineMapper->mDepth + 1;
|
||||
proc->Append(nmapper.mReturn);
|
||||
|
||||
Declaration* pdec = ftype->mParams;
|
||||
Expression* pex = exp->mRight;
|
||||
while (pex)
|
||||
{
|
||||
int nindex = proc->mNumLocals++;
|
||||
Declaration* vdec = new Declaration(pex->mLocation, DT_VARIABLE);
|
||||
|
||||
InterInstruction* ains = new InterInstruction(pex->mLocation, IC_CONSTANT);
|
||||
ains->mDst.mType = IT_POINTER;
|
||||
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||
ains->mConst.mMemory = IM_LOCAL;
|
||||
ains->mConst.mVarIndex = nindex;
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
nmapper.mParams[pdec->mVarIndex] = nindex;
|
||||
|
||||
vdec->mVarIndex = nindex;
|
||||
vdec->mBase = pdec->mBase;
|
||||
if (pdec->mBase->mType == DT_TYPE_ARRAY)
|
||||
ains->mConst.mOperandSize = 2;
|
||||
else
|
||||
ains->mConst.mOperandSize = pdec->mSize;
|
||||
vdec->mSize = ains->mConst.mOperandSize;
|
||||
vdec->mIdent = pdec->mIdent;
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(pex->mLocation, EERR_WRONG_PARAMETER, "Too many arguments for function call");
|
||||
}
|
||||
|
||||
block->Append(ains);
|
||||
|
||||
Expression* texp;
|
||||
|
||||
if (pex->mType == EX_LIST)
|
||||
{
|
||||
texp = pex->mLeft;
|
||||
pex = pex->mRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
texp = pex;
|
||||
pex = nullptr;
|
||||
}
|
||||
|
||||
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
|
||||
|
||||
vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper, &vp);
|
||||
|
||||
if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)
|
||||
{
|
||||
if (pdec && !pdec->mBase->CanAssign(vr.mType))
|
||||
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||
|
||||
vr = Dereference(proc, texp, block, vr, 1);
|
||||
|
||||
if (vr.mReference != 1)
|
||||
mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an adressable expression");
|
||||
|
||||
if (vp.mTemp != vr.mTemp)
|
||||
{
|
||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
|
||||
|
||||
cins->mSrc[0].mType = IT_POINTER;
|
||||
cins->mSrc[0].mTemp = vr.mTemp;
|
||||
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||
cins->mSrc[0].mOperandSize = vr.mType->mSize;
|
||||
cins->mSrc[0].mStride = vr.mType->mStripe;
|
||||
|
||||
cins->mSrc[1].mType = IT_POINTER;
|
||||
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
cins->mSrc[1].mOperandSize = vr.mType->mSize;
|
||||
|
||||
cins->mConst.mOperandSize = vr.mType->mSize;
|
||||
block->Append(cins);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)
|
||||
vr = Dereference(proc, texp, block, vr, 1);
|
||||
else
|
||||
vr = Dereference(proc, texp, block, vr);
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (!pdec->mBase->CanAssign(vr.mType))
|
||||
mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types");
|
||||
vr = CoerceType(proc, texp, block, vr, pdec->mBase);
|
||||
}
|
||||
else if (vr.mType->IsIntegerType() && vr.mType->mSize < 2)
|
||||
{
|
||||
vr = CoerceType(proc, texp, block, vr, TheSignedIntTypeDeclaration);
|
||||
}
|
||||
|
||||
InterInstruction* wins = new InterInstruction(texp->mLocation, IC_STORE);
|
||||
wins->mSrc[1].mMemory = IM_INDIRECT;
|
||||
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
|
||||
wins->mSrc[0].mTemp = vr.mTemp;
|
||||
wins->mSrc[1].mType = IT_POINTER;
|
||||
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||
if (pdec)
|
||||
{
|
||||
if (pdec->mBase->mType == DT_TYPE_ARRAY)
|
||||
wins->mSrc[1].mOperandSize = 2;
|
||||
else
|
||||
wins->mSrc[1].mOperandSize = pdec->mSize;
|
||||
}
|
||||
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY)
|
||||
wins->mSrc[1].mOperandSize = vr.mType->mSize;
|
||||
else
|
||||
wins->mSrc[1].mOperandSize = 2;
|
||||
block->Append(wins);
|
||||
}
|
||||
|
||||
if (pdec)
|
||||
pdec = pdec->mNext;
|
||||
}
|
||||
|
||||
if (pdec)
|
||||
mErrors->Error(exp->mLocation, EERR_WRONG_PARAMETER, "Not enough arguments for function call");
|
||||
|
||||
Declaration* rdec = nullptr;
|
||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
||||
{
|
||||
int nindex = proc->mNumLocals++;
|
||||
nmapper.mResult = nindex;
|
||||
|
||||
rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
|
||||
rdec->mVarIndex = nindex;
|
||||
rdec->mBase = ftype->mBase;
|
||||
rdec->mSize = rdec->mBase->mSize;
|
||||
}
|
||||
|
||||
vl = TranslateExpression(ftype, proc, block, fexp, nullptr, nullptr, &nmapper);
|
||||
|
||||
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||
block->Append(jins);
|
||||
|
||||
block->Close(nmapper.mReturn, nullptr);
|
||||
block = nmapper.mReturn;
|
||||
|
||||
if (rdec)
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||
ins->mDst.mType = IT_POINTER;
|
||||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||
ins->mConst.mOperandSize = rdec->mSize;
|
||||
ins->mConst.mIntConst = rdec->mOffset;
|
||||
ins->mConst.mVarIndex = rdec->mVarIndex;
|
||||
ins->mConst.mMemory = IM_LOCAL;
|
||||
|
||||
block->Append(ins);
|
||||
|
||||
return ExValue(rdec->mBase, ins->mDst.mTemp, 1);
|
||||
}
|
||||
else
|
||||
return ExValue(TheVoidTypeDeclaration);
|
||||
return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -58,6 +58,7 @@ protected:
|
|||
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
|
||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
|
||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, InlineMapper* inlineMapper);
|
||||
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr);
|
||||
|
||||
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
|
||||
};
|
||||
|
|
|
@ -71,6 +71,12 @@ void LinkerObject::AddData(const uint8* data, int size)
|
|||
memcpy(mData, data, size);
|
||||
}
|
||||
|
||||
void LinkerObject::EnsureSpace(int offset, int size)
|
||||
{
|
||||
if (offset + size > mSize)
|
||||
AddSpace(offset + size);
|
||||
}
|
||||
|
||||
uint8* LinkerObject::AddSpace(int size)
|
||||
{
|
||||
if (mSize != size)
|
||||
|
|
|
@ -174,6 +174,7 @@ public:
|
|||
|
||||
void AddData(const uint8* data, int size);
|
||||
uint8* AddSpace(int size);
|
||||
void EnsureSpace(int offset, int size);
|
||||
|
||||
GrowingArray<LinkerReference*> mReferences;
|
||||
|
||||
|
|
|
@ -13750,6 +13750,83 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
|||
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
#if 1
|
||||
if (i + 6 < mIns.Size())
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x00 &&
|
||||
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||
mIns[i + 4].mType == ASMIT_EOR && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0xff &&
|
||||
mIns[i + 5].mType == ASMIT_ASL && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 0].mAddress &&
|
||||
mIns[i + 6].mType == ASMIT_ROL && mIns[i + 6].mMode == ASMIM_IMPLIED)
|
||||
{
|
||||
changed = true;
|
||||
|
||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||
NativeCodeBasicBlock* neblock = proc->AllocateBlock();
|
||||
NativeCodeBasicBlock* rblock = proc->AllocateBlock();
|
||||
|
||||
rblock->mTrueJump = mTrueJump;
|
||||
rblock->mFalseJump = mFalseJump;
|
||||
rblock->mBranch = mBranch;
|
||||
|
||||
for (int j = i + 7; j < mIns.Size(); j++)
|
||||
rblock->mIns.Push(mIns[j]);
|
||||
mIns.SetSize(i + 1);
|
||||
mIns[i + 0].mLive |= LIVE_CPU_REG_C;
|
||||
mIns[i + 0].mType = ASMIT_ASL;
|
||||
|
||||
mTrueJump = neblock;
|
||||
mFalseJump = eblock;
|
||||
mBranch = ASMIT_BCS;
|
||||
|
||||
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
neblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0xff));
|
||||
|
||||
eblock->Close(rblock, nullptr, ASMIT_JMP);
|
||||
neblock->Close(rblock, nullptr, ASMIT_JMP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x00 &&
|
||||
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||
mIns[i + 4].mType == ASMIT_EOR && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0xff &&
|
||||
mIns[i + 5].mType == ASMIT_ASL && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 0].mAddress &&
|
||||
mIns[i + 6].mType == ASMIT_ROL && mIns[i + 6].mMode == ASMIM_IMPLIED)
|
||||
{
|
||||
changed = true;
|
||||
|
||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||
NativeCodeBasicBlock* neblock = proc->AllocateBlock();
|
||||
NativeCodeBasicBlock* rblock = proc->AllocateBlock();
|
||||
|
||||
rblock->mTrueJump = mTrueJump;
|
||||
rblock->mFalseJump = mFalseJump;
|
||||
rblock->mBranch = mBranch;
|
||||
|
||||
for (int j = i + 7; j < mIns.Size(); j++)
|
||||
rblock->mIns.Push(mIns[j]);
|
||||
mIns.SetSize(i + 1);
|
||||
mIns[i + 0].mLive |= LIVE_CPU_REG_C;
|
||||
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_ASL));
|
||||
|
||||
mTrueJump = neblock;
|
||||
mFalseJump = eblock;
|
||||
mBranch = ASMIT_BCS;
|
||||
|
||||
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
neblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0xff));
|
||||
|
||||
eblock->Close(rblock, nullptr, ASMIT_JMP);
|
||||
neblock->Close(rblock, nullptr, ASMIT_JMP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
if (i + 6 < mIns.Size())
|
||||
{
|
||||
|
@ -16415,6 +16492,27 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
|
|||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (mIns.Size() >= 1 && mIns[0].mType == ASMIT_TAY && !(mIns[0].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mEntryRegA)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < mEntryBlocks.Size() && mEntryBlocks[i]->mIns.Size() > 0 && mEntryBlocks[i]->mIns.Last().mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mEntryBlocks[i]->mIns.Last().mMode) && !mEntryBlocks[i]->mFalseJump)
|
||||
i++;
|
||||
if (i == mEntryBlocks.Size())
|
||||
{
|
||||
for (int i = 0; i < mEntryBlocks.Size(); i++)
|
||||
{
|
||||
NativeCodeBasicBlock* b = mEntryBlocks[i];
|
||||
int sz = b->mIns.Size();
|
||||
b->mIns[sz - 1].mType = ASMIT_LDY;
|
||||
b->mIns[sz - 1].mLive |= LIVE_CPU_REG_Y;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
mIns[0].mType = ASMIT_NOP; mIns[0].mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (mIns.Size() >= 1 && mIns[0].mMode == ASMIM_ABSOLUTE_X && !(mIns[0].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_Z)))
|
||||
{
|
||||
|
@ -21860,13 +21958,24 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
#endif
|
||||
// Check load and commutative with current accu value
|
||||
#if 1
|
||||
if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_LDA && mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mValue == mIns[i + 1].mAddress)
|
||||
if (i + 1 < mIns.Size() && mIns[i].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mValue == mIns[i + 1].mAddress)
|
||||
{
|
||||
mIns[i].mType = mIns[i + 1].mType;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
changed = true;
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
if (i + 2 < mIns.Size() && mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_CLC &&
|
||||
mIns[i + 2].IsCommutative() && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mMode == NRDM_ZERO_PAGE && mNDataSet.mRegs[CPU_REG_A].mValue == mIns[i + 2].mAddress)
|
||||
{
|
||||
mIns[i + 2].CopyMode(mIns[i + 0]);
|
||||
mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED;
|
||||
changed = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mIns[i].ValueForwarding(mNDataSet, carryop, !global, final))
|
||||
changed = true;
|
||||
if (carryop != ASMIT_NOP)
|
||||
|
@ -31860,7 +31969,7 @@ void NativeCodeProcedure::CompressTemporaries(void)
|
|||
else
|
||||
mInterProc->mTempSize = tpos - BC_REG_TMP;
|
||||
|
||||
if (mNoFrame && !used[BC_REG_STACK] && mInterProc->mTempSize <= 16)
|
||||
if (mNoFrame && !used[BC_REG_STACK] && mInterProc->mTempSize <= BC_REG_TMP_SAVED - BC_REG_TMP)
|
||||
mStackExpand = 0;
|
||||
}
|
||||
}
|
||||
|
@ -31924,7 +32033,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
|
||||
mIndex = proc->mID;
|
||||
|
||||
int tempSave = proc->mTempSize > 16 && !proc->mSaveTempsLinkerObject && !mInterProc->mInterrupt ? proc->mTempSize - 16 : 0;
|
||||
int tempSave = proc->mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP && !proc->mSaveTempsLinkerObject && !mInterProc->mInterrupt ? proc->mTempSize - (BC_REG_TMP_SAVED - BC_REG_TMP) : 0;
|
||||
int commonFrameSize = proc->mCommonFrameSize;
|
||||
|
||||
mStackExpand = tempSave + proc->mLocalSize;
|
||||
|
@ -32007,7 +32116,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
|
||||
int frameSpace = tempSave;
|
||||
|
||||
tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0;
|
||||
tempSave = proc->mTempSize > BC_REG_TMP_SAVED - BC_REG_TMP ? proc->mTempSize - (BC_REG_TMP_SAVED - BC_REG_TMP) : 0;
|
||||
|
||||
if (!(mGenerator->mCompilerOptions & COPT_NATIVE))
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea));
|
||||
|
|
|
@ -74,7 +74,7 @@ int main2(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.13.178");
|
||||
strcpy(strProductVersion, "1.14.179");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
@ -206,6 +206,10 @@ int main2(int argc, const char** argv)
|
|||
if (arg[2] == '2')
|
||||
compiler->mCompilerOptions |= COPT_VERBOSE2;
|
||||
}
|
||||
else if (arg[1] == 'x' && arg[2] == 'z')
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_EXTENDED_ZERO_PAGE;
|
||||
}
|
||||
else
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,13,178,0
|
||||
PRODUCTVERSION 1,13,178,0
|
||||
FILEVERSION 1,14,179,0
|
||||
PRODUCTVERSION 1,14,179,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.13.178.0"
|
||||
VALUE "FileVersion", "1.14.179.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.13.178.0"
|
||||
VALUE "ProductVersion", "1.14.179.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -4450,15 +4450,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{9F4E2BAD-97D8-4D1A-981F-D6B719A704C0}"
|
||||
"PackageCode" = "8:{9749B605-800D-406D-A8C7-759AA28CA93D}"
|
||||
"ProductCode" = "8:{28347196-C1B9-4B31-9AAB-50EC7E4BFC8E}"
|
||||
"PackageCode" = "8:{F19F2B8B-8649-4939-B1FA-8EF0A6862DD7}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.13.178"
|
||||
"ProductVersion" = "8:1.14.179"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
|
@ -548,6 +548,7 @@ void screen_clear(void)
|
|||
|
||||
__interrupt void joy_interrupt()
|
||||
{
|
||||
// vic.color_border++;
|
||||
// Poll joystick
|
||||
joy_poll(0);
|
||||
|
||||
|
@ -580,6 +581,7 @@ __interrupt void joy_interrupt()
|
|||
}
|
||||
else if (CrossDelay > 0)
|
||||
CrossDelay--;
|
||||
// vic.color_border--;
|
||||
}
|
||||
|
||||
enum GameState
|
||||
|
@ -843,7 +845,7 @@ int main(void)
|
|||
rirq_write(&bottom, 0, &vic.memptr, 0x27);
|
||||
rirq_write(&bottom, 1, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3);
|
||||
rirq_call(&bottom, 2, joy_interrupt);
|
||||
rirq_set(1, 250, &bottom);
|
||||
rirq_set(1, 252, &bottom);
|
||||
|
||||
// sort the raster IRQs
|
||||
rirq_sort();
|
||||
|
|
Loading…
Reference in New Issue